ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rtrace.c
Revision: 2.27
Committed: Sat Feb 22 02:07:29 2003 UTC (21 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.26: +107 -36 lines
Log Message:
Changes and check-in for 3.5 release
Includes new source files and modifications not recorded for many years
See ray/doc/notes/ReleaseNotes for notes between 3.1 and 3.5 release

File Contents

# User Rev Content
1 greg 1.1 #ifndef lint
2 greg 2.27 static const char RCSid[] = "$Id$";
3 greg 1.1 #endif
4     /*
5     * rtrace.c - program and variables for individual ray tracing.
6 greg 2.27 */
7    
8     /* ====================================================================
9     * The Radiance Software License, Version 1.0
10     *
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 greg 1.1 *
41 greg 2.27 * 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 greg 1.1 */
64    
65     /*
66     * Input is in the form:
67     *
68     * xorg yorg zorg xdir ydir zdir
69     *
70     * The direction need not be normalized. Output is flexible.
71 greg 1.7 * If the direction vector is (0,0,0), then the output is flushed.
72 greg 1.1 * 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 greg 1.13 * radiance is computed. The '-i' or '-I' options indicate that
76 greg 1.1 * irradiance values are desired.
77     */
78    
79     #include "ray.h"
80    
81     #include "otypes.h"
82    
83 greg 2.6 #include "resolu.h"
84    
85 greg 2.27 CUBE thescene; /* our scene */
86     OBJECT nsceneobjs; /* number of objects in our scene */
87    
88 greg 1.14 int dimlist[MAXDIM]; /* sampling dimensions */
89     int ndims = 0; /* number of sampling dimensions */
90     int samplendx = 0; /* index for this sample */
91    
92 greg 1.13 int imm_irrad = 0; /* compute immediate irradiance? */
93 gregl 2.25 int lim_dist = 0; /* limit distance? */
94 greg 1.13
95 greg 1.1 int inform = 'a'; /* input format */
96     int outform = 'a'; /* output format */
97     char *outvals = "v"; /* output specification */
98    
99 greg 2.27 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 greg 2.15 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 greg 1.1 int hresolu = 0; /* horizontal (scan) size */
111     int vresolu = 0; /* vertical resolution */
112    
113     double dstrsrc = 0.0; /* square source distribution */
114 greg 1.4 double shadthresh = .05; /* shadow threshold */
115 greg 1.5 double shadcert = .5; /* shadow certainty */
116 greg 2.19 int directrelay = 2; /* number of source relays */
117 greg 1.17 int vspretest = 512; /* virtual source pretest density */
118 greg 2.10 int directvis = 1; /* sources visible? */
119 greg 2.19 double srcsizerat = .2; /* maximum ratio source size/dist. */
120 greg 2.20
121     COLOR cextinction = BLKCOLOR; /* global extinction coefficient */
122 greg 2.22 COLOR salbedo = BLKCOLOR; /* global scattering albedo */
123 greg 2.20 double seccg = 0.; /* global scattering eccentricity */
124     double ssampdist = 0.; /* scatter sampling distance */
125 greg 1.1
126 greg 2.4 double specthresh = .15; /* specular sampling threshold */
127 greg 2.3 double specjitter = 1.; /* specular sampling jitter */
128    
129 greg 2.18 int backvis = 1; /* back face visibility */
130    
131 greg 1.1 int maxdepth = 6; /* maximum recursion depth */
132     double minweight = 4e-3; /* minimum ray weight */
133    
134 greg 2.27 char *ambfile = NULL; /* ambient file name */
135 greg 1.1 COLOR ambval = BLKCOLOR; /* ambient value */
136 greg 2.21 int ambvwt = 0; /* initial weight for ambient value */
137 greg 1.1 double ambacc = 0.2; /* ambient accuracy */
138 greg 2.19 int ambres = 128; /* ambient resolution */
139     int ambdiv = 512; /* ambient divisions */
140 greg 1.1 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 gregl 2.25
146 greg 1.1 static RAY thisray; /* for our convenience */
147    
148 greg 2.27 static void oputo(), oputd(), oputv(), oputl(), oputL(),
149 greg 2.9 oputp(), oputn(), oputN(), oputs(), oputw(), oputm();
150 greg 1.1
151 greg 2.27 static void ourtrace(), tabin();
152     static void (*ray_out[16])(), (*every_out[16])();
153 greg 2.14 static int castonly = 0;
154 greg 1.1
155 greg 2.27 static void puta(), putf(), putd();
156    
157     static void (*putreal)();
158 greg 1.1
159 greg 2.27 void bogusray(), rad(), irrad(), printvals();
160 greg 1.1
161    
162 greg 2.27 void
163 greg 1.1 quit(code) /* quit program */
164     int code;
165     {
166 greg 2.11 #ifndef NIX
167     headclean(); /* delete header file */
168     pfclean(); /* clean up persist files */
169     #endif
170 greg 1.1 exit(code);
171     }
172    
173    
174 greg 2.6 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 greg 2.27 void
189 greg 1.1 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 gregl 2.25 double d;
196 greg 1.2 FVECT orig, direc;
197 greg 1.1 /* set up input */
198     if (fname == NULL)
199     fp = stdin;
200     else if ((fp = fopen(fname, "r")) == NULL) {
201     sprintf(errmsg, "cannot open input file \"%s\"", fname);
202     error(SYSTEM, errmsg);
203     }
204 greg 2.8 #ifdef MSDOS
205     if (inform != 'a')
206     setmode(fileno(fp), O_BINARY);
207     #endif
208 greg 1.1 /* set up output */
209 greg 2.16 setoutput(outvals);
210 greg 1.1 switch (outform) {
211     case 'a': putreal = puta; break;
212     case 'f': putreal = putf; break;
213     case 'd': putreal = putd; break;
214 greg 2.6 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 greg 1.1 }
221 greg 2.12 if (hresolu > 0) {
222     if (vresolu > 0)
223     fprtresolu(hresolu, vresolu, stdout);
224     fflush(stdout);
225     }
226 greg 1.1 /* process file */
227     while (getvec(orig, inform, fp) == 0 &&
228     getvec(direc, inform, fp) == 0) {
229    
230 gregl 2.25 d = normalize(direc);
231     if (d == 0.0) { /* zero ==> flush */
232 gregl 2.24 bogusray();
233 gregl 2.26 if (--nextflush <= 0 || vcount <= 0) {
234 gregl 2.24 fflush(stdout);
235     nextflush = hresolu;
236     }
237     } else {
238     samplendx++;
239 greg 1.1 /* compute and print */
240 gregl 2.24 if (imm_irrad)
241     irrad(orig, direc);
242     else
243 gregl 2.25 rad(orig, direc, lim_dist ? d : 0.0);
244 greg 1.7 /* flush if time */
245 gregl 2.24 if (--nextflush == 0) {
246     fflush(stdout);
247     nextflush = hresolu;
248     }
249 greg 1.1 }
250     if (ferror(stdout))
251     error(SYSTEM, "write error");
252     if (--vcount == 0) /* check for end */
253     break;
254     }
255 greg 2.12 fflush(stdout);
256 greg 1.1 if (vcount > 0)
257     error(USER, "read error");
258 greg 2.12 if (fname != NULL)
259     fclose(fp);
260 greg 1.1 }
261    
262    
263     setoutput(vs) /* set up output tables */
264     register char *vs;
265     {
266 greg 2.27 extern void (*trace)();
267     register void (**table)() = ray_out;
268 greg 1.1
269 greg 1.11 castonly = 1;
270 greg 1.1 while (*vs)
271     switch (*vs++) {
272     case 't': /* trace */
273     *table = NULL;
274     table = every_out;
275     trace = ourtrace;
276 greg 1.11 castonly = 0;
277 greg 1.1 break;
278     case 'o': /* origin */
279     *table++ = oputo;
280     break;
281     case 'd': /* direction */
282     *table++ = oputd;
283     break;
284     case 'v': /* value */
285     *table++ = oputv;
286 greg 1.11 castonly = 0;
287 greg 1.1 break;
288 greg 2.5 case 'l': /* effective distance */
289 greg 1.1 *table++ = oputl;
290 greg 1.11 castonly = 0;
291 greg 1.1 break;
292 greg 2.5 case 'L': /* single ray length */
293     *table++ = oputL;
294     break;
295 greg 1.1 case 'p': /* point */
296     *table++ = oputp;
297     break;
298 greg 2.9 case 'n': /* perturbed normal */
299 greg 1.1 *table++ = oputn;
300 greg 2.9 castonly = 0;
301 greg 1.1 break;
302 greg 2.9 case 'N': /* unperturbed normal */
303     *table++ = oputN;
304     break;
305 greg 1.1 case 's': /* surface */
306     *table++ = oputs;
307     break;
308     case 'w': /* weight */
309     *table++ = oputw;
310     break;
311     case 'm': /* modifier */
312     *table++ = oputm;
313     break;
314     }
315     *table = NULL;
316 gregl 2.24 }
317    
318    
319 greg 2.27 void
320 gregl 2.24 bogusray() /* print out empty record */
321     {
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 greg 1.1 }
327    
328    
329 greg 2.27 void
330 gregl 2.25 rad(org, dir, dmax) /* compute and print ray value(s) */
331 greg 1.1 FVECT org, dir;
332 gregl 2.25 double dmax;
333 greg 1.1 {
334     VCOPY(thisray.rorg, org);
335     VCOPY(thisray.rdir, dir);
336 gregl 2.25 thisray.rmax = dmax;
337 greg 1.1 rayorigin(&thisray, NULL, PRIMARY, 1.0);
338 gregl 2.25 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 greg 1.11 rayvalue(&thisray);
347 greg 2.16 printvals(&thisray);
348 greg 1.1 }
349    
350    
351 greg 2.27 void
352 greg 1.13 irrad(org, dir) /* compute immediate irradiance value */
353 greg 1.1 FVECT org, dir;
354     {
355     register int i;
356    
357     for (i = 0; i < 3; i++) {
358     thisray.rorg[i] = org[i] + dir[i];
359     thisray.rdir[i] = -dir[i];
360     }
361     rayorigin(&thisray, NULL, PRIMARY, 1.0);
362     /* pretend we hit surface */
363 greg 2.16 thisray.rot = 1.0-1e-4;
364 greg 1.1 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 greg 2.16 printvals(&thisray);
371     }
372    
373    
374 greg 2.27 void
375 greg 2.16 printvals(r) /* print requested ray values */
376     RAY *r;
377     {
378 greg 2.27 register void (**tp)();
379 greg 2.16
380     if (ray_out[0] == NULL)
381     return;
382     for (tp = ray_out; *tp != NULL; tp++)
383     (**tp)(r);
384 greg 1.1 if (outform == 'a')
385     putchar('\n');
386     }
387    
388    
389 greg 2.27 int
390 greg 1.1 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 greg 2.5 static double vd[3];
397 greg 1.19 char buf[32];
398     register int i;
399 greg 1.1
400     switch (fmt) {
401     case 'a': /* ascii */
402 greg 1.19 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 greg 1.1 break;
409     case 'f': /* binary float */
410 greg 1.8 if (fread((char *)vf, sizeof(float), 3, fp) != 3)
411 greg 1.1 return(-1);
412     vec[0] = vf[0]; vec[1] = vf[1]; vec[2] = vf[2];
413     break;
414     case 'd': /* binary double */
415 greg 2.5 if (fread((char *)vd, sizeof(double), 3, fp) != 3)
416 greg 1.1 return(-1);
417 greg 2.5 vec[0] = vd[0]; vec[1] = vd[1]; vec[2] = vd[2];
418 greg 1.1 break;
419 greg 2.6 default:
420     error(CONSISTENCY, "botched input format");
421 greg 1.1 }
422     return(0);
423     }
424    
425    
426 greg 2.27 void
427 greg 2.15 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 greg 2.27 if (obj == OVOID) { /* starting over */
435     traset[0] = 0;
436     hitlimit = 0;
437     return;
438     }
439 greg 2.15 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 greg 2.27 static void
455 greg 1.1 ourtrace(r) /* print ray values */
456     RAY *r;
457     {
458 greg 2.27 register void (**tp)();
459 greg 1.1
460     if (every_out[0] == NULL)
461 greg 2.15 return;
462 greg 2.16 if (r->ro == NULL) {
463     if (traincl == 1)
464     return;
465     } else if (traincl != -1 && traincl != inset(traset, r->ro->omod))
466 greg 1.1 return;
467     tabin(r);
468     for (tp = every_out; *tp != NULL; tp++)
469     (**tp)(r);
470     putchar('\n');
471     }
472    
473    
474 greg 2.27 static void
475 greg 1.1 tabin(r) /* tab in appropriate amount */
476     RAY *r;
477     {
478     register RAY *rp;
479    
480     for (rp = r->parent; rp != NULL; rp = rp->parent)
481     putchar('\t');
482     }
483    
484    
485 greg 2.27 static void
486 greg 1.1 oputo(r) /* print origin */
487     register RAY *r;
488     {
489     (*putreal)(r->rorg[0]);
490     (*putreal)(r->rorg[1]);
491     (*putreal)(r->rorg[2]);
492     }
493    
494    
495 greg 2.27 static void
496 greg 1.1 oputd(r) /* print direction */
497     register RAY *r;
498     {
499     (*putreal)(r->rdir[0]);
500     (*putreal)(r->rdir[1]);
501     (*putreal)(r->rdir[2]);
502     }
503    
504    
505 greg 2.27 static void
506 greg 1.1 oputv(r) /* print value */
507     register RAY *r;
508     {
509 greg 2.6 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 greg 1.1 (*putreal)(colval(r->rcol,RED));
519     (*putreal)(colval(r->rcol,GRN));
520     (*putreal)(colval(r->rcol,BLU));
521     }
522    
523    
524 greg 2.27 static void
525 greg 2.5 oputl(r) /* print effective distance */
526 greg 1.1 register RAY *r;
527     {
528 greg 1.9 (*putreal)(r->rt);
529 greg 2.5 }
530    
531    
532 greg 2.27 static void
533 greg 2.5 oputL(r) /* print single ray length */
534     register RAY *r;
535     {
536     (*putreal)(r->rot);
537 greg 1.1 }
538    
539    
540 greg 2.27 static void
541 greg 1.1 oputp(r) /* print point */
542     register RAY *r;
543     {
544     if (r->rot < FHUGE) {
545     (*putreal)(r->rop[0]);
546     (*putreal)(r->rop[1]);
547     (*putreal)(r->rop[2]);
548     } else {
549     (*putreal)(0.0);
550     (*putreal)(0.0);
551     (*putreal)(0.0);
552     }
553     }
554    
555    
556 greg 2.27 static void
557 greg 2.9 oputN(r) /* print unperturbed normal */
558 greg 1.1 register RAY *r;
559     {
560     if (r->rot < FHUGE) {
561     (*putreal)(r->ron[0]);
562     (*putreal)(r->ron[1]);
563     (*putreal)(r->ron[2]);
564     } else {
565     (*putreal)(0.0);
566     (*putreal)(0.0);
567     (*putreal)(0.0);
568     }
569 greg 2.9 }
570    
571    
572 greg 2.27 static void
573 greg 2.9 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 greg 1.1 }
589    
590    
591 greg 2.27 static void
592 greg 1.1 oputs(r) /* print name */
593     register RAY *r;
594     {
595     if (r->ro != NULL)
596     fputs(r->ro->oname, stdout);
597     else
598     putchar('*');
599     putchar('\t');
600     }
601    
602    
603 greg 2.27 static void
604 greg 1.1 oputw(r) /* print weight */
605     register RAY *r;
606     {
607     (*putreal)(r->rweight);
608     }
609    
610    
611 greg 2.27 static void
612 greg 1.1 oputm(r) /* print modifier */
613     register RAY *r;
614     {
615     if (r->ro != NULL)
616 greg 2.23 if (r->ro->omod != OVOID)
617     fputs(objptr(r->ro->omod)->oname, stdout);
618     else
619     fputs(VOIDID, stdout);
620 greg 1.1 else
621     putchar('*');
622     putchar('\t');
623     }
624    
625    
626 greg 2.27 static void
627 greg 1.1 puta(v) /* print ascii value */
628     double v;
629     {
630     printf("%e\t", v);
631     }
632    
633    
634 greg 2.27 static void
635 greg 1.1 putd(v) /* print binary double */
636     double v;
637     {
638 greg 1.8 fwrite((char *)&v, sizeof(v), 1, stdout);
639 greg 1.1 }
640    
641    
642 greg 2.27 static void
643 greg 1.1 putf(v) /* print binary float */
644     double v;
645     {
646     float f = v;
647    
648 greg 1.8 fwrite((char *)&f, sizeof(f), 1, stdout);
649 greg 1.1 }