ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rtrace.c
Revision: 2.14
Committed: Tue May 4 13:26:52 1993 UTC (31 years ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.13: +6 -3 lines
Log Message:
made sure that -I option completely overrides -o option

File Contents

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