ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rtrace.c
Revision: 2.36
Committed: Sun Mar 28 16:31:14 2004 UTC (20 years, 1 month ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.35: +2 -2 lines
Log Message:
Increased -aa default settings

File Contents

# User Rev Content
1 greg 1.1 #ifndef lint
2 greg 2.36 static const char RCSid[] = "$Id: rtrace.c,v 2.35 2003/10/04 14:39:53 greg Exp $";
3 greg 1.1 #endif
4     /*
5     * rtrace.c - program and variables for individual ray tracing.
6 greg 2.27 */
7    
8 greg 2.28 #include "copyright.h"
9 greg 1.1
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 greg 1.7 * If the direction vector is (0,0,0), then the output is flushed.
17 greg 1.1 * 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 greg 1.13 * radiance is computed. The '-i' or '-I' options indicate that
21 greg 1.1 * irradiance values are desired.
22     */
23 greg 2.32
24     #include <time.h>
25 greg 1.1
26 schorsch 2.30 #include "platform.h"
27 greg 1.1 #include "ray.h"
28     #include "otypes.h"
29 greg 2.6 #include "resolu.h"
30    
31 greg 2.27 CUBE thescene; /* our scene */
32     OBJECT nsceneobjs; /* number of objects in our scene */
33    
34 greg 1.14 int dimlist[MAXDIM]; /* sampling dimensions */
35     int ndims = 0; /* number of sampling dimensions */
36     int samplendx = 0; /* index for this sample */
37    
38 greg 1.13 int imm_irrad = 0; /* compute immediate irradiance? */
39 gregl 2.25 int lim_dist = 0; /* limit distance? */
40 greg 1.13
41 greg 1.1 int inform = 'a'; /* input format */
42     int outform = 'a'; /* output format */
43     char *outvals = "v"; /* output specification */
44    
45 greg 2.27 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 greg 2.15 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 greg 1.1 int hresolu = 0; /* horizontal (scan) size */
57     int vresolu = 0; /* vertical resolution */
58    
59     double dstrsrc = 0.0; /* square source distribution */
60 greg 2.35 double shadthresh = .03; /* shadow threshold */
61     double shadcert = .75; /* shadow certainty */
62 greg 2.19 int directrelay = 2; /* number of source relays */
63 greg 1.17 int vspretest = 512; /* virtual source pretest density */
64 greg 2.10 int directvis = 1; /* sources visible? */
65 greg 2.19 double srcsizerat = .2; /* maximum ratio source size/dist. */
66 greg 2.20
67     COLOR cextinction = BLKCOLOR; /* global extinction coefficient */
68 greg 2.22 COLOR salbedo = BLKCOLOR; /* global scattering albedo */
69 greg 2.20 double seccg = 0.; /* global scattering eccentricity */
70     double ssampdist = 0.; /* scatter sampling distance */
71 greg 1.1
72 greg 2.4 double specthresh = .15; /* specular sampling threshold */
73 greg 2.3 double specjitter = 1.; /* specular sampling jitter */
74    
75 greg 2.18 int backvis = 1; /* back face visibility */
76    
77 greg 2.34 int maxdepth = 8; /* maximum recursion depth */
78     double minweight = 2e-3; /* minimum ray weight */
79 greg 1.1
80 greg 2.27 char *ambfile = NULL; /* ambient file name */
81 greg 1.1 COLOR ambval = BLKCOLOR; /* ambient value */
82 greg 2.21 int ambvwt = 0; /* initial weight for ambient value */
83 greg 2.36 double ambacc = 0.15; /* ambient accuracy */
84 greg 2.34 int ambres = 256; /* ambient resolution */
85     int ambdiv = 1024; /* ambient divisions */
86     int ambssamp = 512; /* ambient super-samples */
87 greg 1.1 int ambounce = 0; /* ambient bounces */
88     char *amblist[128]; /* ambient include/exclude list */
89     int ambincl = -1; /* include == 1, exclude == 0 */
90    
91 gregl 2.25
92 greg 1.1 static RAY thisray; /* for our convenience */
93    
94 greg 2.29 static void oputo(), oputd(), oputv(), oputl(), oputL(), oputc(),
95 greg 2.9 oputp(), oputn(), oputN(), oputs(), oputw(), oputm();
96 greg 1.1
97 greg 2.27 static void ourtrace(), tabin();
98     static void (*ray_out[16])(), (*every_out[16])();
99 greg 2.14 static int castonly = 0;
100 greg 1.1
101 greg 2.27 static void puta(), putf(), putd();
102    
103     static void (*putreal)();
104 greg 1.1
105 greg 2.27 void bogusray(), rad(), irrad(), printvals();
106 greg 1.1
107    
108 greg 2.27 void
109 greg 1.1 quit(code) /* quit program */
110     int code;
111     {
112 schorsch 2.31 #ifndef NON_POSIX /* XXX we don't clean up elsewhere? */
113 greg 2.11 headclean(); /* delete header file */
114     pfclean(); /* clean up persist files */
115     #endif
116 greg 1.1 exit(code);
117     }
118    
119    
120 greg 2.6 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 greg 2.27 void
135 greg 1.1 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 gregl 2.25 double d;
142 greg 1.2 FVECT orig, direc;
143 greg 1.1 /* set up input */
144     if (fname == NULL)
145     fp = stdin;
146     else if ((fp = fopen(fname, "r")) == NULL) {
147     sprintf(errmsg, "cannot open input file \"%s\"", fname);
148     error(SYSTEM, errmsg);
149     }
150 schorsch 2.30 #ifdef _WIN32
151 greg 2.8 if (inform != 'a')
152 schorsch 2.30 SET_FILE_BINARY(fp);
153 greg 2.8 #endif
154 greg 1.1 /* set up output */
155 greg 2.16 setoutput(outvals);
156 greg 1.1 switch (outform) {
157     case 'a': putreal = puta; break;
158     case 'f': putreal = putf; break;
159     case 'd': putreal = putd; break;
160 greg 2.6 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 greg 1.1 }
167 greg 2.12 if (hresolu > 0) {
168     if (vresolu > 0)
169     fprtresolu(hresolu, vresolu, stdout);
170     fflush(stdout);
171     }
172 greg 1.1 /* process file */
173     while (getvec(orig, inform, fp) == 0 &&
174     getvec(direc, inform, fp) == 0) {
175    
176 gregl 2.25 d = normalize(direc);
177     if (d == 0.0) { /* zero ==> flush */
178 gregl 2.24 bogusray();
179 gregl 2.26 if (--nextflush <= 0 || vcount <= 0) {
180 gregl 2.24 fflush(stdout);
181     nextflush = hresolu;
182     }
183     } else {
184     samplendx++;
185 greg 1.1 /* compute and print */
186 gregl 2.24 if (imm_irrad)
187     irrad(orig, direc);
188     else
189 gregl 2.25 rad(orig, direc, lim_dist ? d : 0.0);
190 greg 1.7 /* flush if time */
191 gregl 2.24 if (--nextflush == 0) {
192     fflush(stdout);
193     nextflush = hresolu;
194     }
195 greg 1.1 }
196     if (ferror(stdout))
197     error(SYSTEM, "write error");
198     if (--vcount == 0) /* check for end */
199     break;
200     }
201 greg 2.12 fflush(stdout);
202 greg 1.1 if (vcount > 0)
203     error(USER, "read error");
204 greg 2.12 if (fname != NULL)
205     fclose(fp);
206 greg 1.1 }
207    
208    
209     setoutput(vs) /* set up output tables */
210     register char *vs;
211     {
212 greg 2.27 extern void (*trace)();
213     register void (**table)() = ray_out;
214 greg 1.1
215 greg 1.11 castonly = 1;
216 greg 1.1 while (*vs)
217     switch (*vs++) {
218     case 't': /* trace */
219     *table = NULL;
220     table = every_out;
221     trace = ourtrace;
222 greg 1.11 castonly = 0;
223 greg 1.1 break;
224     case 'o': /* origin */
225     *table++ = oputo;
226     break;
227     case 'd': /* direction */
228     *table++ = oputd;
229     break;
230     case 'v': /* value */
231     *table++ = oputv;
232 greg 1.11 castonly = 0;
233 greg 1.1 break;
234 greg 2.5 case 'l': /* effective distance */
235 greg 1.1 *table++ = oputl;
236 greg 1.11 castonly = 0;
237 greg 1.1 break;
238 greg 2.29 case 'c': /* local coordinates */
239     *table++ = oputc;
240     break;
241 greg 2.5 case 'L': /* single ray length */
242     *table++ = oputL;
243     break;
244 greg 1.1 case 'p': /* point */
245     *table++ = oputp;
246     break;
247 greg 2.9 case 'n': /* perturbed normal */
248 greg 1.1 *table++ = oputn;
249 greg 2.9 castonly = 0;
250 greg 1.1 break;
251 greg 2.9 case 'N': /* unperturbed normal */
252     *table++ = oputN;
253     break;
254 greg 1.1 case 's': /* surface */
255     *table++ = oputs;
256     break;
257     case 'w': /* weight */
258     *table++ = oputw;
259     break;
260     case 'm': /* modifier */
261     *table++ = oputm;
262     break;
263     }
264     *table = NULL;
265 gregl 2.24 }
266    
267    
268 greg 2.27 void
269 gregl 2.24 bogusray() /* print out empty record */
270     {
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 greg 1.1 }
276    
277    
278 greg 2.27 void
279 gregl 2.25 rad(org, dir, dmax) /* compute and print ray value(s) */
280 greg 1.1 FVECT org, dir;
281 gregl 2.25 double dmax;
282 greg 1.1 {
283     VCOPY(thisray.rorg, org);
284     VCOPY(thisray.rdir, dir);
285 gregl 2.25 thisray.rmax = dmax;
286 greg 1.1 rayorigin(&thisray, NULL, PRIMARY, 1.0);
287 gregl 2.25 if (castonly) {
288 schorsch 2.33 if (!localhit(&thisray, &thescene)) {
289 gregl 2.25 if (thisray.ro == &Aftplane) { /* clipped */
290     thisray.ro = NULL;
291     thisray.rot = FHUGE;
292     } else
293     sourcehit(&thisray);
294 schorsch 2.33 }
295 gregl 2.25 } else
296 greg 1.11 rayvalue(&thisray);
297 greg 2.16 printvals(&thisray);
298 greg 1.1 }
299    
300    
301 greg 2.27 void
302 greg 1.13 irrad(org, dir) /* compute immediate irradiance value */
303 greg 1.1 FVECT org, dir;
304     {
305     register int i;
306    
307     for (i = 0; i < 3; i++) {
308     thisray.rorg[i] = org[i] + dir[i];
309     thisray.rdir[i] = -dir[i];
310     }
311     rayorigin(&thisray, NULL, PRIMARY, 1.0);
312     /* pretend we hit surface */
313 greg 2.16 thisray.rot = 1.0-1e-4;
314 greg 1.1 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 greg 2.16 printvals(&thisray);
321     }
322    
323    
324 greg 2.27 void
325 greg 2.16 printvals(r) /* print requested ray values */
326     RAY *r;
327     {
328 greg 2.27 register void (**tp)();
329 greg 2.16
330     if (ray_out[0] == NULL)
331     return;
332     for (tp = ray_out; *tp != NULL; tp++)
333     (**tp)(r);
334 greg 1.1 if (outform == 'a')
335     putchar('\n');
336     }
337    
338    
339 greg 2.27 int
340 greg 1.1 getvec(vec, fmt, fp) /* get a vector from fp */
341     register FVECT vec;
342     int fmt;
343     FILE *fp;
344     {
345     static float vf[3];
346 greg 2.5 static double vd[3];
347 greg 1.19 char buf[32];
348     register int i;
349 greg 1.1
350     switch (fmt) {
351     case 'a': /* ascii */
352 greg 1.19 for (i = 0; i < 3; i++) {
353     if (fgetword(buf, sizeof(buf), fp) == NULL ||
354     !isflt(buf))
355     return(-1);
356     vec[i] = atof(buf);
357     }
358 greg 1.1 break;
359     case 'f': /* binary float */
360 greg 1.8 if (fread((char *)vf, sizeof(float), 3, fp) != 3)
361 greg 1.1 return(-1);
362     vec[0] = vf[0]; vec[1] = vf[1]; vec[2] = vf[2];
363     break;
364     case 'd': /* binary double */
365 greg 2.5 if (fread((char *)vd, sizeof(double), 3, fp) != 3)
366 greg 1.1 return(-1);
367 greg 2.5 vec[0] = vd[0]; vec[1] = vd[1]; vec[2] = vd[2];
368 greg 1.1 break;
369 greg 2.6 default:
370     error(CONSISTENCY, "botched input format");
371 greg 1.1 }
372     return(0);
373     }
374    
375    
376 greg 2.27 void
377 greg 2.15 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 greg 2.27 if (obj == OVOID) { /* starting over */
385     traset[0] = 0;
386     hitlimit = 0;
387     return;
388     }
389 greg 2.15 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 greg 2.27 static void
405 greg 1.1 ourtrace(r) /* print ray values */
406     RAY *r;
407     {
408 greg 2.27 register void (**tp)();
409 greg 1.1
410     if (every_out[0] == NULL)
411 greg 2.15 return;
412 greg 2.16 if (r->ro == NULL) {
413     if (traincl == 1)
414     return;
415     } else if (traincl != -1 && traincl != inset(traset, r->ro->omod))
416 greg 1.1 return;
417     tabin(r);
418     for (tp = every_out; *tp != NULL; tp++)
419     (**tp)(r);
420     putchar('\n');
421     }
422    
423    
424 greg 2.27 static void
425 greg 1.1 tabin(r) /* tab in appropriate amount */
426     RAY *r;
427     {
428     register RAY *rp;
429    
430     for (rp = r->parent; rp != NULL; rp = rp->parent)
431     putchar('\t');
432     }
433    
434    
435 greg 2.27 static void
436 greg 1.1 oputo(r) /* print origin */
437 greg 2.29 RAY *r;
438 greg 1.1 {
439     (*putreal)(r->rorg[0]);
440     (*putreal)(r->rorg[1]);
441     (*putreal)(r->rorg[2]);
442     }
443    
444    
445 greg 2.27 static void
446 greg 1.1 oputd(r) /* print direction */
447 greg 2.29 RAY *r;
448 greg 1.1 {
449     (*putreal)(r->rdir[0]);
450     (*putreal)(r->rdir[1]);
451     (*putreal)(r->rdir[2]);
452     }
453    
454    
455 greg 2.27 static void
456 greg 1.1 oputv(r) /* print value */
457 greg 2.29 RAY *r;
458 greg 1.1 {
459 greg 2.6 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 greg 1.1 (*putreal)(colval(r->rcol,RED));
469     (*putreal)(colval(r->rcol,GRN));
470     (*putreal)(colval(r->rcol,BLU));
471     }
472    
473    
474 greg 2.27 static void
475 greg 2.5 oputl(r) /* print effective distance */
476 greg 2.29 RAY *r;
477 greg 1.1 {
478 greg 1.9 (*putreal)(r->rt);
479 greg 2.5 }
480    
481    
482 greg 2.27 static void
483 greg 2.5 oputL(r) /* print single ray length */
484 greg 2.29 RAY *r;
485 greg 2.5 {
486     (*putreal)(r->rot);
487 greg 1.1 }
488    
489    
490 greg 2.27 static void
491 greg 2.29 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 greg 1.1 oputp(r) /* print point */
501 greg 2.29 RAY *r;
502 greg 1.1 {
503     if (r->rot < FHUGE) {
504     (*putreal)(r->rop[0]);
505     (*putreal)(r->rop[1]);
506     (*putreal)(r->rop[2]);
507     } else {
508     (*putreal)(0.0);
509     (*putreal)(0.0);
510     (*putreal)(0.0);
511     }
512     }
513    
514    
515 greg 2.27 static void
516 greg 2.9 oputN(r) /* print unperturbed normal */
517 greg 2.29 RAY *r;
518 greg 1.1 {
519     if (r->rot < FHUGE) {
520     (*putreal)(r->ron[0]);
521     (*putreal)(r->ron[1]);
522     (*putreal)(r->ron[2]);
523     } else {
524     (*putreal)(0.0);
525     (*putreal)(0.0);
526     (*putreal)(0.0);
527     }
528 greg 2.9 }
529    
530    
531 greg 2.27 static void
532 greg 2.9 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 greg 1.1 }
548    
549    
550 greg 2.27 static void
551 greg 1.1 oputs(r) /* print name */
552 greg 2.29 RAY *r;
553 greg 1.1 {
554     if (r->ro != NULL)
555     fputs(r->ro->oname, stdout);
556     else
557     putchar('*');
558     putchar('\t');
559     }
560    
561    
562 greg 2.27 static void
563 greg 1.1 oputw(r) /* print weight */
564 greg 2.29 RAY *r;
565 greg 1.1 {
566     (*putreal)(r->rweight);
567     }
568    
569    
570 greg 2.27 static void
571 greg 1.1 oputm(r) /* print modifier */
572 greg 2.29 RAY *r;
573 greg 1.1 {
574     if (r->ro != NULL)
575 greg 2.23 if (r->ro->omod != OVOID)
576     fputs(objptr(r->ro->omod)->oname, stdout);
577     else
578     fputs(VOIDID, stdout);
579 greg 1.1 else
580     putchar('*');
581     putchar('\t');
582     }
583    
584    
585 greg 2.27 static void
586 greg 1.1 puta(v) /* print ascii value */
587     double v;
588     {
589     printf("%e\t", v);
590     }
591    
592    
593 greg 2.27 static void
594 greg 1.1 putd(v) /* print binary double */
595     double v;
596     {
597 greg 1.8 fwrite((char *)&v, sizeof(v), 1, stdout);
598 greg 1.1 }
599    
600    
601 greg 2.27 static void
602 greg 1.1 putf(v) /* print binary float */
603     double v;
604     {
605     float f = v;
606    
607 greg 1.8 fwrite((char *)&f, sizeof(f), 1, stdout);
608 greg 1.1 }