ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rtrace.c
Revision: 1.12
Committed: Thu Mar 28 10:16:35 1991 UTC (33 years, 1 month ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.11: +25 -6 lines
Log Message:
added -oI option for irradiance after intersection

File Contents

# Content
1 /* Copyright (c) 1986 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 '-oi' or '-oI' 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 int inform = 'a'; /* input format */
34 int outform = 'a'; /* output format */
35 char *outvals = "v"; /* output specification */
36
37 int hresolu = 0; /* horizontal (scan) size */
38 int vresolu = 0; /* vertical resolution */
39
40 double dstrsrc = 0.0; /* square source distribution */
41 double shadthresh = .05; /* shadow threshold */
42 double shadcert = .5; /* shadow certainty */
43
44 int maxdepth = 6; /* maximum recursion depth */
45 double minweight = 4e-3; /* minimum ray weight */
46
47 COLOR ambval = BLKCOLOR; /* ambient value */
48 double ambacc = 0.2; /* ambient accuracy */
49 int ambres = 32; /* ambient resolution */
50 int ambdiv = 128; /* ambient divisions */
51 int ambssamp = 0; /* ambient super-samples */
52 int ambounce = 0; /* ambient bounces */
53 char *amblist[128]; /* ambient include/exclude list */
54 int ambincl = -1; /* include == 1, exclude == 0 */
55
56 static RAY thisray; /* for our convenience */
57
58 static int oputo(), oputd(), oputv(), oputl(),
59 oputp(), oputn(), oputs(), oputw(), oputm();
60
61 static int (*ray_out[10])(), (*every_out[10])();
62 static int castonly;
63
64 static int puta(), putf(), putd();
65
66 static int (*putreal)();
67
68 static double Lambfa[5] = {PI, PI, PI, 0.0, 0.0};
69 static OBJREC Lamb = {
70 OVOID, MAT_PLASTIC, "Lambertian",
71 {0, 5, NULL, Lambfa}, NULL, -1,
72 }; /* a Lambertian surface */
73
74
75 quit(code) /* quit program */
76 int code;
77 {
78 exit(code);
79 }
80
81
82 rtrace(fname) /* trace rays from file */
83 char *fname;
84 {
85 long vcount = hresolu>1 ? hresolu*vresolu : vresolu;
86 long nextflush = hresolu;
87 FILE *fp;
88 FVECT orig, direc;
89 /* set up input */
90 if (fname == NULL)
91 fp = stdin;
92 else if ((fp = fopen(fname, "r")) == NULL) {
93 sprintf(errmsg, "cannot open input file \"%s\"", fname);
94 error(SYSTEM, errmsg);
95 }
96 /* set up output */
97 setoutput(outvals);
98 switch (outform) {
99 case 'a': putreal = puta; break;
100 case 'f': putreal = putf; break;
101 case 'd': putreal = putd; break;
102 }
103 /* process file */
104 while (getvec(orig, inform, fp) == 0 &&
105 getvec(direc, inform, fp) == 0) {
106
107 if (normalize(direc) == 0.0) { /* zero ==> flush */
108 fflush(stdout);
109 continue;
110 }
111 /* compute and print */
112 if (outvals[0] == 'i')
113 irrad(orig, direc);
114 else if (outvals[0] == 'I')
115 Irrad(orig, direc);
116 else
117 radiance(orig, direc);
118 /* flush if time */
119 if (--nextflush == 0) {
120 fflush(stdout);
121 nextflush = hresolu;
122 }
123 if (ferror(stdout))
124 error(SYSTEM, "write error");
125 if (--vcount == 0) /* check for end */
126 break;
127 }
128 if (vcount > 0)
129 error(USER, "read error");
130 fclose(fp);
131 }
132
133
134 setoutput(vs) /* set up output tables */
135 register char *vs;
136 {
137 extern int ourtrace(), (*trace)();
138 register int (**table)() = ray_out;
139
140 castonly = 1;
141 while (*vs)
142 switch (*vs++) {
143 case 't': /* trace */
144 *table = NULL;
145 table = every_out;
146 trace = ourtrace;
147 castonly = 0;
148 break;
149 case 'o': /* origin */
150 *table++ = oputo;
151 break;
152 case 'd': /* direction */
153 *table++ = oputd;
154 break;
155 case 'v': /* value */
156 *table++ = oputv;
157 castonly = 0;
158 break;
159 case 'l': /* length */
160 *table++ = oputl;
161 castonly = 0;
162 break;
163 case 'p': /* point */
164 *table++ = oputp;
165 break;
166 case 'n': /* normal */
167 *table++ = oputn;
168 break;
169 case 's': /* surface */
170 *table++ = oputs;
171 break;
172 case 'w': /* weight */
173 *table++ = oputw;
174 break;
175 case 'm': /* modifier */
176 *table++ = oputm;
177 break;
178 }
179 *table = NULL;
180 }
181
182
183 radiance(org, dir) /* compute radiance value */
184 FVECT org, dir;
185 {
186 register int (**tp)();
187
188 VCOPY(thisray.rorg, org);
189 VCOPY(thisray.rdir, dir);
190 rayorigin(&thisray, NULL, PRIMARY, 1.0);
191 if (castonly)
192 localhit(&thisray, &thescene) || sourcehit(&thisray);
193 else
194 rayvalue(&thisray);
195
196 if (ray_out[0] == NULL)
197 return;
198 for (tp = ray_out; *tp != NULL; tp++)
199 (**tp)(&thisray);
200 if (outform == 'a')
201 putchar('\n');
202 }
203
204
205 irrad(org, dir) /* compute irradiance value */
206 FVECT org, dir;
207 {
208 register int i;
209
210 for (i = 0; i < 3; i++) {
211 thisray.rorg[i] = org[i] + dir[i];
212 thisray.rdir[i] = -dir[i];
213 }
214 rayorigin(&thisray, NULL, PRIMARY, 1.0);
215 /* pretend we hit surface */
216 thisray.rot = 1.0;
217 thisray.rod = 1.0;
218 VCOPY(thisray.ron, dir);
219 for (i = 0; i < 3; i++) /* fudge factor */
220 thisray.rop[i] = org[i] + 1e-4*dir[i];
221 /* compute and print */
222 (*ofun[Lamb.otype].funp)(&Lamb, &thisray);
223 oputv(&thisray);
224 if (outform == 'a')
225 putchar('\n');
226 }
227
228
229 Irrad(org, dir) /* compute irradiance value after intersection */
230 FVECT org, dir;
231 {
232 /* compute intersection */
233 VCOPY(thisray.rorg, org);
234 VCOPY(thisray.rdir, dir);
235 rayorigin(&thisray, NULL, PRIMARY, 1.0);
236 localhit(&thisray, &thescene);
237 if (thisray.ro != NULL) /* pretend we hit Lambertian surf. */
238 (*ofun[Lamb.otype].funp)(&Lamb, &thisray);
239 oputv(&thisray);
240 if (outform == 'a')
241 putchar('\n');
242 }
243
244
245 getvec(vec, fmt, fp) /* get a vector from fp */
246 register FVECT vec;
247 int fmt;
248 FILE *fp;
249 {
250 static float vf[3];
251
252 switch (fmt) {
253 case 'a': /* ascii */
254 if (fscanf(fp, "%lf %lf %lf", vec, vec+1, vec+2) != 3)
255 return(-1);
256 break;
257 case 'f': /* binary float */
258 if (fread((char *)vf, sizeof(float), 3, fp) != 3)
259 return(-1);
260 vec[0] = vf[0]; vec[1] = vf[1]; vec[2] = vf[2];
261 break;
262 case 'd': /* binary double */
263 if (fread((char *)vec, sizeof(double), 3, fp) != 3)
264 return(-1);
265 break;
266 }
267 return(0);
268 }
269
270
271 static
272 ourtrace(r) /* print ray values */
273 RAY *r;
274 {
275 register int (**tp)();
276
277 if (every_out[0] == NULL)
278 return;
279 tabin(r);
280 for (tp = every_out; *tp != NULL; tp++)
281 (**tp)(r);
282 putchar('\n');
283 }
284
285
286 static
287 tabin(r) /* tab in appropriate amount */
288 RAY *r;
289 {
290 register RAY *rp;
291
292 for (rp = r->parent; rp != NULL; rp = rp->parent)
293 putchar('\t');
294 }
295
296
297 static
298 oputo(r) /* print origin */
299 register RAY *r;
300 {
301 (*putreal)(r->rorg[0]);
302 (*putreal)(r->rorg[1]);
303 (*putreal)(r->rorg[2]);
304 }
305
306
307 static
308 oputd(r) /* print direction */
309 register RAY *r;
310 {
311 (*putreal)(r->rdir[0]);
312 (*putreal)(r->rdir[1]);
313 (*putreal)(r->rdir[2]);
314 }
315
316
317 static
318 oputv(r) /* print value */
319 register RAY *r;
320 {
321 (*putreal)(colval(r->rcol,RED));
322 (*putreal)(colval(r->rcol,GRN));
323 (*putreal)(colval(r->rcol,BLU));
324 }
325
326
327 static
328 oputl(r) /* print length */
329 register RAY *r;
330 {
331 (*putreal)(r->rt);
332 }
333
334
335 static
336 oputp(r) /* print point */
337 register RAY *r;
338 {
339 if (r->rot < FHUGE) {
340 (*putreal)(r->rop[0]);
341 (*putreal)(r->rop[1]);
342 (*putreal)(r->rop[2]);
343 } else {
344 (*putreal)(0.0);
345 (*putreal)(0.0);
346 (*putreal)(0.0);
347 }
348 }
349
350
351 static
352 oputn(r) /* print normal */
353 register RAY *r;
354 {
355 if (r->rot < FHUGE) {
356 (*putreal)(r->ron[0]);
357 (*putreal)(r->ron[1]);
358 (*putreal)(r->ron[2]);
359 } else {
360 (*putreal)(0.0);
361 (*putreal)(0.0);
362 (*putreal)(0.0);
363 }
364 }
365
366
367 static
368 oputs(r) /* print name */
369 register RAY *r;
370 {
371 if (r->ro != NULL)
372 fputs(r->ro->oname, stdout);
373 else
374 putchar('*');
375 putchar('\t');
376 }
377
378
379 static
380 oputw(r) /* print weight */
381 register RAY *r;
382 {
383 (*putreal)(r->rweight);
384 }
385
386
387 static
388 oputm(r) /* print modifier */
389 register RAY *r;
390 {
391 if (r->ro != NULL)
392 fputs(objptr(r->ro->omod)->oname, stdout);
393 else
394 putchar('*');
395 putchar('\t');
396 }
397
398
399 static
400 puta(v) /* print ascii value */
401 double v;
402 {
403 printf("%e\t", v);
404 }
405
406
407 static
408 putd(v) /* print binary double */
409 double v;
410 {
411 fwrite((char *)&v, sizeof(v), 1, stdout);
412 }
413
414
415 static
416 putf(v) /* print binary float */
417 double v;
418 {
419 float f = v;
420
421 fwrite((char *)&f, sizeof(f), 1, stdout);
422 }