ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rtrace.c
Revision: 2.5
Committed: Thu Mar 12 09:46:19 1992 UTC (32 years, 1 month ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.4: +17 -4 lines
Log Message:
added -oL output option for single-ray length

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