ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rtrace.c
Revision: 2.14
Committed: Tue May 4 13:26:52 1993 UTC (31 years ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.13: +6 -3 lines
Log Message:
made sure that -I option completely overrides -o option

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