ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rtrace.c
Revision: 2.54
Committed: Wed Apr 5 14:30:38 2006 UTC (18 years ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R8
Changes since 2.53: +2 -2 lines
Log Message:
Changed default in rtrace to -u+ (random sampling)

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: rtrace.c,v 2.53 2006/04/05 06:22:57 greg Exp $";
3 #endif
4 /*
5 * rtrace.c - program and variables for individual ray tracing.
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' or '-I' options indicate that
21 * irradiance values are desired.
22 */
23
24 #include <time.h>
25
26 #include "platform.h"
27 #include "ray.h"
28 #include "ambient.h"
29 #include "source.h"
30 #include "otypes.h"
31 #include "resolu.h"
32 #include "random.h"
33
34 CUBE thescene; /* our scene */
35 OBJECT nsceneobjs; /* number of objects in our scene */
36
37 int dimlist[MAXDIM]; /* sampling dimensions */
38 int ndims = 0; /* number of sampling dimensions */
39 int samplendx = 0; /* index for this sample */
40
41 int imm_irrad = 0; /* compute immediate irradiance? */
42 int lim_dist = 0; /* limit distance? */
43
44 int inform = 'a'; /* input format */
45 int outform = 'a'; /* output format */
46 char *outvals = "v"; /* output specification */
47
48 int do_irrad = 0; /* compute irradiance? */
49
50 int rand_samp = 1; /* pure Monte Carlo sampling? */
51
52 void (*trace)() = NULL; /* trace call */
53
54 char *tralist[128]; /* list of modifers to trace (or no) */
55 int traincl = -1; /* include == 1, exclude == 0 */
56 #ifndef MAXTSET
57 #define MAXTSET 8192 /* maximum number in trace set */
58 #endif
59 OBJECT traset[MAXTSET+1]={0}; /* trace include/exclude set */
60
61 int hresolu = 0; /* horizontal (scan) size */
62 int vresolu = 0; /* vertical resolution */
63
64 double dstrsrc = 0.0; /* square source distribution */
65 double shadthresh = .03; /* shadow threshold */
66 double shadcert = .75; /* shadow certainty */
67 int directrelay = 2; /* number of source relays */
68 int vspretest = 512; /* virtual source pretest density */
69 int directvis = 1; /* sources visible? */
70 double srcsizerat = .2; /* maximum ratio source size/dist. */
71
72 COLOR cextinction = BLKCOLOR; /* global extinction coefficient */
73 COLOR salbedo = BLKCOLOR; /* global scattering albedo */
74 double seccg = 0.; /* global scattering eccentricity */
75 double ssampdist = 0.; /* scatter sampling distance */
76
77 double specthresh = .15; /* specular sampling threshold */
78 double specjitter = 1.; /* specular sampling jitter */
79
80 int backvis = 1; /* back face visibility */
81
82 int maxdepth = -10; /* maximum recursion depth */
83 double minweight = 2e-3; /* minimum ray weight */
84
85 char *ambfile = NULL; /* ambient file name */
86 COLOR ambval = BLKCOLOR; /* ambient value */
87 int ambvwt = 0; /* initial weight for ambient value */
88 double ambacc = 0.15; /* ambient accuracy */
89 int ambres = 256; /* ambient resolution */
90 int ambdiv = 1024; /* ambient divisions */
91 int ambssamp = 512; /* ambient super-samples */
92 int ambounce = 0; /* ambient bounces */
93 char *amblist[AMBLLEN]; /* ambient include/exclude list */
94 int ambincl = -1; /* include == 1, exclude == 0 */
95
96 static int castonly = 0;
97
98 static RAY thisray; /* for our convenience */
99
100 typedef void putf_t(double v);
101 static putf_t puta, putd, putf;
102
103 typedef void oputf_t(RAY *r);
104 static oputf_t oputo, oputd, oputv, oputV, oputl, oputL, oputc, oputp,
105 oputn, oputN, oputs, oputw, oputW, oputm, oputM, oputtilde;
106
107 static void setoutput(char *vs);
108 static void tranotify(OBJECT obj);
109 static void bogusray(void);
110 static void rad(FVECT org, FVECT dir, double dmax);
111 static void irrad(FVECT org, FVECT dir);
112 static void printvals(RAY *r);
113 static int getvec(FVECT vec, int fmt, FILE *fp);
114 static void tabin(RAY *r);
115 static void ourtrace(RAY *r);
116
117 static oputf_t *ray_out[16], *every_out[16];
118 static putf_t *putreal;
119
120 void (*addobjnotify[])() = {ambnotify, tranotify, NULL};
121
122
123 void
124 quit( /* quit program */
125 int code
126 )
127 {
128 #ifndef NON_POSIX /* XXX we don't clean up elsewhere? */
129 headclean(); /* delete header file */
130 pfclean(); /* clean up persist files */
131 #endif
132 exit(code);
133 }
134
135
136 extern char *
137 formstr( /* return format identifier */
138 int f
139 )
140 {
141 switch (f) {
142 case 'a': return("ascii");
143 case 'f': return("float");
144 case 'd': return("double");
145 case 'c': return(COLRFMT);
146 }
147 return("unknown");
148 }
149
150
151 extern void
152 rtrace( /* trace rays from file */
153 char *fname
154 )
155 {
156 unsigned long vcount = (hresolu > 1) ? (unsigned long)hresolu*vresolu
157 : vresolu;
158 long nextflush = hresolu;
159 FILE *fp;
160 double d;
161 FVECT orig, direc;
162 /* set up input */
163 if (fname == NULL)
164 fp = stdin;
165 else if ((fp = fopen(fname, "r")) == NULL) {
166 sprintf(errmsg, "cannot open input file \"%s\"", fname);
167 error(SYSTEM, errmsg);
168 }
169 if (inform != 'a')
170 SET_FILE_BINARY(fp);
171 /* set up output */
172 setoutput(outvals);
173 switch (outform) {
174 case 'a': putreal = puta; break;
175 case 'f': putreal = putf; break;
176 case 'd': putreal = putd; break;
177 case 'c':
178 if (strcmp(outvals, "v"))
179 error(USER, "color format with value output only");
180 break;
181 default:
182 error(CONSISTENCY, "botched output format");
183 }
184 if (hresolu > 0) {
185 if (vresolu > 0)
186 fprtresolu(hresolu, vresolu, stdout);
187 fflush(stdout);
188 }
189 /* process file */
190 while (getvec(orig, inform, fp) == 0 &&
191 getvec(direc, inform, fp) == 0) {
192
193 d = normalize(direc);
194 if (d == 0.0) { /* zero ==> flush */
195 bogusray();
196 if (--nextflush <= 0 || !vcount) {
197 fflush(stdout);
198 nextflush = hresolu;
199 }
200 } else {
201 samplendx++;
202 /* compute and print */
203 if (imm_irrad)
204 irrad(orig, direc);
205 else
206 rad(orig, direc, lim_dist ? d : 0.0);
207 /* flush if time */
208 if (!--nextflush) {
209 fflush(stdout);
210 nextflush = hresolu;
211 }
212 }
213 if (ferror(stdout))
214 error(SYSTEM, "write error");
215 if (vcount && !--vcount) /* check for end */
216 break;
217 }
218 if (fflush(stdout) < 0)
219 error(SYSTEM, "write error");
220 if (vcount)
221 error(USER, "unexpected EOF on input");
222 if (fname != NULL)
223 fclose(fp);
224 }
225
226
227 static void
228 trace_sources(void) /* trace rays to light sources, also */
229 {
230 int sn;
231
232 for (sn = 0; sn < nsources; sn++)
233 source[sn].sflags |= SFOLLOW;
234 }
235
236
237 static void
238 setoutput( /* set up output tables */
239 register char *vs
240 )
241 {
242 register oputf_t **table = ray_out;
243
244 castonly = 1;
245 while (*vs)
246 switch (*vs++) {
247 case 'T': /* trace sources */
248 if (!*vs) break;
249 trace_sources();
250 /* fall through */
251 case 't': /* trace */
252 if (!*vs) break;
253 *table = NULL;
254 table = every_out;
255 trace = ourtrace;
256 castonly = 0;
257 break;
258 case 'o': /* origin */
259 *table++ = oputo;
260 break;
261 case 'd': /* direction */
262 *table++ = oputd;
263 break;
264 case 'v': /* value */
265 *table++ = oputv;
266 castonly = 0;
267 break;
268 case 'V': /* contribution */
269 *table++ = oputV;
270 if (ambounce > 0 && (ambacc > FTINY || ambssamp > 0))
271 error(WARNING,
272 "-otV accuracy depends on -aa 0 -as 0");
273 break;
274 case 'l': /* effective distance */
275 *table++ = oputl;
276 castonly = 0;
277 break;
278 case 'c': /* local coordinates */
279 *table++ = oputc;
280 break;
281 case 'L': /* single ray length */
282 *table++ = oputL;
283 break;
284 case 'p': /* point */
285 *table++ = oputp;
286 break;
287 case 'n': /* perturbed normal */
288 *table++ = oputn;
289 castonly = 0;
290 break;
291 case 'N': /* unperturbed normal */
292 *table++ = oputN;
293 break;
294 case 's': /* surface */
295 *table++ = oputs;
296 break;
297 case 'w': /* weight */
298 *table++ = oputw;
299 break;
300 case 'W': /* coefficient */
301 *table++ = oputW;
302 if (ambounce > 0 && (ambacc > FTINY || ambssamp > 0))
303 error(WARNING,
304 "-otW accuracy depends on -aa 0 -as 0");
305 break;
306 case 'm': /* modifier */
307 *table++ = oputm;
308 break;
309 case 'M': /* material */
310 *table++ = oputM;
311 break;
312 case '~': /* tilde */
313 *table++ = oputtilde;
314 break;
315 }
316 *table = NULL;
317 }
318
319
320 static void
321 bogusray(void) /* print out empty record */
322 {
323 thisray.rorg[0] = thisray.rorg[1] = thisray.rorg[2] =
324 thisray.rdir[0] = thisray.rdir[1] = thisray.rdir[2] = 0.0;
325 thisray.rmax = 0.0;
326 rayorigin(&thisray, PRIMARY, NULL, NULL);
327 printvals(&thisray);
328 }
329
330
331 static void
332 rad( /* compute and print ray value(s) */
333 FVECT org,
334 FVECT dir,
335 double dmax
336 )
337 {
338 VCOPY(thisray.rorg, org);
339 VCOPY(thisray.rdir, dir);
340 thisray.rmax = dmax;
341 rayorigin(&thisray, PRIMARY, NULL, NULL);
342 if (castonly) {
343 if (!localhit(&thisray, &thescene)) {
344 if (thisray.ro == &Aftplane) { /* clipped */
345 thisray.ro = NULL;
346 thisray.rot = FHUGE;
347 } else
348 sourcehit(&thisray);
349 }
350 } else
351 rayvalue(&thisray);
352 printvals(&thisray);
353 }
354
355
356 static void
357 irrad( /* compute immediate irradiance value */
358 FVECT org,
359 FVECT dir
360 )
361 {
362 register int i;
363
364 for (i = 0; i < 3; i++) {
365 thisray.rorg[i] = org[i] + dir[i];
366 thisray.rdir[i] = -dir[i];
367 }
368 thisray.rmax = 0.0;
369 rayorigin(&thisray, PRIMARY, NULL, NULL);
370 /* pretend we hit surface */
371 thisray.rot = 1.0-1e-4;
372 thisray.rod = 1.0;
373 VCOPY(thisray.ron, dir);
374 for (i = 0; i < 3; i++) /* fudge factor */
375 thisray.rop[i] = org[i] + 1e-4*dir[i];
376 /* compute and print */
377 (*ofun[Lamb.otype].funp)(&Lamb, &thisray);
378 printvals(&thisray);
379 }
380
381
382 static void
383 printvals( /* print requested ray values */
384 RAY *r
385 )
386 {
387 register oputf_t **tp;
388
389 if (ray_out[0] == NULL)
390 return;
391 for (tp = ray_out; *tp != NULL; tp++)
392 (**tp)(r);
393 if (outform == 'a')
394 putchar('\n');
395 }
396
397
398 static int
399 getvec( /* get a vector from fp */
400 register FVECT vec,
401 int fmt,
402 FILE *fp
403 )
404 {
405 static float vf[3];
406 static double vd[3];
407 char buf[32];
408 register int i;
409
410 switch (fmt) {
411 case 'a': /* ascii */
412 for (i = 0; i < 3; i++) {
413 if (fgetword(buf, sizeof(buf), fp) == NULL ||
414 !isflt(buf))
415 return(-1);
416 vec[i] = atof(buf);
417 }
418 break;
419 case 'f': /* binary float */
420 if (fread((char *)vf, sizeof(float), 3, fp) != 3)
421 return(-1);
422 vec[0] = vf[0]; vec[1] = vf[1]; vec[2] = vf[2];
423 break;
424 case 'd': /* binary double */
425 if (fread((char *)vd, sizeof(double), 3, fp) != 3)
426 return(-1);
427 vec[0] = vd[0]; vec[1] = vd[1]; vec[2] = vd[2];
428 break;
429 default:
430 error(CONSISTENCY, "botched input format");
431 }
432 return(0);
433 }
434
435
436 static void
437 tranotify( /* record new modifier */
438 OBJECT obj
439 )
440 {
441 static int hitlimit = 0;
442 register OBJREC *o = objptr(obj);
443 register char **tralp;
444
445 if (obj == OVOID) { /* starting over */
446 traset[0] = 0;
447 hitlimit = 0;
448 return;
449 }
450 if (hitlimit || !ismodifier(o->otype))
451 return;
452 for (tralp = tralist; *tralp != NULL; tralp++)
453 if (!strcmp(o->oname, *tralp)) {
454 if (traset[0] >= MAXTSET) {
455 error(WARNING, "too many modifiers in trace list");
456 hitlimit++;
457 return; /* should this be fatal? */
458 }
459 insertelem(traset, obj);
460 return;
461 }
462 }
463
464
465 static void
466 ourtrace( /* print ray values */
467 RAY *r
468 )
469 {
470 register oputf_t **tp;
471
472 if (every_out[0] == NULL)
473 return;
474 if (r->ro == NULL) {
475 if (traincl == 1)
476 return;
477 } else if (traincl != -1 && traincl != inset(traset, r->ro->omod))
478 return;
479 tabin(r);
480 for (tp = every_out; *tp != NULL; tp++)
481 (**tp)(r);
482 if (outform == 'a')
483 putchar('\n');
484 }
485
486
487 static void
488 tabin( /* tab in appropriate amount */
489 RAY *r
490 )
491 {
492 const RAY *rp;
493
494 for (rp = r->parent; rp != NULL; rp = rp->parent)
495 putchar('\t');
496 }
497
498
499 static void
500 oputo( /* print origin */
501 RAY *r
502 )
503 {
504 (*putreal)(r->rorg[0]);
505 (*putreal)(r->rorg[1]);
506 (*putreal)(r->rorg[2]);
507 }
508
509
510 static void
511 oputd( /* print direction */
512 RAY *r
513 )
514 {
515 (*putreal)(r->rdir[0]);
516 (*putreal)(r->rdir[1]);
517 (*putreal)(r->rdir[2]);
518 }
519
520
521 static void
522 oputv( /* print value */
523 RAY *r
524 )
525 {
526 if (outform == 'c') {
527 COLR cout;
528 setcolr(cout, colval(r->rcol,RED),
529 colval(r->rcol,GRN),
530 colval(r->rcol,BLU));
531 fwrite((char *)cout, sizeof(cout), 1, stdout);
532 return;
533 }
534 (*putreal)(colval(r->rcol,RED));
535 (*putreal)(colval(r->rcol,GRN));
536 (*putreal)(colval(r->rcol,BLU));
537 }
538
539
540 static void
541 oputV( /* print value contribution */
542 RAY *r
543 )
544 {
545 double contr[3];
546
547 raycontrib(contr, r, PRIMARY);
548 multcolor(contr, r->rcol);
549 (*putreal)(contr[RED]);
550 (*putreal)(contr[GRN]);
551 (*putreal)(contr[BLU]);
552 }
553
554
555 static void
556 oputl( /* print effective distance */
557 RAY *r
558 )
559 {
560 (*putreal)(r->rt);
561 }
562
563
564 static void
565 oputL( /* print single ray length */
566 RAY *r
567 )
568 {
569 (*putreal)(r->rot);
570 }
571
572
573 static void
574 oputc( /* print local coordinates */
575 RAY *r
576 )
577 {
578 (*putreal)(r->uv[0]);
579 (*putreal)(r->uv[1]);
580 }
581
582
583 static void
584 oputp( /* print point */
585 RAY *r
586 )
587 {
588 if (r->rot < FHUGE) {
589 (*putreal)(r->rop[0]);
590 (*putreal)(r->rop[1]);
591 (*putreal)(r->rop[2]);
592 } else {
593 (*putreal)(0.0);
594 (*putreal)(0.0);
595 (*putreal)(0.0);
596 }
597 }
598
599
600 static void
601 oputN( /* print unperturbed normal */
602 RAY *r
603 )
604 {
605 if (r->rot < FHUGE) {
606 (*putreal)(r->ron[0]);
607 (*putreal)(r->ron[1]);
608 (*putreal)(r->ron[2]);
609 } else {
610 (*putreal)(0.0);
611 (*putreal)(0.0);
612 (*putreal)(0.0);
613 }
614 }
615
616
617 static void
618 oputn( /* print perturbed normal */
619 RAY *r
620 )
621 {
622 FVECT pnorm;
623
624 if (r->rot >= FHUGE) {
625 (*putreal)(0.0);
626 (*putreal)(0.0);
627 (*putreal)(0.0);
628 return;
629 }
630 raynormal(pnorm, r);
631 (*putreal)(pnorm[0]);
632 (*putreal)(pnorm[1]);
633 (*putreal)(pnorm[2]);
634 }
635
636
637 static void
638 oputs( /* print name */
639 RAY *r
640 )
641 {
642 if (r->ro != NULL)
643 fputs(r->ro->oname, stdout);
644 else
645 putchar('*');
646 putchar('\t');
647 }
648
649
650 static void
651 oputw( /* print weight */
652 RAY *r
653 )
654 {
655 (*putreal)(r->rweight);
656 }
657
658
659 static void
660 oputW( /* print coefficient */
661 RAY *r
662 )
663 {
664 double contr[3];
665
666 raycontrib(contr, r, PRIMARY);
667 (*putreal)(contr[RED]);
668 (*putreal)(contr[GRN]);
669 (*putreal)(contr[BLU]);
670 }
671
672
673 static void
674 oputm( /* print modifier */
675 RAY *r
676 )
677 {
678 if (r->ro != NULL)
679 if (r->ro->omod != OVOID)
680 fputs(objptr(r->ro->omod)->oname, stdout);
681 else
682 fputs(VOIDID, stdout);
683 else
684 putchar('*');
685 putchar('\t');
686 }
687
688
689 static void
690 oputM( /* print material */
691 RAY *r
692 )
693 {
694 OBJREC *mat;
695
696 if (r->ro != NULL) {
697 if ((mat = findmaterial(r->ro)) != NULL)
698 fputs(mat->oname, stdout);
699 else
700 fputs(VOIDID, stdout);
701 } else
702 putchar('*');
703 putchar('\t');
704 }
705
706
707 static void
708 oputtilde( /* output tilde (spacer) */
709 RAY *r
710 )
711 {
712 fputs("~\t", stdout);
713 }
714
715
716 static void
717 puta( /* print ascii value */
718 double v
719 )
720 {
721 printf("%e\t", v);
722 }
723
724
725 static void
726 putd(v) /* print binary double */
727 double v;
728 {
729 fwrite((char *)&v, sizeof(v), 1, stdout);
730 }
731
732
733 static void
734 putf(v) /* print binary float */
735 double v;
736 {
737 float f = v;
738
739 fwrite((char *)&f, sizeof(f), 1, stdout);
740 }