ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rv2.c
Revision: 1.25
Committed: Fri Jul 19 15:22:02 1991 UTC (32 years, 9 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.24: +5 -1 lines
Log Message:
made boolean parameter setting more forgiving

File Contents

# Content
1 /* Copyright (c) 1987 Regents of the University of California */
2
3 #ifndef lint
4 static char SCCSid[] = "$SunId$ LBL";
5 #endif
6
7 /*
8 * rv2.c - command routines used in tracing a view.
9 *
10 * 3/24/87
11 */
12
13 #include "ray.h"
14
15 #include "octree.h"
16
17 #include "otypes.h"
18
19 #include "rpaint.h"
20
21 #include <ctype.h>
22
23 #define CTRL(c) ('c'-'@')
24
25 extern char *progname;
26
27
28 getframe(s) /* get a new frame */
29 char *s;
30 {
31 if (getrect(s, &pframe) < 0)
32 return;
33 pdepth = 0;
34 }
35
36
37 getrepaint(s) /* get area and repaint */
38 char *s;
39 {
40 RECT box;
41
42 if (getrect(s, &box) < 0)
43 return;
44 paintrect(&ptrunk, 0, 0, hresolu, vresolu, &box);
45 }
46
47
48 getview(s) /* get/show view parameters */
49 char *s;
50 {
51 FILE *fp;
52 char buf[128];
53 char *fname;
54 int change = 0;
55 VIEW nv;
56
57 if (sscanf(s, "%s", buf) == 1) { /* write parameters to a file */
58 if ((fname = getpath(buf, NULL, 0)) == NULL ||
59 (fp = fopen(fname, "a")) == NULL) {
60 sprintf(errmsg, "cannot open \"%s\"", buf);
61 error(COMMAND, errmsg);
62 return;
63 }
64 fputs(progname, fp);
65 fprintview(&ourview, fp);
66 fputs(sskip(s), fp);
67 fputs("\n", fp);
68 fclose(fp);
69 return;
70 }
71 sprintf(buf, "view type (%c): ", ourview.type);
72 (*dev->comout)(buf);
73 (*dev->comin)(buf, NULL);
74 if (buf[0] == CTRL(C)) return;
75 if (buf[0] && buf[0] != ourview.type) {
76 nv.type = buf[0];
77 change++;
78 } else
79 nv.type = ourview.type;
80 sprintf(buf, "view point (%.6g %.6g %.6g): ",
81 ourview.vp[0], ourview.vp[1], ourview.vp[2]);
82 (*dev->comout)(buf);
83 (*dev->comin)(buf, NULL);
84 if (buf[0] == CTRL(C)) return;
85 if (sscanf(buf, "%lf %lf %lf", &nv.vp[0], &nv.vp[1], &nv.vp[2]) == 3)
86 change++;
87 else
88 VCOPY(nv.vp, ourview.vp);
89 sprintf(buf, "view direction (%.6g %.6g %.6g): ",
90 ourview.vdir[0], ourview.vdir[1], ourview.vdir[2]);
91 (*dev->comout)(buf);
92 (*dev->comin)(buf, NULL);
93 if (buf[0] == CTRL(C)) return;
94 if (sscanf(buf,"%lf %lf %lf",&nv.vdir[0],&nv.vdir[1],&nv.vdir[2]) == 3)
95 change++;
96 else
97 VCOPY(nv.vdir, ourview.vdir);
98 sprintf(buf, "view up (%.6g %.6g %.6g): ",
99 ourview.vup[0], ourview.vup[1], ourview.vup[2]);
100 (*dev->comout)(buf);
101 (*dev->comin)(buf, NULL);
102 if (buf[0] == CTRL(C)) return;
103 if (sscanf(buf,"%lf %lf %lf",&nv.vup[0],&nv.vup[1],&nv.vup[2]) == 3)
104 change++;
105 else
106 VCOPY(nv.vup, ourview.vup);
107 sprintf(buf, "view horiz and vert size (%.6g %.6g): ",
108 ourview.horiz, ourview.vert);
109 (*dev->comout)(buf);
110 (*dev->comin)(buf, NULL);
111 if (buf[0] == CTRL(C)) return;
112 if (sscanf(buf, "%lf %lf", &nv.horiz, &nv.vert) == 2)
113 change++;
114 else {
115 nv.horiz = ourview.horiz; nv.vert = ourview.vert;
116 }
117 sprintf(buf, "view shift and lift (%.6g %.6g): ",
118 ourview.hoff, ourview.voff);
119 (*dev->comout)(buf);
120 (*dev->comin)(buf, NULL);
121 if (buf[0] == CTRL(C)) return;
122 if (sscanf(buf, "%lf %lf", &nv.hoff, &nv.voff) == 2)
123 change++;
124 else {
125 nv.hoff = ourview.hoff; nv.voff = ourview.voff;
126 }
127 if (change)
128 newview(&nv);
129 }
130
131
132 lastview(s) /* return to a previous view */
133 char *s;
134 {
135 char buf[128];
136 char *fname;
137 int success;
138 VIEW nv;
139
140 if (sscanf(s, "%s", buf) == 1) { /* get parameters from a file */
141 copystruct(&nv, &stdview);
142 if ((fname = getpath(buf, NULL, 0)) == NULL ||
143 (success = viewfile(fname, &nv, 0, 0)) == -1) {
144 sprintf(errmsg, "cannot open \"%s\"", buf);
145 error(COMMAND, errmsg);
146 return;
147 }
148 if (!success)
149 error(COMMAND, "wrong file format");
150 else
151 newview(&nv);
152 return;
153 }
154 if (oldview.type == 0) { /* no old view! */
155 error(COMMAND, "no previous view");
156 return;
157 }
158 copystruct(&nv, &ourview);
159 copystruct(&ourview, &oldview);
160 copystruct(&oldview, &nv);
161 newimage();
162 }
163
164
165 getaim(s) /* aim camera */
166 char *s;
167 {
168 extern double tan(), atan();
169 double zfact;
170 VIEW nv;
171
172 if (getinterest(s, 1, nv.vdir, &zfact) < 0)
173 return;
174 nv.type = ourview.type;
175 VCOPY(nv.vp, ourview.vp);
176 VCOPY(nv.vup, ourview.vup);
177 nv.hoff = ourview.hoff; nv.voff = ourview.voff;
178 nv.horiz = ourview.horiz; nv.vert = ourview.vert;
179 zoomview(&nv, zfact);
180 newview(&nv);
181 }
182
183
184 getmove(s) /* move camera */
185 char *s;
186 {
187 FVECT vc;
188 double mag;
189
190 if (getinterest(s, 0, vc, &mag) < 0)
191 return;
192 moveview(0.0, 0.0, mag, vc);
193 }
194
195
196 getrotate(s) /* rotate camera */
197 char *s;
198 {
199 extern double normalize(), tan(), atan();
200 VIEW nv;
201 FVECT v1;
202 double angle, elev, zfact;
203
204 elev = 0.0; zfact = 1.0;
205 if (sscanf(s, "%lf %lf %lf", &angle, &elev, &zfact) < 1) {
206 error(COMMAND, "missing angle");
207 return;
208 }
209 nv.type = ourview.type;
210 VCOPY(nv.vp, ourview.vp);
211 VCOPY(nv.vup, ourview.vup);
212 nv.hoff = ourview.hoff; nv.voff = ourview.voff;
213 spinvector(nv.vdir, ourview.vdir, ourview.vup, angle*(PI/180.));
214 if (elev != 0.0) {
215 fcross(v1, nv.vdir, ourview.vup);
216 normalize(v1);
217 spinvector(nv.vdir, nv.vdir, v1, elev*(PI/180.));
218 }
219 nv.horiz = ourview.horiz; nv.vert = ourview.vert;
220 zoomview(&nv, zfact);
221 newview(&nv);
222 }
223
224
225 getpivot(s) /* pivot viewpoint */
226 register char *s;
227 {
228 FVECT vc;
229 double angle, elev, mag;
230
231 elev = 0.0;
232 if (sscanf(s, "%lf %lf", &angle, &elev) < 1) {
233 error(COMMAND, "missing angle");
234 return;
235 }
236 if (getinterest(sskip(sskip(s)), 0, vc, &mag) < 0)
237 return;
238 moveview(angle, elev, mag, vc);
239 }
240
241
242 getexposure(s) /* get new exposure */
243 char *s;
244 {
245 double atof(), pow(), fabs();
246 char buf[128];
247 register char *cp;
248 register PNODE *p;
249 RECT r;
250 int x, y;
251 double e;
252
253 for (cp = s; isspace(*cp); cp++)
254 ;
255 if (*cp == '\0') { /* normalize to point */
256 if (dev->getcur == NULL)
257 return;
258 (*dev->comout)("Pick point for exposure\n");
259 if ((*dev->getcur)(&x, &y) == ABORT)
260 return;
261 r.l = r.d = 0;
262 r.r = hresolu; r.u = vresolu;
263 p = findrect(x, y, &ptrunk, &r, -1);
264 e = 1.0;
265 } else {
266 if (*cp == '=') { /* absolute setting */
267 p = NULL;
268 e = 1.0/exposure;
269 for (cp++; isspace(*cp); cp++)
270 ;
271 if (*cp == '\0') { /* interactive */
272 sprintf(buf, "exposure (%lf): ", exposure);
273 (*dev->comout)(buf);
274 (*dev->comin)(buf, NULL);
275 for (cp = buf; isspace(*cp); cp++)
276 ;
277 if (*cp == '\0')
278 return;
279 }
280 } else { /* normalize to average */
281 p = &ptrunk;
282 e = 1.0;
283 }
284 if (*cp == '+' || *cp == '-') /* f-stops */
285 e *= pow(2.0, atof(cp));
286 else /* multiplier */
287 e *= atof(cp);
288 }
289 if (p != NULL) { /* relative setting */
290 if (bright(p->v) <= FTINY) {
291 error(COMMAND, "cannot normalize to zero");
292 return;
293 }
294 e *= 0.5 / bright(p->v);
295 }
296 if (e <= FTINY || fabs(1.0 - e) <= FTINY)
297 return;
298 scalepict(&ptrunk, e);
299 exposure *= e;
300 redraw();
301 }
302
303
304 getparam(str, dsc, typ, ptr) /* get variable from user */
305 char *str, *dsc;
306 int typ;
307 register union {int i; double d; COLOR C;} *ptr;
308 {
309 extern char *index();
310 int i0;
311 double d0, d1, d2;
312 char buf[48];
313
314 switch (typ) {
315 case 'i': /* integer */
316 if (sscanf(str, "%d", &i0) != 1) {
317 (*dev->comout)(dsc);
318 sprintf(buf, " (%d): ", ptr->i);
319 (*dev->comout)(buf);
320 (*dev->comin)(buf, NULL);
321 if (sscanf(buf, "%d", &i0) != 1)
322 break;
323 }
324 ptr->i = i0;
325 break;
326 case 'r': /* real */
327 if (sscanf(str, "%lf", &d0) != 1) {
328 (*dev->comout)(dsc);
329 sprintf(buf, " (%.6g): ", ptr->d);
330 (*dev->comout)(buf);
331 (*dev->comin)(buf, NULL);
332 if (sscanf(buf, "%lf", &d0) != 1)
333 break;
334 }
335 ptr->d = d0;
336 break;
337 case 'b': /* boolean */
338 if (sscanf(str, "%1s", buf) != 1) {
339 (*dev->comout)(dsc);
340 sprintf(buf, " (%c): ", ptr->i ? 'y' : 'n');
341 (*dev->comout)(buf);
342 (*dev->comin)(buf, NULL);
343 if (buf[0] == '\0' ||
344 index("yY+1tTnN-0fF", buf[0]) == NULL)
345 break;
346 }
347 ptr->i = index("yY+1tT", buf[0]) != NULL;
348 break;
349 case 'C': /* color */
350 if (sscanf(str, "%lf %lf %lf", &d0, &d1, &d2) != 3) {
351 (*dev->comout)(dsc);
352 sprintf(buf, " (%.6g %.6g %.6g): ",
353 colval(ptr->C,RED),
354 colval(ptr->C,GRN),
355 colval(ptr->C,BLU));
356 (*dev->comout)(buf);
357 (*dev->comin)(buf, NULL);
358 if (sscanf(buf, "%lf %lf %lf", &d0, &d1, &d2) != 3)
359 break;
360 }
361 setcolor(ptr->C, d0, d1, d2);
362 break;
363 }
364 }
365
366
367 setparam(s) /* get/set program parameter */
368 register char *s;
369 {
370 extern int psample;
371 extern double maxdiff;
372 extern double minweight;
373 extern int maxdepth;
374 extern double dstrsrc;
375 extern double shadthresh;
376 extern double shadcert;
377 extern COLOR ambval;
378 extern double ambacc;
379 extern double minarad;
380 extern int ambres;
381 extern int ambdiv;
382 extern int ambssamp;
383 extern int ambounce;
384 extern int directinvis;
385 extern int do_irrad;
386 char buf[128];
387
388 if (s[0] == '\0') {
389 (*dev->comout)(
390 "aa ab ad ar as av b dc di dj dt i lr lw sp st: ");
391 (*dev->comin)(buf, NULL);
392 s = buf;
393 }
394 switch (s[0]) {
395 case 'l': /* limit */
396 switch (s[1]) {
397 case 'w': /* weight */
398 getparam(s+2, "limit weight", 'r', &minweight);
399 break;
400 case 'r': /* reflection */
401 getparam(s+2, "limit reflection", 'i', &maxdepth);
402 break;
403 default:
404 goto badparam;
405 }
406 break;
407 case 'd': /* direct */
408 switch (s[1]) {
409 case 'j': /* jitter */
410 getparam(s+2, "direct jitter", 'r', &dstrsrc);
411 break;
412 case 'c': /* certainty */
413 getparam(s+2, "direct certainty", 'r', &shadcert);
414 break;
415 case 't': /* threshold */
416 getparam(s+2, "direct threshold", 'r', &shadthresh);
417 break;
418 case 'i': /* invisibility */
419 getparam(s+2, "direct invisibility",
420 'b', &directinvis);
421 break;
422 default:
423 goto badparam;
424 }
425 break;
426 case 'b': /* black and white */
427 getparam(s+1, "black and white", 'b', &greyscale);
428 break;
429 case 'i': /* irradiance */
430 getparam(s+1, "irradiance", 'b', &do_irrad);
431 break;
432 case 'a': /* ambient */
433 switch (s[1]) {
434 case 'v': /* value */
435 getparam(s+2, "ambient value", 'C', ambval);
436 break;
437 case 'a': /* accuracy */
438 getparam(s+2, "ambient accuracy", 'r', &ambacc);
439 break;
440 case 'd': /* divisions */
441 getparam(s+2, "ambient divisions", 'i', &ambdiv);
442 break;
443 case 's': /* samples */
444 getparam(s+2, "ambient super-samples", 'i', &ambssamp);
445 break;
446 case 'b': /* bounces */
447 getparam(s+2, "ambient bounces", 'i', &ambounce);
448 break;
449 case 'r':
450 getparam(s+2, "ambient resolution", 'i', &ambres);
451 minarad = ambres > 0 ? thescene.cusize/ambres : 0.0;
452 break;
453 default:
454 goto badparam;
455 }
456 break;
457 case 's': /* sample */
458 switch (s[1]) {
459 case 'p': /* pixel */
460 getparam(s+2, "sample pixel", 'i', &psample);
461 pdepth = 0;
462 break;
463 case 't': /* threshold */
464 getparam(s+2, "sample threshold", 'r', &maxdiff);
465 pdepth = 0;
466 break;
467 default:
468 goto badparam;
469 }
470 break;
471 case '\0': /* nothing */
472 break;
473 default:;
474 badparam:
475 sprintf(errmsg, "%s: unknown variable", s);
476 error(COMMAND, errmsg);
477 break;
478 }
479 }
480
481
482 traceray(s) /* trace a single ray */
483 char *s;
484 {
485 char buf[128];
486 int x, y;
487 RAY thisray;
488
489 if (sscanf(s, "%lf %lf %lf %lf %lf %lf",
490 &thisray.rorg[0], &thisray.rorg[1], &thisray.rorg[2],
491 &thisray.rdir[0], &thisray.rdir[1], &thisray.rdir[2]) != 6) {
492
493 if (dev->getcur == NULL)
494 return;
495 (*dev->comout)("Pick ray\n");
496 if ((*dev->getcur)(&x, &y) == ABORT)
497 return;
498
499 if (viewray(thisray.rorg, thisray.rdir, &ourview,
500 (x+.5)/hresolu, (y+.5)/vresolu) < 0) {
501 error(COMMAND, "not on image");
502 return;
503 }
504
505 } else if (normalize(thisray.rdir) == 0.0) {
506 error(COMMAND, "zero ray direction");
507 return;
508 }
509
510 rayorigin(&thisray, NULL, PRIMARY, 1.0);
511
512 rayvalue(&thisray);
513
514 if (thisray.ro == NULL)
515 (*dev->comout)("ray hit nothing");
516 else {
517 sprintf(buf, "ray hit %s %s \"%s\"",
518 objptr(thisray.ro->omod)->oname,
519 ofun[thisray.ro->otype].funame,
520 thisray.ro->oname);
521 (*dev->comout)(buf);
522 (*dev->comin)(buf, NULL);
523 if (thisray.rot >= FHUGE)
524 (*dev->comout)("at infinity");
525 else {
526 sprintf(buf, "at (%.6g %.6g %.6g)", thisray.rop[0],
527 thisray.rop[1], thisray.rop[2]);
528 (*dev->comout)(buf);
529 }
530 (*dev->comin)(buf, NULL);
531 sprintf(buf, "with value (%.6g %.6g %.6g)",
532 colval(thisray.rcol,RED),
533 colval(thisray.rcol,GRN),
534 colval(thisray.rcol,BLU));
535 (*dev->comout)(buf);
536 }
537 (*dev->comin)(buf, NULL);
538 }
539
540
541 writepict(s) /* write the picture to a file */
542 char *s;
543 {
544 static char buf[128];
545 char *fname;
546 FILE *fp;
547 COLR *scanline;
548 int y;
549
550 if (sscanf(s, "%s", buf) != 1 && buf[0] == '\0') {
551 error(COMMAND, "no file");
552 return;
553 }
554 if ((fname = getpath(buf, NULL, 0)) == NULL ||
555 (fp = fopen(fname, "w")) == NULL) {
556 sprintf(errmsg, "cannot open \"%s\"", buf);
557 error(COMMAND, errmsg);
558 return;
559 }
560 (*dev->comout)("writing \"");
561 (*dev->comout)(fname);
562 (*dev->comout)("\"...\n");
563 /* write header */
564 fputs(progname, fp);
565 fprintview(&ourview, fp);
566 putc('\n', fp);
567 if (exposure != 1.0)
568 fputexpos(exposure, fp);
569 if (dev->pixaspect != 1.0)
570 fputaspect(dev->pixaspect, fp);
571 fputformat(COLRFMT, fp);
572 putc('\n', fp);
573 fputresolu(YMAJOR|YDECR, hresolu, vresolu, fp);
574
575 scanline = (COLR *)malloc(hresolu*sizeof(COLR));
576 if (scanline == NULL)
577 error(SYSTEM, "out of memory in writepict");
578 for (y = vresolu-1; y >= 0; y--) {
579 getpictcolrs(y, scanline, &ptrunk, hresolu, vresolu);
580 if (fwritecolrs(scanline, hresolu, fp) < 0)
581 break;
582 }
583 if (fclose(fp) < 0)
584 error(COMMAND, "write error");
585 free((char *)scanline);
586 }