ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rtrace.c
Revision: 1.20
Committed: Mon Oct 21 12:58:10 1991 UTC (32 years, 6 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.19: +2 -1 lines
Log Message:
added source sampling (-ds option)

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