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

# Content
1 /* Copyright (c) 1991 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 "resolu.h"
22
23 #include <ctype.h>
24
25 #define CTRL(c) ((c)-'@')
26
27 #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 extern char VersionID[];
35 extern char *progname;
36 extern char *octname;
37
38
39 getframe(s) /* get a new frame */
40 char *s;
41 {
42 if (getrect(s, &pframe) < 0)
43 return;
44 pdepth = 0;
45 }
46
47
48 getrepaint(s) /* get area and repaint */
49 char *s;
50 {
51 RECT box;
52
53 if (getrect(s, &box) < 0)
54 return;
55 paintrect(&ptrunk, 0, 0, hresolu, vresolu, &box);
56 }
57
58
59 getview(s) /* get/show view parameters */
60 char *s;
61 {
62 FILE *fp;
63 char buf[128];
64 char *fname;
65 int change = 0;
66 VIEW nv;
67
68 if (sscanf(s, "%s", buf) == 1) { /* write parameters to a file */
69 if ((fname = getpath(buf, NULL, 0)) == NULL ||
70 (fp = fopen(fname, "a")) == NULL) {
71 sprintf(errmsg, "cannot open \"%s\"", buf);
72 error(COMMAND, errmsg);
73 return;
74 }
75 fputs(progname, fp);
76 fprintview(&ourview, fp);
77 fputs(sskip(s), fp);
78 fputs("\n", fp);
79 fclose(fp);
80 return;
81 }
82 sprintf(buf, "view type (%c): ", ourview.type);
83 (*dev->comout)(buf);
84 (*dev->comin)(buf, NULL);
85 if (buf[0] == CTRL('C')) return;
86 if (buf[0] && buf[0] != ourview.type) {
87 nv.type = buf[0];
88 change++;
89 } else
90 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 (*dev->comin)(buf, NULL);
95 if (buf[0] == CTRL('C')) return;
96 if (sscanvec(buf, nv.vp))
97 change++;
98 else
99 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 (*dev->comin)(buf, NULL);
104 if (buf[0] == CTRL('C')) return;
105 if (sscanvec(buf, nv.vdir))
106 change++;
107 else
108 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 (*dev->comin)(buf, NULL);
113 if (buf[0] == CTRL('C')) return;
114 if (sscanvec(buf, nv.vup))
115 change++;
116 else
117 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 (*dev->comin)(buf, NULL);
122 if (buf[0] == CTRL('C')) return;
123 if (sscanf(buf, "%lf %lf", &nv.horiz, &nv.vert) == 2)
124 change++;
125 else {
126 nv.horiz = ourview.horiz; nv.vert = ourview.vert;
127 }
128 sprintf(buf, "view shift and lift (%.6g %.6g): ",
129 ourview.hoff, ourview.voff);
130 (*dev->comout)(buf);
131 (*dev->comin)(buf, NULL);
132 if (buf[0] == CTRL('C')) return;
133 if (sscanf(buf, "%lf %lf", &nv.hoff, &nv.voff) == 2)
134 change++;
135 else {
136 nv.hoff = ourview.hoff; nv.voff = ourview.voff;
137 }
138 if (change)
139 newview(&nv);
140 }
141
142
143 lastview(s) /* return to a previous view */
144 char *s;
145 {
146 char buf[128];
147 char *fname;
148 int success;
149 VIEW nv;
150
151 if (sscanf(s, "%s", buf) == 1) { /* get parameters from a file */
152 copystruct(&nv, &stdview);
153 if ((fname = getpath(buf, NULL, 0)) == NULL ||
154 (success = viewfile(fname, &nv, NULL)) == -1) {
155 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 if (oldview.type == 0) { /* no old view! */
166 error(COMMAND, "no previous view");
167 return;
168 }
169 copystruct(&nv, &ourview);
170 copystruct(&ourview, &oldview);
171 copystruct(&oldview, &nv);
172 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 nv.type = ourview.type;
186 VCOPY(nv.vp, ourview.vp);
187 VCOPY(nv.vup, ourview.vup);
188 nv.hoff = ourview.hoff; nv.voff = ourview.voff;
189 nv.horiz = ourview.horiz; nv.vert = ourview.vert;
190 zoomview(&nv, zfact);
191 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 moveview(0.0, 0.0, mag, vc);
204 }
205
206
207 getrotate(s) /* rotate camera */
208 char *s;
209 {
210 extern double normalize(), tan(), atan();
211 VIEW nv;
212 FVECT v1;
213 double angle, elev, zfact;
214
215 elev = 0.0; zfact = 1.0;
216 if (sscanf(s, "%lf %lf %lf", &angle, &elev, &zfact) < 1) {
217 error(COMMAND, "missing angle");
218 return;
219 }
220 nv.type = ourview.type;
221 VCOPY(nv.vp, ourview.vp);
222 VCOPY(nv.vup, ourview.vup);
223 nv.hoff = ourview.hoff; nv.voff = ourview.voff;
224 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 nv.horiz = ourview.horiz; nv.vert = ourview.vert;
231 zoomview(&nv, zfact);
232 newview(&nv);
233 }
234
235
236 getpivot(s) /* pivot viewpoint */
237 register char *s;
238 {
239 FVECT vc;
240 double angle, elev, mag;
241
242 elev = 0.0;
243 if (sscanf(s, "%lf %lf", &angle, &elev) < 1) {
244 error(COMMAND, "missing angle");
245 return;
246 }
247 if (getinterest(sskip(sskip(s)), 0, vc, &mag) < 0)
248 return;
249 moveview(angle, elev, mag, vc);
250 }
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 r.r = hresolu; r.u = vresolu;
273 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 (*dev->comin)(buf, NULL);
285 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 if (bright(p->v) < 1e-25) {
301 error(COMMAND, "cannot normalize to zero");
302 return;
303 }
304 e *= 0.5 / bright(p->v);
305 }
306 if (e <= FTINY || fabs(1.0 - e) <= FTINY)
307 return;
308 scalepict(&ptrunk, e);
309 exposure *= e;
310 redraw();
311 }
312
313
314 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 extern char *index();
320 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 return(0);
333 }
334 ptr->i = i0;
335 return(1);
336 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 return(0);
344 }
345 ptr->d = d0;
346 return(1);
347 case 'b': /* boolean */
348 if (sscanf(str, "%1s", buf) != 1) {
349 (*dev->comout)(dsc);
350 sprintf(buf, "? (%c): ", ptr->i ? 'y' : 'n');
351 (*dev->comout)(buf);
352 (*dev->comin)(buf, NULL);
353 if (buf[0] == '\0' ||
354 index("yY+1tTnN-0fF", buf[0]) == NULL)
355 return(0);
356 }
357 ptr->i = index("yY+1tT", buf[0]) != NULL;
358 return(1);
359 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 return(0);
370 }
371 setcolor(ptr->C, d0, d1, d2);
372 return(1);
373 }
374 }
375
376
377 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 extern double shadthresh;
386 extern double shadcert;
387 extern COLOR ambval;
388 extern double ambacc;
389 extern int ambres;
390 extern int ambdiv;
391 extern int ambssamp;
392 extern int ambounce;
393 extern int directinvis;
394 extern double srcsizerat;
395 extern int do_irrad;
396 extern double specjitter;
397 extern double specthresh;
398 char buf[128];
399
400 if (s[0] == '\0') {
401 (*dev->comout)(
402 "aa ab ad ar as av b dc di dj ds dt i lr lw ps pt sj st: ");
403 (*dev->comin)(buf, NULL);
404 s = buf;
405 }
406 switch (s[0]) {
407 case 'l': /* limit */
408 switch (s[1]) {
409 case 'w': /* weight */
410 getparam(s+2, "limit weight", 'r', &minweight);
411 break;
412 case 'r': /* reflection */
413 getparam(s+2, "limit reflection", 'i', &maxdepth);
414 break;
415 default:
416 goto badparam;
417 }
418 break;
419 case 'd': /* direct */
420 switch (s[1]) {
421 case 'j': /* jitter */
422 getparam(s+2, "direct jitter", 'r', &dstrsrc);
423 break;
424 case 'c': /* certainty */
425 getparam(s+2, "direct certainty", 'r', &shadcert);
426 break;
427 case 't': /* threshold */
428 getparam(s+2, "direct threshold", 'r', &shadthresh);
429 break;
430 case 'i': /* invisibility */
431 getparam(s+2, "direct invisibility",
432 'b', &directinvis);
433 break;
434 case 's': /* sampling */
435 getparam(s+2, "direct sampling", 'r', &srcsizerat);
436 break;
437 default:
438 goto badparam;
439 }
440 break;
441 case 'b': /* black and white */
442 getparam(s+1, "black and white", 'b', &greyscale);
443 break;
444 case 'i': /* irradiance */
445 getparam(s+1, "irradiance", 'b', &do_irrad);
446 break;
447 case 'a': /* ambient */
448 switch (s[1]) {
449 case 'v': /* value */
450 getparam(s+2, "ambient value", 'C', ambval);
451 break;
452 case 'a': /* accuracy */
453 getparam(s+2, "ambient accuracy", 'r', &ambacc);
454 break;
455 case 'd': /* divisions */
456 getparam(s+2, "ambient divisions", 'i', &ambdiv);
457 break;
458 case 's': /* samples */
459 getparam(s+2, "ambient super-samples", 'i', &ambssamp);
460 break;
461 case 'b': /* bounces */
462 getparam(s+2, "ambient bounces", 'i', &ambounce);
463 break;
464 case 'r':
465 if (getparam(s+2, "ambient resolution", 'i', &ambres))
466 setambres(ambres);
467 break;
468 default:
469 goto badparam;
470 }
471 break;
472 case 'p': /* pixel */
473 switch (s[1]) {
474 case 's': /* sample */
475 if (getparam(s+2, "pixel sample", 'i', &psample))
476 pdepth = 0;
477 break;
478 case 't': /* threshold */
479 if (getparam(s+2, "pixel threshold", 'r', &maxdiff))
480 pdepth = 0;
481 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 break;
494 default:
495 goto badparam;
496 }
497 break;
498 case '\0': /* nothing */
499 break;
500 default:;
501 badparam:
502 *sskip(s) = '\0';
503 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 if (!sscanvec(s, thisray.rorg) ||
518 !sscanvec(sskip(sskip(sskip(s))), thisray.rdir)) {
519
520 if (dev->getcur == NULL)
521 return;
522 (*dev->comout)("Pick ray\n");
523 if ((*dev->getcur)(&x, &y) == ABORT)
524 return;
525
526 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 } 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 (*dev->comin)(buf, NULL);
550 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 (*dev->comin)(buf, NULL);
558 sprintf(buf, "value (%.5g %.5g %.5g) (%.1fL)",
559 colval(thisray.rcol,RED),
560 colval(thisray.rcol,GRN),
561 colval(thisray.rcol,BLU),
562 luminance(thisray.rcol));
563 (*dev->comout)(buf);
564 }
565 (*dev->comin)(buf, NULL);
566 }
567
568
569 writepict(s) /* write the picture to a file */
570 char *s;
571 {
572 static char buf[128];
573 char *fname;
574 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 if ((fname = getpath(buf, NULL, 0)) == NULL ||
583 (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 if (octname != NULL)
595 fprintf(fp, " %s\n", octname);
596 else
597 putc('\n', fp);
598 fprintf(fp, "SOFTWARE= %s\n", VersionID);
599 if (exposure != 1.0)
600 fputexpos(exposure, fp);
601 if (dev->pixaspect != 1.0)
602 fputaspect(dev->pixaspect, fp);
603 fputformat(COLRFMT, fp);
604 putc('\n', fp);
605 fprtresolu(hresolu, vresolu, fp);
606
607 scanline = (COLR *)malloc(hresolu*sizeof(COLR));
608 if (scanline == NULL) {
609 error(COMMAND, "not enough memory!");
610 fclose(fp);
611 unlink(fname);
612 return;
613 }
614 for (y = vresolu-1; y >= 0; y--) {
615 getpictcolrs(y, scanline, &ptrunk, hresolu, vresolu);
616 if (fwritecolrs(scanline, hresolu, fp) < 0)
617 break;
618 }
619 free((char *)scanline);
620 if (fclose(fp) < 0)
621 error(COMMAND, "write error");
622 }