ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rv2.c
Revision: 1.4
Committed: Tue May 30 09:57:13 1989 UTC (34 years, 11 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.3: +19 -11 lines
Log Message:
Added elevation to pivot and zoom to rotate commands

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 COLOR ambval;
395 extern double ambacc;
396 extern double minarad;
397 extern int ambres;
398 extern int ambdiv;
399 extern int ambssamp;
400 extern int ambounce;
401 int i0;
402 double d0, d1, d2;
403 char buf[128];
404
405 if (s[0] == '\0') {
406 (*dev->comout)("aa ab ad ar as av ds lr lw sd sp: ");
407 (*dev->comin)(buf);
408 s = buf;
409 }
410 switch (s[0]) {
411 case 'l': /* limit */
412 switch (s[1]) {
413 case 'w': /* weight */
414 if (sscanf(s+2, "%lf", &d0) != 1) {
415 sprintf(buf, "limit weight (%.6g): ",
416 minweight);
417 (*dev->comout)(buf);
418 (*dev->comin)(buf);
419 if (sscanf(buf, "%lf", &d0) != 1)
420 break;
421 }
422 minweight = d0;
423 break;
424 case 'r': /* reflection */
425 if (sscanf(s+2, "%d", &i0) != 1) {
426 sprintf(buf, "limit reflection (%d): ",
427 maxdepth);
428 (*dev->comout)(buf);
429 (*dev->comin)(buf);
430 if (sscanf(buf, "%d", &i0) != 1)
431 break;
432 }
433 maxdepth = i0;
434 break;
435 default:
436 goto badparam;
437 }
438 break;
439 case 'd': /* distribute source */
440 if (s[1] != 's')
441 goto badparam;
442 if (sscanf(s+2, "%lf", &d0) != 1) {
443 sprintf(buf, "distribute source (%.6g): ", dstrsrc);
444 (*dev->comout)(buf);
445 (*dev->comin)(buf);
446 if (sscanf(buf, "%lf", &d0) != 1)
447 break;
448 }
449 dstrsrc = d0;
450 break;
451 case 'a': /* ambient */
452 switch (s[1]) {
453 case 'v': /* value */
454 if (sscanf(s+2, "%lf %lf %lf", &d0, &d1, &d2) != 3) {
455 sprintf(buf,
456 "ambient value (%.6g %.6g %.6g): ",
457 colval(ambval,RED),
458 colval(ambval,GRN),
459 colval(ambval,BLU));
460 (*dev->comout)(buf);
461 (*dev->comin)(buf);
462 if (sscanf(buf, "%lf %lf %lf",
463 &d0, &d1, &d2) != 3)
464 break;
465 }
466 setcolor(ambval, d0, d1, d2);
467 break;
468 case 'a': /* accuracy */
469 if (sscanf(s+2, "%lf", &d0) != 1) {
470 sprintf(buf, "ambient accuracy (%.6g): ",
471 ambacc);
472 (*dev->comout)(buf);
473 (*dev->comin)(buf);
474 if (sscanf(buf, "%lf", &d0) != 1)
475 break;
476 }
477 ambacc = d0;
478 break;
479 case 'd': /* divisions */
480 if (sscanf(s+2, "%d", &i0) != 1) {
481 sprintf(buf, "ambient divisions (%d): ",
482 ambdiv);
483 (*dev->comout)(buf);
484 (*dev->comin)(buf);
485 if (sscanf(buf, "%d", &i0) != 1)
486 break;
487 }
488 ambdiv = i0;
489 break;
490 case 's': /* samples */
491 if (sscanf(s+2, "%d", &i0) != 1) {
492 sprintf(buf, "ambient super-samples (%d): ",
493 ambssamp);
494 (*dev->comout)(buf);
495 (*dev->comin)(buf);
496 if (sscanf(buf, "%d", &i0) != 1)
497 break;
498 }
499 ambssamp = i0;
500 break;
501 case 'b': /* bounces */
502 if (sscanf(s+2, "%d", &i0) != 1) {
503 sprintf(buf, "ambient bounces (%d): ",
504 ambounce);
505 (*dev->comout)(buf);
506 (*dev->comin)(buf);
507 if (sscanf(buf, "%d", &i0) != 1)
508 break;
509 }
510 ambounce = i0;
511 break;
512 case 'r':
513 if (sscanf(s+2, "%d", &i0) != 1) {
514 sprintf(buf, "ambient resolution (%d): ",
515 ambres);
516 (*dev->comout)(buf);
517 (*dev->comin)(buf);
518 if (sscanf(buf, "%d", &i0) != 1)
519 break;
520 }
521 ambres = i0;
522 minarad = ambres > 0 ? thescene.cusize/ambres : 0.0;
523 break;
524 default:
525 goto badparam;
526 }
527 break;
528 case 's': /* sample */
529 switch (s[1]) {
530 case 'p': /* pixel */
531 if (sscanf(s+2, "%d", &i0) != 1) {
532 sprintf(buf, "sample pixel (%d): ", psample);
533 (*dev->comout)(buf);
534 (*dev->comin)(buf);
535 if (sscanf(buf, "%d", &i0) != 1)
536 break;
537 }
538 psample = i0;
539 pdepth = 0;
540 break;
541 case 'd': /* difference */
542 if (sscanf(s+2, "%lf", &d0) != 1) {
543 sprintf(buf, "sample difference (%.6g): ",
544 maxdiff);
545 (*dev->comout)(buf);
546 (*dev->comin)(buf);
547 if (sscanf(buf, "%lf", &d0) != 1)
548 break;
549 }
550 maxdiff = d0;
551 pdepth = 0;
552 break;
553 default:
554 goto badparam;
555 }
556 break;
557 case '\0': /* nothing */
558 break;
559 default:;
560 badparam:
561 sprintf(errmsg, "%s: unknown variable", s);
562 error(COMMAND, errmsg);
563 break;
564 }
565 }
566
567
568 traceray(s) /* trace a single ray */
569 char *s;
570 {
571 char buf[128];
572 int x, y;
573 RAY thisray;
574
575 if (sscanf(s, "%lf %lf %lf %lf %lf %lf",
576 &thisray.rorg[0], &thisray.rorg[1], &thisray.rorg[2],
577 &thisray.rdir[0], &thisray.rdir[1], &thisray.rdir[2]) != 6) {
578
579 if (dev->getcur == NULL)
580 return;
581 (*dev->comout)("Pick ray\n");
582 if ((*dev->getcur)(&x, &y) == ABORT)
583 return;
584
585 rayview(thisray.rorg, thisray.rdir, &ourview, x+.5, y+.5);
586
587 } else if (normalize(thisray.rdir) == 0.0) {
588 error(COMMAND, "zero ray direction");
589 return;
590 }
591
592 rayorigin(&thisray, NULL, PRIMARY, 1.0);
593
594 rayvalue(&thisray);
595
596 if (thisray.ro == NULL)
597 (*dev->comout)("ray hit nothing");
598 else {
599 sprintf(buf, "ray hit %s %s \"%s\"",
600 objptr(thisray.ro->omod)->oname,
601 ofun[thisray.ro->otype].funame,
602 thisray.ro->oname);
603 (*dev->comout)(buf);
604 (*dev->comin)(buf);
605 if (thisray.rot >= FHUGE)
606 (*dev->comout)("at infinity");
607 else {
608 sprintf(buf, "at (%.6g %.6g %.6g)", thisray.rop[0],
609 thisray.rop[1], thisray.rop[2]);
610 (*dev->comout)(buf);
611 }
612 (*dev->comin)(buf);
613 sprintf(buf, "with value (%.6g %.6g %.6g)",
614 colval(thisray.rcol,RED),
615 colval(thisray.rcol,GRN),
616 colval(thisray.rcol,BLU));
617 (*dev->comout)(buf);
618 }
619 (*dev->comin)(buf);
620 }
621
622
623 writepict(s) /* write the picture to a file */
624 char *s;
625 {
626 static char buf[128];
627 char *fname, *getpath();
628 FILE *fp;
629 COLR *scanline;
630 int y;
631
632 if (sscanf(s, "%s", buf) != 1 && buf[0] == '\0') {
633 error(COMMAND, "no file");
634 return;
635 }
636 if ((fname = getpath(buf, NULL)) == NULL ||
637 (fp = fopen(fname, "w")) == NULL) {
638 sprintf(errmsg, "cannot open \"%s\"", buf);
639 error(COMMAND, errmsg);
640 return;
641 }
642 (*dev->comout)("writing \"");
643 (*dev->comout)(fname);
644 (*dev->comout)("\"...\n");
645 /* write header */
646 fputs(progname, fp);
647 fprintview(&ourview, fp);
648 fputs("\n", fp);
649 if (exposure != 1.0)
650 fprintf(fp, "EXPOSURE=%e\n", exposure);
651 fprintf(fp, "\n-Y %d +X %d\n", ourview.vresolu, ourview.hresolu);
652
653 scanline = (COLR *)malloc(ourview.hresolu*sizeof(COLR));
654 if (scanline == NULL)
655 error(SYSTEM, "out of memory in writepict");
656 for (y = ourview.vresolu-1; y >= 0; y--) {
657 getpictcolrs(y, scanline, &ptrunk,
658 ourview.hresolu, ourview.vresolu);
659 if (fwritecolrs(scanline, ourview.hresolu, fp) < 0)
660 break;
661 }
662 if (fclose(fp) < 0)
663 error(COMMAND, "write error");
664 free((char *)scanline);
665 }