ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rtrace.c
Revision: 2.10
Committed: Thu Nov 19 20:26:10 1992 UTC (31 years, 5 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.9: +1 -1 lines
Log Message:
changed -di to ! -dv

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