ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rv2.c
Revision: 1.9
Committed: Tue Jun 13 10:57:45 1989 UTC (34 years, 10 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.8: +15 -1 lines
Log Message:
Added direct certainty variable (compromise btwn. thresh. & tol.)

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 int x0, y0, x1, y1;
32
33 if (!strcmp("all", s)) {
34 pframe.l = pframe.d = 0;
35 pframe.r = ourview.hresolu;
36 pframe.u = ourview.vresolu;
37 pdepth = 0;
38 return;
39 }
40 if (sscanf(s, "%d %d %d %d", &x0, &y0, &x1, &y1) != 4) {
41 if (dev->getcur == NULL)
42 return;
43 (*dev->comout)("Pick first corner\n");
44 if ((*dev->getcur)(&x0, &y0) == ABORT)
45 return;
46 (*dev->comout)("Pick second corner\n");
47 if ((*dev->getcur)(&x1, &y1) == ABORT)
48 return;
49 }
50 if (x0 < x1) {
51 pframe.l = x0;
52 pframe.r = x1;
53 } else {
54 pframe.l = x1;
55 pframe.r = x0;
56 }
57 if (y0 < y1) {
58 pframe.d = y0;
59 pframe.u = y1;
60 } else {
61 pframe.d = y1;
62 pframe.u = y0;
63 }
64 if (pframe.l < 0) pframe.l = 0;
65 if (pframe.d < 0) pframe.d = 0;
66 if (pframe.r > ourview.hresolu) pframe.r = ourview.hresolu;
67 if (pframe.u > ourview.vresolu) pframe.u = ourview.vresolu;
68 if (pframe.l > pframe.r) pframe.l = pframe.r;
69 if (pframe.d > pframe.u) pframe.d = pframe.u;
70 pdepth = 0;
71 }
72
73
74 getview(s) /* get/show view parameters */
75 char *s;
76 {
77 FILE *fp;
78 char buf[128];
79 char *fname, *getpath();
80 int change = 0;
81 VIEW nv;
82
83 if (sscanf(s, "%s", buf) == 1) { /* write parameters to a file */
84 if ((fname = getpath(buf, NULL)) == NULL ||
85 (fp = fopen(fname, "a")) == NULL) {
86 sprintf(errmsg, "cannot open \"%s\"", buf);
87 error(COMMAND, errmsg);
88 return;
89 }
90 fputs(progname, fp);
91 fprintview(&ourview, fp);
92 fputs("\n", fp);
93 fclose(fp);
94 return;
95 }
96 sprintf(buf, "view type (%c): ", ourview.type);
97 (*dev->comout)(buf);
98 (*dev->comin)(buf);
99 if (buf[0] == CTRL(C)) return;
100 if (buf[0] && buf[0] != ourview.type) {
101 nv.type = buf[0];
102 change++;
103 } else
104 nv.type = ourview.type;
105 sprintf(buf, "view point (%.6g %.6g %.6g): ",
106 ourview.vp[0], ourview.vp[1], ourview.vp[2]);
107 (*dev->comout)(buf);
108 (*dev->comin)(buf);
109 if (buf[0] == CTRL(C)) return;
110 if (sscanf(buf, "%lf %lf %lf", &nv.vp[0], &nv.vp[1], &nv.vp[2]) == 3)
111 change++;
112 else
113 VCOPY(nv.vp, ourview.vp);
114 sprintf(buf, "view direction (%.6g %.6g %.6g): ",
115 ourview.vdir[0], ourview.vdir[1], ourview.vdir[2]);
116 (*dev->comout)(buf);
117 (*dev->comin)(buf);
118 if (buf[0] == CTRL(C)) return;
119 if (sscanf(buf,"%lf %lf %lf",&nv.vdir[0],&nv.vdir[1],&nv.vdir[2]) == 3)
120 change++;
121 else
122 VCOPY(nv.vdir, ourview.vdir);
123 sprintf(buf, "view up (%.6g %.6g %.6g): ",
124 ourview.vup[0], ourview.vup[1], ourview.vup[2]);
125 (*dev->comout)(buf);
126 (*dev->comin)(buf);
127 if (buf[0] == CTRL(C)) return;
128 if (sscanf(buf,"%lf %lf %lf",&nv.vup[0],&nv.vup[1],&nv.vup[2]) == 3)
129 change++;
130 else
131 VCOPY(nv.vup, ourview.vup);
132 sprintf(buf, "view horiz and vert size (%.6g %.6g): ",
133 ourview.horiz, ourview.vert);
134 (*dev->comout)(buf);
135 (*dev->comin)(buf);
136 if (buf[0] == CTRL(C)) return;
137 if (sscanf(buf, "%lf %lf", &nv.horiz, &nv.vert) == 2)
138 change++;
139 else {
140 nv.horiz = ourview.horiz; nv.vert = ourview.vert;
141 }
142 sprintf(buf, "x and y resolution (%d %d): ",
143 ourview.hresolu, ourview.vresolu);
144 (*dev->comout)(buf);
145 (*dev->comin)(buf);
146 if (buf[0] == CTRL(C)) return;
147 if (sscanf(buf, "%d %d", &nv.hresolu, &nv.vresolu) == 2)
148 change++;
149 else {
150 nv.hresolu = ourview.hresolu; nv.vresolu = ourview.vresolu;
151 }
152 if (change)
153 newview(&nv);
154 }
155
156
157 lastview(s) /* return to a previous view */
158 char *s;
159 {
160 char buf[128];
161 char *fname, *getpath();
162 int success;
163 VIEW nv;
164
165 if (sscanf(s, "%s", buf) == 1) { /* get parameters from a file */
166 bcopy(&stdview, &nv, sizeof(VIEW));
167 if ((fname = getpath(buf, NULL)) == NULL ||
168 (success = viewfile(fname, &nv)) == -1) {
169 sprintf(errmsg, "cannot open \"%s\"", buf);
170 error(COMMAND, errmsg);
171 return;
172 }
173 if (!success)
174 error(COMMAND, "wrong file format");
175 else
176 newview(&nv);
177 return;
178 }
179 if (oldview.hresolu == 0) { /* no old view! */
180 error(COMMAND, "no previous view");
181 return;
182 }
183 bcopy(&ourview, &nv, sizeof(VIEW));
184 bcopy(&oldview, &ourview, sizeof(VIEW));
185 bcopy(&nv, &oldview, sizeof(VIEW));
186 newimage();
187 }
188
189
190 getinterest(s, direc, vec, mp) /* get area of interest */
191 char *s;
192 int direc;
193 FVECT vec;
194 double *mp;
195 {
196 int x, y;
197 RAY thisray;
198 register int i;
199
200 if (sscanf(s, "%lf", mp) != 1)
201 *mp = 1.0;
202 else if (*mp < -FTINY) /* negative zoom is reduction */
203 *mp = -1.0 / *mp;
204 else if (*mp <= FTINY) { /* too small */
205 error(COMMAND, "illegal magnification");
206 return(-1);
207 }
208 if (sscanf(s, "%*lf %lf %lf %lf", &vec[0], &vec[1], &vec[2]) != 3) {
209 if (dev->getcur == NULL)
210 return(-1);
211 (*dev->comout)("Pick view center\n");
212 if ((*dev->getcur)(&x, &y) == ABORT)
213 return(-1);
214 rayview(thisray.rorg, thisray.rdir, &ourview, x+.5, y+.5);
215 if (!direc || ourview.type == VT_PAR) {
216 rayorigin(&thisray, NULL, PRIMARY, 1.0);
217 if (!localhit(&thisray, &thescene)) {
218 error(COMMAND, "not a local object");
219 return(-1);
220 }
221 }
222 if (direc)
223 if (ourview.type == VT_PAR)
224 for (i = 0; i < 3; i++)
225 vec[i] = thisray.rop[i] - ourview.vp[i];
226 else
227 VCOPY(vec, thisray.rdir);
228 else
229 VCOPY(vec, thisray.rop);
230 } else if (direc)
231 for (i = 0; i < 3; i++)
232 vec[i] -= ourview.vp[i];
233 return(0);
234 }
235
236
237 getaim(s) /* aim camera */
238 char *s;
239 {
240 extern double tan(), atan();
241 double zfact;
242 VIEW nv;
243
244 if (getinterest(s, 1, nv.vdir, &zfact) < 0)
245 return;
246 VCOPY(nv.vp, ourview.vp);
247 VCOPY(nv.vup, ourview.vup);
248 nv.hresolu = ourview.hresolu; nv.vresolu = ourview.vresolu;
249 if ((nv.type = ourview.type) == VT_PAR) {
250 nv.horiz = ourview.horiz / zfact;
251 nv.vert = ourview.vert / zfact;
252 } else {
253 nv.horiz = atan(tan(ourview.horiz*(PI/180./2.))/zfact) /
254 (PI/180./2.);
255 nv.vert = atan(tan(ourview.vert*(PI/180./2.))/zfact) /
256 (PI/180./2.);
257 }
258 newview(&nv);
259 }
260
261
262 getmove(s) /* move camera */
263 char *s;
264 {
265 FVECT vc;
266 double mag;
267
268 if (getinterest(s, 0, vc, &mag) < 0)
269 return;
270 moveview(0.0, 0.0, mag, vc);
271 }
272
273
274 getrotate(s) /* rotate camera */
275 char *s;
276 {
277 extern double normalize(), tan(), atan();
278 VIEW nv;
279 FVECT v1;
280 double angle, elev, zfact;
281
282 elev = 0.0; zfact = 1.0;
283 if (sscanf(s, "%lf %lf %lf", &angle, &elev, &zfact) < 1) {
284 error(COMMAND, "missing angle");
285 return;
286 }
287 VCOPY(nv.vp, ourview.vp);
288 VCOPY(nv.vup, ourview.vup);
289 nv.hresolu = ourview.hresolu; nv.vresolu = ourview.vresolu;
290 spinvector(nv.vdir, ourview.vdir, ourview.vup, angle*(PI/180.));
291 if (elev != 0.0) {
292 fcross(v1, nv.vdir, ourview.vup);
293 normalize(v1);
294 spinvector(nv.vdir, nv.vdir, v1, elev*(PI/180.));
295 }
296 if ((nv.type = ourview.type) == VT_PAR) {
297 nv.horiz = ourview.horiz / zfact;
298 nv.vert = ourview.vert / zfact;
299 } else {
300 nv.horiz = atan(tan(ourview.horiz*(PI/180./2.))/zfact) /
301 (PI/180./2.);
302 nv.vert = atan(tan(ourview.vert*(PI/180./2.))/zfact) /
303 (PI/180./2.);
304 }
305 newview(&nv);
306 }
307
308
309 getpivot(s) /* pivot viewpoint */
310 register char *s;
311 {
312 FVECT vc;
313 double angle, elev, mag;
314
315 elev = 0.0;
316 if (sscanf(s, "%lf %lf", &angle, &elev) < 1) {
317 error(COMMAND, "missing angle");
318 return;
319 }
320 if (getinterest(sskip(sskip(s)), 0, vc, &mag) < 0)
321 return;
322 moveview(angle, elev, mag, vc);
323 }
324
325
326 getexposure(s) /* get new exposure */
327 char *s;
328 {
329 double atof(), pow(), fabs();
330 char buf[128];
331 register char *cp;
332 register PNODE *p;
333 RECT r;
334 int x, y;
335 double e;
336
337 for (cp = s; isspace(*cp); cp++)
338 ;
339 if (*cp == '\0') { /* normalize to point */
340 if (dev->getcur == NULL)
341 return;
342 (*dev->comout)("Pick point for exposure\n");
343 if ((*dev->getcur)(&x, &y) == ABORT)
344 return;
345 r.l = r.d = 0;
346 r.r = ourview.hresolu; r.u = ourview.vresolu;
347 p = findrect(x, y, &ptrunk, &r, -1);
348 e = 1.0;
349 } else {
350 if (*cp == '=') { /* absolute setting */
351 p = NULL;
352 e = 1.0/exposure;
353 for (cp++; isspace(*cp); cp++)
354 ;
355 if (*cp == '\0') { /* interactive */
356 sprintf(buf, "exposure (%lf): ", exposure);
357 (*dev->comout)(buf);
358 (*dev->comin)(buf);
359 for (cp = buf; isspace(*cp); cp++)
360 ;
361 if (*cp == '\0')
362 return;
363 }
364 } else { /* normalize to average */
365 p = &ptrunk;
366 e = 1.0;
367 }
368 if (*cp == '+' || *cp == '-') /* f-stops */
369 e *= pow(2.0, atof(cp));
370 else /* multiplier */
371 e *= atof(cp);
372 }
373 if (p != NULL) { /* relative setting */
374 if (bright(p->v) <= FTINY) {
375 error(COMMAND, "cannot normalize to zero");
376 return;
377 }
378 e *= 0.5 / bright(p->v);
379 }
380 if (e <= FTINY || fabs(1.0 - e) <= FTINY)
381 return;
382 scalepict(&ptrunk, e);
383 exposure *= e;
384 redraw();
385 }
386
387
388 setparam(s) /* get/set program parameter */
389 register char *s;
390 {
391 extern int psample;
392 extern double maxdiff;
393 extern double minweight;
394 extern int maxdepth;
395 extern double dstrsrc;
396 extern double shadthresh;
397 extern double shadcert;
398 extern COLOR ambval;
399 extern double ambacc;
400 extern double minarad;
401 extern int ambres;
402 extern int ambdiv;
403 extern int ambssamp;
404 extern int ambounce;
405 int i0;
406 double d0, d1, d2;
407 char buf[128];
408
409 if (s[0] == '\0') {
410 (*dev->comout)("aa ab ad ar as av dc dj dt lr lw sp st: ");
411 (*dev->comin)(buf);
412 s = buf;
413 }
414 switch (s[0]) {
415 case 'l': /* limit */
416 switch (s[1]) {
417 case 'w': /* weight */
418 if (sscanf(s+2, "%lf", &d0) != 1) {
419 sprintf(buf, "limit weight (%.6g): ",
420 minweight);
421 (*dev->comout)(buf);
422 (*dev->comin)(buf);
423 if (sscanf(buf, "%lf", &d0) != 1)
424 break;
425 }
426 minweight = d0;
427 break;
428 case 'r': /* reflection */
429 if (sscanf(s+2, "%d", &i0) != 1) {
430 sprintf(buf, "limit reflection (%d): ",
431 maxdepth);
432 (*dev->comout)(buf);
433 (*dev->comin)(buf);
434 if (sscanf(buf, "%d", &i0) != 1)
435 break;
436 }
437 maxdepth = i0;
438 break;
439 default:
440 goto badparam;
441 }
442 break;
443 case 'd': /* direct */
444 switch (s[1]) {
445 case 'j': /* jitter */
446 if (sscanf(s+2, "%lf", &d0) != 1) {
447 sprintf(buf, "direct jitter (%.6g): ",
448 dstrsrc);
449 (*dev->comout)(buf);
450 (*dev->comin)(buf);
451 if (sscanf(buf, "%lf", &d0) != 1)
452 break;
453 }
454 dstrsrc = d0;
455 break;
456 case 'c': /* certainty */
457 if (sscanf(s+2, "%lf", &d0) != 1) {
458 sprintf(buf, "direct certainty (%.6g): ",
459 shadcert);
460 (*dev->comout)(buf);
461 (*dev->comin)(buf);
462 if (sscanf(buf, "%lf", &d0) != 1)
463 break;
464 }
465 shadcert = d0;
466 break;
467 case 't': /* threshold */
468 if (sscanf(s+2, "%lf", &d0) != 1) {
469 sprintf(buf, "direct threshold (%.6g): ",
470 shadthresh);
471 (*dev->comout)(buf);
472 (*dev->comin)(buf);
473 if (sscanf(buf, "%lf", &d0) != 1)
474 break;
475 }
476 shadthresh = d0;
477 break;
478 default:
479 goto badparam;
480 }
481 break;
482 case 'a': /* ambient */
483 switch (s[1]) {
484 case 'v': /* value */
485 if (sscanf(s+2, "%lf %lf %lf", &d0, &d1, &d2) != 3) {
486 sprintf(buf,
487 "ambient value (%.6g %.6g %.6g): ",
488 colval(ambval,RED),
489 colval(ambval,GRN),
490 colval(ambval,BLU));
491 (*dev->comout)(buf);
492 (*dev->comin)(buf);
493 if (sscanf(buf, "%lf %lf %lf",
494 &d0, &d1, &d2) != 3)
495 break;
496 }
497 setcolor(ambval, d0, d1, d2);
498 break;
499 case 'a': /* accuracy */
500 if (sscanf(s+2, "%lf", &d0) != 1) {
501 sprintf(buf, "ambient accuracy (%.6g): ",
502 ambacc);
503 (*dev->comout)(buf);
504 (*dev->comin)(buf);
505 if (sscanf(buf, "%lf", &d0) != 1)
506 break;
507 }
508 ambacc = d0;
509 break;
510 case 'd': /* divisions */
511 if (sscanf(s+2, "%d", &i0) != 1) {
512 sprintf(buf, "ambient divisions (%d): ",
513 ambdiv);
514 (*dev->comout)(buf);
515 (*dev->comin)(buf);
516 if (sscanf(buf, "%d", &i0) != 1)
517 break;
518 }
519 ambdiv = i0;
520 break;
521 case 's': /* samples */
522 if (sscanf(s+2, "%d", &i0) != 1) {
523 sprintf(buf, "ambient super-samples (%d): ",
524 ambssamp);
525 (*dev->comout)(buf);
526 (*dev->comin)(buf);
527 if (sscanf(buf, "%d", &i0) != 1)
528 break;
529 }
530 ambssamp = i0;
531 break;
532 case 'b': /* bounces */
533 if (sscanf(s+2, "%d", &i0) != 1) {
534 sprintf(buf, "ambient bounces (%d): ",
535 ambounce);
536 (*dev->comout)(buf);
537 (*dev->comin)(buf);
538 if (sscanf(buf, "%d", &i0) != 1)
539 break;
540 }
541 ambounce = i0;
542 break;
543 case 'r':
544 if (sscanf(s+2, "%d", &i0) != 1) {
545 sprintf(buf, "ambient resolution (%d): ",
546 ambres);
547 (*dev->comout)(buf);
548 (*dev->comin)(buf);
549 if (sscanf(buf, "%d", &i0) != 1)
550 break;
551 }
552 ambres = i0;
553 minarad = ambres > 0 ? thescene.cusize/ambres : 0.0;
554 break;
555 default:
556 goto badparam;
557 }
558 break;
559 case 's': /* sample */
560 switch (s[1]) {
561 case 'p': /* pixel */
562 if (sscanf(s+2, "%d", &i0) != 1) {
563 sprintf(buf, "sample pixel (%d): ", psample);
564 (*dev->comout)(buf);
565 (*dev->comin)(buf);
566 if (sscanf(buf, "%d", &i0) != 1)
567 break;
568 }
569 psample = i0;
570 pdepth = 0;
571 break;
572 case 't': /* threshold */
573 if (sscanf(s+2, "%lf", &d0) != 1) {
574 sprintf(buf, "sample threshold (%.6g): ",
575 maxdiff);
576 (*dev->comout)(buf);
577 (*dev->comin)(buf);
578 if (sscanf(buf, "%lf", &d0) != 1)
579 break;
580 }
581 maxdiff = d0;
582 pdepth = 0;
583 break;
584 default:
585 goto badparam;
586 }
587 break;
588 case '\0': /* nothing */
589 break;
590 default:;
591 badparam:
592 sprintf(errmsg, "%s: unknown variable", s);
593 error(COMMAND, errmsg);
594 break;
595 }
596 }
597
598
599 traceray(s) /* trace a single ray */
600 char *s;
601 {
602 char buf[128];
603 int x, y;
604 RAY thisray;
605
606 if (sscanf(s, "%lf %lf %lf %lf %lf %lf",
607 &thisray.rorg[0], &thisray.rorg[1], &thisray.rorg[2],
608 &thisray.rdir[0], &thisray.rdir[1], &thisray.rdir[2]) != 6) {
609
610 if (dev->getcur == NULL)
611 return;
612 (*dev->comout)("Pick ray\n");
613 if ((*dev->getcur)(&x, &y) == ABORT)
614 return;
615
616 rayview(thisray.rorg, thisray.rdir, &ourview, x+.5, y+.5);
617
618 } else if (normalize(thisray.rdir) == 0.0) {
619 error(COMMAND, "zero ray direction");
620 return;
621 }
622
623 rayorigin(&thisray, NULL, PRIMARY, 1.0);
624
625 rayvalue(&thisray);
626
627 if (thisray.ro == NULL)
628 (*dev->comout)("ray hit nothing");
629 else {
630 sprintf(buf, "ray hit %s %s \"%s\"",
631 objptr(thisray.ro->omod)->oname,
632 ofun[thisray.ro->otype].funame,
633 thisray.ro->oname);
634 (*dev->comout)(buf);
635 (*dev->comin)(buf);
636 if (thisray.rot >= FHUGE)
637 (*dev->comout)("at infinity");
638 else {
639 sprintf(buf, "at (%.6g %.6g %.6g)", thisray.rop[0],
640 thisray.rop[1], thisray.rop[2]);
641 (*dev->comout)(buf);
642 }
643 (*dev->comin)(buf);
644 sprintf(buf, "with value (%.6g %.6g %.6g)",
645 colval(thisray.rcol,RED),
646 colval(thisray.rcol,GRN),
647 colval(thisray.rcol,BLU));
648 (*dev->comout)(buf);
649 }
650 (*dev->comin)(buf);
651 }
652
653
654 writepict(s) /* write the picture to a file */
655 char *s;
656 {
657 static char buf[128];
658 char *fname, *getpath();
659 FILE *fp;
660 COLR *scanline;
661 int y;
662
663 if (sscanf(s, "%s", buf) != 1 && buf[0] == '\0') {
664 error(COMMAND, "no file");
665 return;
666 }
667 if ((fname = getpath(buf, NULL)) == NULL ||
668 (fp = fopen(fname, "w")) == NULL) {
669 sprintf(errmsg, "cannot open \"%s\"", buf);
670 error(COMMAND, errmsg);
671 return;
672 }
673 (*dev->comout)("writing \"");
674 (*dev->comout)(fname);
675 (*dev->comout)("\"...\n");
676 /* write header */
677 fputs(progname, fp);
678 fprintview(&ourview, fp);
679 fputs("\n", fp);
680 if (exposure != 1.0)
681 fprintf(fp, "EXPOSURE=%e\n", exposure);
682 fprintf(fp, "\n-Y %d +X %d\n", ourview.vresolu, ourview.hresolu);
683
684 scanline = (COLR *)malloc(ourview.hresolu*sizeof(COLR));
685 if (scanline == NULL)
686 error(SYSTEM, "out of memory in writepict");
687 for (y = ourview.vresolu-1; y >= 0; y--) {
688 getpictcolrs(y, scanline, &ptrunk,
689 ourview.hresolu, ourview.vresolu);
690 if (fwritecolrs(scanline, ourview.hresolu, fp) < 0)
691 break;
692 }
693 if (fclose(fp) < 0)
694 error(COMMAND, "write error");
695 free((char *)scanline);
696 }