ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rtrace.c
Revision: 2.25
Committed: Fri Oct 17 10:14:37 1997 UTC (26 years, 6 months ago) by gregl
Content type: text/plain
Branch: MAIN
Changes since 2.24: +18 -7 lines
Log Message:
added -ld boolean option to rtrace for limiting ray distance

File Contents

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