ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rv2.c
Revision: 1.1
Committed: Thu Feb 2 10:41:37 1989 UTC (35 years, 3 months ago) by greg
Content type: text/plain
Branch: MAIN
Log Message:
Initial revision

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     VIEW nv;
79    
80     if (sscanf(s, "%s", buf) == 1) { /* write parameters to a file */
81     if ((fname = getpath(buf, NULL)) == NULL ||
82     (fp = fopen(fname, "a")) == NULL) {
83     sprintf(errmsg, "cannot open \"%s\"", buf);
84     error(COMMAND, errmsg);
85     return;
86     }
87     fputs(VIEWSTR, fp);
88     fprintview(&ourview, fp);
89     fputs("\n", fp);
90     fclose(fp);
91     return;
92     }
93     sprintf(buf, "view type (%c): ", ourview.type);
94     (*dev->comout)(buf);
95     (*dev->comin)(buf);
96     if (buf[0] == CTRL(C)) return;
97     if (buf[0])
98     nv.type = buf[0];
99     else
100     nv.type = ourview.type;
101     sprintf(buf, "view point (%.6g %.6g %.6g): ",
102     ourview.vp[0], ourview.vp[1], ourview.vp[2]);
103     (*dev->comout)(buf);
104     (*dev->comin)(buf);
105     if (buf[0] == CTRL(C)) return;
106     if (sscanf(buf, "%lf %lf %lf", &nv.vp[0], &nv.vp[1], &nv.vp[2]) != 3)
107     VCOPY(nv.vp, ourview.vp);
108     sprintf(buf, "view direction (%.6g %.6g %.6g): ",
109     ourview.vdir[0], ourview.vdir[1], ourview.vdir[2]);
110     (*dev->comout)(buf);
111     (*dev->comin)(buf);
112     if (buf[0] == CTRL(C)) return;
113     if (sscanf(buf,"%lf %lf %lf",&nv.vdir[0],&nv.vdir[1],&nv.vdir[2]) != 3)
114     VCOPY(nv.vdir, ourview.vdir);
115     sprintf(buf, "view up (%.6g %.6g %.6g): ",
116     ourview.vup[0], ourview.vup[1], ourview.vup[2]);
117     (*dev->comout)(buf);
118     (*dev->comin)(buf);
119     if (buf[0] == CTRL(C)) return;
120     if (sscanf(buf,"%lf %lf %lf",&nv.vup[0],&nv.vup[1],&nv.vup[2]) != 3)
121     VCOPY(nv.vup, ourview.vup);
122     sprintf(buf, "view horiz and vert size (%.6g %.6g): ",
123     ourview.horiz, ourview.vert);
124     (*dev->comout)(buf);
125     (*dev->comin)(buf);
126     if (buf[0] == CTRL(C)) return;
127     if (sscanf(buf, "%lf %lf", &nv.horiz, &nv.vert) != 2) {
128     nv.horiz = ourview.horiz; nv.vert = ourview.vert;
129     }
130     sprintf(buf, "x and y resolution (%d %d): ",
131     ourview.hresolu, ourview.vresolu);
132     (*dev->comout)(buf);
133     (*dev->comin)(buf);
134     if (buf[0] == CTRL(C)) return;
135     if (sscanf(buf, "%d %d", &nv.hresolu, &nv.vresolu) != 2) {
136     nv.hresolu = ourview.hresolu; nv.vresolu = ourview.vresolu;
137     }
138     newview(&nv);
139     }
140    
141    
142     lastview(s) /* return to a previous view */
143     char *s;
144     {
145     char buf[128];
146     char *fname, *getpath();
147     int success;
148     VIEW nv;
149    
150     if (sscanf(s, "%s", buf) == 1) { /* get parameters from a file */
151     bcopy(&stdview, &nv, sizeof(VIEW));
152     if ((fname = getpath(buf, NULL)) == NULL ||
153     (success = viewfile(fname, &nv)) == -1) {
154     sprintf(errmsg, "cannot open \"%s\"", buf);
155     error(COMMAND, errmsg);
156     return;
157     }
158     if (!success)
159     error(COMMAND, "wrong file format");
160     else
161     newview(&nv);
162     return;
163     }
164     if (oldview.hresolu == 0) { /* no old view! */
165     error(COMMAND, "no previous view");
166     return;
167     }
168     bcopy(&ourview, &nv, sizeof(VIEW));
169     bcopy(&oldview, &ourview, sizeof(VIEW));
170     bcopy(&nv, &oldview, sizeof(VIEW));
171     newimage();
172     }
173    
174    
175     getinterest(s, direc, vec, mp) /* get area of interest */
176     char *s;
177     int direc;
178     FVECT vec;
179     double *mp;
180     {
181     int x, y;
182     RAY thisray;
183     register int i;
184    
185     if (sscanf(s, "%lf", mp) != 1)
186     *mp = 1.0;
187     else if (*mp < -FTINY) /* negative zoom is reduction */
188     *mp = -1.0 / *mp;
189     else if (*mp <= FTINY) { /* too small */
190     error(COMMAND, "illegal magnification");
191     return(-1);
192     }
193     if (sscanf(s, "%*lf %lf %lf %lf", &vec[0], &vec[1], &vec[2]) != 3) {
194     if (dev->getcur == NULL)
195     return(-1);
196     (*dev->comout)("Pick view center\n");
197     if ((*dev->getcur)(&x, &y) == ABORT)
198     return(-1);
199     rayview(thisray.rorg, thisray.rdir, &ourview, x+.5, y+.5);
200     if (!direc || ourview.type == VT_PAR) {
201     rayorigin(&thisray, NULL, PRIMARY, 1.0);
202     if (!localhit(&thisray, &thescene)) {
203     error(COMMAND, "not a local object");
204     return(-1);
205     }
206     }
207     if (direc)
208     if (ourview.type == VT_PAR)
209     for (i = 0; i < 3; i++)
210     vec[i] = thisray.rop[i] - ourview.vp[i];
211     else
212     VCOPY(vec, thisray.rdir);
213     else
214     VCOPY(vec, thisray.rop);
215     } else if (direc)
216     for (i = 0; i < 3; i++)
217     vec[i] -= ourview.vp[i];
218     return(0);
219     }
220    
221    
222     getaim(s) /* aim camera */
223     char *s;
224     {
225     extern double tan(), atan();
226     double zfact;
227     VIEW nv;
228    
229     if (getinterest(s, 1, nv.vdir, &zfact) < 0)
230     return;
231     VCOPY(nv.vp, ourview.vp);
232     VCOPY(nv.vup, ourview.vup);
233     nv.hresolu = ourview.hresolu; nv.vresolu = ourview.vresolu;
234     if ((nv.type = ourview.type) == VT_PAR) {
235     nv.horiz = ourview.horiz / zfact;
236     nv.vert = ourview.vert / zfact;
237     } else {
238     nv.horiz = atan(tan(ourview.horiz*(PI/180./2.))/zfact) /
239     (PI/180./2.);
240     nv.vert = atan(tan(ourview.vert*(PI/180./2.))/zfact) /
241     (PI/180./2.);
242     }
243     newview(&nv);
244     }
245    
246    
247     getmove(s) /* move camera */
248     char *s;
249     {
250     FVECT vc;
251     double mag;
252    
253     if (getinterest(s, 0, vc, &mag) < 0)
254     return;
255     moveview(0.0, mag, vc);
256     }
257    
258    
259     getrotate(s) /* rotate camera */
260     char *s;
261     {
262     extern double normalize();
263     VIEW nv;
264     FVECT v1;
265     double angle, elev;
266    
267     elev = 0.0;
268     if (sscanf(s, "%lf %lf", &angle, &elev) < 1) {
269     error(COMMAND, "missing angle");
270     return;
271     }
272     nv.type = ourview.type;
273     VCOPY(nv.vp, ourview.vp);
274     VCOPY(nv.vup, ourview.vup);
275     nv.horiz = ourview.horiz; nv.vert = ourview.vert;
276     nv.hresolu = ourview.hresolu; nv.vresolu = ourview.vresolu;
277     spinvector(nv.vdir, ourview.vdir, ourview.vup, angle*(PI/180.));
278     if (elev != 0.0) {
279     fcross(v1, nv.vdir, ourview.vup);
280     normalize(v1);
281     spinvector(nv.vdir, nv.vdir, v1, elev*(PI/180.));
282     }
283     newview(&nv);
284     }
285    
286    
287     getpivot(s) /* pivot viewpoint */
288     register char *s;
289     {
290     FVECT vc;
291     double angle, mag;
292    
293     if (sscanf(s, "%lf", &angle) != 1) {
294     error(COMMAND, "missing angle");
295     return;
296     }
297     if (getinterest(sskip(s), 0, vc, &mag) < 0)
298     return;
299     moveview(angle, mag, vc);
300     }
301    
302    
303     getexposure(s) /* get new exposure */
304     char *s;
305     {
306     double atof(), pow(), fabs();
307     char buf[128];
308     register char *cp;
309     register PNODE *p;
310     RECT r;
311     int x, y;
312     double e;
313    
314     for (cp = s; isspace(*cp); cp++)
315     ;
316     if (*cp == '\0') { /* normalize to point */
317     if (dev->getcur == NULL)
318     return;
319     (*dev->comout)("Pick point for exposure\n");
320     if ((*dev->getcur)(&x, &y) == ABORT)
321     return;
322     r.l = r.d = 0;
323     r.r = ourview.hresolu; r.u = ourview.vresolu;
324     p = findrect(x, y, &ptrunk, &r, -1);
325     e = 1.0;
326     } else {
327     if (*cp == '=') { /* absolute setting */
328     p = NULL;
329     e = 1.0/exposure;
330     for (cp++; isspace(*cp); cp++)
331     ;
332     if (*cp == '\0') { /* interactive */
333     sprintf(buf, "exposure (%lf): ", exposure);
334     (*dev->comout)(buf);
335     (*dev->comin)(buf);
336     for (cp = buf; isspace(*cp); cp++)
337     ;
338     if (*cp == '\0')
339     return;
340     }
341     } else { /* normalize to average */
342     p = &ptrunk;
343     e = 1.0;
344     }
345     if (*cp == '+' || *cp == '-') /* f-stops */
346     e *= pow(2.0, atof(cp));
347     else /* multiplier */
348     e *= atof(cp);
349     }
350     if (p != NULL) { /* relative setting */
351     if (intens(p->v) <= FTINY) {
352     error(COMMAND, "cannot normalize to zero");
353     return;
354     }
355     e *= 0.5 / intens(p->v);
356     }
357     if (e <= FTINY || fabs(1.0 - e) <= FTINY)
358     return;
359     scalepict(&ptrunk, e);
360     exposure *= e;
361     redraw();
362     }
363    
364    
365     setparam(s) /* get/set program parameter */
366     register char *s;
367     {
368     extern int psample;
369     extern double maxdiff;
370     extern double minweight;
371     extern int maxdepth;
372     extern double dstrsrc;
373     extern COLOR ambval;
374     extern double ambacc;
375     extern double minarad;
376     extern int ambres;
377     extern int ambdiv;
378     extern int ambssamp;
379     extern int ambounce;
380     int i0;
381     double d0, d1, d2;
382     char buf[128];
383    
384     if (s[0] == '\0') {
385     (*dev->comout)("aa ab ad ar as av ds lr lw sd sp: ");
386     (*dev->comin)(buf);
387     s = buf;
388     }
389     switch (s[0]) {
390     case 'l': /* limit */
391     switch (s[1]) {
392     case 'w': /* weight */
393     if (sscanf(s+2, "%lf", &d0) != 1) {
394     sprintf(buf, "limit weight (%.6g): ",
395     minweight);
396     (*dev->comout)(buf);
397     (*dev->comin)(buf);
398     if (sscanf(buf, "%lf", &d0) != 1)
399     break;
400     }
401     minweight = d0;
402     break;
403     case 'r': /* reflection */
404     if (sscanf(s+2, "%d", &i0) != 1) {
405     sprintf(buf, "limit reflection (%d): ",
406     maxdepth);
407     (*dev->comout)(buf);
408     (*dev->comin)(buf);
409     if (sscanf(buf, "%d", &i0) != 1)
410     break;
411     }
412     maxdepth = i0;
413     break;
414     default:
415     goto badparam;
416     }
417     break;
418     case 'd': /* distribute source */
419     if (s[1] != 's')
420     goto badparam;
421     if (sscanf(s+2, "%lf", &d0) != 1) {
422     sprintf(buf, "distribute source (%.6g): ", dstrsrc);
423     (*dev->comout)(buf);
424     (*dev->comin)(buf);
425     if (sscanf(buf, "%lf", &d0) != 1)
426     break;
427     }
428     dstrsrc = d0;
429     break;
430     case 'a': /* ambient */
431     switch (s[1]) {
432     case 'v': /* value */
433     if (sscanf(s+2, "%lf %lf %lf", &d0, &d1, &d2) != 3) {
434     sprintf(buf,
435     "ambient value (%.6g %.6g %.6g): ",
436     colval(ambval,RED),
437     colval(ambval,GRN),
438     colval(ambval,BLU));
439     (*dev->comout)(buf);
440     (*dev->comin)(buf);
441     if (sscanf(buf, "%lf %lf %lf",
442     &d0, &d1, &d2) != 3)
443     break;
444     }
445     setcolor(ambval, d0, d1, d2);
446     break;
447     case 'a': /* accuracy */
448     if (sscanf(s+2, "%lf", &d0) != 1) {
449     sprintf(buf, "ambient accuracy (%.6g): ",
450     ambacc);
451     (*dev->comout)(buf);
452     (*dev->comin)(buf);
453     if (sscanf(buf, "%lf", &d0) != 1)
454     break;
455     }
456     ambacc = d0;
457     break;
458     case 'd': /* divisions */
459     if (sscanf(s+2, "%d", &i0) != 1) {
460     sprintf(buf, "ambient divisions (%d): ",
461     ambdiv);
462     (*dev->comout)(buf);
463     (*dev->comin)(buf);
464     if (sscanf(buf, "%d", &i0) != 1)
465     break;
466     }
467     ambdiv = i0;
468     break;
469     case 's': /* samples */
470     if (sscanf(s+2, "%d", &i0) != 1) {
471     sprintf(buf, "ambient super-samples (%d): ",
472     ambssamp);
473     (*dev->comout)(buf);
474     (*dev->comin)(buf);
475     if (sscanf(buf, "%d", &i0) != 1)
476     break;
477     }
478     ambssamp = i0;
479     break;
480     case 'b': /* bounces */
481     if (sscanf(s+2, "%d", &i0) != 1) {
482     sprintf(buf, "ambient bounces (%d): ",
483     ambounce);
484     (*dev->comout)(buf);
485     (*dev->comin)(buf);
486     if (sscanf(buf, "%d", &i0) != 1)
487     break;
488     }
489     ambounce = i0;
490     break;
491     case 'r':
492     if (sscanf(s+2, "%d", &i0) != 1) {
493     sprintf(buf, "ambient resolution (%d): ",
494     ambres);
495     (*dev->comout)(buf);
496     (*dev->comin)(buf);
497     if (sscanf(buf, "%d", &i0) != 1)
498     break;
499     }
500     ambres = i0;
501     minarad = ambres > 0 ? thescene.cusize/ambres : 0.0;
502     break;
503     default:
504     goto badparam;
505     }
506     break;
507     case 's': /* sample */
508     switch (s[1]) {
509     case 'p': /* pixel */
510     if (sscanf(s+2, "%d", &i0) != 1) {
511     sprintf(buf, "sample pixel (%d): ", psample);
512     (*dev->comout)(buf);
513     (*dev->comin)(buf);
514     if (sscanf(buf, "%d", &i0) != 1)
515     break;
516     }
517     psample = i0;
518     pdepth = 0;
519     break;
520     case 'd': /* difference */
521     if (sscanf(s+2, "%lf", &d0) != 1) {
522     sprintf(buf, "sample difference (%.6g): ",
523     maxdiff);
524     (*dev->comout)(buf);
525     (*dev->comin)(buf);
526     if (sscanf(buf, "%lf", &d0) != 1)
527     break;
528     }
529     maxdiff = d0;
530     pdepth = 0;
531     break;
532     default:
533     goto badparam;
534     }
535     break;
536     case '\0': /* nothing */
537     break;
538     default:;
539     badparam:
540     sprintf(errmsg, "%s: unknown variable", s);
541     error(COMMAND, errmsg);
542     break;
543     }
544     }
545    
546    
547     traceray(s) /* trace a single ray */
548     char *s;
549     {
550     char buf[128];
551     int x, y;
552     RAY thisray;
553    
554     if (sscanf(s, "%lf %lf %lf %lf %lf %lf",
555     &thisray.rorg[0], &thisray.rorg[1], &thisray.rorg[2],
556     &thisray.rdir[0], &thisray.rdir[1], &thisray.rdir[2]) != 6) {
557    
558     if (dev->getcur == NULL)
559     return;
560     (*dev->comout)("Pick ray\n");
561     if ((*dev->getcur)(&x, &y) == ABORT)
562     return;
563    
564     rayview(thisray.rorg, thisray.rdir, &ourview, x+.5, y+.5);
565    
566     } else if (normalize(thisray.rdir) == 0.0) {
567     error(COMMAND, "zero ray direction");
568     return;
569     }
570    
571     rayorigin(&thisray, NULL, PRIMARY, 1.0);
572    
573     rayvalue(&thisray);
574    
575     if (thisray.ro == NULL)
576     (*dev->comout)("ray hit nothing");
577     else {
578     sprintf(buf, "ray hit %s %s \"%s\"",
579     objptr(thisray.ro->omod)->oname,
580     ofun[thisray.ro->otype].funame,
581     thisray.ro->oname);
582     (*dev->comout)(buf);
583     (*dev->comin)(buf);
584     if (thisray.rot >= FHUGE)
585     (*dev->comout)("at infinity");
586     else {
587     sprintf(buf, "at (%.6g %.6g %.6g)", thisray.rop[0],
588     thisray.rop[1], thisray.rop[2]);
589     (*dev->comout)(buf);
590     }
591     (*dev->comin)(buf);
592     sprintf(buf, "with value (%.6g %.6g %.6g)",
593     colval(thisray.rcol,RED),
594     colval(thisray.rcol,GRN),
595     colval(thisray.rcol,BLU));
596     (*dev->comout)(buf);
597     }
598     (*dev->comin)(buf);
599     }
600    
601    
602     writepict(s) /* write the picture to a file */
603     char *s;
604     {
605     static char buf[128];
606     char *fname, *getpath();
607     FILE *fp;
608     COLR *scanline;
609     int y;
610    
611     if (sscanf(s, "%s", buf) != 1 && buf[0] == '\0') {
612     error(COMMAND, "no file");
613     return;
614     }
615     if ((fname = getpath(buf, NULL)) == NULL ||
616     (fp = fopen(fname, "w")) == NULL) {
617     sprintf(errmsg, "cannot open \"%s\"", buf);
618     error(COMMAND, errmsg);
619     return;
620     }
621     (*dev->comout)("writing \"");
622     (*dev->comout)(fname);
623     (*dev->comout)("\"...\n");
624     /* write header */
625     fputs(progname, fp);
626     fprintview(&ourview, fp);
627     fputs("\n", fp);
628     if (exposure != 1.0)
629     fprintf(fp, "EXPOSURE=%e\n", exposure);
630     fprintf(fp, "\n-Y %d +X %d\n", ourview.vresolu, ourview.hresolu);
631    
632     scanline = (COLR *)malloc(ourview.hresolu*sizeof(COLR));
633     if (scanline == NULL)
634     error(SYSTEM, "out of memory in writepict");
635     for (y = ourview.vresolu-1; y >= 0; y--) {
636     getpictcolrs(y, scanline, &ptrunk,
637     ourview.hresolu, ourview.vresolu);
638     if (fwritecolrs(scanline, ourview.hresolu, fp) < 0)
639     break;
640     }
641     if (fclose(fp) < 0)
642     error(COMMAND, "write error");
643     free((char *)scanline);
644     }