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

# 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     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     }