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

  1. /* Copyright (c) 1992 Regents of the University of California */
  2.  
  3. #ifndef lint
  4. static char SCCSid[] = "@(#)rtrace.c 2.9 11/6/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(), 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':                /* perturbed normal */
  206.             *table++ = oputn;
  207.             castonly = 0;
  208.             break;
  209.         case 'N':                /* unperturbed normal */
  210.             *table++ = oputN;
  211.             break;
  212.         case 's':                /* surface */
  213.             *table++ = oputs;
  214.             break;
  215.         case 'w':                /* weight */
  216.             *table++ = oputw;
  217.             break;
  218.         case 'm':                /* modifier */
  219.             *table++ = oputm;
  220.             break;
  221.         }
  222.     *table = NULL;
  223. }
  224.  
  225.  
  226. traceray(org, dir)        /* compute and print ray value(s) */
  227. FVECT  org, dir;
  228. {
  229.     register int  (**tp)();
  230.  
  231.     VCOPY(thisray.rorg, org);
  232.     VCOPY(thisray.rdir, dir);
  233.     rayorigin(&thisray, NULL, PRIMARY, 1.0);
  234.     if (castonly)
  235.         localhit(&thisray, &thescene) || sourcehit(&thisray);
  236.     else
  237.         rayvalue(&thisray);
  238.  
  239.     if (ray_out[0] == NULL)
  240.         return;
  241.     for (tp = ray_out; *tp != NULL; tp++)
  242.         (**tp)(&thisray);
  243.     if (outform == 'a')
  244.         putchar('\n');
  245. }
  246.  
  247.  
  248. irrad(org, dir)            /* compute immediate irradiance value */
  249. FVECT  org, dir;
  250. {
  251.     register int  i;
  252.  
  253.     for (i = 0; i < 3; i++) {
  254.         thisray.rorg[i] = org[i] + dir[i];
  255.         thisray.rdir[i] = -dir[i];
  256.     }
  257.     rayorigin(&thisray, NULL, PRIMARY, 1.0);
  258.                     /* pretend we hit surface */
  259.     thisray.rot = 1.0;
  260.     thisray.rod = 1.0;
  261.     VCOPY(thisray.ron, dir);
  262.     for (i = 0; i < 3; i++)        /* fudge factor */
  263.         thisray.rop[i] = org[i] + 1e-4*dir[i];
  264.                     /* compute and print */
  265.     (*ofun[Lamb.otype].funp)(&Lamb, &thisray);
  266.     oputv(&thisray);
  267.     if (outform == 'a')
  268.         putchar('\n');
  269. }
  270.  
  271.  
  272. getvec(vec, fmt, fp)        /* get a vector from fp */
  273. register FVECT  vec;
  274. int  fmt;
  275. FILE  *fp;
  276. {
  277.     extern char  *fgetword();
  278.     static float  vf[3];
  279.     static double  vd[3];
  280.     char  buf[32];
  281.     register int  i;
  282.  
  283.     switch (fmt) {
  284.     case 'a':                    /* ascii */
  285.         for (i = 0; i < 3; i++) {
  286.             if (fgetword(buf, sizeof(buf), fp) == NULL ||
  287.                     !isflt(buf))
  288.                 return(-1);
  289.             vec[i] = atof(buf);
  290.         }
  291.         break;
  292.     case 'f':                    /* binary float */
  293.         if (fread((char *)vf, sizeof(float), 3, fp) != 3)
  294.             return(-1);
  295.         vec[0] = vf[0]; vec[1] = vf[1]; vec[2] = vf[2];
  296.         break;
  297.     case 'd':                    /* binary double */
  298.         if (fread((char *)vd, sizeof(double), 3, fp) != 3)
  299.             return(-1);
  300.         vec[0] = vd[0]; vec[1] = vd[1]; vec[2] = vd[2];
  301.         break;
  302.     default:
  303.         error(CONSISTENCY, "botched input format");
  304.     }
  305.     return(0);
  306. }
  307.  
  308.  
  309. static
  310. ourtrace(r)                /* print ray values */
  311. RAY  *r;
  312. {
  313.     register int  (**tp)();
  314.  
  315.     if (every_out[0] == NULL)
  316.         return;
  317.     tabin(r);
  318.     for (tp = every_out; *tp != NULL; tp++)
  319.         (**tp)(r);
  320.     putchar('\n');
  321. }
  322.  
  323.  
  324. static
  325. tabin(r)                /* tab in appropriate amount */
  326. RAY  *r;
  327. {
  328.     register RAY  *rp;
  329.  
  330.     for (rp = r->parent; rp != NULL; rp = rp->parent)
  331.         putchar('\t');
  332. }
  333.  
  334.  
  335. static
  336. oputo(r)                /* print origin */
  337. register RAY  *r;
  338. {
  339.     (*putreal)(r->rorg[0]);
  340.     (*putreal)(r->rorg[1]);
  341.     (*putreal)(r->rorg[2]);
  342. }
  343.  
  344.  
  345. static
  346. oputd(r)                /* print direction */
  347. register RAY  *r;
  348. {
  349.     (*putreal)(r->rdir[0]);
  350.     (*putreal)(r->rdir[1]);
  351.     (*putreal)(r->rdir[2]);
  352. }
  353.  
  354.  
  355. static
  356. oputv(r)                /* print value */
  357. register RAY  *r;
  358. {
  359.     COLR  cout;
  360.     
  361.     if (outform == 'c') {
  362.         setcolr(cout,    colval(r->rcol,RED),
  363.                 colval(r->rcol,GRN),
  364.                 colval(r->rcol,BLU));
  365.         fwrite((char *)cout, sizeof(cout), 1, stdout);
  366.         return;
  367.     }
  368.     (*putreal)(colval(r->rcol,RED));
  369.     (*putreal)(colval(r->rcol,GRN));
  370.     (*putreal)(colval(r->rcol,BLU));
  371. }
  372.  
  373.  
  374. static
  375. oputl(r)                /* print effective distance */
  376. register RAY  *r;
  377. {
  378.     (*putreal)(r->rt);
  379. }
  380.  
  381.  
  382. static
  383. oputL(r)                /* print single ray length */
  384. register RAY  *r;
  385. {
  386.     (*putreal)(r->rot);
  387. }
  388.  
  389.  
  390. static
  391. oputp(r)                /* print point */
  392. register RAY  *r;
  393. {
  394.     if (r->rot < FHUGE) {
  395.         (*putreal)(r->rop[0]);
  396.         (*putreal)(r->rop[1]);
  397.         (*putreal)(r->rop[2]);
  398.     } else {
  399.         (*putreal)(0.0);
  400.         (*putreal)(0.0);
  401.         (*putreal)(0.0);
  402.     }
  403. }
  404.  
  405.  
  406. static
  407. oputN(r)                /* print unperturbed normal */
  408. register RAY  *r;
  409. {
  410.     if (r->rot < FHUGE) {
  411.         (*putreal)(r->ron[0]);
  412.         (*putreal)(r->ron[1]);
  413.         (*putreal)(r->ron[2]);
  414.     } else {
  415.         (*putreal)(0.0);
  416.         (*putreal)(0.0);
  417.         (*putreal)(0.0);
  418.     }
  419. }
  420.  
  421.  
  422. static
  423. oputn(r)                /* print perturbed normal */
  424. RAY  *r;
  425. {
  426.     FVECT  pnorm;
  427.  
  428.     if (r->rot >= FHUGE) {
  429.         (*putreal)(0.0);
  430.         (*putreal)(0.0);
  431.         (*putreal)(0.0);
  432.         return;
  433.     }
  434.     raynormal(pnorm, r);
  435.     (*putreal)(pnorm[0]);
  436.     (*putreal)(pnorm[1]);
  437.     (*putreal)(pnorm[2]);
  438. }
  439.  
  440.  
  441. static
  442. oputs(r)                /* print name */
  443. register RAY  *r;
  444. {
  445.     if (r->ro != NULL)
  446.         fputs(r->ro->oname, stdout);
  447.     else
  448.         putchar('*');
  449.     putchar('\t');
  450. }
  451.  
  452.  
  453. static
  454. oputw(r)                /* print weight */
  455. register RAY  *r;
  456. {
  457.     (*putreal)(r->rweight);
  458. }
  459.  
  460.  
  461. static
  462. oputm(r)                /* print modifier */
  463. register RAY  *r;
  464. {
  465.     if (r->ro != NULL)
  466.         fputs(objptr(r->ro->omod)->oname, stdout);
  467.     else
  468.         putchar('*');
  469.     putchar('\t');
  470. }
  471.  
  472.  
  473. static
  474. puta(v)                /* print ascii value */
  475. double  v;
  476. {
  477.     printf("%e\t", v);
  478. }
  479.  
  480.  
  481. static
  482. putd(v)                /* print binary double */
  483. double  v;
  484. {
  485.     fwrite((char *)&v, sizeof(v), 1, stdout);
  486. }
  487.  
  488.  
  489. static
  490. putf(v)                /* print binary float */
  491. double  v;
  492. {
  493.     float f = v;
  494.  
  495.     fwrite((char *)&f, sizeof(f), 1, stdout);
  496. }
  497.