ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rv2.c
Revision: 2.8
Committed: Wed Mar 4 16:52:10 1992 UTC (32 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.7: +1 -3 lines
Log Message:
improved assignment and use of minarad and maxarad

File Contents

# User Rev Content
1 greg 1.26 /* Copyright (c) 1991 Regents of the University of California */
2 greg 1.1
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 greg 1.33 #include "resolu.h"
22    
23 greg 1.1 #include <ctype.h>
24    
25 greg 2.4 #define CTRL(c) ((c)-'@')
26 greg 1.1
27 greg 2.6 #ifdef SMLFLT
28     #define sscanvec(s,v) (sscanf(s,"%f %f %f",v,v+1,v+2)==3)
29     #else
30     #define sscanvec(s,v) (sscanf(s,"%lf %lf %lf",v,v+1,v+2)==3)
31     #endif
32    
33    
34 greg 1.29 extern char VersionID[];
35 greg 1.1 extern char *progname;
36 greg 1.29 extern char *octname;
37 greg 1.1
38    
39     getframe(s) /* get a new frame */
40     char *s;
41     {
42 greg 1.12 if (getrect(s, &pframe) < 0)
43 greg 1.1 return;
44     pdepth = 0;
45     }
46    
47    
48 greg 1.12 getrepaint(s) /* get area and repaint */
49     char *s;
50     {
51     RECT box;
52    
53     if (getrect(s, &box) < 0)
54     return;
55 greg 1.14 paintrect(&ptrunk, 0, 0, hresolu, vresolu, &box);
56 greg 1.12 }
57    
58    
59 greg 1.1 getview(s) /* get/show view parameters */
60     char *s;
61     {
62     FILE *fp;
63     char buf[128];
64 greg 1.10 char *fname;
65 greg 1.3 int change = 0;
66 greg 1.1 VIEW nv;
67    
68     if (sscanf(s, "%s", buf) == 1) { /* write parameters to a file */
69 greg 1.10 if ((fname = getpath(buf, NULL, 0)) == NULL ||
70 greg 1.1 (fp = fopen(fname, "a")) == NULL) {
71     sprintf(errmsg, "cannot open \"%s\"", buf);
72     error(COMMAND, errmsg);
73     return;
74     }
75 greg 1.2 fputs(progname, fp);
76 greg 1.1 fprintview(&ourview, fp);
77 greg 1.19 fputs(sskip(s), fp);
78 greg 1.1 fputs("\n", fp);
79     fclose(fp);
80     return;
81     }
82     sprintf(buf, "view type (%c): ", ourview.type);
83     (*dev->comout)(buf);
84 greg 1.18 (*dev->comin)(buf, NULL);
85 greg 2.4 if (buf[0] == CTRL('C')) return;
86 greg 1.3 if (buf[0] && buf[0] != ourview.type) {
87 greg 1.1 nv.type = buf[0];
88 greg 1.3 change++;
89     } else
90 greg 1.1 nv.type = ourview.type;
91     sprintf(buf, "view point (%.6g %.6g %.6g): ",
92     ourview.vp[0], ourview.vp[1], ourview.vp[2]);
93     (*dev->comout)(buf);
94 greg 1.18 (*dev->comin)(buf, NULL);
95 greg 2.4 if (buf[0] == CTRL('C')) return;
96 greg 2.6 if (sscanvec(buf, nv.vp))
97 greg 1.3 change++;
98     else
99 greg 1.1 VCOPY(nv.vp, ourview.vp);
100     sprintf(buf, "view direction (%.6g %.6g %.6g): ",
101     ourview.vdir[0], ourview.vdir[1], ourview.vdir[2]);
102     (*dev->comout)(buf);
103 greg 1.18 (*dev->comin)(buf, NULL);
104 greg 2.4 if (buf[0] == CTRL('C')) return;
105 greg 2.6 if (sscanvec(buf, nv.vdir))
106 greg 1.3 change++;
107     else
108 greg 1.1 VCOPY(nv.vdir, ourview.vdir);
109     sprintf(buf, "view up (%.6g %.6g %.6g): ",
110     ourview.vup[0], ourview.vup[1], ourview.vup[2]);
111     (*dev->comout)(buf);
112 greg 1.18 (*dev->comin)(buf, NULL);
113 greg 2.4 if (buf[0] == CTRL('C')) return;
114 greg 2.6 if (sscanvec(buf, nv.vup))
115 greg 1.3 change++;
116     else
117 greg 1.1 VCOPY(nv.vup, ourview.vup);
118     sprintf(buf, "view horiz and vert size (%.6g %.6g): ",
119     ourview.horiz, ourview.vert);
120     (*dev->comout)(buf);
121 greg 1.18 (*dev->comin)(buf, NULL);
122 greg 2.4 if (buf[0] == CTRL('C')) return;
123 greg 1.3 if (sscanf(buf, "%lf %lf", &nv.horiz, &nv.vert) == 2)
124     change++;
125     else {
126 greg 1.1 nv.horiz = ourview.horiz; nv.vert = ourview.vert;
127     }
128 greg 1.14 sprintf(buf, "view shift and lift (%.6g %.6g): ",
129     ourview.hoff, ourview.voff);
130 greg 1.1 (*dev->comout)(buf);
131 greg 1.18 (*dev->comin)(buf, NULL);
132 greg 2.4 if (buf[0] == CTRL('C')) return;
133 greg 1.14 if (sscanf(buf, "%lf %lf", &nv.hoff, &nv.voff) == 2)
134 greg 1.3 change++;
135     else {
136 greg 1.14 nv.hoff = ourview.hoff; nv.voff = ourview.voff;
137 greg 1.1 }
138 greg 1.3 if (change)
139     newview(&nv);
140 greg 1.1 }
141    
142    
143     lastview(s) /* return to a previous view */
144     char *s;
145     {
146     char buf[128];
147 greg 1.10 char *fname;
148 greg 1.1 int success;
149     VIEW nv;
150    
151     if (sscanf(s, "%s", buf) == 1) { /* get parameters from a file */
152 greg 1.17 copystruct(&nv, &stdview);
153 greg 1.10 if ((fname = getpath(buf, NULL, 0)) == NULL ||
154 greg 1.33 (success = viewfile(fname, &nv, NULL)) == -1) {
155 greg 1.1 sprintf(errmsg, "cannot open \"%s\"", buf);
156     error(COMMAND, errmsg);
157     return;
158     }
159     if (!success)
160     error(COMMAND, "wrong file format");
161     else
162     newview(&nv);
163     return;
164     }
165 greg 1.20 if (oldview.type == 0) { /* no old view! */
166 greg 1.1 error(COMMAND, "no previous view");
167     return;
168     }
169 greg 1.17 copystruct(&nv, &ourview);
170     copystruct(&ourview, &oldview);
171     copystruct(&oldview, &nv);
172 greg 1.1 newimage();
173     }
174    
175    
176     getaim(s) /* aim camera */
177     char *s;
178     {
179     extern double tan(), atan();
180     double zfact;
181     VIEW nv;
182    
183     if (getinterest(s, 1, nv.vdir, &zfact) < 0)
184     return;
185 greg 1.21 nv.type = ourview.type;
186 greg 1.1 VCOPY(nv.vp, ourview.vp);
187     VCOPY(nv.vup, ourview.vup);
188 greg 1.14 nv.hoff = ourview.hoff; nv.voff = ourview.voff;
189 greg 1.21 nv.horiz = ourview.horiz; nv.vert = ourview.vert;
190     zoomview(&nv, zfact);
191 greg 1.1 newview(&nv);
192     }
193    
194    
195     getmove(s) /* move camera */
196     char *s;
197     {
198     FVECT vc;
199     double mag;
200    
201     if (getinterest(s, 0, vc, &mag) < 0)
202     return;
203 greg 1.4 moveview(0.0, 0.0, mag, vc);
204 greg 1.1 }
205    
206    
207     getrotate(s) /* rotate camera */
208     char *s;
209     {
210 greg 1.4 extern double normalize(), tan(), atan();
211 greg 1.1 VIEW nv;
212     FVECT v1;
213 greg 1.4 double angle, elev, zfact;
214 greg 1.1
215 greg 1.4 elev = 0.0; zfact = 1.0;
216     if (sscanf(s, "%lf %lf %lf", &angle, &elev, &zfact) < 1) {
217 greg 1.1 error(COMMAND, "missing angle");
218     return;
219     }
220 greg 1.21 nv.type = ourview.type;
221 greg 1.1 VCOPY(nv.vp, ourview.vp);
222     VCOPY(nv.vup, ourview.vup);
223 greg 1.14 nv.hoff = ourview.hoff; nv.voff = ourview.voff;
224 greg 1.1 spinvector(nv.vdir, ourview.vdir, ourview.vup, angle*(PI/180.));
225     if (elev != 0.0) {
226     fcross(v1, nv.vdir, ourview.vup);
227     normalize(v1);
228     spinvector(nv.vdir, nv.vdir, v1, elev*(PI/180.));
229     }
230 greg 1.21 nv.horiz = ourview.horiz; nv.vert = ourview.vert;
231     zoomview(&nv, zfact);
232 greg 1.1 newview(&nv);
233     }
234    
235    
236     getpivot(s) /* pivot viewpoint */
237     register char *s;
238     {
239     FVECT vc;
240 greg 1.4 double angle, elev, mag;
241 greg 1.1
242 greg 1.4 elev = 0.0;
243     if (sscanf(s, "%lf %lf", &angle, &elev) < 1) {
244 greg 1.1 error(COMMAND, "missing angle");
245     return;
246     }
247 greg 1.4 if (getinterest(sskip(sskip(s)), 0, vc, &mag) < 0)
248 greg 1.1 return;
249 greg 1.4 moveview(angle, elev, mag, vc);
250 greg 1.1 }
251    
252    
253     getexposure(s) /* get new exposure */
254     char *s;
255     {
256     char buf[128];
257     register char *cp;
258     register PNODE *p;
259     RECT r;
260     int x, y;
261     double e;
262    
263     for (cp = s; isspace(*cp); cp++)
264     ;
265     if (*cp == '\0') { /* normalize to point */
266     if (dev->getcur == NULL)
267     return;
268     (*dev->comout)("Pick point for exposure\n");
269     if ((*dev->getcur)(&x, &y) == ABORT)
270     return;
271     r.l = r.d = 0;
272 greg 1.14 r.r = hresolu; r.u = vresolu;
273 greg 1.1 p = findrect(x, y, &ptrunk, &r, -1);
274     e = 1.0;
275     } else {
276     if (*cp == '=') { /* absolute setting */
277     p = NULL;
278     e = 1.0/exposure;
279     for (cp++; isspace(*cp); cp++)
280     ;
281     if (*cp == '\0') { /* interactive */
282     sprintf(buf, "exposure (%lf): ", exposure);
283     (*dev->comout)(buf);
284 greg 1.18 (*dev->comin)(buf, NULL);
285 greg 1.1 for (cp = buf; isspace(*cp); cp++)
286     ;
287     if (*cp == '\0')
288     return;
289     }
290     } else { /* normalize to average */
291     p = &ptrunk;
292     e = 1.0;
293     }
294     if (*cp == '+' || *cp == '-') /* f-stops */
295     e *= pow(2.0, atof(cp));
296     else /* multiplier */
297     e *= atof(cp);
298     }
299     if (p != NULL) { /* relative setting */
300 greg 2.7 if (bright(p->v) < 1e-25) {
301 greg 1.1 error(COMMAND, "cannot normalize to zero");
302     return;
303     }
304 greg 1.6 e *= 0.5 / bright(p->v);
305 greg 1.1 }
306     if (e <= FTINY || fabs(1.0 - e) <= FTINY)
307     return;
308     scalepict(&ptrunk, e);
309     exposure *= e;
310     redraw();
311     }
312    
313    
314 greg 1.24 getparam(str, dsc, typ, ptr) /* get variable from user */
315     char *str, *dsc;
316     int typ;
317     register union {int i; double d; COLOR C;} *ptr;
318     {
319 greg 1.25 extern char *index();
320 greg 1.24 int i0;
321     double d0, d1, d2;
322     char buf[48];
323    
324     switch (typ) {
325     case 'i': /* integer */
326     if (sscanf(str, "%d", &i0) != 1) {
327     (*dev->comout)(dsc);
328     sprintf(buf, " (%d): ", ptr->i);
329     (*dev->comout)(buf);
330     (*dev->comin)(buf, NULL);
331     if (sscanf(buf, "%d", &i0) != 1)
332 greg 1.31 return(0);
333 greg 1.24 }
334     ptr->i = i0;
335 greg 1.31 return(1);
336 greg 1.24 case 'r': /* real */
337     if (sscanf(str, "%lf", &d0) != 1) {
338     (*dev->comout)(dsc);
339     sprintf(buf, " (%.6g): ", ptr->d);
340     (*dev->comout)(buf);
341     (*dev->comin)(buf, NULL);
342     if (sscanf(buf, "%lf", &d0) != 1)
343 greg 1.31 return(0);
344 greg 1.24 }
345     ptr->d = d0;
346 greg 1.31 return(1);
347 greg 1.24 case 'b': /* boolean */
348     if (sscanf(str, "%1s", buf) != 1) {
349     (*dev->comout)(dsc);
350 greg 2.2 sprintf(buf, "? (%c): ", ptr->i ? 'y' : 'n');
351 greg 1.24 (*dev->comout)(buf);
352     (*dev->comin)(buf, NULL);
353 greg 1.25 if (buf[0] == '\0' ||
354     index("yY+1tTnN-0fF", buf[0]) == NULL)
355 greg 1.31 return(0);
356 greg 1.24 }
357 greg 1.25 ptr->i = index("yY+1tT", buf[0]) != NULL;
358 greg 1.31 return(1);
359 greg 1.24 case 'C': /* color */
360     if (sscanf(str, "%lf %lf %lf", &d0, &d1, &d2) != 3) {
361     (*dev->comout)(dsc);
362     sprintf(buf, " (%.6g %.6g %.6g): ",
363     colval(ptr->C,RED),
364     colval(ptr->C,GRN),
365     colval(ptr->C,BLU));
366     (*dev->comout)(buf);
367     (*dev->comin)(buf, NULL);
368     if (sscanf(buf, "%lf %lf %lf", &d0, &d1, &d2) != 3)
369 greg 1.31 return(0);
370 greg 1.24 }
371     setcolor(ptr->C, d0, d1, d2);
372 greg 1.31 return(1);
373 greg 1.24 }
374     }
375    
376    
377 greg 1.1 setparam(s) /* get/set program parameter */
378     register char *s;
379     {
380     extern int psample;
381     extern double maxdiff;
382     extern double minweight;
383     extern int maxdepth;
384     extern double dstrsrc;
385 greg 1.5 extern double shadthresh;
386 greg 1.9 extern double shadcert;
387 greg 1.1 extern COLOR ambval;
388     extern double ambacc;
389     extern int ambres;
390     extern int ambdiv;
391     extern int ambssamp;
392     extern int ambounce;
393 greg 1.23 extern int directinvis;
394 greg 1.30 extern double srcsizerat;
395 greg 1.23 extern int do_irrad;
396 greg 2.5 extern double specjitter;
397     extern double specthresh;
398 greg 1.24 char buf[128];
399 greg 1.1
400     if (s[0] == '\0') {
401 greg 1.23 (*dev->comout)(
402 greg 2.5 "aa ab ad ar as av b dc di dj ds dt i lr lw ps pt sj st: ");
403 greg 1.18 (*dev->comin)(buf, NULL);
404 greg 1.1 s = buf;
405     }
406     switch (s[0]) {
407     case 'l': /* limit */
408     switch (s[1]) {
409     case 'w': /* weight */
410 greg 1.24 getparam(s+2, "limit weight", 'r', &minweight);
411 greg 1.1 break;
412     case 'r': /* reflection */
413 greg 1.24 getparam(s+2, "limit reflection", 'i', &maxdepth);
414 greg 1.1 break;
415     default:
416     goto badparam;
417     }
418     break;
419 greg 1.5 case 'd': /* direct */
420     switch (s[1]) {
421     case 'j': /* jitter */
422 greg 1.24 getparam(s+2, "direct jitter", 'r', &dstrsrc);
423 greg 1.9 break;
424     case 'c': /* certainty */
425 greg 1.24 getparam(s+2, "direct certainty", 'r', &shadcert);
426 greg 1.5 break;
427 greg 1.8 case 't': /* threshold */
428 greg 1.24 getparam(s+2, "direct threshold", 'r', &shadthresh);
429 greg 1.5 break;
430 greg 1.23 case 'i': /* invisibility */
431 greg 1.24 getparam(s+2, "direct invisibility",
432     'b', &directinvis);
433 greg 1.30 break;
434     case 's': /* sampling */
435     getparam(s+2, "direct sampling", 'r', &srcsizerat);
436 greg 1.23 break;
437 greg 1.5 default:
438 greg 1.1 goto badparam;
439     }
440 greg 1.23 break;
441     case 'b': /* black and white */
442 greg 1.24 getparam(s+1, "black and white", 'b', &greyscale);
443 greg 1.23 break;
444     case 'i': /* irradiance */
445 greg 1.24 getparam(s+1, "irradiance", 'b', &do_irrad);
446 greg 1.1 break;
447     case 'a': /* ambient */
448     switch (s[1]) {
449     case 'v': /* value */
450 greg 1.24 getparam(s+2, "ambient value", 'C', ambval);
451 greg 1.1 break;
452     case 'a': /* accuracy */
453 greg 1.24 getparam(s+2, "ambient accuracy", 'r', &ambacc);
454 greg 1.1 break;
455     case 'd': /* divisions */
456 greg 1.24 getparam(s+2, "ambient divisions", 'i', &ambdiv);
457 greg 1.1 break;
458     case 's': /* samples */
459 greg 1.24 getparam(s+2, "ambient super-samples", 'i', &ambssamp);
460 greg 1.1 break;
461     case 'b': /* bounces */
462 greg 1.24 getparam(s+2, "ambient bounces", 'i', &ambounce);
463 greg 1.1 break;
464     case 'r':
465 greg 1.31 if (getparam(s+2, "ambient resolution", 'i', &ambres))
466 greg 2.8 setambres(ambres);
467 greg 1.1 break;
468     default:
469     goto badparam;
470     }
471     break;
472 greg 2.5 case 'p': /* pixel */
473 greg 1.1 switch (s[1]) {
474 greg 2.5 case 's': /* sample */
475     if (getparam(s+2, "pixel sample", 'i', &psample))
476 greg 1.31 pdepth = 0;
477 greg 1.1 break;
478 greg 1.8 case 't': /* threshold */
479 greg 2.5 if (getparam(s+2, "pixel threshold", 'r', &maxdiff))
480 greg 1.31 pdepth = 0;
481 greg 2.5 break;
482     default:
483     goto badparam;
484     }
485     break;
486     case 's': /* specular */
487     switch (s[1]) {
488     case 'j': /* jitter */
489     getparam(s+2, "specular jitter", 'r', &specjitter);
490     break;
491     case 't': /* threshold */
492     getparam(s+2, "specular threshold", 'r', &specthresh);
493 greg 1.1 break;
494     default:
495     goto badparam;
496     }
497     break;
498     case '\0': /* nothing */
499     break;
500     default:;
501     badparam:
502 greg 1.26 *sskip(s) = '\0';
503 greg 1.1 sprintf(errmsg, "%s: unknown variable", s);
504     error(COMMAND, errmsg);
505     break;
506     }
507     }
508    
509    
510     traceray(s) /* trace a single ray */
511     char *s;
512     {
513     char buf[128];
514     int x, y;
515     RAY thisray;
516    
517 greg 2.6 if (!sscanvec(s, thisray.rorg) ||
518     !sscanvec(sskip(sskip(sskip(s))), thisray.rdir)) {
519 greg 1.1
520     if (dev->getcur == NULL)
521     return;
522     (*dev->comout)("Pick ray\n");
523     if ((*dev->getcur)(&x, &y) == ABORT)
524     return;
525    
526 greg 1.21 if (viewray(thisray.rorg, thisray.rdir, &ourview,
527     (x+.5)/hresolu, (y+.5)/vresolu) < 0) {
528     error(COMMAND, "not on image");
529     return;
530     }
531    
532 greg 1.1 } else if (normalize(thisray.rdir) == 0.0) {
533     error(COMMAND, "zero ray direction");
534     return;
535     }
536    
537     rayorigin(&thisray, NULL, PRIMARY, 1.0);
538    
539     rayvalue(&thisray);
540    
541     if (thisray.ro == NULL)
542     (*dev->comout)("ray hit nothing");
543     else {
544     sprintf(buf, "ray hit %s %s \"%s\"",
545     objptr(thisray.ro->omod)->oname,
546     ofun[thisray.ro->otype].funame,
547     thisray.ro->oname);
548     (*dev->comout)(buf);
549 greg 1.18 (*dev->comin)(buf, NULL);
550 greg 1.1 if (thisray.rot >= FHUGE)
551     (*dev->comout)("at infinity");
552     else {
553     sprintf(buf, "at (%.6g %.6g %.6g)", thisray.rop[0],
554     thisray.rop[1], thisray.rop[2]);
555     (*dev->comout)(buf);
556     }
557 greg 1.18 (*dev->comin)(buf, NULL);
558 greg 1.32 sprintf(buf, "value (%.5g %.5g %.5g) (%.1fL)",
559 greg 1.1 colval(thisray.rcol,RED),
560     colval(thisray.rcol,GRN),
561 greg 1.32 colval(thisray.rcol,BLU),
562     luminance(thisray.rcol));
563 greg 1.1 (*dev->comout)(buf);
564     }
565 greg 1.18 (*dev->comin)(buf, NULL);
566 greg 1.1 }
567    
568    
569     writepict(s) /* write the picture to a file */
570     char *s;
571     {
572     static char buf[128];
573 greg 1.10 char *fname;
574 greg 1.1 FILE *fp;
575     COLR *scanline;
576     int y;
577    
578     if (sscanf(s, "%s", buf) != 1 && buf[0] == '\0') {
579     error(COMMAND, "no file");
580     return;
581     }
582 greg 1.10 if ((fname = getpath(buf, NULL, 0)) == NULL ||
583 greg 1.1 (fp = fopen(fname, "w")) == NULL) {
584     sprintf(errmsg, "cannot open \"%s\"", buf);
585     error(COMMAND, errmsg);
586     return;
587     }
588     (*dev->comout)("writing \"");
589     (*dev->comout)(fname);
590     (*dev->comout)("\"...\n");
591     /* write header */
592     fputs(progname, fp);
593     fprintview(&ourview, fp);
594 greg 1.29 if (octname != NULL)
595     fprintf(fp, " %s\n", octname);
596     else
597     putc('\n', fp);
598 greg 1.28 fprintf(fp, "SOFTWARE= %s\n", VersionID);
599 greg 1.1 if (exposure != 1.0)
600 greg 1.13 fputexpos(exposure, fp);
601 greg 1.15 if (dev->pixaspect != 1.0)
602     fputaspect(dev->pixaspect, fp);
603 greg 1.22 fputformat(COLRFMT, fp);
604 greg 1.11 putc('\n', fp);
605 greg 1.33 fprtresolu(hresolu, vresolu, fp);
606 greg 1.1
607 greg 1.14 scanline = (COLR *)malloc(hresolu*sizeof(COLR));
608 greg 1.27 if (scanline == NULL) {
609     error(COMMAND, "not enough memory!");
610     fclose(fp);
611     unlink(fname);
612     return;
613     }
614 greg 1.14 for (y = vresolu-1; y >= 0; y--) {
615     getpictcolrs(y, scanline, &ptrunk, hresolu, vresolu);
616     if (fwritecolrs(scanline, hresolu, fp) < 0)
617 greg 1.1 break;
618     }
619 greg 1.27 free((char *)scanline);
620 greg 1.1 if (fclose(fp) < 0)
621     error(COMMAND, "write error");
622     }