| /*************************************************************************/ |
| /* */ |
| /* 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 <stdio.h> |
| #include <math.h> |
| #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(c) |
| 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(m) |
| 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(M, x, y, z) |
| MATRIX M; |
| REAL x, y, 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(tray) |
| 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(normMat) |
| MATRIX normMat; |
| { |
| POINT tmp; |
| |
| 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(s) |
| 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(EnvFileName) |
| 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 = %d\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; |
| } |
| } |
| |