ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rv2.c
Revision: 2.1
Committed: Tue Nov 12 17:09:52 1991 UTC (32 years, 5 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.33: +0 -0 lines
Log Message:
updated revision number for release 2.0

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 double atof(), pow(), fabs();
250 char buf[128];
251 register char *cp;
252 register PNODE *p;
253 RECT r;
254 int x, y;
255 double e;
256
257 for (cp = s; isspace(*cp); cp++)
258 ;
259 if (*cp == '\0') { /* normalize to point */
260 if (dev->getcur == NULL)
261 return;
262 (*dev->comout)("Pick point for exposure\n");
263 if ((*dev->getcur)(&x, &y) == ABORT)
264 return;
265 r.l = r.d = 0;
266 r.r = hresolu; r.u = vresolu;
267 p = findrect(x, y, &ptrunk, &r, -1);
268 e = 1.0;
269 } else {
270 if (*cp == '=') { /* absolute setting */
271 p = NULL;
272 e = 1.0/exposure;
273 for (cp++; isspace(*cp); cp++)
274 ;
275 if (*cp == '\0') { /* interactive */
276 sprintf(buf, "exposure (%lf): ", exposure);
277 (*dev->comout)(buf);
278 (*dev->comin)(buf, NULL);
279 for (cp = buf; isspace(*cp); cp++)
280 ;
281 if (*cp == '\0')
282 return;
283 }
284 } else { /* normalize to average */
285 p = &ptrunk;
286 e = 1.0;
287 }
288 if (*cp == '+' || *cp == '-') /* f-stops */
289 e *= pow(2.0, atof(cp));
290 else /* multiplier */
291 e *= atof(cp);
292 }
293 if (p != NULL) { /* relative setting */
294 if (bright(p->v) <= FTINY) {
295 error(COMMAND, "cannot normalize to zero");
296 return;
297 }
298 e *= 0.5 / bright(p->v);
299 }
300 if (e <= FTINY || fabs(1.0 - e) <= FTINY)
301 return;
302 scalepict(&ptrunk, e);
303 exposure *= e;
304 redraw();
305 }
306
307
308 getparam(str, dsc, typ, ptr) /* get variable from user */
309 char *str, *dsc;
310 int typ;
311 register union {int i; double d; COLOR C;} *ptr;
312 {
313 extern char *index();
314 int i0;
315 double d0, d1, d2;
316 char buf[48];
317
318 switch (typ) {
319 case 'i': /* integer */
320 if (sscanf(str, "%d", &i0) != 1) {
321 (*dev->comout)(dsc);
322 sprintf(buf, " (%d): ", ptr->i);
323 (*dev->comout)(buf);
324 (*dev->comin)(buf, NULL);
325 if (sscanf(buf, "%d", &i0) != 1)
326 return(0);
327 }
328 ptr->i = i0;
329 return(1);
330 case 'r': /* real */
331 if (sscanf(str, "%lf", &d0) != 1) {
332 (*dev->comout)(dsc);
333 sprintf(buf, " (%.6g): ", ptr->d);
334 (*dev->comout)(buf);
335 (*dev->comin)(buf, NULL);
336 if (sscanf(buf, "%lf", &d0) != 1)
337 return(0);
338 }
339 ptr->d = d0;
340 return(1);
341 case 'b': /* boolean */
342 if (sscanf(str, "%1s", buf) != 1) {
343 (*dev->comout)(dsc);
344 sprintf(buf, " (%c): ", ptr->i ? 'y' : 'n');
345 (*dev->comout)(buf);
346 (*dev->comin)(buf, NULL);
347 if (buf[0] == '\0' ||
348 index("yY+1tTnN-0fF", buf[0]) == NULL)
349 return(0);
350 }
351 ptr->i = index("yY+1tT", buf[0]) != NULL;
352 return(1);
353 case 'C': /* color */
354 if (sscanf(str, "%lf %lf %lf", &d0, &d1, &d2) != 3) {
355 (*dev->comout)(dsc);
356 sprintf(buf, " (%.6g %.6g %.6g): ",
357 colval(ptr->C,RED),
358 colval(ptr->C,GRN),
359 colval(ptr->C,BLU));
360 (*dev->comout)(buf);
361 (*dev->comin)(buf, NULL);
362 if (sscanf(buf, "%lf %lf %lf", &d0, &d1, &d2) != 3)
363 return(0);
364 }
365 setcolor(ptr->C, d0, d1, d2);
366 return(1);
367 }
368 }
369
370
371 setparam(s) /* get/set program parameter */
372 register char *s;
373 {
374 extern int psample;
375 extern double maxdiff;
376 extern double minweight;
377 extern int maxdepth;
378 extern double dstrsrc;
379 extern double shadthresh;
380 extern double shadcert;
381 extern COLOR ambval;
382 extern double ambacc;
383 extern double minarad;
384 extern int ambres;
385 extern int ambdiv;
386 extern int ambssamp;
387 extern int ambounce;
388 extern int directinvis;
389 extern double srcsizerat;
390 extern int do_irrad;
391 char buf[128];
392
393 if (s[0] == '\0') {
394 (*dev->comout)(
395 "aa ab ad ar as av b dc di dj ds dt i lr lw sp st: ");
396 (*dev->comin)(buf, NULL);
397 s = buf;
398 }
399 switch (s[0]) {
400 case 'l': /* limit */
401 switch (s[1]) {
402 case 'w': /* weight */
403 getparam(s+2, "limit weight", 'r', &minweight);
404 break;
405 case 'r': /* reflection */
406 getparam(s+2, "limit reflection", 'i', &maxdepth);
407 break;
408 default:
409 goto badparam;
410 }
411 break;
412 case 'd': /* direct */
413 switch (s[1]) {
414 case 'j': /* jitter */
415 getparam(s+2, "direct jitter", 'r', &dstrsrc);
416 break;
417 case 'c': /* certainty */
418 getparam(s+2, "direct certainty", 'r', &shadcert);
419 break;
420 case 't': /* threshold */
421 getparam(s+2, "direct threshold", 'r', &shadthresh);
422 break;
423 case 'i': /* invisibility */
424 getparam(s+2, "direct invisibility",
425 'b', &directinvis);
426 break;
427 case 's': /* sampling */
428 getparam(s+2, "direct sampling", 'r', &srcsizerat);
429 break;
430 default:
431 goto badparam;
432 }
433 break;
434 case 'b': /* black and white */
435 getparam(s+1, "black and white", 'b', &greyscale);
436 break;
437 case 'i': /* irradiance */
438 getparam(s+1, "irradiance", 'b', &do_irrad);
439 break;
440 case 'a': /* ambient */
441 switch (s[1]) {
442 case 'v': /* value */
443 getparam(s+2, "ambient value", 'C', ambval);
444 break;
445 case 'a': /* accuracy */
446 getparam(s+2, "ambient accuracy", 'r', &ambacc);
447 break;
448 case 'd': /* divisions */
449 getparam(s+2, "ambient divisions", 'i', &ambdiv);
450 break;
451 case 's': /* samples */
452 getparam(s+2, "ambient super-samples", 'i', &ambssamp);
453 break;
454 case 'b': /* bounces */
455 getparam(s+2, "ambient bounces", 'i', &ambounce);
456 break;
457 case 'r':
458 if (getparam(s+2, "ambient resolution", 'i', &ambres))
459 minarad = ambres > 0 ?
460 thescene.cusize/ambres : 0.0;
461 break;
462 default:
463 goto badparam;
464 }
465 break;
466 case 's': /* sample */
467 switch (s[1]) {
468 case 'p': /* pixel */
469 if (getparam(s+2, "sample pixel", 'i', &psample))
470 pdepth = 0;
471 break;
472 case 't': /* threshold */
473 if (getparam(s+2, "sample threshold", 'r', &maxdiff))
474 pdepth = 0;
475 break;
476 default:
477 goto badparam;
478 }
479 break;
480 case '\0': /* nothing */
481 break;
482 default:;
483 badparam:
484 *sskip(s) = '\0';
485 sprintf(errmsg, "%s: unknown variable", s);
486 error(COMMAND, errmsg);
487 break;
488 }
489 }
490
491
492 traceray(s) /* trace a single ray */
493 char *s;
494 {
495 char buf[128];
496 int x, y;
497 RAY thisray;
498
499 if (sscanf(s, "%lf %lf %lf %lf %lf %lf",
500 &thisray.rorg[0], &thisray.rorg[1], &thisray.rorg[2],
501 &thisray.rdir[0], &thisray.rdir[1], &thisray.rdir[2]) != 6) {
502
503 if (dev->getcur == NULL)
504 return;
505 (*dev->comout)("Pick ray\n");
506 if ((*dev->getcur)(&x, &y) == ABORT)
507 return;
508
509 if (viewray(thisray.rorg, thisray.rdir, &ourview,
510 (x+.5)/hresolu, (y+.5)/vresolu) < 0) {
511 error(COMMAND, "not on image");
512 return;
513 }
514
515 } else if (normalize(thisray.rdir) == 0.0) {
516 error(COMMAND, "zero ray direction");
517 return;
518 }
519
520 rayorigin(&thisray, NULL, PRIMARY, 1.0);
521
522 rayvalue(&thisray);
523
524 if (thisray.ro == NULL)
525 (*dev->comout)("ray hit nothing");
526 else {
527 sprintf(buf, "ray hit %s %s \"%s\"",
528 objptr(thisray.ro->omod)->oname,
529 ofun[thisray.ro->otype].funame,
530 thisray.ro->oname);
531 (*dev->comout)(buf);
532 (*dev->comin)(buf, NULL);
533 if (thisray.rot >= FHUGE)
534 (*dev->comout)("at infinity");
535 else {
536 sprintf(buf, "at (%.6g %.6g %.6g)", thisray.rop[0],
537 thisray.rop[1], thisray.rop[2]);
538 (*dev->comout)(buf);
539 }
540 (*dev->comin)(buf, NULL);
541 sprintf(buf, "value (%.5g %.5g %.5g) (%.1fL)",
542 colval(thisray.rcol,RED),
543 colval(thisray.rcol,GRN),
544 colval(thisray.rcol,BLU),
545 luminance(thisray.rcol));
546 (*dev->comout)(buf);
547 }
548 (*dev->comin)(buf, NULL);
549 }
550
551
552 writepict(s) /* write the picture to a file */
553 char *s;
554 {
555 static char buf[128];
556 char *fname;
557 FILE *fp;
558 COLR *scanline;
559 int y;
560
561 if (sscanf(s, "%s", buf) != 1 && buf[0] == '\0') {
562 error(COMMAND, "no file");
563 return;
564 }
565 if ((fname = getpath(buf, NULL, 0)) == NULL ||
566 (fp = fopen(fname, "w")) == NULL) {
567 sprintf(errmsg, "cannot open \"%s\"", buf);
568 error(COMMAND, errmsg);
569 return;
570 }
571 (*dev->comout)("writing \"");
572 (*dev->comout)(fname);
573 (*dev->comout)("\"...\n");
574 /* write header */
575 fputs(progname, fp);
576 fprintview(&ourview, fp);
577 if (octname != NULL)
578 fprintf(fp, " %s\n", octname);
579 else
580 putc('\n', fp);
581 fprintf(fp, "SOFTWARE= %s\n", VersionID);
582 if (exposure != 1.0)
583 fputexpos(exposure, fp);
584 if (dev->pixaspect != 1.0)
585 fputaspect(dev->pixaspect, fp);
586 fputformat(COLRFMT, fp);
587 putc('\n', fp);
588 fprtresolu(hresolu, vresolu, fp);
589
590 scanline = (COLR *)malloc(hresolu*sizeof(COLR));
591 if (scanline == NULL) {
592 error(COMMAND, "not enough memory!");
593 fclose(fp);
594 unlink(fname);
595 return;
596 }
597 for (y = vresolu-1; y >= 0; y--) {
598 getpictcolrs(y, scanline, &ptrunk, hresolu, vresolu);
599 if (fwritecolrs(scanline, hresolu, fp) < 0)
600 break;
601 }
602 free((char *)scanline);
603 if (fclose(fp) < 0)
604 error(COMMAND, "write error");
605 }