/*************************************************************************/ /* */ /* 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 * env.c * * DESCRIPTION * This file contains routines that read environment description files * as well as routines to setup and manipulate the viewing transform, * routines to manipulate lights, colors, and to print the environment. */ #include #include #include #include "rt.h" /* * Define environment specification opcodes. */ #define OP_EYE 'a' #define OP_COI 'b' #define OP_BKGCOL 'c' #define OP_VANG 'd' #define OP_LIGHT 'e' #define OP_RES 'f' #define OP_MAXLEVEL 'g' #define OP_MINWEIGHT 'h' #define OP_PROJECT 'i' #define OP_ANTILEVEL 'j' #define OP_ANTITOL 'k' #define OP_MODELMAT 'l' #define OP_SHAD 'm' #define OP_SHADING 'n' #define OP_DISPLAY_IN 'o' #define OP_DISPLAY_OUT 'p' #define OP_GEOM_FILE 'q' #define OP_TEX_FILE 'r' #define OP_RL_FILE 's' #define OP_TEXTURE 't' #define OP_IMAGE 'u' #define OP_FOOTPRINT 'v' #define OP_TRAVERSAL 'w' #define OP_AMBIENT 'x' #define OP_EXCELL_PRIM 'y' #define OP_EXCELL_DIR 'z' #define OP_EXCELL_SUBDIV '9' #define OP_HIER_SUBLEVEL '1' #define OP_HIER_PRIMNUM '2' #define OP_PREVIEW_BKCULL '3' #define OP_PREVIEW_FILL '4' #define OP_PREVIEW_SPHTESS '5' #define OP_ERROR '0' #define OP_NORM_DB '6' #define OP_DATA_TYPE '7' #define OP_HU_MAX_PRIMS_CELL '8' #define OP_HU_GRIDSIZE '@' #define OP_HU_NUMBUCKETS '#' #define OP_HU_MAX_SUBDIV '$' #define OP_HU_LAZY '*' #define OP_BUNDLE '+' #define OP_BLOCK '%' /* * Define structure for a command table entry (CTE). */ typedef struct { CHAR *command; /* Command name. */ CHAR opcode; /* Command code. */ } CTE; /* * Allocate and initialize the command table. */ CTE cmdtab[] = { {"eye", OP_EYE }, {"center", OP_COI }, {"light", OP_LIGHT }, {"resolution", OP_RES }, {"shadows", OP_SHAD }, {"background", OP_BKGCOL }, {"viewangle", OP_VANG }, {"antilevel", OP_ANTILEVEL }, {"minweight", OP_MINWEIGHT }, {"project", OP_PROJECT }, {"antitolerance", OP_ANTITOL }, {"maxlevel", OP_MAXLEVEL }, {"modelxform", OP_MODELMAT }, {"shading", OP_SHADING }, {"displayin", OP_DISPLAY_IN }, {"displayout", OP_DISPLAY_OUT }, {"geometry", OP_GEOM_FILE }, {"texturetype", OP_TEXTURE }, {"texturefile", OP_TEX_FILE }, {"image", OP_IMAGE }, {"footprint", OP_FOOTPRINT }, {"traversal", OP_TRAVERSAL }, {"rlfile", OP_RL_FILE }, {"ambient", OP_AMBIENT }, {"excellprim", OP_EXCELL_PRIM }, {"excelldir", OP_EXCELL_DIR }, {"excellsubdiv", OP_EXCELL_SUBDIV }, {"hsublevel", OP_HIER_SUBLEVEL }, {"hprim", OP_HIER_PRIMNUM }, {"bfcull", OP_PREVIEW_BKCULL }, {"fill", OP_PREVIEW_FILL }, {"spheretess", OP_PREVIEW_SPHTESS }, {"normdata", OP_NORM_DB }, {"datatype", OP_DATA_TYPE }, {"hu_maxprims", OP_HU_MAX_PRIMS_CELL }, {"hu_gridsize", OP_HU_GRIDSIZE }, {"hu_numbuckets", OP_HU_NUMBUCKETS }, {"hu_maxsubdiv", OP_HU_MAX_SUBDIV }, {"hu_lazy", OP_HU_LAZY }, {"bundle", OP_BUNDLE }, {"block", OP_BLOCK }, {" ", OP_ERROR }, }; #define NUM_COMMANDS (sizeof(cmdtab)/sizeof(CTE)) /* * NAME * PrintEnv - print environment and lights to stdout * * SYNOPSIS * VOID PrintEnv() * * RETURNS * Nothing. */ VOID PrintEnv() { INT i; LIGHT *lp; printf("\nEnvironment:\n"); printf("\tEye pos: \t %f %f %f\n", View.eye[0], View.eye[1], View.eye[2]); printf("\tCenter pos:\t %f %f %f\n", View.coi[0], View.coi[1], View.coi[2]); printf("\tBackground:\t %f %f %f\n", View.bkg[0], View.bkg[1], View.bkg[2]); printf("\tView Angle:\t %f\n", View.vang); printf("\nAmbient Light:\t\t %f %f %f\n", View.ambient[0], View.ambient[1], View.ambient[2]); printf("\nLights:\n"); lp = lights; for (i = 0; i < nlights; i++) { printf("\t[%ld] Pos:\t %f %f %f\n", i, lp->pos[0], lp->pos[1], lp->pos[2]); printf("\t Col:\t %f %f %f\n", lp->col[0], lp->col[1], lp->col[2]); printf("\t Shadow:\t %ld\n", lp->shadow); lp = lp->next; } printf("\n"); printf("Options:\n"); printf("\tTraversal:\t\t\t"); switch (TraversalType) { case TT_LIST: printf("list\n"); break; case TT_HUG: printf("uniform grid hierarchy\n"); printf("\t\t\t\t\t grid size %ld\n", hu_gridsize); printf("\t\t\t\t\t max prims %ld\n", hu_max_prims_cell); printf("\t\t\t\t\t max sublevel %ld\n", hu_max_subdiv_level); printf("\t\t\t\t\t buckets %ld\n", hu_numbuckets); printf("\t\t\t\t\t lazy %ld\n", hu_lazy); break; } printf("\tNormalization DB:\t\t"); printf(ModelNorm ? "yes\n" : "no\n"); printf("\tProjection type:\t\t"); printf(View.projection == PT_PERSP ? "perspective\n" : "orthographic\n"); printf("\tShadows:\t\t\t"); printf(View.shad ? "on\n" : "off\n"); printf("\tShading:\t\t\t"); printf(View.shading ? "on\n" : "off\n"); printf("\tResolution:\t\t\t%ld %ld\n", Display.xres, Display.yres); printf("\tMin Ray Weight:\t\t\t%f\n", Display.minweight); printf("\tMax Anti Subdivison Level:\t%ld\n", Display.maxAAsubdiv); printf("\tAnti tolerance:\t\t\t%f\n", Display.aatolerance); printf("\tBundle: \t\t\t%ld %ld\n", bundlex, bundley); printf("\tBlock: \t\t\t%ld %ld\n", blockx, blocky); if (GeoFile) printf("\tGeometry file:\t\t\t%s\n", GeoFileName); if (PicFile) printf("\tImage file:\t\t\t%s\n", PicFileName); printf("\n"); } /* * NAME * InitEnv - setup the default environment variables * * SYNOPSIS * VOID InitEnv() * * RETURNS * Nothing. */ VOID InitEnv() { /* Default eye position. */ View.eye[0] = 0.5; View.eye[1] = 0.5; View.eye[2] = -1.5; /* Default center position. */ View.coi[0] = 0.5; View.coi[1] = 0.5; View.coi[2] = 0.5; /* Default background color. */ View.bkg[0] = 0.0; View.bkg[1] = 0.0; View.bkg[2] = 0.8; /* Default viewing angle. */ View.vang = 60.0; /* Default ambient light. */ View.ambient[0] = 0.1; View.ambient[1] = 0.1; View.ambient[2] = 0.1; /* Shadows and shading. */ View.shad = TRUE; View.shading = TRUE; /* Perspective projection. */ View.projection = PT_PERSP; /* Default resolution is 100 x 100 */ Display.xres = 100; Display.yres = 100; Display.numpixels = 100*100; /* Default maximum raytrace level. */ Display.maxlevel = 5; /* Default anti-aliasing. */ Display.maxAAsubdiv = 0; Display.aatolerance = .020; Display.aarow = MAX_AA_ROW - 1; Display.aacol = MAX_AA_COL - 1; /* Default ray minimum weight is 0.001. */ Display.minweight = 0.001; /* Default screen size. */ Display.scrDist = 164.5; Display.scrWidth = 190.0; Display.scrHeight = 190.0; Display.scrHalfWidth = Display.scrWidth * 0.5; Display.scrHalfHeight = Display.scrHeight* 0.5; Display.vWscale = Display.scrWidth/(REAL)Display.xres; Display.vHscale = Display.scrHeight/(REAL)Display.yres; /* Init transformation matrices. */ MatrixIdentity(View.vtrans); MatrixIdentity(View.model); GeoFile = FALSE; PicFile = FALSE; ModelNorm = TRUE; ModelTransform = FALSE; DataType = DT_ASCII; TraversalType = TT_LIST; /* Init statistics. * * Stats.total_rays = 0; * Stats.prim_rays = 0; * Stats.shad_rays = 0; * Stats.shad_rays_not_hit = 0; * Stats.shad_rays_hit = 0; * Stats.shad_coherence_rays = 0; * Stats.refl_rays = 0; * Stats.trans_rays = 0; * Stats.aa_rays = 0; * Stats.bound_tests = 0; * Stats.bound_hits = 0; * Stats.bound_misses = 0; * Stats.ray_obj_hit = 0; * Stats.ray_obj_miss = 0; * Stats.max_tree_depth = 0; * Stats.max_objs_ray = 0; * Stats.max_rays_pixel = 0; * Stats.max_objs_pixel = 0; * Stats.total_objs_tested = 0; * Stats.coverage = 0; */ lights = GlobalMalloc(sizeof(LIGHT), "env.c"); bundlex = 25; bundley = 25; blockx = 2; blocky = 2; } /* * NAME * InitLights - setup the default light position and color * * SYNOPSIS * VOID InitLights() * * RETURNS * Nothing. */ VOID InitLights() { nlights = 1; lights->pos[0] = 0.0; lights->pos[1] = 0.0; lights->pos[2] = -2000.0; lights->pos[3] = 1.0; lights->col[0] = 1.0; lights->col[1] = 1.0; lights->col[2] = 1.0; lights->shadow = TRUE; lights->next = NULL; } /* * NAME * InitDisplay - setup display parameters * * SYNOPSIS * VOID InitDisplay() * * RETURNS * Nothing. */ VOID InitDisplay() { REAL aspect; /* Resolution aspect ratio. */ REAL theta; /* View angle in radians. */ aspect = (REAL)Display.xres/(REAL)Display.yres; theta = (View.vang*0.5)*0.0175; Display.scrWidth = Display.scrHeight*aspect; Display.scrDist = (0.5*Display.scrHeight)/tan(theta); Display.scrHalfWidth = Display.scrWidth*0.5; Display.scrHalfHeight = Display.scrHeight*0.5; Display.vWscale = Display.scrWidth/(REAL)Display.xres; Display.vHscale = Display.scrHeight/(REAL)Display.yres; } /* * NAME * VerifyColorRange - verify if a color value lies between 0 and 1 * * SYNOPSIS * BOOL VerifyColorRange(c) * COLOR c; * * RETURNS * TRUE if color is within range, FALSE otherwise. */ BOOL VerifyColorRange(COLOR c) { if (c[0] < 0.0 || c[0] > 1.0 || c[1] < 0.0 || c[1] > 1.0 || c[2] < 0.0 || c[2] > 1.0) { printf("Invalid color %f %f %f.\n", c[0], c[1], c[2]); return (FALSE); } else return (TRUE); } /* * NAME * TransformLights - transform lights to a new position given a matrix * * SYNOPSIS * VOID TransformLights(m) * MATRIX m; // Transformation matrix. * * RETURNS * Nothing. */ VOID TransformLights(MATRIX m) { INT i; LIGHT *lp; lp = lights; for (i = 0; i < nlights; i++) { VecMatMult(lp->pos, m, lp->pos); lp = lp->next; } } /* * NAME * ViewRotate - compute transform that aligns direction x,y,z with +z axis * * SYNOPSIS * VOID ViewRotate(M, x, y, z) * MATRIX M; * REAL x, y, z; * * RETURNS * Nothing. */ VOID ViewRotate(MATRIX M, REAL x, REAL y, REAL z) { REAL r, rx; rx = sqrt(x*x + z*z); if (ABS(rx) < RAYEPS) { MatrixIdentity(M); Rotate(X_AXIS, M, PI_over_2 * (Sign(y))); return; } r = sqrt(x*x + y*y + z*z); M[0][0] = z/rx; M[0][1] = -x*y/(r*rx); M[0][2] = x/r; M[0][3] = 0.0; M[1][0] = 0.0; M[1][1] = rx/r; M[1][2] = y/r; M[1][3] = 0.0; M[2][0] = -x/rx; M[2][1] = -y*z/(r*rx); M[2][2] = z/r; M[2][3] = 0.0; M[3][0] = 0.0; M[3][1] = 0.0; M[3][2] = 0.0; M[3][3] = 1.0; } /* * NAME * CreateViewMatrix - compute view transform matrix and put in View.vtrans * * SYNOPSIS * VOID CreateViewMatrix() * * NOTES * Taken from David Kurlander's program. * * RETURNS * Nothing. */ VOID CreateViewMatrix() { MATRIX T, R; /* Temporary matrices. */ /* Put eye at origin. */ Translate(T, -View.eye[0], -View.eye[1], -View.eye[2]); MatrixMult(View.vtrans, View.vtrans, T); /* Align view direction with Z axis. */ ViewRotate(R, View.coi[0] - View.eye[0], View.coi[1] - View.eye[1], View.coi[2] - View.eye[2]); MatrixMult(View.vtrans, View.vtrans, R); } /* * NAME * TransformViewRay - put ray back in world coordinate system from view coordinate system * * SYNOPSIS * VOID TransformViewRay(tray) * POINT tray; // Ray. * * RETURNS * Nothing. */ VOID TransformViewRay(POINT tray) { VecMatMult(tray, View.vtransInv, tray); } /* * NAME * NormalizeEnv - normalize eye, center of intersect and light positions * * SYNOPSIS * VOID NormalizeEnv(normMat) * MATRIX normMat; // Normalization matrix. * * RETURNS * Nothing. */ VOID NormalizeEnv(MATRIX normMat) { View.eye[3] = 1.0; VecMatMult(View.eye, normMat, View.eye); View.coi[3] = 1.0; VecMatMult(View.coi, normMat, View.coi); TransformLights(normMat); } /* * NAME * LookupCommand - find environment command in table and return opcode * * SYNOPSIS * CHAR LookupCommand(s) * CHAR *s; * * RETURNS * The corresponding opcode. */ CHAR LookupCommand(CHAR *s) { INT i; for (i = 0; i < NUM_COMMANDS; i++) if (strcmp(s, cmdtab[i].command) == 0) return (cmdtab[i].opcode); printf("\n\nInvalid command string %s.\n", s); return (OP_ERROR); } /* * NAME * ReadEnvFile - read and parse environment file * * SYNOPSIS * VOID ReadEnvFile(EnvFileName) * CHAR *EnvFileName; // Environment filename. * * RETURNS * Nothing. */ VOID ReadEnvFile(CHAR *EnvFileName) { INT i, j; /* Indices. */ INT stat; /* Input var status counter. */ INT dummy; CHAR opcode; /* Environment spec opcode. */ CHAR command[30]; /* Environment spec command. */ CHAR opparam[30]; /* Command parameter. */ CHAR dummy_char[60]; CHAR datafile[10]; BOOL lights_set; /* Lights set? */ FILE *pf; /* Input file pointer. */ LIGHT *lptr, *lastlight; /* Light node pointers. */ /* Open command file. */ pf = fopen(EnvFileName, "r"); if (!pf) { printf("Unable to open environment file %s.\n", EnvFileName); exit(-1); } InitEnv(); /* Set defaults. */ nlights = 0; lights_set = FALSE; /* Process command file according to opcodes. */ while (fscanf(pf, "%s", command) != EOF) { opcode = LookupCommand(command); switch (opcode) { /* Eye position. */ case OP_EYE: stat = fscanf(pf, "%lf %lf %lf", &(View.eye[0]), &(View.eye[1]), &(View.eye[2])); if (stat != 3) { printf("error: eye position.\n"); exit(-1); } break; /* Center of interest position. */ case OP_COI: stat = fscanf(pf, "%lf %lf %lf", &(View.coi[0]), &(View.coi[1]), &(View.coi[2])); if (stat != 3) { printf("error: coi position.\n"); exit(-1); } break; /* Background color. */ case OP_BKGCOL: stat = fscanf(pf, "%lf %lf %lf", &(View.bkg[0]), &(View.bkg[1]), &(View.bkg[2])); if (stat != 3) { printf("error: background color.\n"); exit(-1); } if (!VerifyColorRange(View.bkg)) exit(-1); break; /* Viewing angle in degrees. */ case OP_VANG: stat = fscanf(pf, "%lf", &(View.vang)); if (stat != 1) { printf("error: viewing angle.\n"); exit(-1); } if (View.vang < 0.0 || View.vang > 100.0) { printf("Invalid angle %f.\n", View.vang); exit(-1); } break; /* Ambient. */ case OP_AMBIENT: stat = fscanf(pf, "%lf %lf %lf", &(View.ambient[0]), &(View.ambient[1]), &(View.ambient[2])); if (stat != 3) { printf("error: ambient.\n"); exit(-1); } if (!VerifyColorRange(View.ambient)) exit(-1); break; /* Anti-aliasing level. */ case OP_ANTILEVEL: stat = fscanf(pf, "%ld", &(Display.maxAAsubdiv)); if (stat != 1) { printf("View error: antialias level.\n"); exit(-1); } if (Display.maxAAsubdiv < 0 || Display.maxAAsubdiv > 3) { printf("error: antialias level %ld.\n", Display.maxAAsubdiv); exit(-1); } break; /* Recursion level. */ case OP_MAXLEVEL: stat = fscanf(pf, "%ld", &(Display.maxlevel)); printf("maxlevel of ray recursion = %ld\n",Display.maxlevel); fflush(stdout); if (stat != 1) { printf("error: recursion level.\n"); exit(-1); } if (Display.maxlevel > 5 || Display.maxlevel < 0) { printf("error: recursion level %ld.\n", Display.maxlevel); exit(-1); } break; /* Mininum ray weight. */ case OP_MINWEIGHT: stat = fscanf(pf, "%lf", &(Display.minweight)); if (stat != 1) { printf("error: miniumum ray weight.\n"); exit(-1); } if (Display.minweight < 0.0 || Display.minweight > 1.0) { printf("error: invalid ray weight %f.\n", Display.minweight); exit(-1); } break; /* Anti tolerance weight. */ case OP_ANTITOL: stat = fscanf(pf, "%lf", &(Display.aatolerance)); if (stat != 1) { printf("error: anti tolerance weight.\n"); exit(-1); } if (Display.aatolerance < 0.0 || Display.aatolerance > 1.0) { printf("error: invalid anti tolerance weight %f.\n", Display.aatolerance); exit(-1); } break; /* Resolution. */ case OP_RES: stat = fscanf(pf, "%ld %ld", &(Display.xres), &(Display.yres)); if (stat != 2) { printf("error: resolution.\n"); exit(-1); } break; /* Light positions and colors. */ case OP_LIGHT: lights_set = TRUE; if (nlights > 0) lptr = GlobalMalloc(sizeof(LIGHT), "env.c"); else lptr = lights; stat = fscanf(pf, "%lf %lf %lf %lf %lf %lf", &(lptr->pos[0]), &(lptr->pos[1]), &(lptr->pos[2]), &(lptr->col[0]), &(lptr->col[1]), &(lptr->col[2])); if (stat != 6) { printf("error: Lights.\n"); exit(-1); } if (!VerifyColorRange(lptr->col)) exit(-1); lptr->pos[3] = 1.0; stat = fscanf(pf, "%ld", &(lptr->shadow)); if (stat != 1) { printf("error: Lights shadow indicator.\n"); exit(-1); } lptr->next = NULL; if (nlights > 0) lastlight->next = lptr; nlights++; lastlight = lptr; break; /* Model transformation matrix. */ case OP_MODELMAT: for (i = 0; i < 4; i++) for (j = 0; j < 4; j++) { stat = fscanf(pf, "%lf", &(View.model[i][j])); if (stat != 1) { printf("Error in matrix.\n"); exit(-1); } } ModelTransform = TRUE; break; /* Shadow info. */ case OP_SHAD: stat = fscanf(pf, "%s", opparam); if (stat != 1) { printf("error: shadow.\n"); exit(-1); } if (strcmp(opparam, "on") == 0) View.shad = TRUE; else View.shad = FALSE; break; /* Shading info. */ case OP_SHADING: stat = fscanf(pf, "%s", opparam); if (stat != 1) { printf("error: shading %s.\n", opparam); exit(-1); } if (strcmp(opparam, "on") == 0) View.shading = TRUE; else View.shading = FALSE; break; /* Projection type. */ case OP_PROJECT: stat = fscanf(pf, "%s", opparam); if (stat != 1) { printf("error: projection %s.\n", opparam); exit(-1); } if (strcmp(opparam, "perspective") == 0) View.projection = PT_PERSP; else if (strcmp(opparam, "orthographic") == 0) View.projection = PT_ORTHO; else { printf("Invalid projection %s.\n", opparam); exit(-1); } break; /* Database traversal info. */ case OP_TRAVERSAL: stat = fscanf(pf, "%s", opparam); if (stat != 1) { printf("error: traversal %s.\n", opparam); exit(-1); } if (strcmp(opparam, "list") == 0) TraversalType = TT_LIST; else if (strcmp(opparam, "huniform") == 0) TraversalType = TT_HUG; else { printf("Invalid traversal code %s.\n", opparam); exit(-1); } break; /* Geometry file. */ case OP_GEOM_FILE: stat = fscanf(pf, " %s", GeoFileName); if (stat != 1) { printf("error: geometry file.\n"); exit(-1); } GeoFile = TRUE; break; /* Runlength file. */ case OP_RL_FILE: stat = fscanf(pf, " %s", PicFileName); if (stat != 1) { printf("error: runlength file.\n"); exit(-1); } PicFile = TRUE; break; case OP_PREVIEW_BKCULL: stat = fscanf(pf, "%ld", &dummy); if (stat != 1) { printf("error: Preview bkcull.\n"); exit(-1); } break; case OP_PREVIEW_FILL: stat = fscanf(pf, "%ld", &dummy); if (stat != 1) { printf("error: Preview fill.\n"); exit(-1); } break; case OP_PREVIEW_SPHTESS: stat = fscanf(pf, "%s", dummy_char); if (stat != 1) { printf("error: sphere tess.\n"); exit(-1); } break; case OP_NORM_DB: stat = fscanf(pf, "%s", opparam); if (stat != 1) { printf("error: norm database.\n"); exit(-1); } if (strcmp(opparam, "no") == 0) ModelNorm = FALSE; break; case OP_DATA_TYPE: stat = fscanf(pf, "%s", datafile); if (stat != 1) { printf("error: datatype.\n"); exit(-1); } if (strcmp(datafile, "binary") == 0) DataType = DT_BINARY; break; case OP_HU_MAX_PRIMS_CELL: stat = fscanf(pf, "%ld", &hu_max_prims_cell); if (stat != 1) { printf("error: Huniform prims per cell.\n"); exit(-1); } break; case OP_HU_GRIDSIZE: stat = fscanf(pf, "%ld", &hu_gridsize); if (stat != 1) { printf("error: Huniform gridsize.\n"); exit(-1); } break; case OP_HU_NUMBUCKETS: stat = fscanf(pf, "%ld", &hu_numbuckets); if (stat != 1) { printf("error: Huniform numbuckets.\n"); exit(-1); } break; case OP_HU_MAX_SUBDIV: stat = fscanf(pf, "%ld", &hu_max_subdiv_level); if (stat != 1 || hu_max_subdiv_level > 3) { printf("error: Huniform max subdiv level.\n"); exit(-1); } break; case OP_HU_LAZY: stat = fscanf(pf, "%ld", &hu_lazy); if (stat != 1) { printf("error: Huniform lazy.\n"); exit(-1); } break; case OP_BUNDLE: stat = fscanf(pf, "%ld %ld", &bundlex, &bundley); if (stat != 2 ) { printf("error: bundle.\n"); exit(-1); } break; case OP_BLOCK: stat = fscanf(pf, "%ld %ld", &blockx, &blocky); if (stat != 2 ) { printf("error: block.\n"); exit(-1); } break; default: printf("Warning: unrecognized env command: %s.\n", command); break; } } fclose(pf); /* Display parameters reset. */ Display.numpixels = Display.xres*Display.yres; Display.vWscale = Display.scrWidth/Display.xres; Display.vHscale = Display.scrHeight/Display.yres; /* If no light information given, set default. */ if (!lights_set) InitLights(); /* Set up screen parameters. */ InitDisplay(); /* Parameter check; think about lifting this restriction. */ if ((TraversalType != TT_LIST) && ModelNorm == FALSE) { printf("Data must be normalized with this traversal method!.\n"); ModelNorm = TRUE; } }