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

# Content
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 }