ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rv2.c
Revision: 1.3
Committed: Fri Mar 3 18:34:33 1989 UTC (35 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.2: +21 -8 lines
Log Message:
Fixed unintentional change of view in getview()

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, mag, vc);
269 }
270
271
272 getrotate(s) /* rotate camera */
273 char *s;
274 {
275 extern double normalize();
276 VIEW nv;
277 FVECT v1;
278 double angle, elev;
279
280 elev = 0.0;
281 if (sscanf(s, "%lf %lf", &angle, &elev) < 1) {
282 error(COMMAND, "missing angle");
283 return;
284 }
285 nv.type = ourview.type;
286 VCOPY(nv.vp, ourview.vp);
287 VCOPY(nv.vup, ourview.vup);
288 nv.horiz = ourview.horiz; nv.vert = ourview.vert;
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 newview(&nv);
297 }
298
299
300 getpivot(s) /* pivot viewpoint */
301 register char *s;
302 {
303 FVECT vc;
304 double angle, mag;
305
306 if (sscanf(s, "%lf", &angle) != 1) {
307 error(COMMAND, "missing angle");
308 return;
309 }
310 if (getinterest(sskip(s), 0, vc, &mag) < 0)
311 return;
312 moveview(angle, mag, vc);
313 }
314
315
316 getexposure(s) /* get new exposure */
317 char *s;
318 {
319 double atof(), pow(), fabs();
320 char buf[128];
321 register char *cp;
322 register PNODE *p;
323 RECT r;
324 int x, y;
325 double e;
326
327 for (cp = s; isspace(*cp); cp++)
328 ;
329 if (*cp == '\0') { /* normalize to point */
330 if (dev->getcur == NULL)
331 return;
332 (*dev->comout)("Pick point for exposure\n");
333 if ((*dev->getcur)(&x, &y) == ABORT)
334 return;
335 r.l = r.d = 0;
336 r.r = ourview.hresolu; r.u = ourview.vresolu;
337 p = findrect(x, y, &ptrunk, &r, -1);
338 e = 1.0;
339 } else {
340 if (*cp == '=') { /* absolute setting */
341 p = NULL;
342 e = 1.0/exposure;
343 for (cp++; isspace(*cp); cp++)
344 ;
345 if (*cp == '\0') { /* interactive */
346 sprintf(buf, "exposure (%lf): ", exposure);
347 (*dev->comout)(buf);
348 (*dev->comin)(buf);
349 for (cp = buf; isspace(*cp); cp++)
350 ;
351 if (*cp == '\0')
352 return;
353 }
354 } else { /* normalize to average */
355 p = &ptrunk;
356 e = 1.0;
357 }
358 if (*cp == '+' || *cp == '-') /* f-stops */
359 e *= pow(2.0, atof(cp));
360 else /* multiplier */
361 e *= atof(cp);
362 }
363 if (p != NULL) { /* relative setting */
364 if (intens(p->v) <= FTINY) {
365 error(COMMAND, "cannot normalize to zero");
366 return;
367 }
368 e *= 0.5 / intens(p->v);
369 }
370 if (e <= FTINY || fabs(1.0 - e) <= FTINY)
371 return;
372 scalepict(&ptrunk, e);
373 exposure *= e;
374 redraw();
375 }
376
377
378 setparam(s) /* get/set program parameter */
379 register char *s;
380 {
381 extern int psample;
382 extern double maxdiff;
383 extern double minweight;
384 extern int maxdepth;
385 extern double dstrsrc;
386 extern COLOR ambval;
387 extern double ambacc;
388 extern double minarad;
389 extern int ambres;
390 extern int ambdiv;
391 extern int ambssamp;
392 extern int ambounce;
393 int i0;
394 double d0, d1, d2;
395 char buf[128];
396
397 if (s[0] == '\0') {
398 (*dev->comout)("aa ab ad ar as av ds lr lw sd sp: ");
399 (*dev->comin)(buf);
400 s = buf;
401 }
402 switch (s[0]) {
403 case 'l': /* limit */
404 switch (s[1]) {
405 case 'w': /* weight */
406 if (sscanf(s+2, "%lf", &d0) != 1) {
407 sprintf(buf, "limit weight (%.6g): ",
408 minweight);
409 (*dev->comout)(buf);
410 (*dev->comin)(buf);
411 if (sscanf(buf, "%lf", &d0) != 1)
412 break;
413 }
414 minweight = d0;
415 break;
416 case 'r': /* reflection */
417 if (sscanf(s+2, "%d", &i0) != 1) {
418 sprintf(buf, "limit reflection (%d): ",
419 maxdepth);
420 (*dev->comout)(buf);
421 (*dev->comin)(buf);
422 if (sscanf(buf, "%d", &i0) != 1)
423 break;
424 }
425 maxdepth = i0;
426 break;
427 default:
428 goto badparam;
429 }
430 break;
431 case 'd': /* distribute source */
432 if (s[1] != 's')
433 goto badparam;
434 if (sscanf(s+2, "%lf", &d0) != 1) {
435 sprintf(buf, "distribute source (%.6g): ", dstrsrc);
436 (*dev->comout)(buf);
437 (*dev->comin)(buf);
438 if (sscanf(buf, "%lf", &d0) != 1)
439 break;
440 }
441 dstrsrc = d0;
442 break;
443 case 'a': /* ambient */
444 switch (s[1]) {
445 case 'v': /* value */
446 if (sscanf(s+2, "%lf %lf %lf", &d0, &d1, &d2) != 3) {
447 sprintf(buf,
448 "ambient value (%.6g %.6g %.6g): ",
449 colval(ambval,RED),
450 colval(ambval,GRN),
451 colval(ambval,BLU));
452 (*dev->comout)(buf);
453 (*dev->comin)(buf);
454 if (sscanf(buf, "%lf %lf %lf",
455 &d0, &d1, &d2) != 3)
456 break;
457 }
458 setcolor(ambval, d0, d1, d2);
459 break;
460 case 'a': /* accuracy */
461 if (sscanf(s+2, "%lf", &d0) != 1) {
462 sprintf(buf, "ambient accuracy (%.6g): ",
463 ambacc);
464 (*dev->comout)(buf);
465 (*dev->comin)(buf);
466 if (sscanf(buf, "%lf", &d0) != 1)
467 break;
468 }
469 ambacc = d0;
470 break;
471 case 'd': /* divisions */
472 if (sscanf(s+2, "%d", &i0) != 1) {
473 sprintf(buf, "ambient divisions (%d): ",
474 ambdiv);
475 (*dev->comout)(buf);
476 (*dev->comin)(buf);
477 if (sscanf(buf, "%d", &i0) != 1)
478 break;
479 }
480 ambdiv = i0;
481 break;
482 case 's': /* samples */
483 if (sscanf(s+2, "%d", &i0) != 1) {
484 sprintf(buf, "ambient super-samples (%d): ",
485 ambssamp);
486 (*dev->comout)(buf);
487 (*dev->comin)(buf);
488 if (sscanf(buf, "%d", &i0) != 1)
489 break;
490 }
491 ambssamp = i0;
492 break;
493 case 'b': /* bounces */
494 if (sscanf(s+2, "%d", &i0) != 1) {
495 sprintf(buf, "ambient bounces (%d): ",
496 ambounce);
497 (*dev->comout)(buf);
498 (*dev->comin)(buf);
499 if (sscanf(buf, "%d", &i0) != 1)
500 break;
501 }
502 ambounce = i0;
503 break;
504 case 'r':
505 if (sscanf(s+2, "%d", &i0) != 1) {
506 sprintf(buf, "ambient resolution (%d): ",
507 ambres);
508 (*dev->comout)(buf);
509 (*dev->comin)(buf);
510 if (sscanf(buf, "%d", &i0) != 1)
511 break;
512 }
513 ambres = i0;
514 minarad = ambres > 0 ? thescene.cusize/ambres : 0.0;
515 break;
516 default:
517 goto badparam;
518 }
519 break;
520 case 's': /* sample */
521 switch (s[1]) {
522 case 'p': /* pixel */
523 if (sscanf(s+2, "%d", &i0) != 1) {
524 sprintf(buf, "sample pixel (%d): ", psample);
525 (*dev->comout)(buf);
526 (*dev->comin)(buf);
527 if (sscanf(buf, "%d", &i0) != 1)
528 break;
529 }
530 psample = i0;
531 pdepth = 0;
532 break;
533 case 'd': /* difference */
534 if (sscanf(s+2, "%lf", &d0) != 1) {
535 sprintf(buf, "sample difference (%.6g): ",
536 maxdiff);
537 (*dev->comout)(buf);
538 (*dev->comin)(buf);
539 if (sscanf(buf, "%lf", &d0) != 1)
540 break;
541 }
542 maxdiff = d0;
543 pdepth = 0;
544 break;
545 default:
546 goto badparam;
547 }
548 break;
549 case '\0': /* nothing */
550 break;
551 default:;
552 badparam:
553 sprintf(errmsg, "%s: unknown variable", s);
554 error(COMMAND, errmsg);
555 break;
556 }
557 }
558
559
560 traceray(s) /* trace a single ray */
561 char *s;
562 {
563 char buf[128];
564 int x, y;
565 RAY thisray;
566
567 if (sscanf(s, "%lf %lf %lf %lf %lf %lf",
568 &thisray.rorg[0], &thisray.rorg[1], &thisray.rorg[2],
569 &thisray.rdir[0], &thisray.rdir[1], &thisray.rdir[2]) != 6) {
570
571 if (dev->getcur == NULL)
572 return;
573 (*dev->comout)("Pick ray\n");
574 if ((*dev->getcur)(&x, &y) == ABORT)
575 return;
576
577 rayview(thisray.rorg, thisray.rdir, &ourview, x+.5, y+.5);
578
579 } else if (normalize(thisray.rdir) == 0.0) {
580 error(COMMAND, "zero ray direction");
581 return;
582 }
583
584 rayorigin(&thisray, NULL, PRIMARY, 1.0);
585
586 rayvalue(&thisray);
587
588 if (thisray.ro == NULL)
589 (*dev->comout)("ray hit nothing");
590 else {
591 sprintf(buf, "ray hit %s %s \"%s\"",
592 objptr(thisray.ro->omod)->oname,
593 ofun[thisray.ro->otype].funame,
594 thisray.ro->oname);
595 (*dev->comout)(buf);
596 (*dev->comin)(buf);
597 if (thisray.rot >= FHUGE)
598 (*dev->comout)("at infinity");
599 else {
600 sprintf(buf, "at (%.6g %.6g %.6g)", thisray.rop[0],
601 thisray.rop[1], thisray.rop[2]);
602 (*dev->comout)(buf);
603 }
604 (*dev->comin)(buf);
605 sprintf(buf, "with value (%.6g %.6g %.6g)",
606 colval(thisray.rcol,RED),
607 colval(thisray.rcol,GRN),
608 colval(thisray.rcol,BLU));
609 (*dev->comout)(buf);
610 }
611 (*dev->comin)(buf);
612 }
613
614
615 writepict(s) /* write the picture to a file */
616 char *s;
617 {
618 static char buf[128];
619 char *fname, *getpath();
620 FILE *fp;
621 COLR *scanline;
622 int y;
623
624 if (sscanf(s, "%s", buf) != 1 && buf[0] == '\0') {
625 error(COMMAND, "no file");
626 return;
627 }
628 if ((fname = getpath(buf, NULL)) == NULL ||
629 (fp = fopen(fname, "w")) == NULL) {
630 sprintf(errmsg, "cannot open \"%s\"", buf);
631 error(COMMAND, errmsg);
632 return;
633 }
634 (*dev->comout)("writing \"");
635 (*dev->comout)(fname);
636 (*dev->comout)("\"...\n");
637 /* write header */
638 fputs(progname, fp);
639 fprintview(&ourview, fp);
640 fputs("\n", fp);
641 if (exposure != 1.0)
642 fprintf(fp, "EXPOSURE=%e\n", exposure);
643 fprintf(fp, "\n-Y %d +X %d\n", ourview.vresolu, ourview.hresolu);
644
645 scanline = (COLR *)malloc(ourview.hresolu*sizeof(COLR));
646 if (scanline == NULL)
647 error(SYSTEM, "out of memory in writepict");
648 for (y = ourview.vresolu-1; y >= 0; y--) {
649 getpictcolrs(y, scanline, &ptrunk,
650 ourview.hresolu, ourview.vresolu);
651 if (fwritecolrs(scanline, ourview.hresolu, fp) < 0)
652 break;
653 }
654 if (fclose(fp) < 0)
655 error(COMMAND, "write error");
656 free((char *)scanline);
657 }