ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rtrace.c
(Generate patch)

Comparing ray/src/rt/rtrace.c (file contents):
Revision 1.10 by greg, Tue Jun 26 09:00:15 1990 UTC vs.
Revision 2.39 by greg, Thu Apr 14 18:04:12 2005 UTC

# Line 1 | Line 1
1 /* Copyright (c) 1986 Regents of the University of California */
2
1   #ifndef lint
2 < static char SCCSid[] = "$SunId$ LBL";
2 > static const char       RCSid[] = "$Id$";
3   #endif
6
4   /*
5   *  rtrace.c - program and variables for individual ray tracing.
9 *
10 *     6/11/86
6   */
7  
8 + #include "copyright.h"
9 +
10   /*
11   *  Input is in the form:
12   *
# Line 20 | Line 17 | static char SCCSid[] = "$SunId$ LBL";
17   *  All values default to ascii representation of real
18   *  numbers.  Binary representations can be selected
19   *  with '-ff' for float or '-fd' for double.  By default,
20 < *  radiance is computed.  The '-i' option indicates that
20 > *  radiance is computed.  The '-i' or '-I' options indicate that
21   *  irradiance values are desired.
22   */
23  
24 < #include  "ray.h"
24 > #include  <time.h>
25  
26 + #include  "platform.h"
27 + #include  "ray.h"
28 + #include  "ambient.h"
29 + #include  "source.h"
30   #include  "otypes.h"
31 + #include  "resolu.h"
32  
33 + CUBE  thescene;                         /* our scene */
34 + OBJECT  nsceneobjs;                     /* number of objects in our scene */
35 +
36 + int  dimlist[MAXDIM];                   /* sampling dimensions */
37 + int  ndims = 0;                         /* number of sampling dimensions */
38 + int  samplendx = 0;                     /* index for this sample */
39 +
40 + int  imm_irrad = 0;                     /* compute immediate irradiance? */
41 + int  lim_dist = 0;                      /* limit distance? */
42 +
43   int  inform = 'a';                      /* input format */
44   int  outform = 'a';                     /* output format */
45   char  *outvals = "v";                   /* output specification */
46  
47 + int  do_irrad = 0;                      /* compute irradiance? */
48 +
49 + void  (*trace)() = NULL;                /* trace call */
50 +
51 + char  *tralist[128];                    /* list of modifers to trace (or no) */
52 + int  traincl = -1;                      /* include == 1, exclude == 0 */
53 + #define  MAXTSET        511             /* maximum number in trace set */
54 + OBJECT  traset[MAXTSET+1]={0};          /* trace include/exclude set */
55 +
56   int  hresolu = 0;                       /* horizontal (scan) size */
57   int  vresolu = 0;                       /* vertical resolution */
58  
59   double  dstrsrc = 0.0;                  /* square source distribution */
60 < double  shadthresh = .05;               /* shadow threshold */
61 < double  shadcert = .5;                  /* shadow certainty */
60 > double  shadthresh = .03;               /* shadow threshold */
61 > double  shadcert = .75;                 /* shadow certainty */
62 > int  directrelay = 2;                   /* number of source relays */
63 > int  vspretest = 512;                   /* virtual source pretest density */
64 > int  directvis = 1;                     /* sources visible? */
65 > double  srcsizerat = .2;                /* maximum ratio source size/dist. */
66  
67 < int  maxdepth = 6;                      /* maximum recursion depth */
68 < double  minweight = 4e-3;               /* minimum ray weight */
67 > COLOR  cextinction = BLKCOLOR;          /* global extinction coefficient */
68 > COLOR  salbedo = BLKCOLOR;              /* global scattering albedo */
69 > double  seccg = 0.;                     /* global scattering eccentricity */
70 > double  ssampdist = 0.;                 /* scatter sampling distance */
71  
72 + double  specthresh = .15;               /* specular sampling threshold */
73 + double  specjitter = 1.;                /* specular sampling jitter */
74 +
75 + int  backvis = 1;                       /* back face visibility */
76 +
77 + int  maxdepth = 8;                      /* maximum recursion depth */
78 + double  minweight = 2e-3;               /* minimum ray weight */
79 +
80 + char  *ambfile = NULL;                  /* ambient file name */
81   COLOR  ambval = BLKCOLOR;               /* ambient value */
82 < double  ambacc = 0.2;                   /* ambient accuracy */
83 < int  ambres = 32;                       /* ambient resolution */
84 < int  ambdiv = 128;                      /* ambient divisions */
85 < int  ambssamp = 0;                      /* ambient super-samples */
82 > int  ambvwt = 0;                        /* initial weight for ambient value */
83 > double  ambacc = 0.15;                  /* ambient accuracy */
84 > int  ambres = 256;                      /* ambient resolution */
85 > int  ambdiv = 1024;                     /* ambient divisions */
86 > int  ambssamp = 512;                    /* ambient super-samples */
87   int  ambounce = 0;                      /* ambient bounces */
88 < char  *amblist[128];                    /* ambient include/exclude list */
88 > char  *amblist[AMBLLEN];                /* ambient include/exclude list */
89   int  ambincl = -1;                      /* include == 1, exclude == 0 */
90  
91 + static int  castonly = 0;
92 +
93   static RAY  thisray;                    /* for our convenience */
94  
95 < static int  oputo(), oputd(), oputv(), oputl(),
96 <                oputp(), oputn(), oputs(), oputw(), oputm();
95 > typedef void putf_t(double v);
96 > static putf_t puta, putd, putf;
97  
98 < static int  (*ray_out[10])(), (*every_out[10])();
98 > typedef void oputf_t(RAY *r);
99 > static oputf_t  oputo, oputd, oputv, oputl, oputL, oputc,
100 >                oputp, oputn, oputN, oputs, oputw, oputm, oputM;
101  
102 < static int  puta(), putf(), putd();
102 > static void setoutput(char *vs);
103 > static void tranotify(OBJECT obj);
104 > static void bogusray(void);
105 > static void rad(FVECT  org, FVECT  dir, double  dmax);
106 > static void irrad(FVECT  org, FVECT  dir);
107 > static void printvals(RAY  *r);
108 > static int getvec(FVECT  vec, int  fmt, FILE  *fp);
109 > static void tabin(RAY  *r);
110 > static void ourtrace(RAY  *r);
111  
112 < static int  (*putreal)();
112 > static oputf_t *ray_out[16], *every_out[16];
113 > static putf_t *putreal;
114  
115 + void  (*addobjnotify[])() = {ambnotify, tranotify, NULL};
116  
117 < quit(code)                      /* quit program */
118 < int  code;
117 >
118 > void
119 > quit(                   /* quit program */
120 >        int  code
121 > )
122   {
123 + #ifndef  NON_POSIX /* XXX we don't clean up elsewhere? */
124 +        headclean();            /* delete header file */
125 +        pfclean();              /* clean up persist files */
126 + #endif
127          exit(code);
128   }
129  
130  
131 < rtrace(fname)                           /* trace rays from file */
132 < char  *fname;
131 > extern char *
132 > formstr(                                /* return format identifier */
133 >        int  f
134 > )
135   {
136 +        switch (f) {
137 +        case 'a': return("ascii");
138 +        case 'f': return("float");
139 +        case 'd': return("double");
140 +        case 'c': return(COLRFMT);
141 +        }
142 +        return("unknown");
143 + }
144 +
145 +
146 + extern void
147 + rtrace(                         /* trace rays from file */
148 +        char  *fname
149 + )
150 + {
151          long  vcount = hresolu>1 ? hresolu*vresolu : vresolu;
152          long  nextflush = hresolu;
153          FILE  *fp;
154 +        double  d;
155          FVECT  orig, direc;
156                                          /* set up input */
157          if (fname == NULL)
# Line 84 | Line 160 | char  *fname;
160                  sprintf(errmsg, "cannot open input file \"%s\"", fname);
161                  error(SYSTEM, errmsg);
162          }
163 + #ifdef _WIN32
164 +        if (inform != 'a')
165 +                SET_FILE_BINARY(fp);
166 + #endif
167                                          /* set up output */
168          setoutput(outvals);
169          switch (outform) {
170          case 'a': putreal = puta; break;
171          case 'f': putreal = putf; break;
172          case 'd': putreal = putd; break;
173 +        case 'c':
174 +                if (strcmp(outvals, "v"))
175 +                        error(USER, "color format with value output only");
176 +                break;
177 +        default:
178 +                error(CONSISTENCY, "botched output format");
179          }
180 +        if (hresolu > 0) {
181 +                if (vresolu > 0)
182 +                        fprtresolu(hresolu, vresolu, stdout);
183 +                fflush(stdout);
184 +        }
185                                          /* process file */
186          while (getvec(orig, inform, fp) == 0 &&
187                          getvec(direc, inform, fp) == 0) {
188  
189 <                if (normalize(direc) == 0.0) {          /* zero ==> flush */
190 <                        fflush(stdout);
191 <                        continue;
192 <                }
189 >                d = normalize(direc);
190 >                if (d == 0.0) {                         /* zero ==> flush */
191 >                        bogusray();
192 >                        if (--nextflush <= 0 || vcount <= 0) {
193 >                                fflush(stdout);
194 >                                nextflush = hresolu;
195 >                        }
196 >                } else {
197 >                        samplendx++;
198                                                          /* compute and print */
199 <                if (outvals[0] == 'i')
200 <                        irrad(orig, direc);
201 <                else
202 <                        radiance(orig, direc);
199 >                        if (imm_irrad)
200 >                                irrad(orig, direc);
201 >                        else
202 >                                rad(orig, direc, lim_dist ? d : 0.0);
203                                                          /* flush if time */
204 <                if (--nextflush == 0) {
205 <                        fflush(stdout);
206 <                        nextflush = hresolu;
204 >                        if (--nextflush == 0) {
205 >                                fflush(stdout);
206 >                                nextflush = hresolu;
207 >                        }
208                  }
209                  if (ferror(stdout))
210                          error(SYSTEM, "write error");
211                  if (--vcount == 0)                      /* check for end */
212                          break;
213          }
214 +        fflush(stdout);
215          if (vcount > 0)
216                  error(USER, "read error");
217 <        fclose(fp);
217 >        if (fname != NULL)
218 >                fclose(fp);
219   }
220  
221  
222 < setoutput(vs)                           /* set up output tables */
223 < register char  *vs;
222 > static void
223 > setoutput(                              /* set up output tables */
224 >        register char  *vs
225 > )
226   {
227 <        extern int  ourtrace(), (*trace)();
127 <        register int (**table)() = ray_out;
227 >        register oputf_t **table = ray_out;
228  
229 +        castonly = 1;
230          while (*vs)
231                  switch (*vs++) {
232                  case 't':                               /* trace */
233                          *table = NULL;
234                          table = every_out;
235                          trace = ourtrace;
236 +                        castonly = 0;
237                          break;
238                  case 'o':                               /* origin */
239                          *table++ = oputo;
# Line 141 | Line 243 | register char  *vs;
243                          break;
244                  case 'v':                               /* value */
245                          *table++ = oputv;
246 +                        castonly = 0;
247                          break;
248 <                case 'l':                               /* length */
248 >                case 'l':                               /* effective distance */
249                          *table++ = oputl;
250 +                        castonly = 0;
251                          break;
252 +                case 'c':                               /* local coordinates */
253 +                        *table++ = oputc;
254 +                        break;
255 +                case 'L':                               /* single ray length */
256 +                        *table++ = oputL;
257 +                        break;
258                  case 'p':                               /* point */
259                          *table++ = oputp;
260                          break;
261 <                case 'n':                               /* normal */
261 >                case 'n':                               /* perturbed normal */
262                          *table++ = oputn;
263 +                        castonly = 0;
264                          break;
265 +                case 'N':                               /* unperturbed normal */
266 +                        *table++ = oputN;
267 +                        break;
268                  case 's':                               /* surface */
269                          *table++ = oputs;
270                          break;
# Line 160 | Line 274 | register char  *vs;
274                  case 'm':                               /* modifier */
275                          *table++ = oputm;
276                          break;
277 +                case 'M':                               /* material */
278 +                        *table++ = oputM;
279 +                        break;
280                  }
281          *table = NULL;
282   }
283  
284  
285 < radiance(org, dir)              /* compute radiance value */
286 < FVECT  org, dir;
285 > static void
286 > bogusray(void)                  /* print out empty record */
287   {
288 <        register int  (**tp)();
288 >        thisray.rorg[0] = thisray.rorg[1] = thisray.rorg[2] =
289 >        thisray.rdir[0] = thisray.rdir[1] = thisray.rdir[2] = 0.0;
290 >        rayorigin(&thisray, NULL, PRIMARY, 1.0);
291 >        printvals(&thisray);
292 > }
293  
294 +
295 + static void
296 + rad(            /* compute and print ray value(s) */
297 +        FVECT  org,
298 +        FVECT  dir,
299 +        double  dmax
300 + )
301 + {
302          VCOPY(thisray.rorg, org);
303          VCOPY(thisray.rdir, dir);
304 +        thisray.rmax = dmax;
305          rayorigin(&thisray, NULL, PRIMARY, 1.0);
306 <        rayvalue(&thisray);
307 <
308 <        if (ray_out[0] == NULL)
309 <                return;
310 <        for (tp = ray_out; *tp != NULL; tp++)
311 <                (**tp)(&thisray);
312 <        if (outform == 'a')
313 <                putchar('\n');
306 >        if (castonly) {
307 >                if (!localhit(&thisray, &thescene)) {
308 >                        if (thisray.ro == &Aftplane) {  /* clipped */
309 >                                thisray.ro = NULL;
310 >                                thisray.rot = FHUGE;
311 >                        } else
312 >                                sourcehit(&thisray);
313 >                }
314 >        } else
315 >                rayvalue(&thisray);
316 >        printvals(&thisray);
317   }
318  
319  
320 < irrad(org, dir)                 /* compute irradiance value */
321 < FVECT  org, dir;
320 > static void
321 > irrad(                  /* compute immediate irradiance value */
322 >        FVECT  org,
323 >        FVECT  dir
324 > )
325   {
190        static double  Lambfa[5] = {PI, PI, PI, 0.0, 0.0};
191        static OBJREC  Lamb = {
192                OVOID, MAT_PLASTIC, "Lambertian",
193                {0, 5, NULL, Lambfa}, NULL, -1,
194        };
326          register int  i;
327  
328          for (i = 0; i < 3; i++) {
# Line 200 | Line 331 | FVECT  org, dir;
331          }
332          rayorigin(&thisray, NULL, PRIMARY, 1.0);
333                                          /* pretend we hit surface */
334 <        thisray.rot = 1.0;
334 >        thisray.rot = 1.0-1e-4;
335          thisray.rod = 1.0;
336          VCOPY(thisray.ron, dir);
337          for (i = 0; i < 3; i++)         /* fudge factor */
338                  thisray.rop[i] = org[i] + 1e-4*dir[i];
339                                          /* compute and print */
340          (*ofun[Lamb.otype].funp)(&Lamb, &thisray);
341 <        oputv(&thisray);
341 >        printvals(&thisray);
342 > }
343 >
344 >
345 > static void
346 > printvals(                      /* print requested ray values */
347 >        RAY  *r
348 > )
349 > {
350 >        register oputf_t **tp;
351 >
352 >        if (ray_out[0] == NULL)
353 >                return;
354 >        for (tp = ray_out; *tp != NULL; tp++)
355 >                (**tp)(r);
356          if (outform == 'a')
357                  putchar('\n');
358   }
359  
360  
361 < getvec(vec, fmt, fp)            /* get a vector from fp */
362 < register FVECT  vec;
363 < int  fmt;
364 < FILE  *fp;
361 > static int
362 > getvec(         /* get a vector from fp */
363 >        register FVECT  vec,
364 >        int  fmt,
365 >        FILE  *fp
366 > )
367   {
368          static float  vf[3];
369 +        static double  vd[3];
370 +        char  buf[32];
371 +        register int  i;
372  
373          switch (fmt) {
374          case 'a':                                       /* ascii */
375 <                if (fscanf(fp, "%lf %lf %lf", vec, vec+1, vec+2) != 3)
376 <                        return(-1);
375 >                for (i = 0; i < 3; i++) {
376 >                        if (fgetword(buf, sizeof(buf), fp) == NULL ||
377 >                                        !isflt(buf))
378 >                                return(-1);
379 >                        vec[i] = atof(buf);
380 >                }
381                  break;
382          case 'f':                                       /* binary float */
383                  if (fread((char *)vf, sizeof(float), 3, fp) != 3)
# Line 231 | Line 385 | FILE  *fp;
385                  vec[0] = vf[0]; vec[1] = vf[1]; vec[2] = vf[2];
386                  break;
387          case 'd':                                       /* binary double */
388 <                if (fread((char *)vec, sizeof(double), 3, fp) != 3)
388 >                if (fread((char *)vd, sizeof(double), 3, fp) != 3)
389                          return(-1);
390 +                vec[0] = vd[0]; vec[1] = vd[1]; vec[2] = vd[2];
391                  break;
392 +        default:
393 +                error(CONSISTENCY, "botched input format");
394          }
395          return(0);
396   }
397  
398  
399 < static
400 < ourtrace(r)                             /* print ray values */
401 < RAY  *r;
399 > static void
400 > tranotify(                      /* record new modifier */
401 >        OBJECT  obj
402 > )
403   {
404 <        register int  (**tp)();
404 >        static int  hitlimit = 0;
405 >        register OBJREC  *o = objptr(obj);
406 >        register char  **tralp;
407  
408 +        if (obj == OVOID) {             /* starting over */
409 +                traset[0] = 0;
410 +                hitlimit = 0;
411 +                return;
412 +        }
413 +        if (hitlimit || !ismodifier(o->otype))
414 +                return;
415 +        for (tralp = tralist; *tralp != NULL; tralp++)
416 +                if (!strcmp(o->oname, *tralp)) {
417 +                        if (traset[0] >= MAXTSET) {
418 +                                error(WARNING, "too many modifiers in trace list");
419 +                                hitlimit++;
420 +                                return;         /* should this be fatal? */
421 +                        }
422 +                        insertelem(traset, obj);
423 +                        return;
424 +                }
425 + }
426 +
427 +
428 + static void
429 + ourtrace(                               /* print ray values */
430 +        RAY  *r
431 + )
432 + {
433 +        register oputf_t **tp;
434 +
435          if (every_out[0] == NULL)
436                  return;
437 +        if (r->ro == NULL) {
438 +                if (traincl == 1)
439 +                        return;
440 +        } else if (traincl != -1 && traincl != inset(traset, r->ro->omod))
441 +                return;
442          tabin(r);
443          for (tp = every_out; *tp != NULL; tp++)
444                  (**tp)(r);
# Line 254 | Line 446 | RAY  *r;
446   }
447  
448  
449 < static
450 < tabin(r)                                /* tab in appropriate amount */
451 < RAY  *r;
449 > static void
450 > tabin(                          /* tab in appropriate amount */
451 >        RAY  *r
452 > )
453   {
454          register RAY  *rp;
455  
# Line 265 | Line 458 | RAY  *r;
458   }
459  
460  
461 < static
462 < oputo(r)                                /* print origin */
463 < register RAY  *r;
461 > static void
462 > oputo(                          /* print origin */
463 >        RAY  *r
464 > )
465   {
466          (*putreal)(r->rorg[0]);
467          (*putreal)(r->rorg[1]);
# Line 275 | Line 469 | register RAY  *r;
469   }
470  
471  
472 < static
473 < oputd(r)                                /* print direction */
474 < register RAY  *r;
472 > static void
473 > oputd(                          /* print direction */
474 >        RAY  *r
475 > )
476   {
477          (*putreal)(r->rdir[0]);
478          (*putreal)(r->rdir[1]);
# Line 285 | Line 480 | register RAY  *r;
480   }
481  
482  
483 < static
484 < oputv(r)                                /* print value */
485 < register RAY  *r;
483 > static void
484 > oputv(                          /* print value */
485 >        RAY  *r
486 > )
487   {
488 +        COLR  cout;
489 +        
490 +        if (outform == 'c') {
491 +                setcolr(cout,   colval(r->rcol,RED),
492 +                                colval(r->rcol,GRN),
493 +                                colval(r->rcol,BLU));
494 +                fwrite((char *)cout, sizeof(cout), 1, stdout);
495 +                return;
496 +        }
497          (*putreal)(colval(r->rcol,RED));
498          (*putreal)(colval(r->rcol,GRN));
499          (*putreal)(colval(r->rcol,BLU));
500   }
501  
502  
503 < static
504 < oputl(r)                                /* print length */
505 < register RAY  *r;
503 > static void
504 > oputl(                          /* print effective distance */
505 >        RAY  *r
506 > )
507   {
508          (*putreal)(r->rt);
509   }
510  
511  
512 < static
513 < oputp(r)                                /* print point */
514 < register RAY  *r;
512 > static void
513 > oputL(                          /* print single ray length */
514 >        RAY  *r
515 > )
516   {
517 +        (*putreal)(r->rot);
518 + }
519 +
520 +
521 + static void
522 + oputc(                          /* print local coordinates */
523 +        RAY  *r
524 + )
525 + {
526 +        (*putreal)(r->uv[0]);
527 +        (*putreal)(r->uv[1]);
528 + }
529 +
530 +
531 + static void
532 + oputp(                          /* print point */
533 +        RAY  *r
534 + )
535 + {
536          if (r->rot < FHUGE) {
537                  (*putreal)(r->rop[0]);
538                  (*putreal)(r->rop[1]);
# Line 319 | Line 545 | register RAY  *r;
545   }
546  
547  
548 < static
549 < oputn(r)                                /* print normal */
550 < register RAY  *r;
548 > static void
549 > oputN(                          /* print unperturbed normal */
550 >        RAY  *r
551 > )
552   {
553          if (r->rot < FHUGE) {
554                  (*putreal)(r->ron[0]);
# Line 335 | Line 562 | register RAY  *r;
562   }
563  
564  
565 < static
566 < oputs(r)                                /* print name */
567 < register RAY  *r;
565 > static void
566 > oputn(                          /* print perturbed normal */
567 >        RAY  *r
568 > )
569   {
570 +        FVECT  pnorm;
571 +
572 +        if (r->rot >= FHUGE) {
573 +                (*putreal)(0.0);
574 +                (*putreal)(0.0);
575 +                (*putreal)(0.0);
576 +                return;
577 +        }
578 +        raynormal(pnorm, r);
579 +        (*putreal)(pnorm[0]);
580 +        (*putreal)(pnorm[1]);
581 +        (*putreal)(pnorm[2]);
582 + }
583 +
584 +
585 + static void
586 + oputs(                          /* print name */
587 +        RAY  *r
588 + )
589 + {
590          if (r->ro != NULL)
591                  fputs(r->ro->oname, stdout);
592          else
# Line 347 | Line 595 | register RAY  *r;
595   }
596  
597  
598 < static
599 < oputw(r)                                /* print weight */
600 < register RAY  *r;
598 > static void
599 > oputw(                          /* print weight */
600 >        RAY  *r
601 > )
602   {
603          (*putreal)(r->rweight);
604   }
605  
606  
607 < static
608 < oputm(r)                                /* print modifier */
609 < register RAY  *r;
607 > static void
608 > oputm(                          /* print modifier */
609 >        RAY  *r
610 > )
611   {
612          if (r->ro != NULL)
613 <                fputs(objptr(r->ro->omod)->oname, stdout);
613 >                if (r->ro->omod != OVOID)
614 >                        fputs(objptr(r->ro->omod)->oname, stdout);
615 >                else
616 >                        fputs(VOIDID, stdout);
617          else
618                  putchar('*');
619          putchar('\t');
620   }
621  
622  
623 < static
624 < puta(v)                         /* print ascii value */
625 < double  v;
623 > static void
624 > oputM(                          /* print material */
625 >        RAY  *r
626 > )
627   {
628 +        OBJREC  *mat;
629 +
630 +        if (r->ro != NULL) {
631 +                if ((mat = findmaterial(r->ro)) != NULL)
632 +                        fputs(mat->oname, stdout);
633 +                else
634 +                        fputs(VOIDID, stdout);
635 +        } else
636 +                putchar('*');
637 +        putchar('\t');
638 + }
639 +
640 +
641 + static void
642 + puta(                           /* print ascii value */
643 +        double  v
644 + )
645 + {
646          printf("%e\t", v);
647   }
648  
649  
650 < static
650 > static void
651   putd(v)                         /* print binary double */
652   double  v;
653   {
# Line 383 | Line 655 | double  v;
655   }
656  
657  
658 < static
658 > static void
659   putf(v)                         /* print binary float */
660   double  v;
661   {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines