ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rtrace.c
Revision: 2.32
Committed: Wed Jul 16 01:32:53 2003 UTC (20 years, 9 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.31: +3 -1 lines
Log Message:
Minor compile fixes

File Contents

# User Rev Content
1 greg 1.1 #ifndef lint
2 greg 2.32 static const char RCSid[] = "$Id: rtrace.c,v 2.31 2003/06/30 14:59:12 schorsch 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 1.4 double shadthresh = .05; /* shadow threshold */
61 greg 1.5 double shadcert = .5; /* 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 1.1 int maxdepth = 6; /* maximum recursion depth */
78     double minweight = 4e-3; /* minimum ray weight */
79    
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 1.1 double ambacc = 0.2; /* ambient accuracy */
84 greg 2.19 int ambres = 128; /* ambient resolution */
85     int ambdiv = 512; /* ambient divisions */
86 greg 1.1 int ambssamp = 0; /* ambient super-samples */
87     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     if (!localhit(&thisray, &thescene))
289     if (thisray.ro == &Aftplane) { /* clipped */
290     thisray.ro = NULL;
291     thisray.rot = FHUGE;
292     } else
293     sourcehit(&thisray);
294     } else
295 greg 1.11 rayvalue(&thisray);
296 greg 2.16 printvals(&thisray);
297 greg 1.1 }
298    
299    
300 greg 2.27 void
301 greg 1.13 irrad(org, dir) /* compute immediate irradiance value */
302 greg 1.1 FVECT org, dir;
303     {
304     register int i;
305    
306     for (i = 0; i < 3; i++) {
307     thisray.rorg[i] = org[i] + dir[i];
308     thisray.rdir[i] = -dir[i];
309     }
310     rayorigin(&thisray, NULL, PRIMARY, 1.0);
311     /* pretend we hit surface */
312 greg 2.16 thisray.rot = 1.0-1e-4;
313 greg 1.1 thisray.rod = 1.0;
314     VCOPY(thisray.ron, dir);
315     for (i = 0; i < 3; i++) /* fudge factor */
316     thisray.rop[i] = org[i] + 1e-4*dir[i];
317     /* compute and print */
318     (*ofun[Lamb.otype].funp)(&Lamb, &thisray);
319 greg 2.16 printvals(&thisray);
320     }
321    
322    
323 greg 2.27 void
324 greg 2.16 printvals(r) /* print requested ray values */
325     RAY *r;
326     {
327 greg 2.27 register void (**tp)();
328 greg 2.16
329     if (ray_out[0] == NULL)
330     return;
331     for (tp = ray_out; *tp != NULL; tp++)
332     (**tp)(r);
333 greg 1.1 if (outform == 'a')
334     putchar('\n');
335     }
336    
337    
338 greg 2.27 int
339 greg 1.1 getvec(vec, fmt, fp) /* get a vector from fp */
340     register FVECT vec;
341     int fmt;
342     FILE *fp;
343     {
344     static float vf[3];
345 greg 2.5 static double vd[3];
346 greg 1.19 char buf[32];
347     register int i;
348 greg 1.1
349     switch (fmt) {
350     case 'a': /* ascii */
351 greg 1.19 for (i = 0; i < 3; i++) {
352     if (fgetword(buf, sizeof(buf), fp) == NULL ||
353     !isflt(buf))
354     return(-1);
355     vec[i] = atof(buf);
356     }
357 greg 1.1 break;
358     case 'f': /* binary float */
359 greg 1.8 if (fread((char *)vf, sizeof(float), 3, fp) != 3)
360 greg 1.1 return(-1);
361     vec[0] = vf[0]; vec[1] = vf[1]; vec[2] = vf[2];
362     break;
363     case 'd': /* binary double */
364 greg 2.5 if (fread((char *)vd, sizeof(double), 3, fp) != 3)
365 greg 1.1 return(-1);
366 greg 2.5 vec[0] = vd[0]; vec[1] = vd[1]; vec[2] = vd[2];
367 greg 1.1 break;
368 greg 2.6 default:
369     error(CONSISTENCY, "botched input format");
370 greg 1.1 }
371     return(0);
372     }
373    
374    
375 greg 2.27 void
376 greg 2.15 tranotify(obj) /* record new modifier */
377     OBJECT obj;
378     {
379     static int hitlimit = 0;
380     register OBJREC *o = objptr(obj);
381     register char **tralp;
382    
383 greg 2.27 if (obj == OVOID) { /* starting over */
384     traset[0] = 0;
385     hitlimit = 0;
386     return;
387     }
388 greg 2.15 if (hitlimit || !ismodifier(o->otype))
389     return;
390     for (tralp = tralist; *tralp != NULL; tralp++)
391     if (!strcmp(o->oname, *tralp)) {
392     if (traset[0] >= MAXTSET) {
393     error(WARNING, "too many modifiers in trace list");
394     hitlimit++;
395     return; /* should this be fatal? */
396     }
397     insertelem(traset, obj);
398     return;
399     }
400     }
401    
402    
403 greg 2.27 static void
404 greg 1.1 ourtrace(r) /* print ray values */
405     RAY *r;
406     {
407 greg 2.27 register void (**tp)();
408 greg 1.1
409     if (every_out[0] == NULL)
410 greg 2.15 return;
411 greg 2.16 if (r->ro == NULL) {
412     if (traincl == 1)
413     return;
414     } else if (traincl != -1 && traincl != inset(traset, r->ro->omod))
415 greg 1.1 return;
416     tabin(r);
417     for (tp = every_out; *tp != NULL; tp++)
418     (**tp)(r);
419     putchar('\n');
420     }
421    
422    
423 greg 2.27 static void
424 greg 1.1 tabin(r) /* tab in appropriate amount */
425     RAY *r;
426     {
427     register RAY *rp;
428    
429     for (rp = r->parent; rp != NULL; rp = rp->parent)
430     putchar('\t');
431     }
432    
433    
434 greg 2.27 static void
435 greg 1.1 oputo(r) /* print origin */
436 greg 2.29 RAY *r;
437 greg 1.1 {
438     (*putreal)(r->rorg[0]);
439     (*putreal)(r->rorg[1]);
440     (*putreal)(r->rorg[2]);
441     }
442    
443    
444 greg 2.27 static void
445 greg 1.1 oputd(r) /* print direction */
446 greg 2.29 RAY *r;
447 greg 1.1 {
448     (*putreal)(r->rdir[0]);
449     (*putreal)(r->rdir[1]);
450     (*putreal)(r->rdir[2]);
451     }
452    
453    
454 greg 2.27 static void
455 greg 1.1 oputv(r) /* print value */
456 greg 2.29 RAY *r;
457 greg 1.1 {
458 greg 2.6 COLR cout;
459    
460     if (outform == 'c') {
461     setcolr(cout, colval(r->rcol,RED),
462     colval(r->rcol,GRN),
463     colval(r->rcol,BLU));
464     fwrite((char *)cout, sizeof(cout), 1, stdout);
465     return;
466     }
467 greg 1.1 (*putreal)(colval(r->rcol,RED));
468     (*putreal)(colval(r->rcol,GRN));
469     (*putreal)(colval(r->rcol,BLU));
470     }
471    
472    
473 greg 2.27 static void
474 greg 2.5 oputl(r) /* print effective distance */
475 greg 2.29 RAY *r;
476 greg 1.1 {
477 greg 1.9 (*putreal)(r->rt);
478 greg 2.5 }
479    
480    
481 greg 2.27 static void
482 greg 2.5 oputL(r) /* print single ray length */
483 greg 2.29 RAY *r;
484 greg 2.5 {
485     (*putreal)(r->rot);
486 greg 1.1 }
487    
488    
489 greg 2.27 static void
490 greg 2.29 oputc(r) /* print local coordinates */
491     RAY *r;
492     {
493     (*putreal)(r->uv[0]);
494     (*putreal)(r->uv[1]);
495     }
496    
497    
498     static void
499 greg 1.1 oputp(r) /* print point */
500 greg 2.29 RAY *r;
501 greg 1.1 {
502     if (r->rot < FHUGE) {
503     (*putreal)(r->rop[0]);
504     (*putreal)(r->rop[1]);
505     (*putreal)(r->rop[2]);
506     } else {
507     (*putreal)(0.0);
508     (*putreal)(0.0);
509     (*putreal)(0.0);
510     }
511     }
512    
513    
514 greg 2.27 static void
515 greg 2.9 oputN(r) /* print unperturbed normal */
516 greg 2.29 RAY *r;
517 greg 1.1 {
518     if (r->rot < FHUGE) {
519     (*putreal)(r->ron[0]);
520     (*putreal)(r->ron[1]);
521     (*putreal)(r->ron[2]);
522     } else {
523     (*putreal)(0.0);
524     (*putreal)(0.0);
525     (*putreal)(0.0);
526     }
527 greg 2.9 }
528    
529    
530 greg 2.27 static void
531 greg 2.9 oputn(r) /* print perturbed normal */
532     RAY *r;
533     {
534     FVECT pnorm;
535    
536     if (r->rot >= FHUGE) {
537     (*putreal)(0.0);
538     (*putreal)(0.0);
539     (*putreal)(0.0);
540     return;
541     }
542     raynormal(pnorm, r);
543     (*putreal)(pnorm[0]);
544     (*putreal)(pnorm[1]);
545     (*putreal)(pnorm[2]);
546 greg 1.1 }
547    
548    
549 greg 2.27 static void
550 greg 1.1 oputs(r) /* print name */
551 greg 2.29 RAY *r;
552 greg 1.1 {
553     if (r->ro != NULL)
554     fputs(r->ro->oname, stdout);
555     else
556     putchar('*');
557     putchar('\t');
558     }
559    
560    
561 greg 2.27 static void
562 greg 1.1 oputw(r) /* print weight */
563 greg 2.29 RAY *r;
564 greg 1.1 {
565     (*putreal)(r->rweight);
566     }
567    
568    
569 greg 2.27 static void
570 greg 1.1 oputm(r) /* print modifier */
571 greg 2.29 RAY *r;
572 greg 1.1 {
573     if (r->ro != NULL)
574 greg 2.23 if (r->ro->omod != OVOID)
575     fputs(objptr(r->ro->omod)->oname, stdout);
576     else
577     fputs(VOIDID, stdout);
578 greg 1.1 else
579     putchar('*');
580     putchar('\t');
581     }
582    
583    
584 greg 2.27 static void
585 greg 1.1 puta(v) /* print ascii value */
586     double v;
587     {
588     printf("%e\t", v);
589     }
590    
591    
592 greg 2.27 static void
593 greg 1.1 putd(v) /* print binary double */
594     double v;
595     {
596 greg 1.8 fwrite((char *)&v, sizeof(v), 1, stdout);
597 greg 1.1 }
598    
599    
600 greg 2.27 static void
601 greg 1.1 putf(v) /* print binary float */
602     double v;
603     {
604     float f = v;
605    
606 greg 1.8 fwrite((char *)&f, sizeof(f), 1, stdout);
607 greg 1.1 }