ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rtrace.c
Revision: 2.5
Committed: Thu Mar 12 09:46:19 1992 UTC (32 years, 1 month ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.4: +17 -4 lines
Log Message:
added -oL output option for single-ray length

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