home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / raytrace / radiance / simplerd.lha / simplerad / FinalFTP / WalkT / scene.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-05-22  |  10.0 KB  |  291 lines

  1. /**********************************************************************/
  2. /* scene.c                                                            */
  3. /*                                                                    */
  4. /* Read in polygons from and input file of format:                    */
  5. /*                                                                    */
  6. /* Number polygons <number-polygons>                                  */
  7. /* Polgon_Info                                                        */
  8. /* where:                                                             */
  9. /*  Polygon_Info = Polygon [Polygon_Info]                             */
  10. /*  Polygon = Poly <poly-name><id> <#vertices> {                      */
  11. /*              colour norm vert }                                    */
  12. /*  colour = B { { vec } { vect } ... }                               */
  13. /*  vert = vert { vertices }                                          */
  14. /*  norm  = norm { normals }                                          */
  15. /*  vertices = { vec } { vec } ...                                    */
  16. /*  normals  = { vec } { vec } ...                                    */
  17. /*  vec = val val val                                                 */
  18. /*  val = floating point value                                        */
  19. /*                                                                    */
  20. /* Copyright (C) 1992, Bernard Kwok                                   */
  21. /* All rights reserved.                                               */
  22. /* Revision 1.0                                                       */
  23. /* May, 1992                                                          */
  24. /**********************************************************************/
  25. #include <stdio.h>
  26. #include <string.h>
  27. #include "geo.h"
  28. #include "scene.h"
  29.  
  30. /**********************************************************************/
  31. #define Read_EndMarker(fp) (fscanf(fp," }\n"))
  32. #define Print_EndMarker(fp) (printf(" }\n"))
  33.  
  34. SMesh Scene;                    /* Input scene */
  35. SLogType ReadLog;               /* Input log */
  36. float tmpf[5];                  /* For floating pt reading only ! */
  37. FILE *meshf;                    /* File of input polygons */ 
  38. char *meshfilename;
  39.  
  40. void ReadScene();
  41. void Read_SPolygon();
  42. void Print_Vector();
  43. void Read_Vector();
  44. extern char *ProgName;
  45. extern void *SpectraToRGB();
  46.  
  47. /**********************************************************************/
  48. /* Initialize size of world */
  49. /**********************************************************************/
  50. void Init_WorldSize(rlog)
  51.      SLogType *rlog;
  52. {
  53.   rlog->worldbox.min.x = VERY_LARGE / 2.0;
  54.   rlog->worldbox.min.y = VERY_LARGE / 2.0;
  55.   rlog->worldbox.min.z = VERY_LARGE / 2.0;
  56.   rlog->worldbox.max.x = -VERY_LARGE / 2.0;
  57.   rlog->worldbox.max.y = -VERY_LARGE / 2.0;
  58.   rlog->worldbox.max.z = -VERY_LARGE / 2.0;
  59.   rlog->worldSize = VERY_LARGE / 2.0;
  60. }
  61.  
  62. /**********************************************************************/
  63. /* Find minimum axis aligned bounding box size for the world */
  64. /**********************************************************************/
  65. void Update_WorldSize(pt)
  66.      Vector pt;
  67. {
  68.   if (pt.x > ReadLog.worldbox.max.x)  ReadLog.worldbox.max.x = pt.x;
  69.   if (pt.y > ReadLog.worldbox.max.y)  ReadLog.worldbox.max.y = pt.y;
  70.   if (pt.z > ReadLog.worldbox.max.z)  ReadLog.worldbox.max.z = pt.z;
  71.  
  72.   if (pt.x < ReadLog.worldbox.min.x)  ReadLog.worldbox.min.x = pt.x;
  73.   if (pt.y < ReadLog.worldbox.min.y)  ReadLog.worldbox.min.y = pt.y;
  74.   if (pt.z < ReadLog.worldbox.min.z)  ReadLog.worldbox.min.z = pt.z;
  75. }
  76.  
  77. /**********************************************************************/
  78. /* Make bounding sphere and bounding box of world */
  79. /**********************************************************************/
  80. void BoxWorld(rlog)
  81.      SLogType *rlog;
  82. {
  83.   if (rlog->worldbox.min.x > rlog->worldbox.max.x) {
  84.     printf("Oh oh. the world min is greater than the max!\n");
  85.     exit(1);
  86.   }
  87.   rlog->worldbox.min.x -= ENLARGE_WORLD;
  88.   rlog->worldbox.min.y -= ENLARGE_WORLD;
  89.   rlog->worldbox.min.z -= ENLARGE_WORLD;
  90.   rlog->worldbox.max.x += ENLARGE_WORLD;
  91.   rlog->worldbox.max.y += ENLARGE_WORLD;
  92.   rlog->worldbox.max.z += ENLARGE_WORLD;
  93.  
  94.   rlog->worldSize = 0.5 * (vdist(&(rlog->worldbox.max), 
  95.                  &(rlog->worldbox.min)) + 0.5);
  96. }
  97.  
  98. /**********************************************************************/
  99. /* Print a vector                                                     */
  100. /**********************************************************************/
  101. void Print_Vector(v)
  102.      Vector *v;
  103. { printf(" { %g %g %g }", v->x, v->y, v->z); }
  104.  
  105. /**********************************************************************/
  106. /* Read a vector                                                      */
  107. /**********************************************************************/
  108. void Read_Vector(fp, v)
  109.      FILE *fp;
  110.      Vector *v;
  111. {
  112.   fscanf(fp, " { %g %g %g }", &tmpf[0], &tmpf[1], &tmpf[2]);
  113.   v->x = tmpf[0]; v->y = tmpf[1]; v->z = tmpf[2];
  114. }
  115.  
  116. /**********************************************************************/
  117. /* Read in a polygon                                                  */
  118. /**********************************************************************/
  119. void Read_SPolygon(pptr)
  120.      SPolygon *pptr;
  121. {
  122.   int i;
  123.   char *tmp = "                   ";
  124.   int no_patch_colour, no_vtx_colour;
  125.  
  126.   /* Read in name and number of vertices for the patch */
  127.   fscanf(meshf,"Poly %s %d {", tmp, &(pptr->numVert));
  128.   pptr->id = ReadLog.totpoly++;
  129.   if (ReadLog.log) printf("Poly %s %d {\n", tmp, pptr->numVert);
  130.   
  131.   /* Set id and type */
  132.   if (pptr->numVert == 4) {
  133.     pptr->name = PATCH_ID;
  134.     pptr->class = PATCH;
  135.   } else if (pptr->numVert == 3) {
  136.     pptr->name = TRI_ID;
  137.     pptr->class = TRIANGLE;
  138.   } else {
  139.     fprintf(stderr, "Sorry, only quadtralaterals and triangles allowed\n");
  140.     exit(1);
  141.   }
  142.  
  143.   /* Read patch average colour */
  144.   fscanf(meshf,"  B { %g %g %g }\n", &tmpf[0], &tmpf[1], &tmpf[2]);  
  145.   pptr->B[0] = tmpf[0];
  146.   pptr->B[1] = tmpf[1];
  147.   pptr->B[2] = tmpf[2];  
  148.   if (ReadLog.log)
  149.     printf("\tB { %g %g %g }\n", pptr->B[0], pptr->B[1], pptr->B[2]);
  150.  
  151.   /* Read vertex colours of patch */
  152.   fscanf(meshf,"  vtx_B {");
  153.   if (ReadLog.log) printf("\tvtx_B {");
  154.   for (i=0;i<(pptr->numVert);i++) {
  155.     fscanf(meshf, " { %g %g %g }", &tmpf[0], &tmpf[1], &tmpf[2]);  
  156.     pptr->vtx_B[i][0] = tmpf[0];
  157.     pptr->vtx_B[i][1] = tmpf[1];
  158.     pptr->vtx_B[i][2] = tmpf[2];  
  159.     if (ReadLog.log)
  160.       printf(" { %g %g %g }", (pptr->vtx_B[i][0]), 
  161.          (pptr->vtx_B[i][1]), (pptr->vtx_B[i][2]));
  162.   }
  163.   Read_EndMarker(meshf);
  164.   if (ReadLog.log) Print_EndMarker(meshf);
  165.   
  166.   /* Set vertex colour or patch colour if the other is not specified 
  167.      otherwise skip this step */
  168.   no_patch_colour = (pptr->B[0] < 0.0);
  169.   no_vtx_colour = (pptr->vtx_B[0][0] < 0.0);
  170.   
  171.   if (no_vtx_colour && no_patch_colour) {
  172.     fprintf(stderr, "Must give colour for patchs OR vertices.\n");
  173.     exit(1);
  174.   }
  175.  
  176.   if ((no_vtx_colour && !no_patch_colour) ||
  177.       (!no_vtx_colour && no_patch_colour)) {
  178.     if (no_patch_colour) {
  179.       pptr->B[0] = pptr->B[1] = pptr->B[2] = 0.0;
  180.       for (i=0;i<pptr->numVert;i++) {
  181.     pptr->B[0] += pptr->vtx_B[i][0];
  182.     pptr->B[1] += pptr->vtx_B[i][1];
  183.     pptr->B[2] += pptr->vtx_B[i][2];
  184.       }
  185.       pptr->B[0] /= pptr->numVert;
  186.       pptr->B[1] /= pptr->numVert;
  187.       pptr->B[2] /= pptr->numVert;
  188.     }
  189.     else if (no_vtx_colour) {
  190.       for (i=0;i<pptr->numVert;i++) {
  191.     pptr->vtx_B[i][0] = pptr->B[0];
  192.     pptr->vtx_B[i][1] = pptr->B[1];
  193.     pptr->vtx_B[i][2] = pptr->B[2]; 
  194.       }
  195.     }
  196.   }
  197.  
  198.   /* Scale colour */
  199.   SpectraToRGB(pptr);
  200.  
  201.   /* Read normals of patch */
  202.   fscanf(meshf, "  norm {");
  203.   if (ReadLog.log) printf("\tnorm {");
  204.   for (i=0;i<(pptr->numVert);i++) {
  205.     Read_Vector(meshf, &pptr->normal[i]);
  206.     if (ReadLog.log) Print_Vector(&pptr->normal[i]);
  207.   }
  208.   Read_EndMarker(meshf);
  209.   if (ReadLog.log) Print_EndMarker(meshf);
  210.  
  211.   /* Read vertices of patch */
  212.   fscanf(meshf, "  vert {");
  213.   if (ReadLog.log) printf("\tvert {");
  214.   for (i=0;i<(pptr->numVert);i++) {
  215.     Read_Vector(meshf, &pptr->vertex[i]);
  216.     Update_WorldSize(pptr->vertex[i]);
  217.     if (ReadLog.log) Print_Vector(&pptr->vertex[i]);
  218.   }
  219.   Read_EndMarker(meshf);
  220.   if (ReadLog.log) Print_EndMarker(meshf);
  221.  
  222.   fscanf(meshf,"}\n");
  223.   if (ReadLog.log) Print_EndMarker(meshf);
  224. }
  225.  
  226. /**********************************************************************/
  227. /* Read in scene from file */
  228. /**********************************************************************/
  229. void ReadScene(filename, mesh)
  230.      char *filename;
  231.      SMesh *mesh;
  232. {
  233.   int i;
  234.   int npolys;
  235.   SPolygon *pptr;
  236.  
  237.   if (!(meshf = fopen(filename, "r"))) {
  238.     fprintf(stderr,"%s: cannot read object file %s\n", ProgName, filename);
  239.     exit(1);
  240.   }
  241.  
  242.   /* Initialize size of the scene */
  243.   Init_WorldSize(&ReadLog);
  244.  
  245.   /* Find out # of polygons and allocate space for them */
  246.   fscanf(meshf,"Number polygons %d\n", &npolys);
  247.   if (ReadLog.log) printf("\tNumber polygons %d\n", npolys);
  248.   mesh->num_polys = npolys;
  249.   pptr = mesh->polys = (SPolygon *) malloc(npolys * sizeof(SPolygon));
  250.   if (pptr == 0) {
  251.     fprintf(stderr,"walk: Insufficient memory to load scene. Sorry.\n");
  252.     exit(1);
  253.   }
  254.  
  255.   /* Read in all the polygon info */
  256.   for (i=0;i<npolys;i++) {
  257.     Read_SPolygon(pptr);
  258.     pptr++;
  259.   }
  260.  
  261.   /* Find box around the world */
  262.   BoxWorld(&ReadLog);
  263.   printf("\n\tReading Statistics\n");
  264.   printf("\t------------------\n");
  265.   printf("\tRead %d polygons from file %s.\n", npolys, filename);
  266.   printf("\tWorlds radius: %g\n", ReadLog.worldSize);
  267.   printf("\tBox around world %g %g %g to %g %g %g\n", 
  268.      ReadLog.worldbox.min.x, ReadLog.worldbox.min.y, 
  269.      ReadLog.worldbox.min.z,
  270.      ReadLog.worldbox.max.x, ReadLog.worldbox.max.y, 
  271.      ReadLog.worldbox.max.z);
  272.   printf("\n");
  273.   fclose(meshf);
  274. }
  275.  
  276. /**********************************************************************/
  277. /* Read in the scene from file */
  278. /**********************************************************************/
  279. void Init_Scene()
  280. {
  281.   char *tmp = "                                                  ";
  282.  
  283.   if (meshfilename == "") {
  284.     printf(">> Mesh input file: ");
  285.     scanf("%s", tmp);
  286.     meshfilename = tmp;
  287.   }
  288.   ReadLog.log = 0;
  289.   ReadScene(meshfilename, &Scene);
  290. }
  291.