home *** CD-ROM | disk | FTP | other *** search
- /**********************************************************************/
- /* scene.c */
- /* */
- /* Read in polygons from and input file of format: */
- /* */
- /* Number polygons <number-polygons> */
- /* Polgon_Info */
- /* where: */
- /* Polygon_Info = Polygon [Polygon_Info] */
- /* Polygon = Poly <poly-name><id> <#vertices> { */
- /* colour norm vert } */
- /* colour = B { { vec } { vect } ... } */
- /* vert = vert { vertices } */
- /* norm = norm { normals } */
- /* vertices = { vec } { vec } ... */
- /* normals = { vec } { vec } ... */
- /* vec = val val val */
- /* val = floating point value */
- /* */
- /* Copyright (C) 1992, Bernard Kwok */
- /* All rights reserved. */
- /* Revision 1.0 */
- /* May, 1992 */
- /**********************************************************************/
- #include <stdio.h>
- #include <string.h>
- #include "geo.h"
- #include "scene.h"
-
- /**********************************************************************/
- #define Read_EndMarker(fp) (fscanf(fp," }\n"))
- #define Print_EndMarker(fp) (printf(" }\n"))
-
- SMesh Scene; /* Input scene */
- SLogType ReadLog; /* Input log */
- float tmpf[5]; /* For floating pt reading only ! */
- FILE *meshf; /* File of input polygons */
- char *meshfilename;
-
- void ReadScene();
- void Read_SPolygon();
- void Print_Vector();
- void Read_Vector();
- extern char *ProgName;
- extern void *SpectraToRGB();
-
- /**********************************************************************/
- /* Initialize size of world */
- /**********************************************************************/
- void Init_WorldSize(rlog)
- SLogType *rlog;
- {
- rlog->worldbox.min.x = VERY_LARGE / 2.0;
- rlog->worldbox.min.y = VERY_LARGE / 2.0;
- rlog->worldbox.min.z = VERY_LARGE / 2.0;
- rlog->worldbox.max.x = -VERY_LARGE / 2.0;
- rlog->worldbox.max.y = -VERY_LARGE / 2.0;
- rlog->worldbox.max.z = -VERY_LARGE / 2.0;
- rlog->worldSize = VERY_LARGE / 2.0;
- }
-
- /**********************************************************************/
- /* Find minimum axis aligned bounding box size for the world */
- /**********************************************************************/
- void Update_WorldSize(pt)
- Vector pt;
- {
- if (pt.x > ReadLog.worldbox.max.x) ReadLog.worldbox.max.x = pt.x;
- if (pt.y > ReadLog.worldbox.max.y) ReadLog.worldbox.max.y = pt.y;
- if (pt.z > ReadLog.worldbox.max.z) ReadLog.worldbox.max.z = pt.z;
-
- if (pt.x < ReadLog.worldbox.min.x) ReadLog.worldbox.min.x = pt.x;
- if (pt.y < ReadLog.worldbox.min.y) ReadLog.worldbox.min.y = pt.y;
- if (pt.z < ReadLog.worldbox.min.z) ReadLog.worldbox.min.z = pt.z;
- }
-
- /**********************************************************************/
- /* Make bounding sphere and bounding box of world */
- /**********************************************************************/
- void BoxWorld(rlog)
- SLogType *rlog;
- {
- if (rlog->worldbox.min.x > rlog->worldbox.max.x) {
- printf("Oh oh. the world min is greater than the max!\n");
- exit(1);
- }
- rlog->worldbox.min.x -= ENLARGE_WORLD;
- rlog->worldbox.min.y -= ENLARGE_WORLD;
- rlog->worldbox.min.z -= ENLARGE_WORLD;
- rlog->worldbox.max.x += ENLARGE_WORLD;
- rlog->worldbox.max.y += ENLARGE_WORLD;
- rlog->worldbox.max.z += ENLARGE_WORLD;
-
- rlog->worldSize = 0.5 * (vdist(&(rlog->worldbox.max),
- &(rlog->worldbox.min)) + 0.5);
- }
-
- /**********************************************************************/
- /* Print a vector */
- /**********************************************************************/
- void Print_Vector(v)
- Vector *v;
- { printf(" { %g %g %g }", v->x, v->y, v->z); }
-
- /**********************************************************************/
- /* Read a vector */
- /**********************************************************************/
- void Read_Vector(fp, v)
- FILE *fp;
- Vector *v;
- {
- fscanf(fp, " { %g %g %g }", &tmpf[0], &tmpf[1], &tmpf[2]);
- v->x = tmpf[0]; v->y = tmpf[1]; v->z = tmpf[2];
- }
-
- /**********************************************************************/
- /* Read in a polygon */
- /**********************************************************************/
- void Read_SPolygon(pptr)
- SPolygon *pptr;
- {
- int i;
- char *tmp = " ";
- int no_patch_colour, no_vtx_colour;
-
- /* Read in name and number of vertices for the patch */
- fscanf(meshf,"Poly %s %d {", tmp, &(pptr->numVert));
- pptr->id = ReadLog.totpoly++;
- if (ReadLog.log) printf("Poly %s %d {\n", tmp, pptr->numVert);
-
- /* Set id and type */
- if (pptr->numVert == 4) {
- pptr->name = PATCH_ID;
- pptr->class = PATCH;
- } else if (pptr->numVert == 3) {
- pptr->name = TRI_ID;
- pptr->class = TRIANGLE;
- } else {
- fprintf(stderr, "Sorry, only quadtralaterals and triangles allowed\n");
- exit(1);
- }
-
- /* Read patch average colour */
- fscanf(meshf," B { %g %g %g }\n", &tmpf[0], &tmpf[1], &tmpf[2]);
- pptr->B[0] = tmpf[0];
- pptr->B[1] = tmpf[1];
- pptr->B[2] = tmpf[2];
- if (ReadLog.log)
- printf("\tB { %g %g %g }\n", pptr->B[0], pptr->B[1], pptr->B[2]);
-
- /* Read vertex colours of patch */
- fscanf(meshf," vtx_B {");
- if (ReadLog.log) printf("\tvtx_B {");
- for (i=0;i<(pptr->numVert);i++) {
- fscanf(meshf, " { %g %g %g }", &tmpf[0], &tmpf[1], &tmpf[2]);
- pptr->vtx_B[i][0] = tmpf[0];
- pptr->vtx_B[i][1] = tmpf[1];
- pptr->vtx_B[i][2] = tmpf[2];
- if (ReadLog.log)
- printf(" { %g %g %g }", (pptr->vtx_B[i][0]),
- (pptr->vtx_B[i][1]), (pptr->vtx_B[i][2]));
- }
- Read_EndMarker(meshf);
- if (ReadLog.log) Print_EndMarker(meshf);
-
- /* Set vertex colour or patch colour if the other is not specified
- otherwise skip this step */
- no_patch_colour = (pptr->B[0] < 0.0);
- no_vtx_colour = (pptr->vtx_B[0][0] < 0.0);
-
- if (no_vtx_colour && no_patch_colour) {
- fprintf(stderr, "Must give colour for patchs OR vertices.\n");
- exit(1);
- }
-
- if ((no_vtx_colour && !no_patch_colour) ||
- (!no_vtx_colour && no_patch_colour)) {
- if (no_patch_colour) {
- pptr->B[0] = pptr->B[1] = pptr->B[2] = 0.0;
- for (i=0;i<pptr->numVert;i++) {
- pptr->B[0] += pptr->vtx_B[i][0];
- pptr->B[1] += pptr->vtx_B[i][1];
- pptr->B[2] += pptr->vtx_B[i][2];
- }
- pptr->B[0] /= pptr->numVert;
- pptr->B[1] /= pptr->numVert;
- pptr->B[2] /= pptr->numVert;
- }
- else if (no_vtx_colour) {
- for (i=0;i<pptr->numVert;i++) {
- pptr->vtx_B[i][0] = pptr->B[0];
- pptr->vtx_B[i][1] = pptr->B[1];
- pptr->vtx_B[i][2] = pptr->B[2];
- }
- }
- }
-
- /* Scale colour */
- SpectraToRGB(pptr);
-
- /* Read normals of patch */
- fscanf(meshf, " norm {");
- if (ReadLog.log) printf("\tnorm {");
- for (i=0;i<(pptr->numVert);i++) {
- Read_Vector(meshf, &pptr->normal[i]);
- if (ReadLog.log) Print_Vector(&pptr->normal[i]);
- }
- Read_EndMarker(meshf);
- if (ReadLog.log) Print_EndMarker(meshf);
-
- /* Read vertices of patch */
- fscanf(meshf, " vert {");
- if (ReadLog.log) printf("\tvert {");
- for (i=0;i<(pptr->numVert);i++) {
- Read_Vector(meshf, &pptr->vertex[i]);
- Update_WorldSize(pptr->vertex[i]);
- if (ReadLog.log) Print_Vector(&pptr->vertex[i]);
- }
- Read_EndMarker(meshf);
- if (ReadLog.log) Print_EndMarker(meshf);
-
- fscanf(meshf,"}\n");
- if (ReadLog.log) Print_EndMarker(meshf);
- }
-
- /**********************************************************************/
- /* Read in scene from file */
- /**********************************************************************/
- void ReadScene(filename, mesh)
- char *filename;
- SMesh *mesh;
- {
- int i;
- int npolys;
- SPolygon *pptr;
-
- if (!(meshf = fopen(filename, "r"))) {
- fprintf(stderr,"%s: cannot read object file %s\n", ProgName, filename);
- exit(1);
- }
-
- /* Initialize size of the scene */
- Init_WorldSize(&ReadLog);
-
- /* Find out # of polygons and allocate space for them */
- fscanf(meshf,"Number polygons %d\n", &npolys);
- if (ReadLog.log) printf("\tNumber polygons %d\n", npolys);
- mesh->num_polys = npolys;
- pptr = mesh->polys = (SPolygon *) malloc(npolys * sizeof(SPolygon));
- if (pptr == 0) {
- fprintf(stderr,"walk: Insufficient memory to load scene. Sorry.\n");
- exit(1);
- }
-
- /* Read in all the polygon info */
- for (i=0;i<npolys;i++) {
- Read_SPolygon(pptr);
- pptr++;
- }
-
- /* Find box around the world */
- BoxWorld(&ReadLog);
- printf("\n\tReading Statistics\n");
- printf("\t------------------\n");
- printf("\tRead %d polygons from file %s.\n", npolys, filename);
- printf("\tWorlds radius: %g\n", ReadLog.worldSize);
- printf("\tBox around world %g %g %g to %g %g %g\n",
- ReadLog.worldbox.min.x, ReadLog.worldbox.min.y,
- ReadLog.worldbox.min.z,
- ReadLog.worldbox.max.x, ReadLog.worldbox.max.y,
- ReadLog.worldbox.max.z);
- printf("\n");
- fclose(meshf);
- }
-
- /**********************************************************************/
- /* Read in the scene from file */
- /**********************************************************************/
- void Init_Scene()
- {
- char *tmp = " ";
-
- if (meshfilename == "") {
- printf(">> Mesh input file: ");
- scanf("%s", tmp);
- meshfilename = tmp;
- }
- ReadLog.log = 0;
- ReadScene(meshfilename, &Scene);
- }
-