ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rv2.c
Revision: 2.6
Committed: Fri Jan 17 09:27:17 1992 UTC (32 years, 3 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.5: +12 -6 lines
Log Message:
fixed bug in use of scanf() with SMLFLT defined

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) <= FTINY) {
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 double minarad;
390 extern int ambres;
391 extern int ambdiv;
392 extern int ambssamp;
393 extern int ambounce;
394 extern int directinvis;
395 extern double srcsizerat;
396 extern int do_irrad;
397 extern double specjitter;
398 extern double specthresh;
399 char buf[128];
400
401 if (s[0] == '\0') {
402 (*dev->comout)(
403 "aa ab ad ar as av b dc di dj ds dt i lr lw ps pt sj st: ");
404 (*dev->comin)(buf, NULL);
405 s = buf;
406 }
407 switch (s[0]) {
408 case 'l': /* limit */
409 switch (s[1]) {
410 case 'w': /* weight */
411 getparam(s+2, "limit weight", 'r', &minweight);
412 break;
413 case 'r': /* reflection */
414 getparam(s+2, "limit reflection", 'i', &maxdepth);
415 break;
416 default:
417 goto badparam;
418 }
419 break;
420 case 'd': /* direct */
421 switch (s[1]) {
422 case 'j': /* jitter */
423 getparam(s+2, "direct jitter", 'r', &dstrsrc);
424 break;
425 case 'c': /* certainty */
426 getparam(s+2, "direct certainty", 'r', &shadcert);
427 break;
428 case 't': /* threshold */
429 getparam(s+2, "direct threshold", 'r', &shadthresh);
430 break;
431 case 'i': /* invisibility */
432 getparam(s+2, "direct invisibility",
433 'b', &directinvis);
434 break;
435 case 's': /* sampling */
436 getparam(s+2, "direct sampling", 'r', &srcsizerat);
437 break;
438 default:
439 goto badparam;
440 }
441 break;
442 case 'b': /* black and white */
443 getparam(s+1, "black and white", 'b', &greyscale);
444 break;
445 case 'i': /* irradiance */
446 getparam(s+1, "irradiance", 'b', &do_irrad);
447 break;
448 case 'a': /* ambient */
449 switch (s[1]) {
450 case 'v': /* value */
451 getparam(s+2, "ambient value", 'C', ambval);
452 break;
453 case 'a': /* accuracy */
454 getparam(s+2, "ambient accuracy", 'r', &ambacc);
455 break;
456 case 'd': /* divisions */
457 getparam(s+2, "ambient divisions", 'i', &ambdiv);
458 break;
459 case 's': /* samples */
460 getparam(s+2, "ambient super-samples", 'i', &ambssamp);
461 break;
462 case 'b': /* bounces */
463 getparam(s+2, "ambient bounces", 'i', &ambounce);
464 break;
465 case 'r':
466 if (getparam(s+2, "ambient resolution", 'i', &ambres))
467 minarad = ambres > 0 ?
468 thescene.cusize/ambres : 0.0;
469 break;
470 default:
471 goto badparam;
472 }
473 break;
474 case 'p': /* pixel */
475 switch (s[1]) {
476 case 's': /* sample */
477 if (getparam(s+2, "pixel sample", 'i', &psample))
478 pdepth = 0;
479 break;
480 case 't': /* threshold */
481 if (getparam(s+2, "pixel threshold", 'r', &maxdiff))
482 pdepth = 0;
483 break;
484 default:
485 goto badparam;
486 }
487 break;
488 case 's': /* specular */
489 switch (s[1]) {
490 case 'j': /* jitter */
491 getparam(s+2, "specular jitter", 'r', &specjitter);
492 break;
493 case 't': /* threshold */
494 getparam(s+2, "specular threshold", 'r', &specthresh);
495 break;
496 default:
497 goto badparam;
498 }
499 break;
500 case '\0': /* nothing */
501 break;
502 default:;
503 badparam:
504 *sskip(s) = '\0';
505 sprintf(errmsg, "%s: unknown variable", s);
506 error(COMMAND, errmsg);
507 break;
508 }
509 }
510
511
512 traceray(s) /* trace a single ray */
513 char *s;
514 {
515 char buf[128];
516 int x, y;
517 RAY thisray;
518
519 if (!sscanvec(s, thisray.rorg) ||
520 !sscanvec(sskip(sskip(sskip(s))), thisray.rdir)) {
521
522 if (dev->getcur == NULL)
523 return;
524 (*dev->comout)("Pick ray\n");
525 if ((*dev->getcur)(&x, &y) == ABORT)
526 return;
527
528 if (viewray(thisray.rorg, thisray.rdir, &ourview,
529 (x+.5)/hresolu, (y+.5)/vresolu) < 0) {
530 error(COMMAND, "not on image");
531 return;
532 }
533
534 } else if (normalize(thisray.rdir) == 0.0) {
535 error(COMMAND, "zero ray direction");
536 return;
537 }
538
539 rayorigin(&thisray, NULL, PRIMARY, 1.0);
540
541 rayvalue(&thisray);
542
543 if (thisray.ro == NULL)
544 (*dev->comout)("ray hit nothing");
545 else {
546 sprintf(buf, "ray hit %s %s \"%s\"",
547 objptr(thisray.ro->omod)->oname,
548 ofun[thisray.ro->otype].funame,
549 thisray.ro->oname);
550 (*dev->comout)(buf);
551 (*dev->comin)(buf, NULL);
552 if (thisray.rot >= FHUGE)
553 (*dev->comout)("at infinity");
554 else {
555 sprintf(buf, "at (%.6g %.6g %.6g)", thisray.rop[0],
556 thisray.rop[1], thisray.rop[2]);
557 (*dev->comout)(buf);
558 }
559 (*dev->comin)(buf, NULL);
560 sprintf(buf, "value (%.5g %.5g %.5g) (%.1fL)",
561 colval(thisray.rcol,RED),
562 colval(thisray.rcol,GRN),
563 colval(thisray.rcol,BLU),
564 luminance(thisray.rcol));
565 (*dev->comout)(buf);
566 }
567 (*dev->comin)(buf, NULL);
568 }
569
570
571 writepict(s) /* write the picture to a file */
572 char *s;
573 {
574 static char buf[128];
575 char *fname;
576 FILE *fp;
577 COLR *scanline;
578 int y;
579
580 if (sscanf(s, "%s", buf) != 1 && buf[0] == '\0') {
581 error(COMMAND, "no file");
582 return;
583 }
584 if ((fname = getpath(buf, NULL, 0)) == NULL ||
585 (fp = fopen(fname, "w")) == NULL) {
586 sprintf(errmsg, "cannot open \"%s\"", buf);
587 error(COMMAND, errmsg);
588 return;
589 }
590 (*dev->comout)("writing \"");
591 (*dev->comout)(fname);
592 (*dev->comout)("\"...\n");
593 /* write header */
594 fputs(progname, fp);
595 fprintview(&ourview, fp);
596 if (octname != NULL)
597 fprintf(fp, " %s\n", octname);
598 else
599 putc('\n', fp);
600 fprintf(fp, "SOFTWARE= %s\n", VersionID);
601 if (exposure != 1.0)
602 fputexpos(exposure, fp);
603 if (dev->pixaspect != 1.0)
604 fputaspect(dev->pixaspect, fp);
605 fputformat(COLRFMT, fp);
606 putc('\n', fp);
607 fprtresolu(hresolu, vresolu, fp);
608
609 scanline = (COLR *)malloc(hresolu*sizeof(COLR));
610 if (scanline == NULL) {
611 error(COMMAND, "not enough memory!");
612 fclose(fp);
613 unlink(fname);
614 return;
615 }
616 for (y = vresolu-1; y >= 0; y--) {
617 getpictcolrs(y, scanline, &ptrunk, hresolu, vresolu);
618 if (fwritecolrs(scanline, hresolu, fp) < 0)
619 break;
620 }
621 free((char *)scanline);
622 if (fclose(fp) < 0)
623 error(COMMAND, "write error");
624 }