ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rtrace.c
Revision: 2.18
Committed: Wed Dec 21 09:52:00 1994 UTC (29 years, 4 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.17: +2 -0 lines
Log Message:
added -bv option for back face visibility (normally on)

File Contents

# Content
1 /* Copyright (c) 1994 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 char *tralist[128]; /* list of modifers to trace (or no) */
46 int traincl = -1; /* include == 1, exclude == 0 */
47 #define MAXTSET 511 /* maximum number in trace set */
48 OBJECT traset[MAXTSET+1]={0}; /* trace include/exclude set */
49
50 int hresolu = 0; /* horizontal (scan) size */
51 int vresolu = 0; /* vertical resolution */
52
53 double dstrsrc = 0.0; /* square source distribution */
54 double shadthresh = .05; /* shadow threshold */
55 double shadcert = .5; /* shadow certainty */
56 int directrelay = 1; /* number of source relays */
57 int vspretest = 512; /* virtual source pretest density */
58 int directvis = 1; /* sources visible? */
59 double srcsizerat = .25; /* maximum ratio source size/dist. */
60
61 double specthresh = .15; /* specular sampling threshold */
62 double specjitter = 1.; /* specular sampling jitter */
63
64 int backvis = 1; /* back face visibility */
65
66 int maxdepth = 6; /* maximum recursion depth */
67 double minweight = 4e-3; /* minimum ray weight */
68
69 COLOR ambval = BLKCOLOR; /* ambient value */
70 double ambacc = 0.2; /* ambient accuracy */
71 int ambres = 32; /* ambient resolution */
72 int ambdiv = 128; /* ambient divisions */
73 int ambssamp = 0; /* ambient super-samples */
74 int ambounce = 0; /* ambient bounces */
75 char *amblist[128]; /* ambient include/exclude list */
76 int ambincl = -1; /* include == 1, exclude == 0 */
77
78 extern OBJREC Lamb; /* a Lambertian surface */
79
80 static RAY thisray; /* for our convenience */
81
82 static int oputo(), oputd(), oputv(), oputl(), oputL(),
83 oputp(), oputn(), oputN(), oputs(), oputw(), oputm();
84
85 static int ourtrace(), tabin();
86 static int (*ray_out[16])(), (*every_out[16])();
87 static int castonly = 0;
88
89 static int puta(), putf(), putd();
90
91 static int (*putreal)();
92
93
94 quit(code) /* quit program */
95 int code;
96 {
97 #ifndef NIX
98 headclean(); /* delete header file */
99 pfclean(); /* clean up persist files */
100 #endif
101 exit(code);
102 }
103
104
105 char *
106 formstr(f) /* return format identifier */
107 int f;
108 {
109 switch (f) {
110 case 'a': return("ascii");
111 case 'f': return("float");
112 case 'd': return("double");
113 case 'c': return(COLRFMT);
114 }
115 return("unknown");
116 }
117
118
119 rtrace(fname) /* trace rays from file */
120 char *fname;
121 {
122 long vcount = hresolu>1 ? hresolu*vresolu : vresolu;
123 long nextflush = hresolu;
124 FILE *fp;
125 FVECT orig, direc;
126 /* set up input */
127 if (fname == NULL)
128 fp = stdin;
129 else if ((fp = fopen(fname, "r")) == NULL) {
130 sprintf(errmsg, "cannot open input file \"%s\"", fname);
131 error(SYSTEM, errmsg);
132 }
133 #ifdef MSDOS
134 if (inform != 'a')
135 setmode(fileno(fp), O_BINARY);
136 #endif
137 /* set up output */
138 setoutput(outvals);
139 switch (outform) {
140 case 'a': putreal = puta; break;
141 case 'f': putreal = putf; break;
142 case 'd': putreal = putd; break;
143 case 'c':
144 if (strcmp(outvals, "v"))
145 error(USER, "color format with value output only");
146 break;
147 default:
148 error(CONSISTENCY, "botched output format");
149 }
150 if (hresolu > 0) {
151 if (vresolu > 0)
152 fprtresolu(hresolu, vresolu, stdout);
153 fflush(stdout);
154 }
155 /* process file */
156 while (getvec(orig, inform, fp) == 0 &&
157 getvec(direc, inform, fp) == 0) {
158
159 if (normalize(direc) == 0.0) { /* zero ==> flush */
160 fflush(stdout);
161 continue;
162 }
163 samplendx++;
164 /* compute and print */
165 if (imm_irrad)
166 irrad(orig, direc);
167 else
168 rad(orig, direc);
169 /* flush if time */
170 if (--nextflush == 0) {
171 fflush(stdout);
172 nextflush = hresolu;
173 }
174 if (ferror(stdout))
175 error(SYSTEM, "write error");
176 if (--vcount == 0) /* check for end */
177 break;
178 }
179 fflush(stdout);
180 if (vcount > 0)
181 error(USER, "read error");
182 if (fname != NULL)
183 fclose(fp);
184 }
185
186
187 setoutput(vs) /* set up output tables */
188 register char *vs;
189 {
190 extern int (*trace)();
191 register int (**table)() = ray_out;
192
193 castonly = 1;
194 while (*vs)
195 switch (*vs++) {
196 case 't': /* trace */
197 *table = NULL;
198 table = every_out;
199 trace = ourtrace;
200 castonly = 0;
201 break;
202 case 'o': /* origin */
203 *table++ = oputo;
204 break;
205 case 'd': /* direction */
206 *table++ = oputd;
207 break;
208 case 'v': /* value */
209 *table++ = oputv;
210 castonly = 0;
211 break;
212 case 'l': /* effective distance */
213 *table++ = oputl;
214 castonly = 0;
215 break;
216 case 'L': /* single ray length */
217 *table++ = oputL;
218 break;
219 case 'p': /* point */
220 *table++ = oputp;
221 break;
222 case 'n': /* perturbed normal */
223 *table++ = oputn;
224 castonly = 0;
225 break;
226 case 'N': /* unperturbed normal */
227 *table++ = oputN;
228 break;
229 case 's': /* surface */
230 *table++ = oputs;
231 break;
232 case 'w': /* weight */
233 *table++ = oputw;
234 break;
235 case 'm': /* modifier */
236 *table++ = oputm;
237 break;
238 }
239 *table = NULL;
240 }
241
242
243 rad(org, dir) /* compute and print ray value(s) */
244 FVECT org, dir;
245 {
246 VCOPY(thisray.rorg, org);
247 VCOPY(thisray.rdir, dir);
248 thisray.rmax = 0.0;
249 rayorigin(&thisray, NULL, PRIMARY, 1.0);
250 if (castonly)
251 localhit(&thisray, &thescene) || sourcehit(&thisray);
252 else
253 rayvalue(&thisray);
254 printvals(&thisray);
255 }
256
257
258 irrad(org, dir) /* compute immediate irradiance value */
259 FVECT org, dir;
260 {
261 register int i;
262
263 for (i = 0; i < 3; i++) {
264 thisray.rorg[i] = org[i] + dir[i];
265 thisray.rdir[i] = -dir[i];
266 }
267 rayorigin(&thisray, NULL, PRIMARY, 1.0);
268 /* pretend we hit surface */
269 thisray.rot = 1.0-1e-4;
270 thisray.rod = 1.0;
271 VCOPY(thisray.ron, dir);
272 for (i = 0; i < 3; i++) /* fudge factor */
273 thisray.rop[i] = org[i] + 1e-4*dir[i];
274 /* compute and print */
275 (*ofun[Lamb.otype].funp)(&Lamb, &thisray);
276 printvals(&thisray);
277 }
278
279
280 printvals(r) /* print requested ray values */
281 RAY *r;
282 {
283 register int (**tp)();
284
285 if (ray_out[0] == NULL)
286 return;
287 for (tp = ray_out; *tp != NULL; tp++)
288 (**tp)(r);
289 if (outform == 'a')
290 putchar('\n');
291 }
292
293
294 getvec(vec, fmt, fp) /* get a vector from fp */
295 register FVECT vec;
296 int fmt;
297 FILE *fp;
298 {
299 extern char *fgetword();
300 static float vf[3];
301 static double vd[3];
302 char buf[32];
303 register int i;
304
305 switch (fmt) {
306 case 'a': /* ascii */
307 for (i = 0; i < 3; i++) {
308 if (fgetword(buf, sizeof(buf), fp) == NULL ||
309 !isflt(buf))
310 return(-1);
311 vec[i] = atof(buf);
312 }
313 break;
314 case 'f': /* binary float */
315 if (fread((char *)vf, sizeof(float), 3, fp) != 3)
316 return(-1);
317 vec[0] = vf[0]; vec[1] = vf[1]; vec[2] = vf[2];
318 break;
319 case 'd': /* binary double */
320 if (fread((char *)vd, sizeof(double), 3, fp) != 3)
321 return(-1);
322 vec[0] = vd[0]; vec[1] = vd[1]; vec[2] = vd[2];
323 break;
324 default:
325 error(CONSISTENCY, "botched input format");
326 }
327 return(0);
328 }
329
330
331 tranotify(obj) /* record new modifier */
332 OBJECT obj;
333 {
334 static int hitlimit = 0;
335 register OBJREC *o = objptr(obj);
336 register char **tralp;
337
338 if (hitlimit || !ismodifier(o->otype))
339 return;
340 for (tralp = tralist; *tralp != NULL; tralp++)
341 if (!strcmp(o->oname, *tralp)) {
342 if (traset[0] >= MAXTSET) {
343 error(WARNING, "too many modifiers in trace list");
344 hitlimit++;
345 return; /* should this be fatal? */
346 }
347 insertelem(traset, obj);
348 return;
349 }
350 }
351
352
353 static
354 ourtrace(r) /* print ray values */
355 RAY *r;
356 {
357 register int (**tp)();
358
359 if (every_out[0] == NULL)
360 return;
361 if (r->ro == NULL) {
362 if (traincl == 1)
363 return;
364 } else if (traincl != -1 && traincl != inset(traset, r->ro->omod))
365 return;
366 tabin(r);
367 for (tp = every_out; *tp != NULL; tp++)
368 (**tp)(r);
369 putchar('\n');
370 }
371
372
373 static
374 tabin(r) /* tab in appropriate amount */
375 RAY *r;
376 {
377 register RAY *rp;
378
379 for (rp = r->parent; rp != NULL; rp = rp->parent)
380 putchar('\t');
381 }
382
383
384 static
385 oputo(r) /* print origin */
386 register RAY *r;
387 {
388 (*putreal)(r->rorg[0]);
389 (*putreal)(r->rorg[1]);
390 (*putreal)(r->rorg[2]);
391 }
392
393
394 static
395 oputd(r) /* print direction */
396 register RAY *r;
397 {
398 (*putreal)(r->rdir[0]);
399 (*putreal)(r->rdir[1]);
400 (*putreal)(r->rdir[2]);
401 }
402
403
404 static
405 oputv(r) /* print value */
406 register RAY *r;
407 {
408 COLR cout;
409
410 if (outform == 'c') {
411 setcolr(cout, colval(r->rcol,RED),
412 colval(r->rcol,GRN),
413 colval(r->rcol,BLU));
414 fwrite((char *)cout, sizeof(cout), 1, stdout);
415 return;
416 }
417 (*putreal)(colval(r->rcol,RED));
418 (*putreal)(colval(r->rcol,GRN));
419 (*putreal)(colval(r->rcol,BLU));
420 }
421
422
423 static
424 oputl(r) /* print effective distance */
425 register RAY *r;
426 {
427 (*putreal)(r->rt);
428 }
429
430
431 static
432 oputL(r) /* print single ray length */
433 register RAY *r;
434 {
435 (*putreal)(r->rot);
436 }
437
438
439 static
440 oputp(r) /* print point */
441 register RAY *r;
442 {
443 if (r->rot < FHUGE) {
444 (*putreal)(r->rop[0]);
445 (*putreal)(r->rop[1]);
446 (*putreal)(r->rop[2]);
447 } else {
448 (*putreal)(0.0);
449 (*putreal)(0.0);
450 (*putreal)(0.0);
451 }
452 }
453
454
455 static
456 oputN(r) /* print unperturbed normal */
457 register RAY *r;
458 {
459 if (r->rot < FHUGE) {
460 (*putreal)(r->ron[0]);
461 (*putreal)(r->ron[1]);
462 (*putreal)(r->ron[2]);
463 } else {
464 (*putreal)(0.0);
465 (*putreal)(0.0);
466 (*putreal)(0.0);
467 }
468 }
469
470
471 static
472 oputn(r) /* print perturbed normal */
473 RAY *r;
474 {
475 FVECT pnorm;
476
477 if (r->rot >= FHUGE) {
478 (*putreal)(0.0);
479 (*putreal)(0.0);
480 (*putreal)(0.0);
481 return;
482 }
483 raynormal(pnorm, r);
484 (*putreal)(pnorm[0]);
485 (*putreal)(pnorm[1]);
486 (*putreal)(pnorm[2]);
487 }
488
489
490 static
491 oputs(r) /* print name */
492 register RAY *r;
493 {
494 if (r->ro != NULL)
495 fputs(r->ro->oname, stdout);
496 else
497 putchar('*');
498 putchar('\t');
499 }
500
501
502 static
503 oputw(r) /* print weight */
504 register RAY *r;
505 {
506 (*putreal)(r->rweight);
507 }
508
509
510 static
511 oputm(r) /* print modifier */
512 register RAY *r;
513 {
514 if (r->ro != NULL)
515 fputs(objptr(r->ro->omod)->oname, stdout);
516 else
517 putchar('*');
518 putchar('\t');
519 }
520
521
522 static
523 puta(v) /* print ascii value */
524 double v;
525 {
526 printf("%e\t", v);
527 }
528
529
530 static
531 putd(v) /* print binary double */
532 double v;
533 {
534 fwrite((char *)&v, sizeof(v), 1, stdout);
535 }
536
537
538 static
539 putf(v) /* print binary float */
540 double v;
541 {
542 float f = v;
543
544 fwrite((char *)&f, sizeof(f), 1, stdout);
545 }