ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rtrace.c
Revision: 2.23
Committed: Tue Jan 14 19:54:27 1997 UTC (27 years, 3 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.22: +4 -1 lines
Log Message:
fixed bug in printing void materials.

File Contents

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