ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rtrace.c
Revision: 2.11
Committed: Wed Jan 20 15:19:51 1993 UTC (31 years, 3 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.10: +4 -0 lines
Log Message:
added -P and -PP persist options

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