home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 8 / CDASC08.ISO / NEWS / RADIANCE / SRC / RT / RTRACE / RTRACE.C
C/C++ Source or Header  |  1993-10-07  |  10KB  |  474 lines

  1. /* Copyright (c) 1992 Regents of the University of California */
  2.  
  3. #ifndef lint
  4. static char SCCSid[] = "@(#)rtrace.c 2.8 10/15/92 LBL";
  5. #endif
  6.  
  7. /*
  8.  *  rtrace.c - program and variables for individual ray tracing.
  9.  *
  10.  *     6/11/86
  11.  */
  12.  
  13. /*
  14.  *  Input is in the form:
  15.  *
  16.  *    xorg    yorg    zorg    xdir    ydir    zdir
  17.  *
  18.  *  The direction need not be normalized.  Output is flexible.
  19.  *  If the direction vector is (0,0,0), then the output is flushed.
  20.  *  All values default to ascii representation of real
  21.  *  numbers.  Binary representations can be selected
  22.  *  with '-ff' for float or '-fd' for double.  By default,
  23.  *  radiance is computed.  The '-i' or '-I' options indicate that
  24.  *  irradiance values are desired.
  25.  */
  26.  
  27. #include  "ray.h"
  28.  
  29. #include  "octree.h"
  30.  
  31. #include  "otypes.h"
  32.  
  33. #include  "resolu.h"
  34.  
  35. int  dimlist[MAXDIM];            /* sampling dimensions */
  36. int  ndims = 0;                /* number of sampling dimensions */
  37. int  samplendx = 0;            /* index for this sample */
  38.  
  39. int  imm_irrad = 0;            /* compute immediate irradiance? */
  40.  
  41. int  inform = 'a';            /* input format */
  42. int  outform = 'a';            /* output format */
  43. char  *outvals = "v";            /* output specification */
  44.  
  45. int  hresolu = 0;            /* horizontal (scan) size */
  46. int  vresolu = 0;            /* vertical resolution */
  47.  
  48. double  dstrsrc = 0.0;            /* square source distribution */
  49. double  shadthresh = .05;        /* shadow threshold */
  50. double  shadcert = .5;            /* shadow certainty */
  51. int  directrelay = 1;            /* number of source relays */
  52. int  vspretest = 512;            /* virtual source pretest density */
  53. int  directinvis = 0;            /* sources invisible? */
  54. double  srcsizerat = .25;        /* maximum ratio source size/dist. */
  55.  
  56. double  specthresh = .15;        /* specular sampling threshold */
  57. double  specjitter = 1.;        /* specular sampling jitter */
  58.  
  59. int  maxdepth = 6;            /* maximum recursion depth */
  60. double  minweight = 4e-3;        /* minimum ray weight */
  61.  
  62. COLOR  ambval = BLKCOLOR;        /* ambient value */
  63. double  ambacc = 0.2;            /* ambient accuracy */
  64. int  ambres = 32;            /* ambient resolution */
  65. int  ambdiv = 128;            /* ambient divisions */
  66. int  ambssamp = 0;            /* ambient super-samples */
  67. int  ambounce = 0;            /* ambient bounces */
  68. char  *amblist[128];            /* ambient include/exclude list */
  69. int  ambincl = -1;            /* include == 1, exclude == 0 */
  70.  
  71. extern OBJREC  Lamb;            /* a Lambertian surface */
  72.  
  73. static RAY  thisray;            /* for our convenience */
  74.  
  75. static int  oputo(), oputd(), oputv(), oputl(), oputL(),
  76.         oputp(), oputn(), oputs(), oputw(), oputm();
  77.  
  78. static int  (*ray_out[10])(), (*every_out[10])();
  79. static int  castonly;
  80.  
  81. static int  puta(), putf(), putd();
  82.  
  83. static int  (*putreal)();
  84.  
  85.  
  86. quit(code)            /* quit program */
  87. int  code;
  88. {
  89.     exit(code);
  90. }
  91.  
  92.  
  93. char *
  94. formstr(f)                /* return format identifier */
  95. int  f;
  96. {
  97.     switch (f) {
  98.     case 'a': return("ascii");
  99.     case 'f': return("float");
  100.     case 'd': return("double");
  101.     case 'c': return(COLRFMT);
  102.     }
  103.     return("unknown");
  104. }
  105.  
  106.  
  107. rtrace(fname)                /* trace rays from file */
  108. char  *fname;
  109. {
  110.     long  vcount = hresolu>1 ? hresolu*vresolu : vresolu;
  111.     long  nextflush = hresolu;
  112.     FILE  *fp;
  113.     FVECT  orig, direc;
  114.                     /* set up input */
  115.     if (fname == NULL)
  116.         fp = stdin;
  117.     else if ((fp = fopen(fname, "r")) == NULL) {
  118.         sprintf(errmsg, "cannot open input file \"%s\"", fname);
  119.         error(SYSTEM, errmsg);
  120.     }
  121. #ifdef MSDOS
  122.     if (inform != 'a')
  123.         setmode(fileno(fp), O_BINARY);
  124. #endif
  125.                     /* set up output */
  126.     setoutput(outvals);
  127.     switch (outform) {
  128.     case 'a': putreal = puta; break;
  129.     case 'f': putreal = putf; break;
  130.     case 'd': putreal = putd; break;
  131.     case 'c': 
  132.         if (strcmp(outvals, "v"))
  133.             error(USER, "color format with value output only");
  134.         break;
  135.     default:
  136.         error(CONSISTENCY, "botched output format");
  137.     }
  138.     if (hresolu > 0 && vresolu > 0)
  139.         fprtresolu(hresolu, vresolu, stdout);
  140.                     /* process file */
  141.     while (getvec(orig, inform, fp) == 0 &&
  142.             getvec(direc, inform, fp) == 0) {
  143.  
  144.         if (normalize(direc) == 0.0) {        /* zero ==> flush */
  145.             fflush(stdout);
  146.             continue;
  147.         }
  148.         samplendx++;
  149.                             /* compute and print */
  150.         if (imm_irrad)
  151.             irrad(orig, direc);
  152.         else
  153.             traceray(orig, direc);
  154.                             /* flush if time */
  155.         if (--nextflush == 0) {
  156.             fflush(stdout);
  157.             nextflush = hresolu;
  158.         }
  159.         if (ferror(stdout))
  160.             error(SYSTEM, "write error");
  161.         if (--vcount == 0)            /* check for end */
  162.             break;
  163.     }
  164.     if (vcount > 0)
  165.         error(USER, "read error");
  166.     fclose(fp);
  167. }
  168.  
  169.  
  170. setoutput(vs)                /* set up output tables */
  171. register char  *vs;
  172. {
  173.     extern int  ourtrace(), (*trace)();
  174.     register int (**table)() = ray_out;
  175.  
  176.     castonly = 1;
  177.     while (*vs)
  178.         switch (*vs++) {
  179.         case 't':                /* trace */
  180.             *table = NULL;
  181.             table = every_out;
  182.             trace = ourtrace;
  183.             castonly = 0;
  184.             break;
  185.         case 'o':                /* origin */
  186.             *table++ = oputo;
  187.             break;
  188.         case 'd':                /* direction */
  189.             *table++ = oputd;
  190.             break;
  191.         case 'v':                /* value */
  192.             *table++ = oputv;
  193.             castonly = 0;
  194.             break;
  195.         case 'l':                /* effective distance */
  196.             *table++ = oputl;
  197.             castonly = 0;
  198.             break;
  199.         case 'L':                /* single ray length */
  200.             *table++ = oputL;
  201.             break;
  202.         case 'p':                /* point */
  203.             *table++ = oputp;
  204.             break;
  205.         case 'n':                /* normal */
  206.             *table++ = oputn;
  207.             break;
  208.         case 's':                /* surface */
  209.             *table++ = oputs;
  210.             break;
  211.         case 'w':                /* weight */
  212.             *table++ = oputw;
  213.             break;
  214.         case 'm':                /* modifier */
  215.             *table++ = oputm;
  216.             break;
  217.         }
  218.     *table = NULL;
  219. }
  220.  
  221.  
  222. traceray(org, dir)        /* compute and print ray value(s) */
  223. FVECT  org, dir;
  224. {
  225.     register int  (**tp)();
  226.  
  227.     VCOPY(thisray.rorg, org);
  228.     VCOPY(thisray.rdir, dir);
  229.     rayorigin(&thisray, NULL, PRIMARY, 1.0);
  230.     if (castonly)
  231.         localhit(&thisray, &thescene) || sourcehit(&thisray);
  232.     else
  233.         rayvalue(&thisray);
  234.  
  235.     if (ray_out[0] == NULL)
  236.         return;
  237.     for (tp = ray_out; *tp != NULL; tp++)
  238.         (**tp)(&thisray);
  239.     if (outform == 'a')
  240.         putchar('\n');
  241. }
  242.  
  243.  
  244. irrad(org, dir)            /* compute immediate irradiance value */
  245. FVECT  org, dir;
  246. {
  247.     register int  i;
  248.  
  249.     for (i = 0; i < 3; i++) {
  250.         thisray.rorg[i] = org[i] + dir[i];
  251.         thisray.rdir[i] = -dir[i];
  252.     }
  253.     rayorigin(&thisray, NULL, PRIMARY, 1.0);
  254.                     /* pretend we hit surface */
  255.     thisray.rot = 1.0;
  256.     thisray.rod = 1.0;
  257.     VCOPY(thisray.ron, dir);
  258.     for (i = 0; i < 3; i++)        /* fudge factor */
  259.         thisray.rop[i] = org[i] + 1e-4*dir[i];
  260.                     /* compute and print */
  261.     (*ofun[Lamb.otype].funp)(&Lamb, &thisray);
  262.     oputv(&thisray);
  263.     if (outform == 'a')
  264.         putchar('\n');
  265. }
  266.  
  267.  
  268. getvec(vec, fmt, fp)        /* get a vector from fp */
  269. register FVECT  vec;
  270. int  fmt;
  271. FILE  *fp;
  272. {
  273.     extern char  *fgetword();
  274.     static float  vf[3];
  275.     static double  vd[3];
  276.     char  buf[32];
  277.     register int  i;
  278.  
  279.     switch (fmt) {
  280.     case 'a':                    /* ascii */
  281.         for (i = 0; i < 3; i++) {
  282.             if (fgetword(buf, sizeof(buf), fp) == NULL ||
  283.                     !isflt(buf))
  284.                 return(-1);
  285.             vec[i] = atof(buf);
  286.         }
  287.         break;
  288.     case 'f':                    /* binary float */
  289.         if (fread((char *)vf, sizeof(float), 3, fp) != 3)
  290.             return(-1);
  291.         vec[0] = vf[0]; vec[1] = vf[1]; vec[2] = vf[2];
  292.         break;
  293.     case 'd':                    /* binary double */
  294.         if (fread((char *)vd, sizeof(double), 3, fp) != 3)
  295.             return(-1);
  296.         vec[0] = vd[0]; vec[1] = vd[1]; vec[2] = vd[2];
  297.         break;
  298.     default:
  299.         error(CONSISTENCY, "botched input format");
  300.     }
  301.     return(0);
  302. }
  303.  
  304.  
  305. static
  306. ourtrace(r)                /* print ray values */
  307. RAY  *r;
  308. {
  309.     register int  (**tp)();
  310.  
  311.     if (every_out[0] == NULL)
  312.         return;
  313.     tabin(r);
  314.     for (tp = every_out; *tp != NULL; tp++)
  315.         (**tp)(r);
  316.     putchar('\n');
  317. }
  318.  
  319.  
  320. static
  321. tabin(r)                /* tab in appropriate amount */
  322. RAY  *r;
  323. {
  324.     register RAY  *rp;
  325.  
  326.     for (rp = r->parent; rp != NULL; rp = rp->parent)
  327.         putchar('\t');
  328. }
  329.  
  330.  
  331. static
  332. oputo(r)                /* print origin */
  333. register RAY  *r;
  334. {
  335.     (*putreal)(r->rorg[0]);
  336.     (*putreal)(r->rorg[1]);
  337.     (*putreal)(r->rorg[2]);
  338. }
  339.  
  340.  
  341. static
  342. oputd(r)                /* print direction */
  343. register RAY  *r;
  344. {
  345.     (*putreal)(r->rdir[0]);
  346.     (*putreal)(r->rdir[1]);
  347.     (*putreal)(r->rdir[2]);
  348. }
  349.  
  350.  
  351. static
  352. oputv(r)                /* print value */
  353. register RAY  *r;
  354. {
  355.     COLR  cout;
  356.     
  357.     if (outform == 'c') {
  358.         setcolr(cout,    colval(r->rcol,RED),
  359.                 colval(r->rcol,GRN),
  360.                 colval(r->rcol,BLU));
  361.         fwrite((char *)cout, sizeof(cout), 1, stdout);
  362.         return;
  363.     }
  364.     (*putreal)(colval(r->rcol,RED));
  365.     (*putreal)(colval(r->rcol,GRN));
  366.     (*putreal)(colval(r->rcol,BLU));
  367. }
  368.  
  369.  
  370. static
  371. oputl(r)                /* print effective distance */
  372. register RAY  *r;
  373. {
  374.     (*putreal)(r->rt);
  375. }
  376.  
  377.  
  378. static
  379. oputL(r)                /* print single ray length */
  380. register RAY  *r;
  381. {
  382.     (*putreal)(r->rot);
  383. }
  384.  
  385.  
  386. static
  387. oputp(r)                /* print point */
  388. register RAY  *r;
  389. {
  390.     if (r->rot < FHUGE) {
  391.         (*putreal)(r->rop[0]);
  392.         (*putreal)(r->rop[1]);
  393.         (*putreal)(r->rop[2]);
  394.     } else {
  395.         (*putreal)(0.0);
  396.         (*putreal)(0.0);
  397.         (*putreal)(0.0);
  398.     }
  399. }
  400.  
  401.  
  402. static
  403. oputn(r)                /* print normal */
  404. register RAY  *r;
  405. {
  406.     if (r->rot < FHUGE) {
  407.         (*putreal)(r->ron[0]);
  408.         (*putreal)(r->ron[1]);
  409.         (*putreal)(r->ron[2]);
  410.     } else {
  411.         (*putreal)(0.0);
  412.         (*putreal)(0.0);
  413.         (*putreal)(0.0);
  414.     }
  415. }
  416.  
  417.  
  418. static
  419. oputs(r)                /* print name */
  420. register RAY  *r;
  421. {
  422.     if (r->ro != NULL)
  423.         fputs(r->ro->oname, stdout);
  424.     else
  425.         putchar('*');
  426.     putchar('\t');
  427. }
  428.  
  429.  
  430. static
  431. oputw(r)                /* print weight */
  432. register RAY  *r;
  433. {
  434.     (*putreal)(r->rweight);
  435. }
  436.  
  437.  
  438. static
  439. oputm(r)                /* print modifier */
  440. register RAY  *r;
  441. {
  442.     if (r->ro != NULL)
  443.         fputs(objptr(r->ro->omod)->oname, stdout);
  444.     else
  445.         putchar('*');
  446.     putchar('\t');
  447. }
  448.  
  449.  
  450. static
  451. puta(v)                /* print ascii value */
  452. double  v;
  453. {
  454.     printf("%e\t", v);
  455. }
  456.  
  457.  
  458. static
  459. putd(v)                /* print binary double */
  460. double  v;
  461. {
  462.     fwrite((char *)&v, sizeof(v), 1, stdout);
  463. }
  464.  
  465.  
  466. static
  467. putf(v)                /* print binary float */
  468. double  v;
  469. {
  470.     float f = v;
  471.  
  472.     fwrite((char *)&f, sizeof(f), 1, stdout);
  473. }
  474.