home *** CD-ROM | disk | FTP | other *** search
/ Encyclopedia of Graphics File Formats Companion / GFF_CD.ISO / formats / uray / code / support.c < prev    next >
C/C++ Source or Header  |  1994-06-20  |  11KB  |  369 lines

  1. /************************************************************************
  2.  *                                    *
  3.  *            Copyright (c) 1988, David B. Wecker            *
  4.  *                All Rights Reserved                *
  5.  *                                    *
  6.  * This file is part of DBW_uRAY                    *
  7.  *                                    *
  8.  * DBW_uRAY is distributed in the hope that it will be useful, but    *
  9.  * WITHOUT ANY WARRANTY. No author or distributor accepts        *
  10.  * responsibility to anyone for the consequences of using it or for    *
  11.  * whether it serves any particular purpose or works at all, unless    *
  12.  * he says so in writing. Refer to the DBW_uRAY General Public        *
  13.  * License for full details.                        *
  14.  *                                    *
  15.  * Everyone is granted permission to copy, modify and redistribute    *
  16.  * DBW_uRAY, but only under the conditions described in the        *
  17.  * DBW_uRAY General Public License. A copy of this license is        *
  18.  * supposed to have been given to you along with DBW_uRAY so you    *
  19.  * can know your rights and responsibilities. It should be in a file    *
  20.  * named LICENSE. Among other things, the copyright notice and this    *
  21.  * notice must be preserved on all copies.                *
  22.  ************************************************************************
  23.  *                                    *
  24.  * Authors:                                *
  25.  *    DBW - David B. Wecker                        *
  26.  *                                    *
  27.  * Versions:                                *
  28.  *    V1.0 881023 DBW    - First released version            *
  29.  *    V1.1 881110 DBW - Fixed scan coherence code            *
  30.  *    V1.2 881125 DBW - Removed ALL scan coherence code (useless)    *
  31.  *              added "fat" extent boxes            *
  32.  *    V1.3 881203 DBW - Fixed single precision TOLerances        *
  33.  *                                    *
  34.  ************************************************************************/
  35.  
  36. #include "uray.h"
  37.  
  38. /************************************************************************/
  39. /********************* support (misc) routines **************************/
  40. /************************************************************************/
  41.  
  42.  
  43. /* leave the program. if msg is not NULL then an error occurred */
  44. /* also, return any used resources at this point */
  45.  
  46. void leave(msg,arg1,arg2)
  47. char    *msg,*arg1,*arg2;
  48.     {
  49.  
  50.     /* are we writing a .tmp file */
  51.     if (bpp && fp) fclose(fp);
  52.  
  53.     /* are we writing a .ilbm file (go back and put in the colortable) */
  54.     if (fp2) {
  55.     fseek(fp2,(long)pos2,0); wfil(fp2,4,&lsize);
  56.     lsize -= BODYsize;
  57.     lsize += FORMsize;
  58.     fseek(fp2,(long)pos1,0); wfil(fp2,4,&lsize);
  59.     fseek(fp2,(long)pos3,0);
  60.     fwrite(colors,1,48,fp2);
  61.     fclose(fp2);
  62.     }
  63.  
  64.     /* is there an error message */
  65.     if (msg) {
  66.     fprintf(stderr,"\nURAY: ");
  67.     fprintf(stderr,msg,arg1,arg2);
  68.     fprintf(stderr,"\n");
  69.     exit(-2);
  70.     }
  71.     exit(1);
  72.     }
  73.  
  74. /* do a malloc and make sure that we got the memory */
  75. char *my_malloc(size)
  76.     {
  77.     char    *result,*malloc();
  78.  
  79.     if (!(result = malloc(size))) leave("Can't malloc memory");
  80.     return result;
  81.     }
  82.  
  83. /* do a calloc and make sure that we got the memory */
  84. char *my_calloc(size,num)
  85.     {
  86.     char    *result,*calloc();
  87.  
  88.     if (!(result = calloc(size,num))) leave("Can't calloc memory");
  89.     return result;
  90.     }
  91.  
  92. /* allocate and initialize a node (for input routine) */
  93. NODE    *doalloc(typ) {
  94.     NODE    *nod;
  95.     EXTENT  *newe;
  96.  
  97.     /* get memory for the new object */
  98.     switch (typ) {
  99.     case TYP_E:    nod = (NODE *)my_malloc(sizeof(EXTENT));    break;
  100.     case TYP_S:    nod = (NODE *)my_malloc(sizeof(SPHERE));    break;
  101.     case TYP_T:    nod = (NODE *)my_malloc(sizeof(TRIANGLE));  break;
  102.     case TYP_Q:    nod = (NODE *)my_malloc(sizeof(QUAD));        break;
  103.     case TYP_R:    nod = (NODE *)my_malloc(sizeof(RING));        break;
  104.     case TYP_L:    nod = (NODE *)my_malloc(sizeof(LIGHT));        break;
  105.     }
  106.  
  107.     if (typ == TYP_L) return;
  108.  
  109.     nod->next    = NULL;
  110.     nod->typ    = typ;
  111.  
  112.     /* if this is an extent, just return it */
  113.     if (typ == TYP_E) {
  114.     extcnt++;
  115.     return nod;
  116.     }
  117.  
  118.     /* else get memory for an extent around the object (and count the obj) */
  119.     newe    = (EXTENT *)doalloc(TYP_E);
  120.     newe->child    = nod;
  121.     objcnt++;
  122.  
  123.     /* and link it in to the extent tree */
  124.     newe->next    = nodes;
  125.     nodes    = (NODE *)newe;
  126.  
  127.     /* return the object to the user */
  128.     return nod;
  129.     }
  130.  
  131. /* add a light to the list of lights (for fast lookup) */
  132. void addlight(nod)
  133. NODE    *nod;
  134.     {
  135.     LIGHT   *l;
  136.  
  137.     if (nod->att->kl == 0.0) return;
  138.  
  139.     l = (LIGHT *)doalloc(TYP_L);
  140.     l->next    = lights;
  141.     l->child    = nod;
  142.     lights    = l;
  143.     }
  144.  
  145. /* debug routine (see DEBUG_dumpnodes in uray.h) for dumping nodes */
  146. void dumpnodes(n,lev)
  147. NODE    *n;
  148.     {
  149.     int        i;
  150.     EXTENT  *e;
  151.  
  152.     /* do each node at this level */
  153.     while (n) {
  154.  
  155.     /* space over the current level amount */
  156.     for (i=0; i<lev; i++) printf(".");
  157.  
  158.     /* print out type of node */
  159.     printf(" %c",TYPstr[n->typ]);
  160.  
  161.     /* if an extent, then go down recursively */
  162.     if (n->typ == TYP_E) {
  163.         e = (EXTENT *)n;
  164.         if (e->child->typ != TYP_E)    printf("%c",TYPstr[e->child->typ]);
  165.         else            printf(" ");
  166.  
  167.         /* print extent range */
  168.         printf(" [%7.4f,%7.4f] [%7.4f,%7.4f] [%7.4f,%7.4f]\n",
  169.         e->min[0],e->max[0],e->min[1],e->max[1],
  170.              e->min[2],e->max[2]);
  171.  
  172.         /* do recursion */
  173.         if (e->child->typ == TYP_E) dumpnodes(e->child,lev+1);
  174.         }
  175.  
  176.     /* get next node at this level */
  177.     n = n->next;
  178.     }
  179.     }
  180.  
  181. /* make vector into unit vector */
  182. void vunit(A,B)
  183. VEC A,B;
  184.     {
  185.     register FLTDBL  tmp;
  186.  
  187.     tmp = 1.0 / vnorm(A);
  188.     vscale(tmp, A, B);
  189.     }
  190.  
  191. /* find the normal to a sphere */
  192. void spherenormal(intersect,s,normal)
  193. VEC    intersect,normal;
  194. SPHERE    *s;
  195.     {
  196.     VEC    v1;
  197.  
  198.     /* get the direction from the center */
  199.     vcomb(-1.0, intersect, s->cen, v1);
  200.  
  201.     /* then normalize */
  202.     vunit(v1,normal);
  203.     }    
  204.  
  205. /* find the normal to a plane */
  206. void planenormal(s,normal)
  207. QUAD    *s;
  208. VEC    normal;
  209.     {
  210.     VEC    v1;
  211.  
  212.     /* first do vector cross product */
  213.     vcross(s->v1,s->v2,v1);
  214.  
  215.     /* then normalize */
  216.     vunit(v1,normal);
  217.     }
  218.  
  219. /* read the input .dat file  */
  220. void readinput()
  221.     {
  222.     int        i,j;
  223.     FLTDBL    val;
  224.     int        tmp1,tmp2;
  225.  
  226.     /* get the input file open */
  227.     printf("Creating objects\n");
  228.     sprintf(str,"%s.dat",basnam);
  229.     fp = fopen(str,"r");
  230.     if (!fp) leave("Bad input file");
  231.  
  232.     /* read each line of the file */
  233.     while (fgets(str,80,fp)) {
  234.  
  235.     /* every legal (~comment) line must start with a string and a num */
  236.     if (sscanf(str,SCAN1,cmd,&val) != 2) continue;
  237.  
  238.     /* read in the global parameters */
  239.     if (!strcmp(cmd,"DEPTH"))    depth        = (int)val;
  240.     else if (!strcmp(cmd,"ROWS"))    rows        = (short)val;
  241.     else if (!strcmp(cmd,"START"))    startrow    = (short)val;
  242.     else if (!strcmp(cmd,"END"))    endrow        = (short)val;
  243.     else if (!strcmp(cmd,"COLS"))    cols        = (short)val;
  244.     else if (!strcmp(cmd,"BPP"))    bpp        = (short)val;
  245.     else if (!strcmp(cmd,"AOV"))    aov        = (int)val;
  246.     else if (!strcmp(cmd,"ASPECT"))    aspect        = val;
  247.     else if (!strcmp(cmd,"NEAR"))
  248.         sscanf(str,SCAN2,cmd,&NEAR[0],&NEAR[1],&NEAR[2]);
  249.     else if (!strcmp(cmd,"FAR"))
  250.         sscanf(str,SCAN2,cmd,&FAR[0],&FAR[1],&FAR[2]);
  251.     else if (!strcmp(cmd,"GROUND"))
  252.         sscanf(str,SCAN2,cmd,&GROUND[0],&GROUND[1],&GROUND[2]);
  253.     else if (!strcmp(cmd,"BASE"))    base        = val;
  254.  
  255.     /* read in attributes */
  256.     else if (!strcmp(cmd,"ATTRIBUTES")) {
  257.         natts   = (int)val;
  258.         atts    = (ATT *)my_calloc(sizeof(ATT),natts);
  259.  
  260.         /* read in each attribute line */
  261.         for (i=0; i<natts; i++) {
  262.         fgets(str,80,fp);
  263.         if (sscanf(str,SCAN3,
  264.             &atts[i].color[0],&atts[i].color[1],&atts[i].color[2],
  265.             &atts[i].kd,&atts[i].ks,&atts[i].kt,&atts[i].ir,
  266.             &atts[i].kl,&atts[i].dist,&atts[i].kf,
  267.             &tmp1,&tmp2,
  268.             &atts[i].p1[0],&atts[i].p1[1],&atts[i].p1[2],
  269.             &atts[i].p2[0],&atts[i].p2[1],&atts[i].p2[2])
  270.             < 12
  271.             ) leave("Bad attribute");
  272.         atts[i].wave = (short)tmp1;
  273.         atts[i].tex  = (short)tmp2;
  274.         }
  275.         }
  276.  
  277.     /* read in waves */
  278.     else if (!strcmp(cmd,"WAVES")) {
  279.         nwaves  = (int)val;
  280.         waves   = (WAVE *)my_calloc(sizeof(WAVE),nwaves);
  281.  
  282.         /* read in each wave line */
  283.         for (i=0; i<nwaves; i++) {
  284.         fgets(str,80,fp);
  285.         if (sscanf(str,SCAN4,
  286.             &waves[i].cen[0],&waves[i].cen[1],&waves[i].cen[2],
  287.             &waves[i].amp,&waves[i].phase,&waves[i].length,
  288.             &waves[i].damp)
  289.             < 7) leave("Bad wave");
  290.         }
  291.         }
  292.  
  293.     /* read in an object - SPHERE */
  294.     else if (!strcmp(cmd,"SPHERE")) {
  295.         sph        = (SPHERE *)doalloc(TYP_S);
  296.         sscanf(str,SCAN5,cmd,&j,
  297.         &sph->cen[0],&sph->cen[1],&sph->cen[2],
  298.         &sph->rad);
  299.         sph->rad *= sph->rad;
  300.         sph->att  = &atts[j];
  301.         if (sph->rad < TOL) sph->rad = TOL;
  302.         addlight(sph);
  303.         }
  304.  
  305.     /* read in an object - QUAD */
  306.     else if (!strcmp(cmd,"QUAD")) {
  307.         qua        = (QUAD *)doalloc(TYP_Q);
  308.         sscanf(str,SCAN6,cmd,&j,
  309.         &qua->p0[0],&qua->p0[1],&qua->p0[2],
  310.         &qua->v1[0],&qua->v1[1],&qua->v1[2],
  311.         &qua->v2[0],&qua->v2[1],&qua->v2[2]);
  312.         qua->att = &atts[j];
  313.         addlight(qua);
  314.         }
  315.  
  316.     /* read in an object - TRIANGLE */
  317.     else if (!strcmp(cmd,"TRIANGLE")) {
  318.         tri        = (TRIANGLE *)doalloc(TYP_T);
  319.         sscanf(str,SCAN6,cmd,&j,
  320.         &tri->p0[0],&tri->p0[1],&tri->p0[2],
  321.         &tri->v1[0],&tri->v1[1],&tri->v1[2],
  322.         &tri->v2[0],&tri->v2[1],&tri->v2[2]);
  323.         tri->att = &atts[j];
  324.         addlight(tri);
  325.         }
  326.  
  327.     /* read in an object - RING */
  328.     else if (!strcmp(cmd,"RING")) {
  329.         rin        = (RING *)doalloc(TYP_R);
  330.         sscanf(str,SCAN7,cmd,&j,
  331.         &rin->p0[0],&rin->p0[1],&rin->p0[2],
  332.         &rin->v1[0],&rin->v1[1],&rin->v1[2],
  333.         &rin->v2[0],&rin->v2[1],&rin->v2[2],
  334.         &rin->rad1,&rin->rad2);
  335.         rin->rad1 *= rin->rad1;
  336.         rin->rad2 *= rin->rad2;
  337.         rin->att = &atts[j];
  338.         vunit(rin->v1,rin->v1);
  339.         vunit(rin->v2,rin->v2);
  340.         addlight(rin);
  341.         }
  342.     }
  343.  
  344.     /* fix up global parameters */
  345.     if (endrow > rows)        endrow   = rows;
  346.     if (startrow >= endrow) startrow = endrow - 1;
  347.     if (startrow < 0)        startrow = 0;
  348.     cols &= 0xFFF8;
  349.  
  350.     /* print out what we read in (sanity check) */
  351.     printf("\n");
  352.     printf("    Input file name: %14s\n",basnam);
  353.     printf("    Maximum recursion depth: %6d\n",depth);
  354.     printf("    Dimensions:              %6d rows (%d,%d)  %d columns\n",
  355.     rows,startrow,endrow,cols);
  356.     printf("    Bits/Pixel:              %6d\n",bpp);
  357.     printf("    Angle of view:           %6d degrees\n",aov);
  358.     printf("    Aspect ratio:            %6.3f\n",(double)aspect);
  359.     printf("    Number of attributes:    %6d\n",natts);
  360.     printf("    Number of waves:         %6d\n",nwaves);
  361.     printf("\n");
  362.  
  363.     /* terminate the input file */
  364.     fclose(fp);
  365.     fp = NULL;
  366.     }
  367.  
  368.  
  369.