ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rv2.c
Revision: 1.7
Committed: Wed Jun 7 22:22:40 1989 UTC (34 years, 10 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.6: +2 -2 lines
Log Message:
Changed "direct threshold" name to "direct tolerance"

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 greg 1.6 if (bright(p->v) <= FTINY) {
373 greg 1.1 error(COMMAND, "cannot normalize to zero");
374     return;
375     }
376 greg 1.6 e *= 0.5 / bright(p->v);
377 greg 1.1 }
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 greg 1.5 extern double shadthresh;
395 greg 1.1 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 greg 1.5 (*dev->comout)("aa ab ad ar as av dj dt lr lw sd sp: ");
408 greg 1.1 (*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 greg 1.5 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 greg 1.7 case 't': /* tolerance */
454 greg 1.5 if (sscanf(s+2, "%lf", &d0) != 1) {
455 greg 1.7 sprintf(buf, "direct tolerance (%.6g): ",
456 greg 1.5 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 greg 1.1 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     }