ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rv2.c
Revision: 1.5
Committed: Wed Jun 7 08:35:26 1989 UTC (34 years, 10 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.4: +27 -10 lines
Log Message:
Efficient approximation to direct component with many sources
Glow type changed
Spot type eliminated

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