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.8 by greg, Fri Jan 19 00:00:26 1990 UTC vs.
Revision 2.28 by greg, Tue Feb 25 02:47:23 2003 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  
# Line 28 | Line 25 | static char SCCSid[] = "$SunId$ LBL";
25  
26   #include  "otypes.h"
27  
28 + #include  "resolu.h"
29 +
30 + CUBE  thescene;                         /* our scene */
31 + OBJECT  nsceneobjs;                     /* number of objects in our scene */
32 +
33 + int  dimlist[MAXDIM];                   /* sampling dimensions */
34 + int  ndims = 0;                         /* number of sampling dimensions */
35 + int  samplendx = 0;                     /* index for this sample */
36 +
37 + int  imm_irrad = 0;                     /* compute immediate irradiance? */
38 + int  lim_dist = 0;                      /* limit distance? */
39 +
40   int  inform = 'a';                      /* input format */
41   int  outform = 'a';                     /* output format */
42   char  *outvals = "v";                   /* output specification */
43  
44 + int  do_irrad = 0;                      /* compute irradiance? */
45 +
46 + void  (*trace)() = NULL;                /* trace call */
47 +
48 + extern void  ambnotify(), tranotify();
49 + void  (*addobjnotify[])() = {ambnotify, tranotify, NULL};
50 + char  *tralist[128];                    /* list of modifers to trace (or no) */
51 + int  traincl = -1;                      /* include == 1, exclude == 0 */
52 + #define  MAXTSET        511             /* maximum number in trace set */
53 + OBJECT  traset[MAXTSET+1]={0};          /* trace include/exclude set */
54 +
55   int  hresolu = 0;                       /* horizontal (scan) size */
56   int  vresolu = 0;                       /* vertical resolution */
57  
58   double  dstrsrc = 0.0;                  /* square source distribution */
59   double  shadthresh = .05;               /* shadow threshold */
60   double  shadcert = .5;                  /* shadow certainty */
61 + int  directrelay = 2;                   /* number of source relays */
62 + int  vspretest = 512;                   /* virtual source pretest density */
63 + int  directvis = 1;                     /* sources visible? */
64 + double  srcsizerat = .2;                /* maximum ratio source size/dist. */
65  
66 + COLOR  cextinction = BLKCOLOR;          /* global extinction coefficient */
67 + COLOR  salbedo = BLKCOLOR;              /* global scattering albedo */
68 + double  seccg = 0.;                     /* global scattering eccentricity */
69 + double  ssampdist = 0.;                 /* scatter sampling distance */
70 +
71 + double  specthresh = .15;               /* specular sampling threshold */
72 + double  specjitter = 1.;                /* specular sampling jitter */
73 +
74 + int  backvis = 1;                       /* back face visibility */
75 +
76   int  maxdepth = 6;                      /* maximum recursion depth */
77   double  minweight = 4e-3;               /* minimum ray weight */
78  
79 + char  *ambfile = NULL;                  /* ambient file name */
80   COLOR  ambval = BLKCOLOR;               /* ambient value */
81 + int  ambvwt = 0;                        /* initial weight for ambient value */
82   double  ambacc = 0.2;                   /* ambient accuracy */
83 < int  ambres = 32;                       /* ambient resolution */
84 < int  ambdiv = 128;                      /* ambient divisions */
83 > int  ambres = 128;                      /* ambient resolution */
84 > int  ambdiv = 512;                      /* ambient divisions */
85   int  ambssamp = 0;                      /* ambient super-samples */
86   int  ambounce = 0;                      /* ambient bounces */
87   char  *amblist[128];                    /* ambient include/exclude list */
88   int  ambincl = -1;                      /* include == 1, exclude == 0 */
89  
90 +
91   static RAY  thisray;                    /* for our convenience */
92  
93 < extern int  oputo(), oputd(), oputv(), oputl(),
94 <                oputp(), oputn(), oputs(), oputw(), oputm();
93 > static void  oputo(), oputd(), oputv(), oputl(), oputL(),
94 >                oputp(), oputn(), oputN(), oputs(), oputw(), oputm();
95  
96 < static int  (*ray_out[10])(), (*every_out[10])();
96 > static void  ourtrace(), tabin();
97 > static void  (*ray_out[16])(), (*every_out[16])();
98 > static int  castonly = 0;
99  
100 < extern int  puta(), putf(), putd();
100 > static void  puta(), putf(), putd();
101  
102 < static int  (*putreal)();
102 > static void  (*putreal)();
103  
104 + void    bogusray(), rad(), irrad(), printvals();
105  
106 +
107 + void
108   quit(code)                      /* quit program */
109   int  code;
110   {
111 + #ifndef  NIX
112 +        headclean();            /* delete header file */
113 +        pfclean();              /* clean up persist files */
114 + #endif
115          exit(code);
116   }
117  
118  
119 + char *
120 + formstr(f)                              /* return format identifier */
121 + int  f;
122 + {
123 +        switch (f) {
124 +        case 'a': return("ascii");
125 +        case 'f': return("float");
126 +        case 'd': return("double");
127 +        case 'c': return(COLRFMT);
128 +        }
129 +        return("unknown");
130 + }
131 +
132 +
133 + void
134   rtrace(fname)                           /* trace rays from file */
135   char  *fname;
136   {
137          long  vcount = hresolu>1 ? hresolu*vresolu : vresolu;
138          long  nextflush = hresolu;
139          FILE  *fp;
140 +        double  d;
141          FVECT  orig, direc;
142                                          /* set up input */
143          if (fname == NULL)
# Line 84 | Line 146 | char  *fname;
146                  sprintf(errmsg, "cannot open input file \"%s\"", fname);
147                  error(SYSTEM, errmsg);
148          }
149 + #ifdef MSDOS
150 +        if (inform != 'a')
151 +                setmode(fileno(fp), O_BINARY);
152 + #endif
153                                          /* set up output */
154          setoutput(outvals);
155          switch (outform) {
156          case 'a': putreal = puta; break;
157          case 'f': putreal = putf; break;
158          case 'd': putreal = putd; break;
159 +        case 'c':
160 +                if (strcmp(outvals, "v"))
161 +                        error(USER, "color format with value output only");
162 +                break;
163 +        default:
164 +                error(CONSISTENCY, "botched output format");
165          }
166 +        if (hresolu > 0) {
167 +                if (vresolu > 0)
168 +                        fprtresolu(hresolu, vresolu, stdout);
169 +                fflush(stdout);
170 +        }
171                                          /* process file */
172          while (getvec(orig, inform, fp) == 0 &&
173                          getvec(direc, inform, fp) == 0) {
174  
175 <                if (normalize(direc) == 0.0) {          /* zero ==> flush */
176 <                        fflush(stdout);
177 <                        continue;
178 <                }
175 >                d = normalize(direc);
176 >                if (d == 0.0) {                         /* zero ==> flush */
177 >                        bogusray();
178 >                        if (--nextflush <= 0 || vcount <= 0) {
179 >                                fflush(stdout);
180 >                                nextflush = hresolu;
181 >                        }
182 >                } else {
183 >                        samplendx++;
184                                                          /* compute and print */
185 <                if (outvals[0] == 'i')
186 <                        irrad(orig, direc);
187 <                else
188 <                        radiance(orig, direc);
185 >                        if (imm_irrad)
186 >                                irrad(orig, direc);
187 >                        else
188 >                                rad(orig, direc, lim_dist ? d : 0.0);
189                                                          /* flush if time */
190 <                if (--nextflush == 0) {
191 <                        fflush(stdout);
192 <                        nextflush = hresolu;
190 >                        if (--nextflush == 0) {
191 >                                fflush(stdout);
192 >                                nextflush = hresolu;
193 >                        }
194                  }
195                  if (ferror(stdout))
196                          error(SYSTEM, "write error");
197                  if (--vcount == 0)                      /* check for end */
198                          break;
199          }
200 +        fflush(stdout);
201          if (vcount > 0)
202                  error(USER, "read error");
203 <        fclose(fp);
203 >        if (fname != NULL)
204 >                fclose(fp);
205   }
206  
207  
208   setoutput(vs)                           /* set up output tables */
209   register char  *vs;
210   {
211 <        extern int  ourtrace(), (*trace)();
212 <        register int (**table)() = ray_out;
211 >        extern void  (*trace)();
212 >        register void (**table)() = ray_out;
213  
214 +        castonly = 1;
215          while (*vs)
216                  switch (*vs++) {
217                  case 't':                               /* trace */
218                          *table = NULL;
219                          table = every_out;
220                          trace = ourtrace;
221 +                        castonly = 0;
222                          break;
223                  case 'o':                               /* origin */
224                          *table++ = oputo;
# Line 141 | Line 228 | register char  *vs;
228                          break;
229                  case 'v':                               /* value */
230                          *table++ = oputv;
231 +                        castonly = 0;
232                          break;
233 <                case 'l':                               /* length */
233 >                case 'l':                               /* effective distance */
234                          *table++ = oputl;
235 +                        castonly = 0;
236                          break;
237 +                case 'L':                               /* single ray length */
238 +                        *table++ = oputL;
239 +                        break;
240                  case 'p':                               /* point */
241                          *table++ = oputp;
242                          break;
243 <                case 'n':                               /* normal */
243 >                case 'n':                               /* perturbed normal */
244                          *table++ = oputn;
245 +                        castonly = 0;
246                          break;
247 +                case 'N':                               /* unperturbed normal */
248 +                        *table++ = oputN;
249 +                        break;
250                  case 's':                               /* surface */
251                          *table++ = oputs;
252                          break;
# Line 165 | Line 261 | register char  *vs;
261   }
262  
263  
264 < radiance(org, dir)              /* compute radiance value */
265 < FVECT  org, dir;
264 > void
265 > bogusray()                      /* print out empty record */
266   {
267 <        register int  (**tp)();
267 >        thisray.rorg[0] = thisray.rorg[1] = thisray.rorg[2] =
268 >        thisray.rdir[0] = thisray.rdir[1] = thisray.rdir[2] = 0.0;
269 >        rayorigin(&thisray, NULL, PRIMARY, 1.0);
270 >        printvals(&thisray);
271 > }
272  
273 +
274 + void
275 + rad(org, dir, dmax)             /* compute and print ray value(s) */
276 + FVECT  org, dir;
277 + double  dmax;
278 + {
279          VCOPY(thisray.rorg, org);
280          VCOPY(thisray.rdir, dir);
281 +        thisray.rmax = dmax;
282          rayorigin(&thisray, NULL, PRIMARY, 1.0);
283 <        rayvalue(&thisray);
284 <
285 <        if (ray_out[0] == NULL)
286 <                return;
287 <        for (tp = ray_out; *tp != NULL; tp++)
288 <                (**tp)(&thisray);
289 <        if (outform == 'a')
290 <                putchar('\n');
283 >        if (castonly) {
284 >                if (!localhit(&thisray, &thescene))
285 >                        if (thisray.ro == &Aftplane) {  /* clipped */
286 >                                thisray.ro = NULL;
287 >                                thisray.rot = FHUGE;
288 >                        } else
289 >                                sourcehit(&thisray);
290 >        } else
291 >                rayvalue(&thisray);
292 >        printvals(&thisray);
293   }
294  
295  
296 < irrad(org, dir)                 /* compute irradiance value */
296 > void
297 > irrad(org, dir)                 /* compute immediate irradiance value */
298   FVECT  org, dir;
299   {
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        };
300          register int  i;
301  
302          for (i = 0; i < 3; i++) {
# Line 200 | Line 305 | FVECT  org, dir;
305          }
306          rayorigin(&thisray, NULL, PRIMARY, 1.0);
307                                          /* pretend we hit surface */
308 <        thisray.rot = 1.0;
308 >        thisray.rot = 1.0-1e-4;
309          thisray.rod = 1.0;
310          VCOPY(thisray.ron, dir);
311          for (i = 0; i < 3; i++)         /* fudge factor */
312                  thisray.rop[i] = org[i] + 1e-4*dir[i];
313                                          /* compute and print */
314          (*ofun[Lamb.otype].funp)(&Lamb, &thisray);
315 <        oputv(&thisray);
315 >        printvals(&thisray);
316 > }
317 >
318 >
319 > void
320 > printvals(r)                    /* print requested ray values */
321 > RAY  *r;
322 > {
323 >        register void  (**tp)();
324 >
325 >        if (ray_out[0] == NULL)
326 >                return;
327 >        for (tp = ray_out; *tp != NULL; tp++)
328 >                (**tp)(r);
329          if (outform == 'a')
330                  putchar('\n');
331   }
332  
333  
334 + int
335   getvec(vec, fmt, fp)            /* get a vector from fp */
336   register FVECT  vec;
337   int  fmt;
338   FILE  *fp;
339   {
340          static float  vf[3];
341 +        static double  vd[3];
342 +        char  buf[32];
343 +        register int  i;
344  
345          switch (fmt) {
346          case 'a':                                       /* ascii */
347 <                if (fscanf(fp, "%lf %lf %lf", vec, vec+1, vec+2) != 3)
348 <                        return(-1);
347 >                for (i = 0; i < 3; i++) {
348 >                        if (fgetword(buf, sizeof(buf), fp) == NULL ||
349 >                                        !isflt(buf))
350 >                                return(-1);
351 >                        vec[i] = atof(buf);
352 >                }
353                  break;
354          case 'f':                                       /* binary float */
355                  if (fread((char *)vf, sizeof(float), 3, fp) != 3)
# Line 231 | Line 357 | FILE  *fp;
357                  vec[0] = vf[0]; vec[1] = vf[1]; vec[2] = vf[2];
358                  break;
359          case 'd':                                       /* binary double */
360 <                if (fread((char *)vec, sizeof(double), 3, fp) != 3)
360 >                if (fread((char *)vd, sizeof(double), 3, fp) != 3)
361                          return(-1);
362 +                vec[0] = vd[0]; vec[1] = vd[1]; vec[2] = vd[2];
363                  break;
364 +        default:
365 +                error(CONSISTENCY, "botched input format");
366          }
367          return(0);
368   }
369  
370  
371 < static
371 > void
372 > tranotify(obj)                  /* record new modifier */
373 > OBJECT  obj;
374 > {
375 >        static int  hitlimit = 0;
376 >        register OBJREC  *o = objptr(obj);
377 >        register char  **tralp;
378 >
379 >        if (obj == OVOID) {             /* starting over */
380 >                traset[0] = 0;
381 >                hitlimit = 0;
382 >                return;
383 >        }
384 >        if (hitlimit || !ismodifier(o->otype))
385 >                return;
386 >        for (tralp = tralist; *tralp != NULL; tralp++)
387 >                if (!strcmp(o->oname, *tralp)) {
388 >                        if (traset[0] >= MAXTSET) {
389 >                                error(WARNING, "too many modifiers in trace list");
390 >                                hitlimit++;
391 >                                return;         /* should this be fatal? */
392 >                        }
393 >                        insertelem(traset, obj);
394 >                        return;
395 >                }
396 > }
397 >
398 >
399 > static void
400   ourtrace(r)                             /* print ray values */
401   RAY  *r;
402   {
403 <        register int  (**tp)();
403 >        register void  (**tp)();
404  
405          if (every_out[0] == NULL)
406                  return;
407 +        if (r->ro == NULL) {
408 +                if (traincl == 1)
409 +                        return;
410 +        } else if (traincl != -1 && traincl != inset(traset, r->ro->omod))
411 +                return;
412          tabin(r);
413          for (tp = every_out; *tp != NULL; tp++)
414                  (**tp)(r);
# Line 254 | Line 416 | RAY  *r;
416   }
417  
418  
419 < static
419 > static void
420   tabin(r)                                /* tab in appropriate amount */
421   RAY  *r;
422   {
# Line 265 | Line 427 | RAY  *r;
427   }
428  
429  
430 < static
430 > static void
431   oputo(r)                                /* print origin */
432   register RAY  *r;
433   {
# Line 275 | Line 437 | register RAY  *r;
437   }
438  
439  
440 < static
440 > static void
441   oputd(r)                                /* print direction */
442   register RAY  *r;
443   {
# Line 285 | Line 447 | register RAY  *r;
447   }
448  
449  
450 < static
450 > static void
451   oputv(r)                                /* print value */
452   register RAY  *r;
453   {
454 +        COLR  cout;
455 +        
456 +        if (outform == 'c') {
457 +                setcolr(cout,   colval(r->rcol,RED),
458 +                                colval(r->rcol,GRN),
459 +                                colval(r->rcol,BLU));
460 +                fwrite((char *)cout, sizeof(cout), 1, stdout);
461 +                return;
462 +        }
463          (*putreal)(colval(r->rcol,RED));
464          (*putreal)(colval(r->rcol,GRN));
465          (*putreal)(colval(r->rcol,BLU));
466   }
467  
468  
469 < static
470 < oputl(r)                                /* print length */
469 > static void
470 > oputl(r)                                /* print effective distance */
471   register RAY  *r;
472   {
473 <        if (r->rot < FHUGE)
303 <                (*putreal)(r->rot);
304 <        else
305 <                (*putreal)(0.0);
473 >        (*putreal)(r->rt);
474   }
475  
476  
477 < static
477 > static void
478 > oputL(r)                                /* print single ray length */
479 > register RAY  *r;
480 > {
481 >        (*putreal)(r->rot);
482 > }
483 >
484 >
485 > static void
486   oputp(r)                                /* print point */
487   register RAY  *r;
488   {
# Line 322 | Line 498 | register RAY  *r;
498   }
499  
500  
501 < static
502 < oputn(r)                                /* print normal */
501 > static void
502 > oputN(r)                                /* print unperturbed normal */
503   register RAY  *r;
504   {
505          if (r->rot < FHUGE) {
# Line 338 | Line 514 | register RAY  *r;
514   }
515  
516  
517 < static
517 > static void
518 > oputn(r)                                /* print perturbed normal */
519 > RAY  *r;
520 > {
521 >        FVECT  pnorm;
522 >
523 >        if (r->rot >= FHUGE) {
524 >                (*putreal)(0.0);
525 >                (*putreal)(0.0);
526 >                (*putreal)(0.0);
527 >                return;
528 >        }
529 >        raynormal(pnorm, r);
530 >        (*putreal)(pnorm[0]);
531 >        (*putreal)(pnorm[1]);
532 >        (*putreal)(pnorm[2]);
533 > }
534 >
535 >
536 > static void
537   oputs(r)                                /* print name */
538   register RAY  *r;
539   {
# Line 350 | Line 545 | register RAY  *r;
545   }
546  
547  
548 < static
548 > static void
549   oputw(r)                                /* print weight */
550   register RAY  *r;
551   {
# Line 358 | Line 553 | register RAY  *r;
553   }
554  
555  
556 < static
556 > static void
557   oputm(r)                                /* print modifier */
558   register RAY  *r;
559   {
560          if (r->ro != NULL)
561 <                fputs(objptr(r->ro->omod)->oname, stdout);
561 >                if (r->ro->omod != OVOID)
562 >                        fputs(objptr(r->ro->omod)->oname, stdout);
563 >                else
564 >                        fputs(VOIDID, stdout);
565          else
566                  putchar('*');
567          putchar('\t');
568   }
569  
570  
571 < static
571 > static void
572   puta(v)                         /* print ascii value */
573   double  v;
574   {
# Line 378 | Line 576 | double  v;
576   }
577  
578  
579 < static
579 > static void
580   putd(v)                         /* print binary double */
581   double  v;
582   {
# Line 386 | Line 584 | double  v;
584   }
585  
586  
587 < static
587 > static void
588   putf(v)                         /* print binary float */
589   double  v;
590   {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines