ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rv2.c
Revision: 2.5
Committed: Wed Jan 15 16:55:21 1992 UTC (32 years, 9 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.4: +19 -5 lines
Log Message:
added change of s options and changed old s options to p options

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