ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rtrace.c
Revision: 2.17
Committed: Tue Dec 20 20:18:34 1994 UTC (29 years, 4 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.16: +2 -1 lines
Log Message:
added -vo and -va (fore and aft clipping plane) view options

File Contents

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