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.12 by greg, Thu Mar 28 10:16:35 1991 UTC vs.
Revision 2.29 by greg, Fri Apr 18 17:29:22 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 '-oi' or '-oI' options indicate that
20 > *  radiance is computed.  The '-i' or '-I' options indicate that
21   *  irradiance values are desired.
22   */
23  
24   #include  "ray.h"
25  
29 #include  "octree.h"
30
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 < static int  oputo(), oputd(), oputv(), oputl(),
94 <                oputp(), oputn(), oputs(), oputw(), oputm();
93 > static void  oputo(), oputd(), oputv(), oputl(), oputL(), oputc(),
94 >                oputp(), oputn(), oputN(), oputs(), oputw(), oputm();
95  
96 < static int  (*ray_out[10])(), (*every_out[10])();
97 < static int  castonly;
96 > static void  ourtrace(), tabin();
97 > static void  (*ray_out[16])(), (*every_out[16])();
98 > static int  castonly = 0;
99  
100 < static int  puta(), putf(), putd();
100 > static void  puta(), putf(), putd();
101  
102 < static int  (*putreal)();
102 > static void  (*putreal)();
103  
104 < static double  Lambfa[5] = {PI, PI, PI, 0.0, 0.0};
69 < static OBJREC  Lamb = {
70 <        OVOID, MAT_PLASTIC, "Lambertian",
71 <        {0, 5, NULL, Lambfa}, NULL, -1,
72 < };                                      /* a Lambertian surface */
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 93 | 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 if (outvals[0] == 'I')
188 <                        Irrad(orig, direc);
116 <                else
117 <                        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)
# Line 156 | Line 230 | register char  *vs;
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 'c':                               /* local coordinates */
238 +                        *table++ = oputc;
239 +                        break;
240 +                case 'L':                               /* single ray length */
241 +                        *table++ = oputL;
242 +                        break;
243                  case 'p':                               /* point */
244                          *table++ = oputp;
245                          break;
246 <                case 'n':                               /* normal */
246 >                case 'n':                               /* perturbed normal */
247                          *table++ = oputn;
248 +                        castonly = 0;
249                          break;
250 +                case 'N':                               /* unperturbed normal */
251 +                        *table++ = oputN;
252 +                        break;
253                  case 's':                               /* surface */
254                          *table++ = oputs;
255                          break;
# Line 180 | Line 264 | register char  *vs;
264   }
265  
266  
267 < radiance(org, dir)              /* compute radiance value */
268 < FVECT  org, dir;
267 > void
268 > bogusray()                      /* print out empty record */
269   {
270 <        register int  (**tp)();
270 >        thisray.rorg[0] = thisray.rorg[1] = thisray.rorg[2] =
271 >        thisray.rdir[0] = thisray.rdir[1] = thisray.rdir[2] = 0.0;
272 >        rayorigin(&thisray, NULL, PRIMARY, 1.0);
273 >        printvals(&thisray);
274 > }
275  
276 +
277 + void
278 + rad(org, dir, dmax)             /* compute and print ray value(s) */
279 + FVECT  org, dir;
280 + double  dmax;
281 + {
282          VCOPY(thisray.rorg, org);
283          VCOPY(thisray.rdir, dir);
284 +        thisray.rmax = dmax;
285          rayorigin(&thisray, NULL, PRIMARY, 1.0);
286 <        if (castonly)
287 <                localhit(&thisray, &thescene) || sourcehit(&thisray);
288 <        else
286 >        if (castonly) {
287 >                if (!localhit(&thisray, &thescene))
288 >                        if (thisray.ro == &Aftplane) {  /* clipped */
289 >                                thisray.ro = NULL;
290 >                                thisray.rot = FHUGE;
291 >                        } else
292 >                                sourcehit(&thisray);
293 >        } else
294                  rayvalue(&thisray);
295 <
196 <        if (ray_out[0] == NULL)
197 <                return;
198 <        for (tp = ray_out; *tp != NULL; tp++)
199 <                (**tp)(&thisray);
200 <        if (outform == 'a')
201 <                putchar('\n');
295 >        printvals(&thisray);
296   }
297  
298  
299 < irrad(org, dir)                 /* compute irradiance value */
299 > void
300 > irrad(org, dir)                 /* compute immediate irradiance value */
301   FVECT  org, dir;
302   {
303          register int  i;
# Line 213 | Line 308 | FVECT  org, dir;
308          }
309          rayorigin(&thisray, NULL, PRIMARY, 1.0);
310                                          /* pretend we hit surface */
311 <        thisray.rot = 1.0;
311 >        thisray.rot = 1.0-1e-4;
312          thisray.rod = 1.0;
313          VCOPY(thisray.ron, dir);
314          for (i = 0; i < 3; i++)         /* fudge factor */
315                  thisray.rop[i] = org[i] + 1e-4*dir[i];
316                                          /* compute and print */
317          (*ofun[Lamb.otype].funp)(&Lamb, &thisray);
318 <        oputv(&thisray);
224 <        if (outform == 'a')
225 <                putchar('\n');
318 >        printvals(&thisray);
319   }
320  
321  
322 < Irrad(org, dir)         /* compute irradiance value after intersection */
323 < FVECT  org, dir;
322 > void
323 > printvals(r)                    /* print requested ray values */
324 > RAY  *r;
325   {
326 <                                        /* compute intersection */
327 <        VCOPY(thisray.rorg, org);
328 <        VCOPY(thisray.rdir, dir);
329 <        rayorigin(&thisray, NULL, PRIMARY, 1.0);
330 <        localhit(&thisray, &thescene);
331 <        if (thisray.ro != NULL)         /* pretend we hit Lambertian surf. */
238 <                (*ofun[Lamb.otype].funp)(&Lamb, &thisray);
239 <        oputv(&thisray);
326 >        register void  (**tp)();
327 >
328 >        if (ray_out[0] == NULL)
329 >                return;
330 >        for (tp = ray_out; *tp != NULL; tp++)
331 >                (**tp)(r);
332          if (outform == 'a')
333                  putchar('\n');
334   }
335  
336  
337 + int
338   getvec(vec, fmt, fp)            /* get a vector from fp */
339   register FVECT  vec;
340   int  fmt;
341   FILE  *fp;
342   {
343          static float  vf[3];
344 +        static double  vd[3];
345 +        char  buf[32];
346 +        register int  i;
347  
348          switch (fmt) {
349          case 'a':                                       /* ascii */
350 <                if (fscanf(fp, "%lf %lf %lf", vec, vec+1, vec+2) != 3)
351 <                        return(-1);
350 >                for (i = 0; i < 3; i++) {
351 >                        if (fgetword(buf, sizeof(buf), fp) == NULL ||
352 >                                        !isflt(buf))
353 >                                return(-1);
354 >                        vec[i] = atof(buf);
355 >                }
356                  break;
357          case 'f':                                       /* binary float */
358                  if (fread((char *)vf, sizeof(float), 3, fp) != 3)
# Line 260 | Line 360 | FILE  *fp;
360                  vec[0] = vf[0]; vec[1] = vf[1]; vec[2] = vf[2];
361                  break;
362          case 'd':                                       /* binary double */
363 <                if (fread((char *)vec, sizeof(double), 3, fp) != 3)
363 >                if (fread((char *)vd, sizeof(double), 3, fp) != 3)
364                          return(-1);
365 +                vec[0] = vd[0]; vec[1] = vd[1]; vec[2] = vd[2];
366                  break;
367 +        default:
368 +                error(CONSISTENCY, "botched input format");
369          }
370          return(0);
371   }
372  
373  
374 < static
374 > void
375 > tranotify(obj)                  /* record new modifier */
376 > OBJECT  obj;
377 > {
378 >        static int  hitlimit = 0;
379 >        register OBJREC  *o = objptr(obj);
380 >        register char  **tralp;
381 >
382 >        if (obj == OVOID) {             /* starting over */
383 >                traset[0] = 0;
384 >                hitlimit = 0;
385 >                return;
386 >        }
387 >        if (hitlimit || !ismodifier(o->otype))
388 >                return;
389 >        for (tralp = tralist; *tralp != NULL; tralp++)
390 >                if (!strcmp(o->oname, *tralp)) {
391 >                        if (traset[0] >= MAXTSET) {
392 >                                error(WARNING, "too many modifiers in trace list");
393 >                                hitlimit++;
394 >                                return;         /* should this be fatal? */
395 >                        }
396 >                        insertelem(traset, obj);
397 >                        return;
398 >                }
399 > }
400 >
401 >
402 > static void
403   ourtrace(r)                             /* print ray values */
404   RAY  *r;
405   {
406 <        register int  (**tp)();
406 >        register void  (**tp)();
407  
408          if (every_out[0] == NULL)
409                  return;
410 +        if (r->ro == NULL) {
411 +                if (traincl == 1)
412 +                        return;
413 +        } else if (traincl != -1 && traincl != inset(traset, r->ro->omod))
414 +                return;
415          tabin(r);
416          for (tp = every_out; *tp != NULL; tp++)
417                  (**tp)(r);
# Line 283 | Line 419 | RAY  *r;
419   }
420  
421  
422 < static
422 > static void
423   tabin(r)                                /* tab in appropriate amount */
424   RAY  *r;
425   {
# Line 294 | Line 430 | RAY  *r;
430   }
431  
432  
433 < static
433 > static void
434   oputo(r)                                /* print origin */
435 < register RAY  *r;
435 > RAY  *r;
436   {
437          (*putreal)(r->rorg[0]);
438          (*putreal)(r->rorg[1]);
# Line 304 | Line 440 | register RAY  *r;
440   }
441  
442  
443 < static
443 > static void
444   oputd(r)                                /* print direction */
445 < register RAY  *r;
445 > RAY  *r;
446   {
447          (*putreal)(r->rdir[0]);
448          (*putreal)(r->rdir[1]);
# Line 314 | Line 450 | register RAY  *r;
450   }
451  
452  
453 < static
453 > static void
454   oputv(r)                                /* print value */
455 < register RAY  *r;
455 > RAY  *r;
456   {
457 +        COLR  cout;
458 +        
459 +        if (outform == 'c') {
460 +                setcolr(cout,   colval(r->rcol,RED),
461 +                                colval(r->rcol,GRN),
462 +                                colval(r->rcol,BLU));
463 +                fwrite((char *)cout, sizeof(cout), 1, stdout);
464 +                return;
465 +        }
466          (*putreal)(colval(r->rcol,RED));
467          (*putreal)(colval(r->rcol,GRN));
468          (*putreal)(colval(r->rcol,BLU));
469   }
470  
471  
472 < static
473 < oputl(r)                                /* print length */
474 < register RAY  *r;
472 > static void
473 > oputl(r)                                /* print effective distance */
474 > RAY  *r;
475   {
476          (*putreal)(r->rt);
477   }
478  
479  
480 < static
480 > static void
481 > oputL(r)                                /* print single ray length */
482 > RAY  *r;
483 > {
484 >        (*putreal)(r->rot);
485 > }
486 >
487 >
488 > static void
489 > oputc(r)                                /* print local coordinates */
490 > RAY  *r;
491 > {
492 >        (*putreal)(r->uv[0]);
493 >        (*putreal)(r->uv[1]);
494 > }
495 >
496 >
497 > static void
498   oputp(r)                                /* print point */
499 < register RAY  *r;
499 > RAY  *r;
500   {
501          if (r->rot < FHUGE) {
502                  (*putreal)(r->rop[0]);
# Line 348 | Line 510 | register RAY  *r;
510   }
511  
512  
513 < static
514 < oputn(r)                                /* print normal */
515 < register RAY  *r;
513 > static void
514 > oputN(r)                                /* print unperturbed normal */
515 > RAY  *r;
516   {
517          if (r->rot < FHUGE) {
518                  (*putreal)(r->ron[0]);
# Line 364 | Line 526 | register RAY  *r;
526   }
527  
528  
529 < static
529 > static void
530 > oputn(r)                                /* print perturbed normal */
531 > RAY  *r;
532 > {
533 >        FVECT  pnorm;
534 >
535 >        if (r->rot >= FHUGE) {
536 >                (*putreal)(0.0);
537 >                (*putreal)(0.0);
538 >                (*putreal)(0.0);
539 >                return;
540 >        }
541 >        raynormal(pnorm, r);
542 >        (*putreal)(pnorm[0]);
543 >        (*putreal)(pnorm[1]);
544 >        (*putreal)(pnorm[2]);
545 > }
546 >
547 >
548 > static void
549   oputs(r)                                /* print name */
550 < register RAY  *r;
550 > RAY  *r;
551   {
552          if (r->ro != NULL)
553                  fputs(r->ro->oname, stdout);
# Line 376 | Line 557 | register RAY  *r;
557   }
558  
559  
560 < static
560 > static void
561   oputw(r)                                /* print weight */
562 < register RAY  *r;
562 > RAY  *r;
563   {
564          (*putreal)(r->rweight);
565   }
566  
567  
568 < static
568 > static void
569   oputm(r)                                /* print modifier */
570 < register RAY  *r;
570 > RAY  *r;
571   {
572          if (r->ro != NULL)
573 <                fputs(objptr(r->ro->omod)->oname, stdout);
573 >                if (r->ro->omod != OVOID)
574 >                        fputs(objptr(r->ro->omod)->oname, stdout);
575 >                else
576 >                        fputs(VOIDID, stdout);
577          else
578                  putchar('*');
579          putchar('\t');
580   }
581  
582  
583 < static
583 > static void
584   puta(v)                         /* print ascii value */
585   double  v;
586   {
# Line 404 | Line 588 | double  v;
588   }
589  
590  
591 < static
591 > static void
592   putd(v)                         /* print binary double */
593   double  v;
594   {
# Line 412 | Line 596 | double  v;
596   }
597  
598  
599 < static
599 > static void
600   putf(v)                         /* print binary float */
601   double  v;
602   {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines