home *** CD-ROM | disk | FTP | other *** search
- /************************************************************************
- * *
- * Copyright (c) 1988, David B. Wecker *
- * All Rights Reserved *
- * *
- * This file is part of DBW_uRAY *
- * *
- * DBW_uRAY is distributed in the hope that it will be useful, but *
- * WITHOUT ANY WARRANTY. No author or distributor accepts *
- * responsibility to anyone for the consequences of using it or for *
- * whether it serves any particular purpose or works at all, unless *
- * he says so in writing. Refer to the DBW_uRAY General Public *
- * License for full details. *
- * *
- * Everyone is granted permission to copy, modify and redistribute *
- * DBW_uRAY, but only under the conditions described in the *
- * DBW_uRAY General Public License. A copy of this license is *
- * supposed to have been given to you along with DBW_uRAY so you *
- * can know your rights and responsibilities. It should be in a file *
- * named COPYING. Among other things, the copyright notice and this *
- * notice must be preserved on all copies. *
- ************************************************************************
- * *
- * Authors: *
- * DBW - David B. Wecker *
- * *
- * Versions: *
- * V1.0 881023 DBW - First released version *
- * V1.1 881110 DBW - Fixed scan coherence code *
- * V1.2 881125 DBW - Removed ALL scan coherence code (useless) *
- * added "fat" extent boxes *
- * *
- ************************************************************************/
-
- #include "uray.h"
-
- /************************************************************************/
- /********************* support (misc) routines **************************/
- /************************************************************************/
-
-
- /* leave the program. if msg is not NULL then an error occurred */
- /* also, return any used resources at this point */
-
- void leave(msg,arg1,arg2)
- char *msg,*arg1,*arg2;
- {
-
- /* are we writing a .tmp file */
- if (bpp && fp) fclose(fp);
-
- /* are we writing a .ilbm file (go back and put in the colortable) */
- if (fp2) {
- fseek(fp2,(long)pos2,0); wfil(fp2,4,&lsize);
- lsize -= BODYsize;
- lsize += FORMsize;
- fseek(fp2,(long)pos1,0); wfil(fp2,4,&lsize);
- fseek(fp2,(long)pos3,0);
- fwrite(colors,1,48,fp2);
- fclose(fp2);
- }
-
- /* is there an error message */
- if (msg) {
- fprintf(stderr,"\nURAY: ");
- fprintf(stderr,msg,arg1,arg2);
- fprintf(stderr,"\n");
- exit(-2);
- }
- exit(1);
- }
-
- /* do a malloc and make sure that we got the memory */
- char *my_malloc(size)
- {
- char *result,*malloc();
-
- if (!(result = malloc(size))) leave("Can't malloc memory");
- return result;
- }
-
- /* do a calloc and make sure that we got the memory */
- char *my_calloc(size,num)
- {
- char *result,*calloc();
-
- if (!(result = calloc(size,num))) leave("Can't calloc memory");
- return result;
- }
-
- /* allocate and initialize a node (for input routine) */
- NODE *doalloc(typ) {
- NODE *nod;
- EXTENT *newe;
-
- /* get memory for the new object */
- switch (typ) {
- case TYP_E: nod = (NODE *)my_malloc(sizeof(EXTENT)); break;
- case TYP_S: nod = (NODE *)my_malloc(sizeof(SPHERE)); break;
- case TYP_T: nod = (NODE *)my_malloc(sizeof(TRIANGLE)); break;
- case TYP_Q: nod = (NODE *)my_malloc(sizeof(QUAD)); break;
- case TYP_R: nod = (NODE *)my_malloc(sizeof(RING)); break;
- case TYP_L: nod = (NODE *)my_malloc(sizeof(LIGHT)); break;
- }
-
- if (typ == TYP_L) return;
-
- nod->next = NULL;
- nod->typ = typ;
-
- /* if this is an extent, just return it */
- if (typ == TYP_E) {
- extcnt++;
- return nod;
- }
-
- /* else get memory for an extent around the object (and count the obj) */
- newe = (EXTENT *)doalloc(TYP_E);
- newe->child = nod;
- objcnt++;
-
- /* and link it in to the extent tree */
- newe->next = nodes;
- nodes = (NODE *)newe;
-
- /* return the object to the user */
- return nod;
- }
-
- /* add a light to the list of lights (for fast lookup) */
- void addlight(nod)
- NODE *nod;
- {
- LIGHT *l;
-
- if (nod->att->kl == 0.0) return;
-
- l = (LIGHT *)doalloc(TYP_L);
- l->next = lights;
- l->child = nod;
- lights = l;
- }
-
- /* debug routine (see DEBUG_dumpnodes in uray.h) for dumping nodes */
- void dumpnodes(n,lev)
- NODE *n;
- {
- int i;
- EXTENT *e;
-
- /* do each node at this level */
- while (n) {
-
- /* space over the current level amount */
- for (i=0; i<lev; i++) printf(".");
-
- /* print out type of node */
- printf(" %c",TYPstr[n->typ]);
-
- /* if an extent, then go down recursively */
- if (n->typ == TYP_E) {
- e = (EXTENT *)n;
- if (e->child->typ != TYP_E) printf("%c",TYPstr[e->child->typ]);
- else printf(" ");
-
- /* print extent range */
- printf(" [%7.4f,%7.4f] [%7.4f,%7.4f] [%7.4f,%7.4f]\n",
- e->min[0],e->max[0],e->min[1],e->max[1],
- e->min[2],e->max[2]);
-
- /* do recursion */
- if (e->child->typ == TYP_E) dumpnodes(e->child,lev+1);
- }
-
- /* get next node at this level */
- n = n->next;
- }
- }
-
- /* make vector into unit vector */
- void vunit(A,B)
- VEC A,B;
- {
- register FLTDBL tmp;
-
- tmp = 1.0 / vnorm(A);
- vscale(tmp, A, B);
- }
-
- /* find the normal to a sphere */
- void spherenormal(intersect,s,normal)
- VEC intersect,normal;
- SPHERE *s;
- {
- VEC v1;
-
- /* get the direction from the center */
- vcomb(-1.0, intersect, s->cen, v1);
-
- /* then normalize */
- vunit(v1,normal);
- }
-
- /* find the normal to a plane */
- void planenormal(s,normal)
- QUAD *s;
- VEC normal;
- {
- VEC v1;
-
- /* first do vector cross product */
- vcross(s->v1,s->v2,v1);
-
- /* then normalize */
- vunit(v1,normal);
- }
-
- /* read the input .dat file */
- void readinput()
- {
- int i,j;
- FLTDBL val;
- int tmp1,tmp2;
-
- /* get the input file open */
- printf("Creating objects\n");
- sprintf(str,"%s.dat",basnam);
- fp = fopen(str,"r");
- if (!fp) leave("Bad input file");
-
- /* read each line of the file */
- while (fgets(str,80,fp)) {
-
- /* every legal (~comment) line must start with a string and a num */
- if (sscanf(str,SCAN1,cmd,&val) != 2) continue;
-
- /* read in the global parameters */
- if (!strcmp(cmd,"DEPTH")) depth = (int)val;
- else if (!strcmp(cmd,"ROWS")) rows = (short)val;
- else if (!strcmp(cmd,"START")) startrow = (short)val;
- else if (!strcmp(cmd,"END")) endrow = (short)val;
- else if (!strcmp(cmd,"COLS")) cols = (short)val;
- else if (!strcmp(cmd,"BPP")) bpp = (short)val;
- else if (!strcmp(cmd,"AOV")) aov = (int)val;
- else if (!strcmp(cmd,"ASPECT")) aspect = val;
- else if (!strcmp(cmd,"NEAR"))
- sscanf(str,SCAN2,cmd,&NEAR[0],&NEAR[1],&NEAR[2]);
- else if (!strcmp(cmd,"FAR"))
- sscanf(str,SCAN2,cmd,&FAR[0],&FAR[1],&FAR[2]);
- else if (!strcmp(cmd,"GROUND"))
- sscanf(str,SCAN2,cmd,&GROUND[0],&GROUND[1],&GROUND[2]);
- else if (!strcmp(cmd,"BASE")) base = val;
-
- /* read in attributes */
- else if (!strcmp(cmd,"ATTRIBUTES")) {
- natts = (int)val;
- atts = (ATT *)my_calloc(sizeof(ATT),natts);
-
- /* read in each attribute line */
- for (i=0; i<natts; i++) {
- fgets(str,80,fp);
- if (sscanf(str,SCAN3,
- &atts[i].color[0],&atts[i].color[1],&atts[i].color[2],
- &atts[i].kd,&atts[i].ks,&atts[i].kt,&atts[i].ir,
- &atts[i].kl,&atts[i].dist,&atts[i].kf,
- &tmp1,&tmp2,
- &atts[i].p1[0],&atts[i].p1[1],&atts[i].p1[2],
- &atts[i].p2[0],&atts[i].p2[1],&atts[i].p2[2])
- < 12
- ) leave("Bad attribute");
- atts[i].wave = (short)tmp1;
- atts[i].tex = (short)tmp2;
- }
- }
-
- /* read in waves */
- else if (!strcmp(cmd,"WAVES")) {
- nwaves = (int)val;
- waves = (WAVE *)my_calloc(sizeof(WAVE),nwaves);
-
- /* read in each wave line */
- for (i=0; i<nwaves; i++) {
- fgets(str,80,fp);
- if (sscanf(str,SCAN4,
- &waves[i].cen[0],&waves[i].cen[1],&waves[i].cen[2],
- &waves[i].amp,&waves[i].phase,&waves[i].length,
- &waves[i].damp)
- < 7) leave("Bad wave");
- }
- }
-
- /* read in an object - SPHERE */
- else if (!strcmp(cmd,"SPHERE")) {
- sph = (SPHERE *)doalloc(TYP_S);
- sscanf(str,SCAN5,cmd,&j,
- &sph->cen[0],&sph->cen[1],&sph->cen[2],
- &sph->rad);
- sph->rad *= sph->rad;
- sph->att = &atts[j];
- if (sph->rad < TOL) sph->rad = TOL;
- addlight(sph);
- }
-
- /* read in an object - QUAD */
- else if (!strcmp(cmd,"QUAD")) {
- qua = (QUAD *)doalloc(TYP_Q);
- sscanf(str,SCAN6,cmd,&j,
- &qua->p0[0],&qua->p0[1],&qua->p0[2],
- &qua->v1[0],&qua->v1[1],&qua->v1[2],
- &qua->v2[0],&qua->v2[1],&qua->v2[2]);
- qua->att = &atts[j];
- addlight(qua);
- }
-
- /* read in an object - TRIANGLE */
- else if (!strcmp(cmd,"TRIANGLE")) {
- tri = (TRIANGLE *)doalloc(TYP_T);
- sscanf(str,SCAN6,cmd,&j,
- &tri->p0[0],&tri->p0[1],&tri->p0[2],
- &tri->v1[0],&tri->v1[1],&tri->v1[2],
- &tri->v2[0],&tri->v2[1],&tri->v2[2]);
- tri->att = &atts[j];
- addlight(tri);
- }
-
- /* read in an object - RING */
- else if (!strcmp(cmd,"RING")) {
- rin = (RING *)doalloc(TYP_R);
- sscanf(str,SCAN7,cmd,&j,
- &rin->p0[0],&rin->p0[1],&rin->p0[2],
- &rin->v1[0],&rin->v1[1],&rin->v1[2],
- &rin->v2[0],&rin->v2[1],&rin->v2[2],
- &rin->rad1,&rin->rad2);
- rin->rad1 *= rin->rad1;
- rin->rad2 *= rin->rad2;
- rin->att = &atts[j];
- vunit(rin->v1,rin->v1);
- vunit(rin->v2,rin->v2);
- addlight(rin);
- }
- }
-
- /* fix up global parameters */
- if (endrow > rows) endrow = rows;
- if (startrow >= endrow) startrow = endrow - 1;
- if (startrow < 0) startrow = 0;
- cols &= 0xFFF8;
-
- /* print out what we read in (sanity check) */
- printf("\n");
- printf(" Input file name: %14s\n",basnam);
- printf(" Maximum recursion depth: %6d\n",depth);
- printf(" Dimensions: %6d rows (%d,%d) %d columns\n",
- rows,startrow,endrow,cols);
- printf(" Bits/Pixel: %6d\n",bpp);
- printf(" Angle of view: %6d degrees\n",aov);
- printf(" Aspect ratio: %6.3f\n",(double)aspect);
- printf(" Number of attributes: %6d\n",natts);
- printf(" Number of waves: %6d\n",nwaves);
- printf("\n");
-
- /* terminate the input file */
- fclose(fp);
- fp = NULL;
- }
-
-
-