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

# Content
1 /* Copyright (c) 1992 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 * If the direction vector is (0,0,0), then the output is flushed.
20 * 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 * radiance is computed. The '-i' or '-I' options indicate that
24 * irradiance values are desired.
25 */
26
27 #include "ray.h"
28
29 #include "octree.h"
30
31 #include "otypes.h"
32
33 #include "resolu.h"
34
35 int dimlist[MAXDIM]; /* sampling dimensions */
36 int ndims = 0; /* number of sampling dimensions */
37 int samplendx = 0; /* index for this sample */
38
39 int imm_irrad = 0; /* compute immediate irradiance? */
40
41 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 double shadthresh = .05; /* shadow threshold */
50 double shadcert = .5; /* shadow certainty */
51 int directrelay = 1; /* number of source relays */
52 int vspretest = 512; /* virtual source pretest density */
53 int directvis = 1; /* sources visible? */
54 double srcsizerat = .25; /* maximum ratio source size/dist. */
55
56 double specthresh = .15; /* specular sampling threshold */
57 double specjitter = 1.; /* specular sampling jitter */
58
59 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 int ambres = 32; /* ambient resolution */
65 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 extern OBJREC Lamb; /* a Lambertian surface */
72
73 static RAY thisray; /* for our convenience */
74
75 static int oputo(), oputd(), oputv(), oputl(), oputL(),
76 oputp(), oputn(), oputN(), oputs(), oputw(), oputm();
77
78 static int (*ray_out[10])(), (*every_out[10])();
79 static int castonly;
80
81 static int puta(), putf(), putd();
82
83 static int (*putreal)();
84
85
86 quit(code) /* quit program */
87 int code;
88 {
89 #ifndef NIX
90 headclean(); /* delete header file */
91 pfclean(); /* clean up persist files */
92 #endif
93 exit(code);
94 }
95
96
97 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 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 FVECT orig, direc;
118 /* 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 #ifdef MSDOS
126 if (inform != 'a')
127 setmode(fileno(fp), O_BINARY);
128 #endif
129 /* 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 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 }
142 if (hresolu > 0) {
143 if (vresolu > 0)
144 fprtresolu(hresolu, vresolu, stdout);
145 fflush(stdout);
146 }
147 /* process file */
148 while (getvec(orig, inform, fp) == 0 &&
149 getvec(direc, inform, fp) == 0) {
150
151 if (normalize(direc) == 0.0) { /* zero ==> flush */
152 fflush(stdout);
153 continue;
154 }
155 samplendx++;
156 /* compute and print */
157 if (imm_irrad)
158 irrad(orig, direc);
159 else
160 traceray(orig, direc);
161 /* flush if time */
162 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 fflush(stdout);
172 if (vcount > 0)
173 error(USER, "read error");
174 if (fname != NULL)
175 fclose(fp);
176 }
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 castonly = 1;
186 while (*vs)
187 switch (*vs++) {
188 case 't': /* trace */
189 *table = NULL;
190 table = every_out;
191 trace = ourtrace;
192 castonly = 0;
193 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 castonly = 0;
203 break;
204 case 'l': /* effective distance */
205 *table++ = oputl;
206 castonly = 0;
207 break;
208 case 'L': /* single ray length */
209 *table++ = oputL;
210 break;
211 case 'p': /* point */
212 *table++ = oputp;
213 break;
214 case 'n': /* perturbed normal */
215 *table++ = oputn;
216 castonly = 0;
217 break;
218 case 'N': /* unperturbed normal */
219 *table++ = oputN;
220 break;
221 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 traceray(org, dir) /* compute and print ray value(s) */
236 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 if (castonly)
244 localhit(&thisray, &thescene) || sourcehit(&thisray);
245 else
246 rayvalue(&thisray);
247
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 irrad(org, dir) /* compute immediate irradiance value */
258 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 extern char *fgetword();
287 static float vf[3];
288 static double vd[3];
289 char buf[32];
290 register int i;
291
292 switch (fmt) {
293 case 'a': /* ascii */
294 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 break;
301 case 'f': /* binary float */
302 if (fread((char *)vf, sizeof(float), 3, fp) != 3)
303 return(-1);
304 vec[0] = vf[0]; vec[1] = vf[1]; vec[2] = vf[2];
305 break;
306 case 'd': /* binary double */
307 if (fread((char *)vd, sizeof(double), 3, fp) != 3)
308 return(-1);
309 vec[0] = vd[0]; vec[1] = vd[1]; vec[2] = vd[2];
310 break;
311 default:
312 error(CONSISTENCY, "botched input format");
313 }
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 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 (*putreal)(colval(r->rcol,RED));
378 (*putreal)(colval(r->rcol,GRN));
379 (*putreal)(colval(r->rcol,BLU));
380 }
381
382
383 static
384 oputl(r) /* print effective distance */
385 register RAY *r;
386 {
387 (*putreal)(r->rt);
388 }
389
390
391 static
392 oputL(r) /* print single ray length */
393 register RAY *r;
394 {
395 (*putreal)(r->rot);
396 }
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 oputN(r) /* print unperturbed normal */
417 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 }
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 }
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 fwrite((char *)&v, sizeof(v), 1, stdout);
495 }
496
497
498 static
499 putf(v) /* print binary float */
500 double v;
501 {
502 float f = v;
503
504 fwrite((char *)&f, sizeof(f), 1, stdout);
505 }