ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rtrace.c
Revision: 2.12
Committed: Fri Jan 22 09:51:20 1993 UTC (31 years, 3 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.11: +8 -3 lines
Log Message:
bug fixes and improvements on stdio flushing

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