ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rtrace.c
Revision: 2.20
Committed: Fri Dec 8 18:49:12 1995 UTC (28 years, 4 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.19: +6 -1 lines
Log Message:
added M_MIST (mist) material and global participating medium

File Contents

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