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.20 by greg, Mon Oct 21 12:58:10 1991 UTC vs.
Revision 2.33 by schorsch, Mon Jul 21 22:30:19 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 24 | Line 21 | static char SCCSid[] = "$SunId$ LBL";
21   *  irradiance values are desired.
22   */
23  
24 < #include  "ray.h"
24 > #include  <time.h>
25  
26 < #include  "octree.h"
27 <
26 > #include  "platform.h"
27 > #include  "ray.h"
28   #include  "otypes.h"
29 + #include  "resolu.h"
30  
31 + CUBE  thescene;                         /* our scene */
32 + OBJECT  nsceneobjs;                     /* number of objects in our scene */
33 +
34   int  dimlist[MAXDIM];                   /* sampling dimensions */
35   int  ndims = 0;                         /* number of sampling dimensions */
36   int  samplendx = 0;                     /* index for this sample */
37  
38   int  imm_irrad = 0;                     /* compute immediate irradiance? */
39 + int  lim_dist = 0;                      /* limit distance? */
40  
41   int  inform = 'a';                      /* input format */
42   int  outform = 'a';                     /* output format */
43   char  *outvals = "v";                   /* output specification */
44  
45 + int  do_irrad = 0;                      /* compute irradiance? */
46 +
47 + void  (*trace)() = NULL;                /* trace call */
48 +
49 + extern void  ambnotify(), tranotify();
50 + void  (*addobjnotify[])() = {ambnotify, tranotify, NULL};
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 */
62 < int  directrelay = 1;                   /* number of source relays */
62 > int  directrelay = 2;                   /* number of source relays */
63   int  vspretest = 512;                   /* virtual source pretest density */
64 < int  directinvis = 0;                   /* sources invisible? */
65 < double  srcsizerat = .25;               /* maximum ratio source size/dist. */
64 > int  directvis = 1;                     /* sources visible? */
65 > double  srcsizerat = .2;                /* maximum ratio source size/dist. */
66  
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 = 6;                      /* maximum recursion depth */
78   double  minweight = 4e-3;               /* minimum ray weight */
79  
80 + char  *ambfile = NULL;                  /* ambient file name */
81   COLOR  ambval = BLKCOLOR;               /* ambient value */
82 + int  ambvwt = 0;                        /* initial weight for ambient value */
83   double  ambacc = 0.2;                   /* ambient accuracy */
84 < int  ambres = 32;                       /* ambient resolution */
85 < int  ambdiv = 128;                      /* ambient divisions */
84 > int  ambres = 128;                      /* ambient resolution */
85 > int  ambdiv = 512;                      /* ambient divisions */
86   int  ambssamp = 0;                      /* ambient super-samples */
87   int  ambounce = 0;                      /* ambient bounces */
88   char  *amblist[128];                    /* ambient include/exclude list */
89   int  ambincl = -1;                      /* include == 1, exclude == 0 */
90  
66 extern OBJREC  Lamb;                    /* a Lambertian surface */
91  
92   static RAY  thisray;                    /* for our convenience */
93  
94 < static int  oputo(), oputd(), oputv(), oputl(),
95 <                oputp(), oputn(), oputs(), oputw(), oputm();
94 > static void  oputo(), oputd(), oputv(), oputl(), oputL(), oputc(),
95 >                oputp(), oputn(), oputN(), oputs(), oputw(), oputm();
96  
97 < static int  (*ray_out[10])(), (*every_out[10])();
98 < static int  castonly;
97 > static void  ourtrace(), tabin();
98 > static void  (*ray_out[16])(), (*every_out[16])();
99 > static int  castonly = 0;
100  
101 < static int  puta(), putf(), putd();
101 > static void  puta(), putf(), putd();
102  
103 < static int  (*putreal)();
103 > static void  (*putreal)();
104  
105 + void    bogusray(), rad(), irrad(), printvals();
106  
107 +
108 + void
109   quit(code)                      /* quit program */
110   int  code;
111   {
112 + #ifndef  NON_POSIX /* XXX we don't clean up elsewhere? */
113 +        headclean();            /* delete header file */
114 +        pfclean();              /* clean up persist files */
115 + #endif
116          exit(code);
117   }
118  
119  
120 + char *
121 + formstr(f)                              /* return format identifier */
122 + int  f;
123 + {
124 +        switch (f) {
125 +        case 'a': return("ascii");
126 +        case 'f': return("float");
127 +        case 'd': return("double");
128 +        case 'c': return(COLRFMT);
129 +        }
130 +        return("unknown");
131 + }
132 +
133 +
134 + void
135   rtrace(fname)                           /* trace rays from file */
136   char  *fname;
137   {
138          long  vcount = hresolu>1 ? hresolu*vresolu : vresolu;
139          long  nextflush = hresolu;
140          FILE  *fp;
141 +        double  d;
142          FVECT  orig, direc;
143                                          /* set up input */
144          if (fname == NULL)
# Line 99 | Line 147 | char  *fname;
147                  sprintf(errmsg, "cannot open input file \"%s\"", fname);
148                  error(SYSTEM, errmsg);
149          }
150 + #ifdef _WIN32
151 +        if (inform != 'a')
152 +                SET_FILE_BINARY(fp);
153 + #endif
154                                          /* set up output */
155          setoutput(outvals);
156          switch (outform) {
157          case 'a': putreal = puta; break;
158          case 'f': putreal = putf; break;
159          case 'd': putreal = putd; break;
160 +        case 'c':
161 +                if (strcmp(outvals, "v"))
162 +                        error(USER, "color format with value output only");
163 +                break;
164 +        default:
165 +                error(CONSISTENCY, "botched output format");
166          }
167 +        if (hresolu > 0) {
168 +                if (vresolu > 0)
169 +                        fprtresolu(hresolu, vresolu, stdout);
170 +                fflush(stdout);
171 +        }
172                                          /* process file */
173          while (getvec(orig, inform, fp) == 0 &&
174                          getvec(direc, inform, fp) == 0) {
175  
176 <                if (normalize(direc) == 0.0) {          /* zero ==> flush */
177 <                        fflush(stdout);
178 <                        continue;
179 <                }
180 <                samplendx++;
176 >                d = normalize(direc);
177 >                if (d == 0.0) {                         /* zero ==> flush */
178 >                        bogusray();
179 >                        if (--nextflush <= 0 || vcount <= 0) {
180 >                                fflush(stdout);
181 >                                nextflush = hresolu;
182 >                        }
183 >                } else {
184 >                        samplendx++;
185                                                          /* compute and print */
186 <                if (imm_irrad)
187 <                        irrad(orig, direc);
188 <                else
189 <                        traceray(orig, direc);
186 >                        if (imm_irrad)
187 >                                irrad(orig, direc);
188 >                        else
189 >                                rad(orig, direc, lim_dist ? d : 0.0);
190                                                          /* flush if time */
191 <                if (--nextflush == 0) {
192 <                        fflush(stdout);
193 <                        nextflush = hresolu;
191 >                        if (--nextflush == 0) {
192 >                                fflush(stdout);
193 >                                nextflush = hresolu;
194 >                        }
195                  }
196                  if (ferror(stdout))
197                          error(SYSTEM, "write error");
198                  if (--vcount == 0)                      /* check for end */
199                          break;
200          }
201 +        fflush(stdout);
202          if (vcount > 0)
203                  error(USER, "read error");
204 <        fclose(fp);
204 >        if (fname != NULL)
205 >                fclose(fp);
206   }
207  
208  
209   setoutput(vs)                           /* set up output tables */
210   register char  *vs;
211   {
212 <        extern int  ourtrace(), (*trace)();
213 <        register int (**table)() = ray_out;
212 >        extern void  (*trace)();
213 >        register void (**table)() = ray_out;
214  
215          castonly = 1;
216          while (*vs)
# Line 161 | Line 231 | register char  *vs;
231                          *table++ = oputv;
232                          castonly = 0;
233                          break;
234 <                case 'l':                               /* length */
234 >                case 'l':                               /* effective distance */
235                          *table++ = oputl;
236                          castonly = 0;
237                          break;
238 +                case 'c':                               /* local coordinates */
239 +                        *table++ = oputc;
240 +                        break;
241 +                case 'L':                               /* single ray length */
242 +                        *table++ = oputL;
243 +                        break;
244                  case 'p':                               /* point */
245                          *table++ = oputp;
246                          break;
247 <                case 'n':                               /* normal */
247 >                case 'n':                               /* perturbed normal */
248                          *table++ = oputn;
249 +                        castonly = 0;
250                          break;
251 +                case 'N':                               /* unperturbed normal */
252 +                        *table++ = oputN;
253 +                        break;
254                  case 's':                               /* surface */
255                          *table++ = oputs;
256                          break;
# Line 185 | Line 265 | register char  *vs;
265   }
266  
267  
268 < traceray(org, dir)              /* compute and print ray value(s) */
269 < FVECT  org, dir;
268 > void
269 > bogusray()                      /* print out empty record */
270   {
271 <        register int  (**tp)();
271 >        thisray.rorg[0] = thisray.rorg[1] = thisray.rorg[2] =
272 >        thisray.rdir[0] = thisray.rdir[1] = thisray.rdir[2] = 0.0;
273 >        rayorigin(&thisray, NULL, PRIMARY, 1.0);
274 >        printvals(&thisray);
275 > }
276  
277 +
278 + void
279 + rad(org, dir, dmax)             /* compute and print ray value(s) */
280 + FVECT  org, dir;
281 + double  dmax;
282 + {
283          VCOPY(thisray.rorg, org);
284          VCOPY(thisray.rdir, dir);
285 +        thisray.rmax = dmax;
286          rayorigin(&thisray, NULL, PRIMARY, 1.0);
287 <        if (castonly)
288 <                localhit(&thisray, &thescene) || sourcehit(&thisray);
289 <        else
287 >        if (castonly) {
288 >                if (!localhit(&thisray, &thescene)) {
289 >                        if (thisray.ro == &Aftplane) {  /* clipped */
290 >                                thisray.ro = NULL;
291 >                                thisray.rot = FHUGE;
292 >                        } else
293 >                                sourcehit(&thisray);
294 >                }
295 >        } else
296                  rayvalue(&thisray);
297 <
201 <        if (ray_out[0] == NULL)
202 <                return;
203 <        for (tp = ray_out; *tp != NULL; tp++)
204 <                (**tp)(&thisray);
205 <        if (outform == 'a')
206 <                putchar('\n');
297 >        printvals(&thisray);
298   }
299  
300  
301 + void
302   irrad(org, dir)                 /* compute immediate irradiance value */
303   FVECT  org, dir;
304   {
# Line 218 | Line 310 | FVECT  org, dir;
310          }
311          rayorigin(&thisray, NULL, PRIMARY, 1.0);
312                                          /* pretend we hit surface */
313 <        thisray.rot = 1.0;
313 >        thisray.rot = 1.0-1e-4;
314          thisray.rod = 1.0;
315          VCOPY(thisray.ron, dir);
316          for (i = 0; i < 3; i++)         /* fudge factor */
317                  thisray.rop[i] = org[i] + 1e-4*dir[i];
318                                          /* compute and print */
319          (*ofun[Lamb.otype].funp)(&Lamb, &thisray);
320 <        oputv(&thisray);
320 >        printvals(&thisray);
321 > }
322 >
323 >
324 > void
325 > printvals(r)                    /* print requested ray values */
326 > RAY  *r;
327 > {
328 >        register void  (**tp)();
329 >
330 >        if (ray_out[0] == NULL)
331 >                return;
332 >        for (tp = ray_out; *tp != NULL; tp++)
333 >                (**tp)(r);
334          if (outform == 'a')
335                  putchar('\n');
336   }
337  
338  
339 + int
340   getvec(vec, fmt, fp)            /* get a vector from fp */
341   register FVECT  vec;
342   int  fmt;
343   FILE  *fp;
344   {
239        extern char  *fgetword();
240        extern double  atof();
345          static float  vf[3];
346 +        static double  vd[3];
347          char  buf[32];
348          register int  i;
349  
# Line 257 | Line 362 | FILE  *fp;
362                  vec[0] = vf[0]; vec[1] = vf[1]; vec[2] = vf[2];
363                  break;
364          case 'd':                                       /* binary double */
365 <                if (fread((char *)vec, sizeof(double), 3, fp) != 3)
365 >                if (fread((char *)vd, sizeof(double), 3, fp) != 3)
366                          return(-1);
367 +                vec[0] = vd[0]; vec[1] = vd[1]; vec[2] = vd[2];
368                  break;
369 +        default:
370 +                error(CONSISTENCY, "botched input format");
371          }
372          return(0);
373   }
374  
375  
376 < static
376 > void
377 > tranotify(obj)                  /* record new modifier */
378 > OBJECT  obj;
379 > {
380 >        static int  hitlimit = 0;
381 >        register OBJREC  *o = objptr(obj);
382 >        register char  **tralp;
383 >
384 >        if (obj == OVOID) {             /* starting over */
385 >                traset[0] = 0;
386 >                hitlimit = 0;
387 >                return;
388 >        }
389 >        if (hitlimit || !ismodifier(o->otype))
390 >                return;
391 >        for (tralp = tralist; *tralp != NULL; tralp++)
392 >                if (!strcmp(o->oname, *tralp)) {
393 >                        if (traset[0] >= MAXTSET) {
394 >                                error(WARNING, "too many modifiers in trace list");
395 >                                hitlimit++;
396 >                                return;         /* should this be fatal? */
397 >                        }
398 >                        insertelem(traset, obj);
399 >                        return;
400 >                }
401 > }
402 >
403 >
404 > static void
405   ourtrace(r)                             /* print ray values */
406   RAY  *r;
407   {
408 <        register int  (**tp)();
408 >        register void  (**tp)();
409  
410          if (every_out[0] == NULL)
411                  return;
412 +        if (r->ro == NULL) {
413 +                if (traincl == 1)
414 +                        return;
415 +        } else if (traincl != -1 && traincl != inset(traset, r->ro->omod))
416 +                return;
417          tabin(r);
418          for (tp = every_out; *tp != NULL; tp++)
419                  (**tp)(r);
# Line 280 | Line 421 | RAY  *r;
421   }
422  
423  
424 < static
424 > static void
425   tabin(r)                                /* tab in appropriate amount */
426   RAY  *r;
427   {
# Line 291 | Line 432 | RAY  *r;
432   }
433  
434  
435 < static
435 > static void
436   oputo(r)                                /* print origin */
437 < register RAY  *r;
437 > RAY  *r;
438   {
439          (*putreal)(r->rorg[0]);
440          (*putreal)(r->rorg[1]);
# Line 301 | Line 442 | register RAY  *r;
442   }
443  
444  
445 < static
445 > static void
446   oputd(r)                                /* print direction */
447 < register RAY  *r;
447 > RAY  *r;
448   {
449          (*putreal)(r->rdir[0]);
450          (*putreal)(r->rdir[1]);
# Line 311 | Line 452 | register RAY  *r;
452   }
453  
454  
455 < static
455 > static void
456   oputv(r)                                /* print value */
457 < register RAY  *r;
457 > RAY  *r;
458   {
459 +        COLR  cout;
460 +        
461 +        if (outform == 'c') {
462 +                setcolr(cout,   colval(r->rcol,RED),
463 +                                colval(r->rcol,GRN),
464 +                                colval(r->rcol,BLU));
465 +                fwrite((char *)cout, sizeof(cout), 1, stdout);
466 +                return;
467 +        }
468          (*putreal)(colval(r->rcol,RED));
469          (*putreal)(colval(r->rcol,GRN));
470          (*putreal)(colval(r->rcol,BLU));
471   }
472  
473  
474 < static
475 < oputl(r)                                /* print length */
476 < register RAY  *r;
474 > static void
475 > oputl(r)                                /* print effective distance */
476 > RAY  *r;
477   {
478          (*putreal)(r->rt);
479   }
480  
481  
482 < static
482 > static void
483 > oputL(r)                                /* print single ray length */
484 > RAY  *r;
485 > {
486 >        (*putreal)(r->rot);
487 > }
488 >
489 >
490 > static void
491 > oputc(r)                                /* print local coordinates */
492 > RAY  *r;
493 > {
494 >        (*putreal)(r->uv[0]);
495 >        (*putreal)(r->uv[1]);
496 > }
497 >
498 >
499 > static void
500   oputp(r)                                /* print point */
501 < register RAY  *r;
501 > RAY  *r;
502   {
503          if (r->rot < FHUGE) {
504                  (*putreal)(r->rop[0]);
# Line 345 | Line 512 | register RAY  *r;
512   }
513  
514  
515 < static
516 < oputn(r)                                /* print normal */
517 < register RAY  *r;
515 > static void
516 > oputN(r)                                /* print unperturbed normal */
517 > RAY  *r;
518   {
519          if (r->rot < FHUGE) {
520                  (*putreal)(r->ron[0]);
# Line 361 | Line 528 | register RAY  *r;
528   }
529  
530  
531 < static
531 > static void
532 > oputn(r)                                /* print perturbed normal */
533 > RAY  *r;
534 > {
535 >        FVECT  pnorm;
536 >
537 >        if (r->rot >= FHUGE) {
538 >                (*putreal)(0.0);
539 >                (*putreal)(0.0);
540 >                (*putreal)(0.0);
541 >                return;
542 >        }
543 >        raynormal(pnorm, r);
544 >        (*putreal)(pnorm[0]);
545 >        (*putreal)(pnorm[1]);
546 >        (*putreal)(pnorm[2]);
547 > }
548 >
549 >
550 > static void
551   oputs(r)                                /* print name */
552 < register RAY  *r;
552 > RAY  *r;
553   {
554          if (r->ro != NULL)
555                  fputs(r->ro->oname, stdout);
# Line 373 | Line 559 | register RAY  *r;
559   }
560  
561  
562 < static
562 > static void
563   oputw(r)                                /* print weight */
564 < register RAY  *r;
564 > RAY  *r;
565   {
566          (*putreal)(r->rweight);
567   }
568  
569  
570 < static
570 > static void
571   oputm(r)                                /* print modifier */
572 < register RAY  *r;
572 > RAY  *r;
573   {
574          if (r->ro != NULL)
575 <                fputs(objptr(r->ro->omod)->oname, stdout);
575 >                if (r->ro->omod != OVOID)
576 >                        fputs(objptr(r->ro->omod)->oname, stdout);
577 >                else
578 >                        fputs(VOIDID, stdout);
579          else
580                  putchar('*');
581          putchar('\t');
582   }
583  
584  
585 < static
585 > static void
586   puta(v)                         /* print ascii value */
587   double  v;
588   {
# Line 401 | Line 590 | double  v;
590   }
591  
592  
593 < static
593 > static void
594   putd(v)                         /* print binary double */
595   double  v;
596   {
# Line 409 | Line 598 | double  v;
598   }
599  
600  
601 < static
601 > static void
602   putf(v)                         /* print binary float */
603   double  v;
604   {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines