ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rtrace.c
Revision: 2.29
Committed: Fri Apr 18 17:29:22 2003 UTC (21 years ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.28: +23 -11 lines
Log Message:
Added rtrace -oc option to output local (u,v) coordinates

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