Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*************************************************************************/
- /* */
- /* Copyright (c) 1994 Stanford University */
- /* */
- /* All rights reserved. */
- /* */
- /* Permission is given to use, copy, and modify this software for any */
- /* non-commercial purpose as long as this copyright notice is not */
- /* removed. All other uses, including redistribution in whole or in */
- /* part, are forbidden without prior written permission. */
- /* */
- /* This software is provided with absolutely no warranty and no */
- /* support. */
- /* */
- /*************************************************************************/
- /*
- * NAME
- * geo.c
- *
- * DESCRIPTION
- * This file contains routines that read both ascii and binary geometry
- * files, as well as routines to normalize, print, and make a linked
- * list of the geometry info.
- *
- */
- #include <stdio.h>
- #include <fcntl.h>
- #include <math.h>
- #include "rt.h"
- /*
- * Allocate and initialize sphere function pointer array.
- */
- static PPROCS SphProcs =
- {
- SphName,
- SphPrint,
- SphRead,
- NULL,
- SphTransform,
- SphIntersect,
- SphPeIntersect,
- SphNormal,
- SphDataNormalize,
- SphBoundBox
- };
- /*
- * Allocate and initialize polygon function pointer array.
- */
- static PPROCS PolyProcs =
- {
- PolyName,
- PolyPrint,
- PolyRead,
- NULL,
- PolyTransform,
- PolyIntersect,
- PolyPeIntersect,
- PolyNormal,
- PolyDataNormalize,
- PolyBoundBox
- };
- /*
- * Allocate and initialize triangle function pointer array.
- */
- static PPROCS TriProcs =
- {
- TriName,
- TriPrint,
- TriRead,
- NULL,
- TriTransform,
- TriIntersect,
- TriPeIntersect,
- TriNormal,
- TriDataNormalize,
- TriBoundBox
- };
- /*
- * NAME
- * MakeElementArray - make array of all primitive elements
- *
- * SYNOPSIS
- * ELEMENT **MakeElementArray(totalElements)
- * INT *totalElements;
- *
- * RETURNS
- * Pointer to array of primitives.
- *
- */
- ELEMENT **MakeElementArray(totalElements)
- INT *totalElements;
- {
- INT i;
- OBJECT *po; /* Ptr to object. */
- INT currArrayPosition = 0;
- ELEMENT **npepa;
- po = gm->modelroot;
- *totalElements = 0;
- while (po)
- {
- (*totalElements) += po->numelements;
- po = po->next;
- }
- po = gm->modelroot;
- npepa = ObjectMalloc(OT_PEPARRAY, *totalElements);
- while (po)
- {
- for (i = 0; i < po->numelements; i++)
- npepa[currArrayPosition++] = po->pelem + i;
- po = po->next;
- }
- return (npepa);
- }
- /*
- * NAME
- * PrintGeo - print object geometry list
- *
- * SYNOPSIS
- * VOID PrintGeo(po)
- * OBJECT *po; // Ptr to object list to print.
- *
- * RETURNS
- * Nothing.
- */
- VOID PrintGeo(po)
- OBJECT *po;
- {
- while (po)
- {
- fprintf(stdout, "Object %s\n", po->name);
- fprintf(stdout, "\tcolor %f %f %f %f %f %f\n",
- po->surf->fcolor[0], po->surf->fcolor[1],
- po->surf->fcolor[2], po->surf->bcolor[0],
- po->surf->bcolor[1], po->surf->bcolor[2]);
- fprintf(stdout, "\tcoeffs %f %f %f %f %f\n",
- po->surf->kdiff, po->surf->kspec, po->surf->ktran,
- po->surf->refrindex, po->surf->kspecn);
- (*po->procs->print)(po);
- po = po->next;
- }
- }
- /*
- * NAME
- * NormalizeGeo - normalize geometry to be within unit cube
- *
- * SYNOPSIS
- * VOID NormalizeData(po, model, modelInvT)
- * OBJECT *po; // Ptr to object list to normalize.
- * MATRIX model; // Model matrix.
- * MATRIX modelInvT; // Model inverse transpose.
- *
- * RETURNS
- * Nothing.
- */
- VOID NormalizeGeo(po, model, modelInvT)
- OBJECT *po;
- MATRIX model;
- MATRIX modelInvT;
- {
- REAL norm_minx; /* Normalize min values. */
- REAL norm_miny;
- REAL norm_minz;
- REAL norm_maxx; /* Normalize max values. */
- REAL norm_maxy;
- REAL norm_maxz;
- REAL scale_min; /* Object min max values. */
- REAL scale_max;
- REAL scale; /* Normalization scale val. */
- REAL trans; /* Normalization xlat val. */
- OBJECT *poHead; /* Ptr to head of object list*/
- MATRIX normMat; /* Normalization matrix. */
- MATRIX tempMat; /* Temporary work matrix. */
- poHead = po; /* Save ptr to head of list. */
- if (! (TraversalType == TT_LIST && ModelNorm == FALSE) )
- {
- /* Find global bound box min/max. */
- norm_minx = norm_miny = norm_minz = HUGE_REAL;
- norm_maxx = norm_maxy = norm_maxz = -HUGE_REAL;
- while (po)
- {
- norm_minx = Min(norm_minx, po->bv.dnear[0]);
- norm_miny = Min(norm_miny, po->bv.dnear[1]);
- norm_minz = Min(norm_minz, po->bv.dnear[2]);
- norm_maxx = Max(norm_maxx, po->bv.dfar[0]);
- norm_maxy = Max(norm_maxy, po->bv.dfar[1]);
- norm_maxz = Max(norm_maxz, po->bv.dfar[2]);
- po = po->next;
- }
- /* Compute scale factor. */
- scale_min = Min(norm_minx, norm_miny);
- scale_min = Min(scale_min, norm_minz);
- scale_max = Max(norm_maxx, norm_maxy);
- scale_max = Max(scale_max, norm_maxz);
- scale = 1.0/(scale_max - scale_min);
- trans = (-scale_min*scale);
- Scale(tempMat, scale, scale, scale);
- Translate(normMat, trans, trans, trans);
- MatrixMult(normMat, tempMat, normMat);
- /* Now, normalize object data. */
- po = poHead;
- while (po)
- {
- (*po->procs->normalize)(po, normMat);
- po = po->next;
- }
- }
- }
- /*
- * NAME
- * ReadGeoFile - read in the geometry file
- *
- * SYNOPSIS
- * VOID ReadGeoFile(GeoFileName)
- * CHAR *GeoFileName; // File to open.
- *
- * DESCRIPTION
- * Read in the model file - call primitive object routines to read in
- * their own data. Objects are put in a linked list.
- *
- * Transform objects by modeling transformation if any.
- *
- * If TT_LIST traversal, ModelNorm parameter indicates whether data will
- * be normalized.
- *
- * RETURNS
- * Nothing.
- */
- VOID ReadGeoFile(GeoFileName)
- CHAR *GeoFileName;
- {
- INT i;
- INT dummy;
- INT stat; /* Input read counter. */
- CHAR comchar;
- CHAR primop; /* Primitive opcode. */
- CHAR objstr[NAME_LEN]; /* Object descriptions. */
- CHAR objname[NAME_LEN];
- FILE *pf; /* Ptr to geo file desc. */
- SURF *ps; /* Ptr to surface desc. */
- MATRIX model; /* Model matrix. */
- MATRIX modelInv; /* Model matrix inverse. */
- MATRIX modelInvT; /* Model matrix inv transpose*/
- OBJECT *po; /* Ptr to object. */
- OBJECT *prev; /* Ptr to previous object. */
- OBJECT *curr; /* Ptr to current object. */
- ELEMENT *pe; /* Ptr to the element list. */
- /* Open the model file. */
- pf = fopen(GeoFileName, "r");
- if (!pf)
- {
- printf("Unable to open model file %s.\n", GeoFileName);
- exit(1);
- }
- /* Initialize pointers and counters. */
- curr = NULL;
- prev = NULL;
- gm->modelroot = NULL;
- prim_obj_cnt = 0;
- prim_elem_cnt = 0;
- /* Retrieve model transform. */
- MatrixCopy(model, View.model);
- MatrixInverse(modelInv, model);
- MatrixTranspose(modelInvT, modelInv);
- /* Check for comments. */
- if ((comchar = getc(pf)) != '#')
- ungetc(comchar, pf);
- else
- {
- comchar = '\0'; /* Set to other than '#'. */
- while (comchar != '#')
- if ((comchar = getc(pf)) == EOF)
- {
- fprintf(stderr, "Incorrect comment in geometry file.\n");
- exit(-1);
- }
- }
- /* Process the file data for each object. */
- while ((stat = fscanf(pf, "%s %s", objstr, objname)) != EOF)
- {
- if (stat != 2 || strcmp(objstr, "object") != 0)
- {
- printf("Invalid object definition %s.\n", objstr);
- exit(-1);
- }
- /* Allocate next object and set list pointers. */
- prim_obj_cnt++;
- curr = GlobalMalloc(sizeof(OBJECT), "geo.c");
- curr->index = prim_obj_cnt;
- curr->next = NULL;
- strcpy(curr->name, objname);
- if (gm->modelroot == NULL)
- gm->modelroot = curr;
- else
- prev->next = curr;
- /* Get surface characteristics. */
- ps = GlobalMalloc(sizeof(SURF), "geo.c");
- curr->surf = ps;
- stat = fscanf(pf, "%lf %lf %lf %lf %lf %lf",
- &(ps->fcolor[0]), &(ps->fcolor[1]), &(ps->fcolor[2]),
- &(ps->bcolor[0]), &(ps->bcolor[1]), &(ps->bcolor[2]));
- if (stat != 6)
- {
- printf("Object color incorrect.\n");
- exit(-1);
- }
- stat = fscanf(pf, "%lf %lf %lf %lf %lf",
- &(ps->kdiff), &(ps->kspec), &(ps->ktran),
- &(ps->refrindex), &(ps->kspecn));
- if (stat != 5)
- {
- printf("Object surface coefficients incorrect.\n");
- exit(-1);
- }
- /* Get texture and flag information. */
- stat = fscanf(pf, "%ld %ld %ld %ld\n", &dummy, &dummy, &dummy, &dummy);
- if (stat != 4)
- {
- printf("Texture and/or flag information not all present.\n");
- exit(-1);
- }
- /* Get primitive opcode. */
- stat = fscanf(pf, "%c %ld", &primop, &(curr->numelements));
- if (stat != 2)
- {
- printf("Object primitive opcode.\n");
- exit(-1);
- }
- switch (primop)
- {
- case 's':
- curr->procs = &SphProcs;
- break;
- case 'p':
- curr->procs = &PolyProcs;
- break;
- case 't':
- curr->procs = &TriProcs;
- break;
- case 'c':
- case 'q':
- printf("Code for cylinders and quadrics not implemented yet.\n");
- exit(-1);
- default:
- printf("Invalid primitive type \'%c\'.\n", primop);
- exit(-1);
- }
- /* Allocate primitive elements and create indices. */
- pe = GlobalMalloc(sizeof(ELEMENT)*curr->numelements, "geo.c");
- curr->pelem = pe;
- prim_elem_cnt += curr->numelements;
- for (i = 1; i <= curr->numelements; i++, pe++)
- pe->index = i;
- /* Read, transform, and compute bounding box for object. */
- (*curr->procs->read)(curr, pf);
- (*curr->procs->transform)(curr, model, modelInvT);
- (*curr->procs->bbox)(curr);
- prev = curr;
- }
- NormalizeGeo(gm->modelroot, model, modelInvT);
- fclose(pf);
- }
Advertisement
Add Comment
Please, Sign In to add comment