ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rtrace.c
Revision: 1.12
Committed: Thu Mar 28 10:16:35 1991 UTC (33 years, 1 month ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.11: +25 -6 lines
Log Message:
added -oI option for irradiance after intersection

File Contents

# User Rev Content
1 greg 1.1 /* Copyright (c) 1986 Regents of the University of California */
2    
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.12 * radiance is computed. The '-oi' or '-oI' 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     int inform = 'a'; /* input format */
34     int outform = 'a'; /* output format */
35     char *outvals = "v"; /* output specification */
36    
37     int hresolu = 0; /* horizontal (scan) size */
38     int vresolu = 0; /* vertical resolution */
39    
40     double dstrsrc = 0.0; /* square source distribution */
41 greg 1.4 double shadthresh = .05; /* shadow threshold */
42 greg 1.5 double shadcert = .5; /* shadow certainty */
43 greg 1.1
44     int maxdepth = 6; /* maximum recursion depth */
45     double minweight = 4e-3; /* minimum ray weight */
46    
47     COLOR ambval = BLKCOLOR; /* ambient value */
48     double ambacc = 0.2; /* ambient accuracy */
49 greg 1.6 int ambres = 32; /* ambient resolution */
50 greg 1.1 int ambdiv = 128; /* ambient divisions */
51     int ambssamp = 0; /* ambient super-samples */
52     int ambounce = 0; /* ambient bounces */
53     char *amblist[128]; /* ambient include/exclude list */
54     int ambincl = -1; /* include == 1, exclude == 0 */
55    
56     static RAY thisray; /* for our convenience */
57    
58 greg 1.10 static int oputo(), oputd(), oputv(), oputl(),
59 greg 1.1 oputp(), oputn(), oputs(), oputw(), oputm();
60    
61     static int (*ray_out[10])(), (*every_out[10])();
62 greg 1.11 static int castonly;
63 greg 1.1
64 greg 1.10 static int puta(), putf(), putd();
65 greg 1.1
66     static int (*putreal)();
67    
68 greg 1.12 static double Lambfa[5] = {PI, PI, PI, 0.0, 0.0};
69     static OBJREC Lamb = {
70     OVOID, MAT_PLASTIC, "Lambertian",
71     {0, 5, NULL, Lambfa}, NULL, -1,
72     }; /* a Lambertian surface */
73 greg 1.1
74 greg 1.12
75 greg 1.1 quit(code) /* quit program */
76     int code;
77     {
78     exit(code);
79     }
80    
81    
82     rtrace(fname) /* trace rays from file */
83     char *fname;
84     {
85     long vcount = hresolu>1 ? hresolu*vresolu : vresolu;
86     long nextflush = hresolu;
87     FILE *fp;
88 greg 1.2 FVECT orig, direc;
89 greg 1.1 /* set up input */
90     if (fname == NULL)
91     fp = stdin;
92     else if ((fp = fopen(fname, "r")) == NULL) {
93     sprintf(errmsg, "cannot open input file \"%s\"", fname);
94     error(SYSTEM, errmsg);
95     }
96     /* set up output */
97     setoutput(outvals);
98     switch (outform) {
99     case 'a': putreal = puta; break;
100     case 'f': putreal = putf; break;
101     case 'd': putreal = putd; break;
102     }
103     /* process file */
104     while (getvec(orig, inform, fp) == 0 &&
105     getvec(direc, inform, fp) == 0) {
106    
107 greg 1.7 if (normalize(direc) == 0.0) { /* zero ==> flush */
108     fflush(stdout);
109     continue;
110     }
111 greg 1.1 /* compute and print */
112     if (outvals[0] == 'i')
113     irrad(orig, direc);
114 greg 1.12 else if (outvals[0] == 'I')
115     Irrad(orig, direc);
116 greg 1.1 else
117     radiance(orig, direc);
118 greg 1.7 /* flush if time */
119 greg 1.1 if (--nextflush == 0) {
120     fflush(stdout);
121     nextflush = hresolu;
122     }
123     if (ferror(stdout))
124     error(SYSTEM, "write error");
125     if (--vcount == 0) /* check for end */
126     break;
127     }
128     if (vcount > 0)
129     error(USER, "read error");
130     fclose(fp);
131     }
132    
133    
134     setoutput(vs) /* set up output tables */
135     register char *vs;
136     {
137     extern int ourtrace(), (*trace)();
138     register int (**table)() = ray_out;
139    
140 greg 1.11 castonly = 1;
141 greg 1.1 while (*vs)
142     switch (*vs++) {
143     case 't': /* trace */
144     *table = NULL;
145     table = every_out;
146     trace = ourtrace;
147 greg 1.11 castonly = 0;
148 greg 1.1 break;
149     case 'o': /* origin */
150     *table++ = oputo;
151     break;
152     case 'd': /* direction */
153     *table++ = oputd;
154     break;
155     case 'v': /* value */
156     *table++ = oputv;
157 greg 1.11 castonly = 0;
158 greg 1.1 break;
159     case 'l': /* length */
160     *table++ = oputl;
161 greg 1.11 castonly = 0;
162 greg 1.1 break;
163     case 'p': /* point */
164     *table++ = oputp;
165     break;
166     case 'n': /* normal */
167     *table++ = oputn;
168     break;
169     case 's': /* surface */
170     *table++ = oputs;
171     break;
172     case 'w': /* weight */
173     *table++ = oputw;
174     break;
175     case 'm': /* modifier */
176     *table++ = oputm;
177     break;
178     }
179     *table = NULL;
180     }
181    
182    
183     radiance(org, dir) /* compute radiance value */
184     FVECT org, dir;
185     {
186     register int (**tp)();
187    
188     VCOPY(thisray.rorg, org);
189     VCOPY(thisray.rdir, dir);
190     rayorigin(&thisray, NULL, PRIMARY, 1.0);
191 greg 1.11 if (castonly)
192     localhit(&thisray, &thescene) || sourcehit(&thisray);
193     else
194     rayvalue(&thisray);
195 greg 1.1
196     if (ray_out[0] == NULL)
197     return;
198     for (tp = ray_out; *tp != NULL; tp++)
199     (**tp)(&thisray);
200     if (outform == 'a')
201     putchar('\n');
202     }
203    
204    
205     irrad(org, dir) /* compute irradiance value */
206     FVECT org, dir;
207     {
208     register int i;
209    
210     for (i = 0; i < 3; i++) {
211     thisray.rorg[i] = org[i] + dir[i];
212     thisray.rdir[i] = -dir[i];
213     }
214     rayorigin(&thisray, NULL, PRIMARY, 1.0);
215     /* pretend we hit surface */
216     thisray.rot = 1.0;
217     thisray.rod = 1.0;
218     VCOPY(thisray.ron, dir);
219     for (i = 0; i < 3; i++) /* fudge factor */
220     thisray.rop[i] = org[i] + 1e-4*dir[i];
221     /* compute and print */
222     (*ofun[Lamb.otype].funp)(&Lamb, &thisray);
223 greg 1.12 oputv(&thisray);
224     if (outform == 'a')
225     putchar('\n');
226     }
227    
228    
229     Irrad(org, dir) /* compute irradiance value after intersection */
230     FVECT org, dir;
231     {
232     /* compute intersection */
233     VCOPY(thisray.rorg, org);
234     VCOPY(thisray.rdir, dir);
235     rayorigin(&thisray, NULL, PRIMARY, 1.0);
236     localhit(&thisray, &thescene);
237     if (thisray.ro != NULL) /* pretend we hit Lambertian surf. */
238     (*ofun[Lamb.otype].funp)(&Lamb, &thisray);
239 greg 1.1 oputv(&thisray);
240     if (outform == 'a')
241     putchar('\n');
242     }
243    
244    
245     getvec(vec, fmt, fp) /* get a vector from fp */
246     register FVECT vec;
247     int fmt;
248     FILE *fp;
249     {
250     static float vf[3];
251    
252     switch (fmt) {
253     case 'a': /* ascii */
254     if (fscanf(fp, "%lf %lf %lf", vec, vec+1, vec+2) != 3)
255     return(-1);
256     break;
257     case 'f': /* binary float */
258 greg 1.8 if (fread((char *)vf, sizeof(float), 3, fp) != 3)
259 greg 1.1 return(-1);
260     vec[0] = vf[0]; vec[1] = vf[1]; vec[2] = vf[2];
261     break;
262     case 'd': /* binary double */
263 greg 1.8 if (fread((char *)vec, sizeof(double), 3, fp) != 3)
264 greg 1.1 return(-1);
265     break;
266     }
267     return(0);
268     }
269    
270    
271     static
272     ourtrace(r) /* print ray values */
273     RAY *r;
274     {
275     register int (**tp)();
276    
277     if (every_out[0] == NULL)
278     return;
279     tabin(r);
280     for (tp = every_out; *tp != NULL; tp++)
281     (**tp)(r);
282     putchar('\n');
283     }
284    
285    
286     static
287     tabin(r) /* tab in appropriate amount */
288     RAY *r;
289     {
290     register RAY *rp;
291    
292     for (rp = r->parent; rp != NULL; rp = rp->parent)
293     putchar('\t');
294     }
295    
296    
297     static
298     oputo(r) /* print origin */
299     register RAY *r;
300     {
301     (*putreal)(r->rorg[0]);
302     (*putreal)(r->rorg[1]);
303     (*putreal)(r->rorg[2]);
304     }
305    
306    
307     static
308     oputd(r) /* print direction */
309     register RAY *r;
310     {
311     (*putreal)(r->rdir[0]);
312     (*putreal)(r->rdir[1]);
313     (*putreal)(r->rdir[2]);
314     }
315    
316    
317     static
318     oputv(r) /* print value */
319     register RAY *r;
320     {
321     (*putreal)(colval(r->rcol,RED));
322     (*putreal)(colval(r->rcol,GRN));
323     (*putreal)(colval(r->rcol,BLU));
324     }
325    
326    
327     static
328     oputl(r) /* print length */
329     register RAY *r;
330     {
331 greg 1.9 (*putreal)(r->rt);
332 greg 1.1 }
333    
334    
335     static
336     oputp(r) /* print point */
337     register RAY *r;
338     {
339     if (r->rot < FHUGE) {
340     (*putreal)(r->rop[0]);
341     (*putreal)(r->rop[1]);
342     (*putreal)(r->rop[2]);
343     } else {
344     (*putreal)(0.0);
345     (*putreal)(0.0);
346     (*putreal)(0.0);
347     }
348     }
349    
350    
351     static
352     oputn(r) /* print normal */
353     register RAY *r;
354     {
355     if (r->rot < FHUGE) {
356     (*putreal)(r->ron[0]);
357     (*putreal)(r->ron[1]);
358     (*putreal)(r->ron[2]);
359     } else {
360     (*putreal)(0.0);
361     (*putreal)(0.0);
362     (*putreal)(0.0);
363     }
364     }
365    
366    
367     static
368     oputs(r) /* print name */
369     register RAY *r;
370     {
371     if (r->ro != NULL)
372     fputs(r->ro->oname, stdout);
373     else
374     putchar('*');
375     putchar('\t');
376     }
377    
378    
379     static
380     oputw(r) /* print weight */
381     register RAY *r;
382     {
383     (*putreal)(r->rweight);
384     }
385    
386    
387     static
388     oputm(r) /* print modifier */
389     register RAY *r;
390     {
391     if (r->ro != NULL)
392     fputs(objptr(r->ro->omod)->oname, stdout);
393     else
394     putchar('*');
395     putchar('\t');
396     }
397    
398    
399     static
400     puta(v) /* print ascii value */
401     double v;
402     {
403     printf("%e\t", v);
404     }
405    
406    
407     static
408     putd(v) /* print binary double */
409     double v;
410     {
411 greg 1.8 fwrite((char *)&v, sizeof(v), 1, stdout);
412 greg 1.1 }
413    
414    
415     static
416     putf(v) /* print binary float */
417     double v;
418     {
419     float f = v;
420    
421 greg 1.8 fwrite((char *)&f, sizeof(f), 1, stdout);
422 greg 1.1 }