ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rtrace.c
Revision: 2.19
Committed: Mon Aug 21 10:29:20 1995 UTC (28 years, 8 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.18: +4 -4 lines
Log Message:
increase default parameters for more accurate calculations

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