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

# User Rev Content
1 greg 1.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 greg 1.3 int change = 0;
79 greg 1.1 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 greg 1.2 fputs(progname, fp);
89 greg 1.1 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 greg 1.3 if (buf[0] && buf[0] != ourview.type) {
99 greg 1.1 nv.type = buf[0];
100 greg 1.3 change++;
101     } else
102 greg 1.1 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 greg 1.3 if (sscanf(buf, "%lf %lf %lf", &nv.vp[0], &nv.vp[1], &nv.vp[2]) == 3)
109     change++;
110     else
111 greg 1.1 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 greg 1.3 if (sscanf(buf,"%lf %lf %lf",&nv.vdir[0],&nv.vdir[1],&nv.vdir[2]) == 3)
118     change++;
119     else
120 greg 1.1 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 greg 1.3 if (sscanf(buf,"%lf %lf %lf",&nv.vup[0],&nv.vup[1],&nv.vup[2]) == 3)
127     change++;
128     else
129 greg 1.1 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 greg 1.3 if (sscanf(buf, "%lf %lf", &nv.horiz, &nv.vert) == 2)
136     change++;
137     else {
138 greg 1.1 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 greg 1.3 if (sscanf(buf, "%d %d", &nv.hresolu, &nv.vresolu) == 2)
146     change++;
147     else {
148 greg 1.1 nv.hresolu = ourview.hresolu; nv.vresolu = ourview.vresolu;
149     }
150 greg 1.3 if (change)
151     newview(&nv);
152 greg 1.1 }
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 greg 1.4 moveview(0.0, 0.0, mag, vc);
269 greg 1.1 }
270    
271    
272     getrotate(s) /* rotate camera */
273     char *s;
274     {
275 greg 1.4 extern double normalize(), tan(), atan();
276 greg 1.1 VIEW nv;
277     FVECT v1;
278 greg 1.4 double angle, elev, zfact;
279 greg 1.1
280 greg 1.4 elev = 0.0; zfact = 1.0;
281     if (sscanf(s, "%lf %lf %lf", &angle, &elev, &zfact) < 1) {
282 greg 1.1 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 greg 1.4 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 greg 1.1 newview(&nv);
304     }
305    
306    
307     getpivot(s) /* pivot viewpoint */
308     register char *s;
309     {
310     FVECT vc;
311 greg 1.4 double angle, elev, mag;
312 greg 1.1
313 greg 1.4 elev = 0.0;
314     if (sscanf(s, "%lf %lf", &angle, &elev) < 1) {
315 greg 1.1 error(COMMAND, "missing angle");
316     return;
317     }
318 greg 1.4 if (getinterest(sskip(sskip(s)), 0, vc, &mag) < 0)
319 greg 1.1 return;
320 greg 1.4 moveview(angle, elev, mag, vc);
321 greg 1.1 }
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     }