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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines