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.3 by greg, Wed Jun 7 08:35:23 1989 UTC vs.
Revision 2.27 by greg, Sat Feb 22 02:07:29 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.
6 + */
7 +
8 + /* ====================================================================
9 + * The Radiance Software License, Version 1.0
10   *
11 < *     6/11/86
11 > * Copyright (c) 1990 - 2002 The Regents of the University of California,
12 > * through Lawrence Berkeley National Laboratory.   All rights reserved.
13 > *
14 > * Redistribution and use in source and binary forms, with or without
15 > * modification, are permitted provided that the following conditions
16 > * are met:
17 > *
18 > * 1. Redistributions of source code must retain the above copyright
19 > *         notice, this list of conditions and the following disclaimer.
20 > *
21 > * 2. Redistributions in binary form must reproduce the above copyright
22 > *       notice, this list of conditions and the following disclaimer in
23 > *       the documentation and/or other materials provided with the
24 > *       distribution.
25 > *
26 > * 3. The end-user documentation included with the redistribution,
27 > *           if any, must include the following acknowledgment:
28 > *             "This product includes Radiance software
29 > *                 (http://radsite.lbl.gov/)
30 > *                 developed by the Lawrence Berkeley National Laboratory
31 > *               (http://www.lbl.gov/)."
32 > *       Alternately, this acknowledgment may appear in the software itself,
33 > *       if and wherever such third-party acknowledgments normally appear.
34 > *
35 > * 4. The names "Radiance," "Lawrence Berkeley National Laboratory"
36 > *       and "The Regents of the University of California" must
37 > *       not be used to endorse or promote products derived from this
38 > *       software without prior written permission. For written
39 > *       permission, please contact [email protected].
40 > *
41 > * 5. Products derived from this software may not be called "Radiance",
42 > *       nor may "Radiance" appear in their name, without prior written
43 > *       permission of Lawrence Berkeley National Laboratory.
44 > *
45 > * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
46 > * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
47 > * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
48 > * DISCLAIMED.   IN NO EVENT SHALL Lawrence Berkeley National Laboratory OR
49 > * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
50 > * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
51 > * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
52 > * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
53 > * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
54 > * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
55 > * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
56 > * SUCH DAMAGE.
57 > * ====================================================================
58 > *
59 > * This software consists of voluntary contributions made by many
60 > * individuals on behalf of Lawrence Berkeley National Laboratory.   For more
61 > * information on Lawrence Berkeley National Laboratory, please see
62 > * <http://www.lbl.gov/>.
63   */
64  
65   /*
# Line 16 | Line 68 | static char SCCSid[] = "$SunId$ LBL";
68   *      xorg    yorg    zorg    xdir    ydir    zdir
69   *
70   *  The direction need not be normalized.  Output is flexible.
71 + *  If the direction vector is (0,0,0), then the output is flushed.
72   *  All values default to ascii representation of real
73   *  numbers.  Binary representations can be selected
74   *  with '-ff' for float or '-fd' for double.  By default,
75 < *  radiance is computed.  The '-i' option indicates that
75 > *  radiance is computed.  The '-i' or '-I' options indicate that
76   *  irradiance values are desired.
77   */
78  
# Line 27 | Line 80 | static char SCCSid[] = "$SunId$ LBL";
80  
81   #include  "otypes.h"
82  
83 + #include  "resolu.h"
84 +
85 + CUBE  thescene;                         /* our scene */
86 + OBJECT  nsceneobjs;                     /* number of objects in our scene */
87 +
88 + int  dimlist[MAXDIM];                   /* sampling dimensions */
89 + int  ndims = 0;                         /* number of sampling dimensions */
90 + int  samplendx = 0;                     /* index for this sample */
91 +
92 + int  imm_irrad = 0;                     /* compute immediate irradiance? */
93 + int  lim_dist = 0;                      /* limit distance? */
94 +
95   int  inform = 'a';                      /* input format */
96   int  outform = 'a';                     /* output format */
97   char  *outvals = "v";                   /* output specification */
98  
99 + int  do_irrad = 0;                      /* compute irradiance? */
100 +
101 + void  (*trace)() = NULL;                /* trace call */
102 +
103 + extern void  ambnotify(), tranotify();
104 + void  (*addobjnotify[])() = {ambnotify, tranotify, NULL};
105 + char  *tralist[128];                    /* list of modifers to trace (or no) */
106 + int  traincl = -1;                      /* include == 1, exclude == 0 */
107 + #define  MAXTSET        511             /* maximum number in trace set */
108 + OBJECT  traset[MAXTSET+1]={0};          /* trace include/exclude set */
109 +
110   int  hresolu = 0;                       /* horizontal (scan) size */
111   int  vresolu = 0;                       /* vertical resolution */
112  
113   double  dstrsrc = 0.0;                  /* square source distribution */
114 < double  shadthresh = .01;               /* shadow threshold */
114 > double  shadthresh = .05;               /* shadow threshold */
115 > double  shadcert = .5;                  /* shadow certainty */
116 > int  directrelay = 2;                   /* number of source relays */
117 > int  vspretest = 512;                   /* virtual source pretest density */
118 > int  directvis = 1;                     /* sources visible? */
119 > double  srcsizerat = .2;                /* maximum ratio source size/dist. */
120  
121 + COLOR  cextinction = BLKCOLOR;          /* global extinction coefficient */
122 + COLOR  salbedo = BLKCOLOR;              /* global scattering albedo */
123 + double  seccg = 0.;                     /* global scattering eccentricity */
124 + double  ssampdist = 0.;                 /* scatter sampling distance */
125 +
126 + double  specthresh = .15;               /* specular sampling threshold */
127 + double  specjitter = 1.;                /* specular sampling jitter */
128 +
129 + int  backvis = 1;                       /* back face visibility */
130 +
131   int  maxdepth = 6;                      /* maximum recursion depth */
132   double  minweight = 4e-3;               /* minimum ray weight */
133  
134 + char  *ambfile = NULL;                  /* ambient file name */
135   COLOR  ambval = BLKCOLOR;               /* ambient value */
136 + int  ambvwt = 0;                        /* initial weight for ambient value */
137   double  ambacc = 0.2;                   /* ambient accuracy */
138   int  ambres = 128;                      /* ambient resolution */
139 < int  ambdiv = 128;                      /* ambient divisions */
139 > int  ambdiv = 512;                      /* ambient divisions */
140   int  ambssamp = 0;                      /* ambient super-samples */
141   int  ambounce = 0;                      /* ambient bounces */
142   char  *amblist[128];                    /* ambient include/exclude list */
143   int  ambincl = -1;                      /* include == 1, exclude == 0 */
144  
145 +
146   static RAY  thisray;                    /* for our convenience */
147  
148 < extern int  oputo(), oputd(), oputv(), oputl(),
149 <                oputp(), oputn(), oputs(), oputw(), oputm();
148 > static void  oputo(), oputd(), oputv(), oputl(), oputL(),
149 >                oputp(), oputn(), oputN(), oputs(), oputw(), oputm();
150  
151 < static int  (*ray_out[10])(), (*every_out[10])();
151 > static void  ourtrace(), tabin();
152 > static void  (*ray_out[16])(), (*every_out[16])();
153 > static int  castonly = 0;
154  
155 < extern int  puta(), putf(), putd();
155 > static void  puta(), putf(), putd();
156  
157 < static int  (*putreal)();
157 > static void  (*putreal)();
158  
159 + void    bogusray(), rad(), irrad(), printvals();
160  
161 +
162 + void
163   quit(code)                      /* quit program */
164   int  code;
165   {
166 + #ifndef  NIX
167 +        headclean();            /* delete header file */
168 +        pfclean();              /* clean up persist files */
169 + #endif
170          exit(code);
171   }
172  
173  
174 + char *
175 + formstr(f)                              /* return format identifier */
176 + int  f;
177 + {
178 +        switch (f) {
179 +        case 'a': return("ascii");
180 +        case 'f': return("float");
181 +        case 'd': return("double");
182 +        case 'c': return(COLRFMT);
183 +        }
184 +        return("unknown");
185 + }
186 +
187 +
188 + void
189   rtrace(fname)                           /* trace rays from file */
190   char  *fname;
191   {
192          long  vcount = hresolu>1 ? hresolu*vresolu : vresolu;
193          long  nextflush = hresolu;
194          FILE  *fp;
195 +        double  d;
196          FVECT  orig, direc;
197                                          /* set up input */
198          if (fname == NULL)
# Line 82 | Line 201 | char  *fname;
201                  sprintf(errmsg, "cannot open input file \"%s\"", fname);
202                  error(SYSTEM, errmsg);
203          }
204 + #ifdef MSDOS
205 +        if (inform != 'a')
206 +                setmode(fileno(fp), O_BINARY);
207 + #endif
208                                          /* set up output */
209          setoutput(outvals);
210          switch (outform) {
211          case 'a': putreal = puta; break;
212          case 'f': putreal = putf; break;
213          case 'd': putreal = putd; break;
214 +        case 'c':
215 +                if (strcmp(outvals, "v"))
216 +                        error(USER, "color format with value output only");
217 +                break;
218 +        default:
219 +                error(CONSISTENCY, "botched output format");
220          }
221 +        if (hresolu > 0) {
222 +                if (vresolu > 0)
223 +                        fprtresolu(hresolu, vresolu, stdout);
224 +                fflush(stdout);
225 +        }
226                                          /* process file */
227          while (getvec(orig, inform, fp) == 0 &&
228                          getvec(direc, inform, fp) == 0) {
229  
230 <                if (normalize(direc) == 0.0)
231 <                        error(USER, "zero direction vector");
230 >                d = normalize(direc);
231 >                if (d == 0.0) {                         /* zero ==> flush */
232 >                        bogusray();
233 >                        if (--nextflush <= 0 || vcount <= 0) {
234 >                                fflush(stdout);
235 >                                nextflush = hresolu;
236 >                        }
237 >                } else {
238 >                        samplendx++;
239                                                          /* compute and print */
240 <                if (outvals[0] == 'i')
241 <                        irrad(orig, direc);
242 <                else
243 <                        radiance(orig, direc);
244 <                                                        /* flush if requested */
245 <                if (--nextflush == 0) {
246 <                        fflush(stdout);
247 <                        nextflush = hresolu;
240 >                        if (imm_irrad)
241 >                                irrad(orig, direc);
242 >                        else
243 >                                rad(orig, direc, lim_dist ? d : 0.0);
244 >                                                        /* flush if time */
245 >                        if (--nextflush == 0) {
246 >                                fflush(stdout);
247 >                                nextflush = hresolu;
248 >                        }
249                  }
250                  if (ferror(stdout))
251                          error(SYSTEM, "write error");
252                  if (--vcount == 0)                      /* check for end */
253                          break;
254          }
255 +        fflush(stdout);
256          if (vcount > 0)
257                  error(USER, "read error");
258 <        fclose(fp);
258 >        if (fname != NULL)
259 >                fclose(fp);
260   }
261  
262  
263   setoutput(vs)                           /* set up output tables */
264   register char  *vs;
265   {
266 <        extern int  ourtrace(), (*trace)();
267 <        register int (**table)() = ray_out;
266 >        extern void  (*trace)();
267 >        register void (**table)() = ray_out;
268  
269 +        castonly = 1;
270          while (*vs)
271                  switch (*vs++) {
272                  case 't':                               /* trace */
273                          *table = NULL;
274                          table = every_out;
275                          trace = ourtrace;
276 +                        castonly = 0;
277                          break;
278                  case 'o':                               /* origin */
279                          *table++ = oputo;
# Line 137 | Line 283 | register char  *vs;
283                          break;
284                  case 'v':                               /* value */
285                          *table++ = oputv;
286 +                        castonly = 0;
287                          break;
288 <                case 'l':                               /* length */
288 >                case 'l':                               /* effective distance */
289                          *table++ = oputl;
290 +                        castonly = 0;
291                          break;
292 +                case 'L':                               /* single ray length */
293 +                        *table++ = oputL;
294 +                        break;
295                  case 'p':                               /* point */
296                          *table++ = oputp;
297                          break;
298 <                case 'n':                               /* normal */
298 >                case 'n':                               /* perturbed normal */
299                          *table++ = oputn;
300 +                        castonly = 0;
301                          break;
302 +                case 'N':                               /* unperturbed normal */
303 +                        *table++ = oputN;
304 +                        break;
305                  case 's':                               /* surface */
306                          *table++ = oputs;
307                          break;
# Line 161 | Line 316 | register char  *vs;
316   }
317  
318  
319 < radiance(org, dir)              /* compute radiance value */
320 < FVECT  org, dir;
319 > void
320 > bogusray()                      /* print out empty record */
321   {
322 <        register int  (**tp)();
322 >        thisray.rorg[0] = thisray.rorg[1] = thisray.rorg[2] =
323 >        thisray.rdir[0] = thisray.rdir[1] = thisray.rdir[2] = 0.0;
324 >        rayorigin(&thisray, NULL, PRIMARY, 1.0);
325 >        printvals(&thisray);
326 > }
327  
328 +
329 + void
330 + rad(org, dir, dmax)             /* compute and print ray value(s) */
331 + FVECT  org, dir;
332 + double  dmax;
333 + {
334          VCOPY(thisray.rorg, org);
335          VCOPY(thisray.rdir, dir);
336 +        thisray.rmax = dmax;
337          rayorigin(&thisray, NULL, PRIMARY, 1.0);
338 <        rayvalue(&thisray);
339 <
340 <        if (ray_out[0] == NULL)
341 <                return;
342 <        for (tp = ray_out; *tp != NULL; tp++)
343 <                (**tp)(&thisray);
344 <        if (outform == 'a')
345 <                putchar('\n');
338 >        if (castonly) {
339 >                if (!localhit(&thisray, &thescene))
340 >                        if (thisray.ro == &Aftplane) {  /* clipped */
341 >                                thisray.ro = NULL;
342 >                                thisray.rot = FHUGE;
343 >                        } else
344 >                                sourcehit(&thisray);
345 >        } else
346 >                rayvalue(&thisray);
347 >        printvals(&thisray);
348   }
349  
350  
351 < irrad(org, dir)                 /* compute irradiance value */
351 > void
352 > irrad(org, dir)                 /* compute immediate irradiance value */
353   FVECT  org, dir;
354   {
186        static double  Lambfa[5] = {PI, PI, PI, 0.0, 0.0};
187        static OBJREC  Lamb = {
188                OVOID, MAT_PLASTIC, "Lambertian",
189                {0, 5, NULL, Lambfa}, NULL, -1,
190        };
355          register int  i;
356  
357          for (i = 0; i < 3; i++) {
# Line 196 | Line 360 | FVECT  org, dir;
360          }
361          rayorigin(&thisray, NULL, PRIMARY, 1.0);
362                                          /* pretend we hit surface */
363 <        thisray.rot = 1.0;
363 >        thisray.rot = 1.0-1e-4;
364          thisray.rod = 1.0;
365          VCOPY(thisray.ron, dir);
366          for (i = 0; i < 3; i++)         /* fudge factor */
367                  thisray.rop[i] = org[i] + 1e-4*dir[i];
368                                          /* compute and print */
369          (*ofun[Lamb.otype].funp)(&Lamb, &thisray);
370 <        oputv(&thisray);
370 >        printvals(&thisray);
371 > }
372 >
373 >
374 > void
375 > printvals(r)                    /* print requested ray values */
376 > RAY  *r;
377 > {
378 >        register void  (**tp)();
379 >
380 >        if (ray_out[0] == NULL)
381 >                return;
382 >        for (tp = ray_out; *tp != NULL; tp++)
383 >                (**tp)(r);
384          if (outform == 'a')
385                  putchar('\n');
386   }
387  
388  
389 + int
390   getvec(vec, fmt, fp)            /* get a vector from fp */
391   register FVECT  vec;
392   int  fmt;
393   FILE  *fp;
394   {
395          static float  vf[3];
396 +        static double  vd[3];
397 +        char  buf[32];
398 +        register int  i;
399  
400          switch (fmt) {
401          case 'a':                                       /* ascii */
402 <                if (fscanf(fp, "%lf %lf %lf", vec, vec+1, vec+2) != 3)
403 <                        return(-1);
402 >                for (i = 0; i < 3; i++) {
403 >                        if (fgetword(buf, sizeof(buf), fp) == NULL ||
404 >                                        !isflt(buf))
405 >                                return(-1);
406 >                        vec[i] = atof(buf);
407 >                }
408                  break;
409          case 'f':                                       /* binary float */
410 <                if (fread(vf, sizeof(float), 3, fp) != 3)
410 >                if (fread((char *)vf, sizeof(float), 3, fp) != 3)
411                          return(-1);
412                  vec[0] = vf[0]; vec[1] = vf[1]; vec[2] = vf[2];
413                  break;
414          case 'd':                                       /* binary double */
415 <                if (fread(vec, sizeof(double), 3, fp) != 3)
415 >                if (fread((char *)vd, sizeof(double), 3, fp) != 3)
416                          return(-1);
417 +                vec[0] = vd[0]; vec[1] = vd[1]; vec[2] = vd[2];
418                  break;
419 +        default:
420 +                error(CONSISTENCY, "botched input format");
421          }
422          return(0);
423   }
424  
425  
426 < static
426 > void
427 > tranotify(obj)                  /* record new modifier */
428 > OBJECT  obj;
429 > {
430 >        static int  hitlimit = 0;
431 >        register OBJREC  *o = objptr(obj);
432 >        register char  **tralp;
433 >
434 >        if (obj == OVOID) {             /* starting over */
435 >                traset[0] = 0;
436 >                hitlimit = 0;
437 >                return;
438 >        }
439 >        if (hitlimit || !ismodifier(o->otype))
440 >                return;
441 >        for (tralp = tralist; *tralp != NULL; tralp++)
442 >                if (!strcmp(o->oname, *tralp)) {
443 >                        if (traset[0] >= MAXTSET) {
444 >                                error(WARNING, "too many modifiers in trace list");
445 >                                hitlimit++;
446 >                                return;         /* should this be fatal? */
447 >                        }
448 >                        insertelem(traset, obj);
449 >                        return;
450 >                }
451 > }
452 >
453 >
454 > static void
455   ourtrace(r)                             /* print ray values */
456   RAY  *r;
457   {
458 <        register int  (**tp)();
458 >        register void  (**tp)();
459  
460          if (every_out[0] == NULL)
461                  return;
462 +        if (r->ro == NULL) {
463 +                if (traincl == 1)
464 +                        return;
465 +        } else if (traincl != -1 && traincl != inset(traset, r->ro->omod))
466 +                return;
467          tabin(r);
468          for (tp = every_out; *tp != NULL; tp++)
469                  (**tp)(r);
# Line 250 | Line 471 | RAY  *r;
471   }
472  
473  
474 < static
474 > static void
475   tabin(r)                                /* tab in appropriate amount */
476   RAY  *r;
477   {
# Line 261 | Line 482 | RAY  *r;
482   }
483  
484  
485 < static
485 > static void
486   oputo(r)                                /* print origin */
487   register RAY  *r;
488   {
# Line 271 | Line 492 | register RAY  *r;
492   }
493  
494  
495 < static
495 > static void
496   oputd(r)                                /* print direction */
497   register RAY  *r;
498   {
# Line 281 | Line 502 | register RAY  *r;
502   }
503  
504  
505 < static
505 > static void
506   oputv(r)                                /* print value */
507   register RAY  *r;
508   {
509 +        COLR  cout;
510 +        
511 +        if (outform == 'c') {
512 +                setcolr(cout,   colval(r->rcol,RED),
513 +                                colval(r->rcol,GRN),
514 +                                colval(r->rcol,BLU));
515 +                fwrite((char *)cout, sizeof(cout), 1, stdout);
516 +                return;
517 +        }
518          (*putreal)(colval(r->rcol,RED));
519          (*putreal)(colval(r->rcol,GRN));
520          (*putreal)(colval(r->rcol,BLU));
521   }
522  
523  
524 < static
525 < oputl(r)                                /* print length */
524 > static void
525 > oputl(r)                                /* print effective distance */
526   register RAY  *r;
527   {
528 <        if (r->rot < FHUGE)
299 <                (*putreal)(r->rot);
300 <        else
301 <                (*putreal)(0.0);
528 >        (*putreal)(r->rt);
529   }
530  
531  
532 < static
532 > static void
533 > oputL(r)                                /* print single ray length */
534 > register RAY  *r;
535 > {
536 >        (*putreal)(r->rot);
537 > }
538 >
539 >
540 > static void
541   oputp(r)                                /* print point */
542   register RAY  *r;
543   {
# Line 318 | Line 553 | register RAY  *r;
553   }
554  
555  
556 < static
557 < oputn(r)                                /* print normal */
556 > static void
557 > oputN(r)                                /* print unperturbed normal */
558   register RAY  *r;
559   {
560          if (r->rot < FHUGE) {
# Line 334 | Line 569 | register RAY  *r;
569   }
570  
571  
572 < static
572 > static void
573 > oputn(r)                                /* print perturbed normal */
574 > RAY  *r;
575 > {
576 >        FVECT  pnorm;
577 >
578 >        if (r->rot >= FHUGE) {
579 >                (*putreal)(0.0);
580 >                (*putreal)(0.0);
581 >                (*putreal)(0.0);
582 >                return;
583 >        }
584 >        raynormal(pnorm, r);
585 >        (*putreal)(pnorm[0]);
586 >        (*putreal)(pnorm[1]);
587 >        (*putreal)(pnorm[2]);
588 > }
589 >
590 >
591 > static void
592   oputs(r)                                /* print name */
593   register RAY  *r;
594   {
# Line 346 | Line 600 | register RAY  *r;
600   }
601  
602  
603 < static
603 > static void
604   oputw(r)                                /* print weight */
605   register RAY  *r;
606   {
# Line 354 | Line 608 | register RAY  *r;
608   }
609  
610  
611 < static
611 > static void
612   oputm(r)                                /* print modifier */
613   register RAY  *r;
614   {
615          if (r->ro != NULL)
616 <                fputs(objptr(r->ro->omod)->oname, stdout);
616 >                if (r->ro->omod != OVOID)
617 >                        fputs(objptr(r->ro->omod)->oname, stdout);
618 >                else
619 >                        fputs(VOIDID, stdout);
620          else
621                  putchar('*');
622          putchar('\t');
623   }
624  
625  
626 < static
626 > static void
627   puta(v)                         /* print ascii value */
628   double  v;
629   {
# Line 374 | Line 631 | double  v;
631   }
632  
633  
634 < static
634 > static void
635   putd(v)                         /* print binary double */
636   double  v;
637   {
638 <        fwrite(&v, sizeof(v), 1, stdout);
638 >        fwrite((char *)&v, sizeof(v), 1, stdout);
639   }
640  
641  
642 < static
642 > static void
643   putf(v)                         /* print binary float */
644   double  v;
645   {
646          float f = v;
647  
648 <        fwrite(&f, sizeof(f), 1, stdout);
648 >        fwrite((char *)&f, sizeof(f), 1, stdout);
649   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines