ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rtrace.c
Revision: 1.14
Committed: Tue May 21 17:41:23 1991 UTC (32 years, 11 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.13: +5 -0 lines
Log Message:
added stratified random sampling with urand

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