ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rv3.c
Revision: 2.7
Committed: Thu Dec 22 11:46:19 1994 UTC (29 years, 4 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.6: +6 -0 lines
Log Message:
made view changes properly manage fore and aft clipping planes

File Contents

# User Rev Content
1 greg 2.6 /* Copyright (c) 1994 Regents of the University of California */
2 greg 1.1
3     #ifndef lint
4     static char SCCSid[] = "$SunId$ LBL";
5     #endif
6    
7     /*
8     * rv3.c - miscellaneous routines for rview.
9     *
10     * 5/11/87
11     */
12    
13     #include "ray.h"
14    
15 greg 1.7 #include "octree.h"
16    
17 greg 1.1 #include "rpaint.h"
18    
19     #include "random.h"
20 greg 1.7
21 greg 1.13 #ifndef WFLUSH
22 greg 2.4 #ifdef SPEED
23     #define WFLUSH (5*SPEED)
24     #else
25     #define WFLUSH 100 /* flush after this many rays */
26     #endif
27 greg 1.13 #endif
28 greg 1.7
29 greg 2.2 #ifdef SMLFLT
30     #define sscanvec(s,v) (sscanf(s,"%f %f %f",v,v+1,v+2)==3)
31     #else
32     #define sscanvec(s,v) (sscanf(s,"%lf %lf %lf",v,v+1,v+2)==3)
33     #endif
34 greg 1.13
35 greg 2.2
36 greg 1.7 getrect(s, r) /* get a box */
37     char *s;
38     register RECT *r;
39     {
40     int x0, y0, x1, y1;
41    
42     if (*s && !strncmp(s, "all", strlen(s))) {
43     r->l = r->d = 0;
44 greg 1.9 r->r = hresolu;
45     r->u = vresolu;
46 greg 1.7 return(0);
47     }
48     if (sscanf(s, "%d %d %d %d", &x0, &y0, &x1, &y1) != 4) {
49     if (dev->getcur == NULL)
50     return(-1);
51     (*dev->comout)("Pick first corner\n");
52     if ((*dev->getcur)(&x0, &y0) == ABORT)
53     return(-1);
54     (*dev->comout)("Pick second corner\n");
55     if ((*dev->getcur)(&x1, &y1) == ABORT)
56     return(-1);
57     }
58     if (x0 < x1) {
59     r->l = x0;
60     r->r = x1;
61     } else {
62     r->l = x1;
63     r->r = x0;
64     }
65     if (y0 < y1) {
66     r->d = y0;
67     r->u = y1;
68     } else {
69     r->d = y1;
70     r->u = y0;
71     }
72     if (r->l < 0) r->l = 0;
73     if (r->d < 0) r->d = 0;
74 greg 1.9 if (r->r > hresolu) r->r = hresolu;
75     if (r->u > vresolu) r->u = vresolu;
76 greg 1.7 if (r->l > r->r) r->l = r->r;
77     if (r->d > r->u) r->d = r->u;
78     return(0);
79     }
80    
81    
82     getinterest(s, direc, vec, mp) /* get area of interest */
83     char *s;
84     int direc;
85     FVECT vec;
86     double *mp;
87     {
88     int x, y;
89     RAY thisray;
90     register int i;
91    
92     if (sscanf(s, "%lf", mp) != 1)
93     *mp = 1.0;
94     else if (*mp < -FTINY) /* negative zoom is reduction */
95     *mp = -1.0 / *mp;
96     else if (*mp <= FTINY) { /* too small */
97     error(COMMAND, "illegal magnification");
98     return(-1);
99     }
100 greg 2.2 if (!sscanvec(sskip(s), vec)) {
101 greg 1.7 if (dev->getcur == NULL)
102     return(-1);
103     (*dev->comout)("Pick view center\n");
104     if ((*dev->getcur)(&x, &y) == ABORT)
105     return(-1);
106 greg 2.6 if ((thisray.rmax = viewray(thisray.rorg, thisray.rdir,
107     &ourview, (x+.5)/hresolu, (y+.5)/vresolu)) < -FTINY) {
108 greg 1.17 error(COMMAND, "not on image");
109     return(-1);
110     }
111 greg 1.7 if (!direc || ourview.type == VT_PAR) {
112     rayorigin(&thisray, NULL, PRIMARY, 1.0);
113     if (!localhit(&thisray, &thescene)) {
114     error(COMMAND, "not a local object");
115     return(-1);
116     }
117     }
118     if (direc)
119     if (ourview.type == VT_PAR)
120     for (i = 0; i < 3; i++)
121     vec[i] = thisray.rop[i] - ourview.vp[i];
122     else
123     VCOPY(vec, thisray.rdir);
124     else
125     VCOPY(vec, thisray.rop);
126     } else if (direc)
127     for (i = 0; i < 3; i++)
128     vec[i] -= ourview.vp[i];
129     return(0);
130     }
131 greg 1.1
132    
133     float * /* keep consistent with COLOR typedef */
134     greyof(col) /* convert color to greyscale */
135     register COLOR col;
136     {
137     static COLOR gcol;
138     double b;
139    
140     b = bright(col);
141     setcolor(gcol, b, b, b);
142     return(gcol);
143     }
144    
145    
146     paint(p, xmin, ymin, xmax, ymax) /* compute and paint a rectangle */
147     register PNODE *p;
148     int xmin, ymin, xmax, ymax;
149     {
150 greg 2.5 extern unsigned long nrays;
151     static unsigned long lastflush = 0;
152 greg 1.1 static RAY thisray;
153     double h, v;
154    
155     if (xmax - xmin <= 0 || ymax - ymin <= 0) { /* empty */
156     p->x = xmin;
157     p->y = ymin;
158     setcolor(p->v, 0.0, 0.0, 0.0);
159     return;
160     }
161     /* jitter ray direction */
162 greg 1.15 h = xmin + (xmax-xmin)*frandom();
163     v = ymin + (ymax-ymin)*frandom();
164 greg 1.1
165 greg 2.6 if ((thisray.rmax = viewray(thisray.rorg, thisray.rdir, &ourview,
166     h/hresolu, v/vresolu)) < -FTINY) {
167 greg 1.17 setcolor(thisray.rcol, 0.0, 0.0, 0.0);
168     } else {
169     rayorigin(&thisray, NULL, PRIMARY, 1.0);
170 greg 1.20 samplendx++;
171 greg 1.17 rayvalue(&thisray);
172     }
173 greg 1.1
174 greg 1.15 p->x = h;
175     p->y = v;
176 greg 1.1 copycolor(p->v, thisray.rcol);
177     scalecolor(p->v, exposure);
178    
179     (*dev->paintr)(greyscale?greyof(p->v):p->v, xmin, ymin, xmax, ymax);
180 greg 1.13
181     if (dev->flush != NULL && nrays - lastflush >= WFLUSH) {
182     lastflush = nrays;
183     (*dev->flush)();
184     }
185 greg 1.1 }
186    
187    
188     newimage() /* start a new image */
189     {
190     /* free old image */
191     freepkids(&ptrunk);
192 greg 1.19 /* save reserve memory */
193     fillreserves();
194 greg 1.9 /* compute resolution */
195 greg 1.10 hresolu = dev->xsiz;
196     vresolu = dev->ysiz;
197 greg 1.11 normaspect(viewaspect(&ourview), &dev->pixaspect, &hresolu, &vresolu);
198 greg 1.1 pframe.l = pframe.d = 0;
199 greg 1.9 pframe.r = hresolu; pframe.u = vresolu;
200 greg 1.1 pdepth = 0;
201     /* clear device */
202 greg 1.9 (*dev->clear)(hresolu, vresolu);
203 greg 1.1 /* get first value */
204 greg 1.9 paint(&ptrunk, 0, 0, hresolu, vresolu);
205 greg 1.1 }
206    
207    
208     redraw() /* redraw the image */
209     {
210 greg 1.9 (*dev->clear)(hresolu, vresolu);
211 greg 1.1 (*dev->comout)("redrawing...\n");
212 greg 1.9 repaint(0, 0, hresolu, vresolu);
213 greg 1.1 (*dev->comout)("\n");
214     }
215    
216    
217     repaint(xmin, ymin, xmax, ymax) /* repaint a region */
218     int xmin, ymin, xmax, ymax;
219     {
220     RECT reg;
221    
222     reg.l = xmin; reg.r = xmax;
223     reg.d = ymin; reg.u = ymax;
224    
225 greg 1.9 paintrect(&ptrunk, 0, 0, hresolu, vresolu, &reg);
226 greg 1.1 }
227    
228    
229     paintrect(p, xmin, ymin, xmax, ymax, r) /* paint picture rectangle */
230     register PNODE *p;
231     int xmin, ymin, xmax, ymax;
232     register RECT *r;
233     {
234     int mx, my;
235    
236     if (xmax - xmin <= 0 || ymax - ymin <= 0)
237     return;
238    
239     if (p->kid == NULL) {
240     (*dev->paintr)(greyscale?greyof(p->v):p->v,
241     xmin, ymin, xmax, ymax); /* do this */
242     return;
243     }
244     mx = (xmin + xmax) >> 1; /* do kids */
245     my = (ymin + ymax) >> 1;
246     if (mx > r->l) {
247     if (my > r->d)
248     paintrect(p->kid+DL, xmin, ymin, mx, my, r);
249     if (my < r->u)
250     paintrect(p->kid+UL, xmin, my, mx, ymax, r);
251     }
252     if (mx < r->r) {
253     if (my > r->d)
254     paintrect(p->kid+DR, mx, ymin, xmax, my, r);
255     if (my < r->u)
256     paintrect(p->kid+UR, mx, my, xmax, ymax, r);
257     }
258     }
259    
260    
261     PNODE *
262     findrect(x, y, p, r, pd) /* find a rectangle */
263     int x, y;
264     register PNODE *p;
265     register RECT *r;
266     int pd;
267     {
268     int mx, my;
269    
270     while (p->kid != NULL && pd--) {
271    
272     mx = (r->l + r->r) >> 1;
273     my = (r->d + r->u) >> 1;
274    
275     if (x < mx) {
276     r->r = mx;
277     if (y < my) {
278     r->u = my;
279     p = p->kid+DL;
280     } else {
281     r->d = my;
282     p = p->kid+UL;
283     }
284     } else {
285     r->l = mx;
286     if (y < my) {
287     r->u = my;
288     p = p->kid+DR;
289     } else {
290     r->d = my;
291     p = p->kid+UR;
292     }
293     }
294     }
295     return(p);
296     }
297    
298    
299     scalepict(p, sf) /* scale picture values */
300     register PNODE *p;
301     double sf;
302     {
303     scalecolor(p->v, sf); /* do this node */
304    
305     if (p->kid == NULL)
306     return;
307     /* do children */
308     scalepict(p->kid+DL, sf);
309     scalepict(p->kid+DR, sf);
310     scalepict(p->kid+UL, sf);
311     scalepict(p->kid+UR, sf);
312     }
313    
314    
315     getpictcolrs(yoff, scan, p, xsiz, ysiz) /* get scanline from picture */
316     int yoff;
317     register COLR *scan;
318     register PNODE *p;
319     int xsiz, ysiz;
320     {
321     register int mx;
322     int my;
323    
324     if (p->kid == NULL) { /* do this node */
325     setcolr(scan[0], colval(p->v,RED),
326     colval(p->v,GRN),
327     colval(p->v,BLU));
328     for (mx = 1; mx < xsiz; mx++)
329     copycolr(scan[mx], scan[0]);
330     return;
331     }
332     /* do kids */
333     mx = xsiz >> 1;
334     my = ysiz >> 1;
335     if (yoff < my) {
336     getpictcolrs(yoff, scan, p->kid+DL, mx, my);
337     getpictcolrs(yoff, scan+mx, p->kid+DR, xsiz-mx, my);
338     } else {
339     getpictcolrs(yoff-my, scan, p->kid+UL, mx, ysiz-my);
340     getpictcolrs(yoff-my, scan+mx, p->kid+UR, xsiz-mx, ysiz-my);
341     }
342     }
343    
344    
345     pcopy(p1, p2) /* copy paint node p1 into p2 */
346     register PNODE *p1, *p2;
347     {
348     copycolor(p2->v, p1->v);
349     p2->x = p1->x;
350     p2->y = p1->y;
351     }
352    
353    
354     freepkids(p) /* free pnode's children */
355     register PNODE *p;
356     {
357     if (p->kid == NULL)
358     return;
359     freepkids(p->kid+DL);
360     freepkids(p->kid+DR);
361     freepkids(p->kid+UL);
362     freepkids(p->kid+UR);
363     free((char *)p->kid);
364     p->kid = NULL;
365     }
366    
367    
368     newview(vp) /* change viewing parameters */
369     register VIEW *vp;
370     {
371     char *err;
372    
373 greg 1.6 if ((err = setview(vp)) != NULL) {
374 greg 1.1 sprintf(errmsg, "view not set - %s", err);
375     error(COMMAND, errmsg);
376 greg 1.12 } else if (bcmp((char *)vp, (char *)&ourview, sizeof(VIEW))) {
377     copystruct(&oldview, &ourview);
378     copystruct(&ourview, vp);
379 greg 1.14 newimage();
380 greg 1.1 }
381     }
382    
383    
384 greg 1.4 moveview(angle, elev, mag, vc) /* move viewpoint */
385     double angle, elev, mag;
386 greg 1.1 FVECT vc;
387     {
388     double d;
389 greg 1.4 FVECT v1;
390 greg 1.1 VIEW nv;
391     register int i;
392    
393     VCOPY(nv.vup, ourview.vup);
394 greg 1.9 nv.hoff = ourview.hoff; nv.voff = ourview.voff;
395 greg 1.1 spinvector(nv.vdir, ourview.vdir, ourview.vup, angle*(PI/180.));
396 greg 1.4 if (elev != 0.0) {
397 greg 1.5 fcross(v1, ourview.vup, nv.vdir);
398 greg 1.4 normalize(v1);
399     spinvector(nv.vdir, nv.vdir, v1, elev*(PI/180.));
400     }
401 greg 1.1 if ((nv.type = ourview.type) == VT_PAR) {
402     nv.horiz = ourview.horiz / mag;
403     nv.vert = ourview.vert / mag;
404 greg 1.3 d = 0.0; /* don't move closer */
405 greg 1.2 for (i = 0; i < 3; i++)
406 greg 1.3 d += (vc[i] - ourview.vp[i])*ourview.vdir[i];
407 greg 2.7 nv.vfore = ourview.vfore;
408     nv.vaft = ourview.vaft;
409 greg 1.1 } else {
410     nv.horiz = ourview.horiz;
411     nv.vert = ourview.vert;
412 greg 1.2 d = sqrt(dist2(ourview.vp, vc)) / mag;
413 greg 2.7 nv.vfore = ourview.vfore + d - d*mag;
414     if (nv.vfore < 0.0) nv.vfore = 0.0;
415     nv.vaft = ourview.vaft + d - d*mag;
416     if (nv.vaft < nv.vfore) nv.vaft = 0.0;
417 greg 1.1 }
418 greg 1.2 for (i = 0; i < 3; i++)
419     nv.vp[i] = vc[i] - d*nv.vdir[i];
420 greg 1.1 newview(&nv);
421 greg 1.17 }
422    
423    
424     zoomview(vp, zf) /* zoom in our out */
425     register VIEW *vp;
426     double zf;
427     {
428     switch (vp->type) {
429     case VT_PAR: /* parallel view */
430     case VT_ANG: /* angular fisheye */
431     vp->horiz /= zf;
432     vp->vert /= zf;
433     return;
434     case VT_PER: /* perspective view */
435     vp->horiz = atan(tan(vp->horiz*(PI/180./2.))/zf) /
436     (PI/180./2.);
437     vp->vert = atan(tan(vp->vert*(PI/180./2.))/zf) /
438     (PI/180./2.);
439     return;
440     case VT_HEM: /* hemispherical fisheye */
441     vp->horiz = sin(vp->horiz*(PI/180./2.))/zf;
442     if (vp->horiz >= 1.0-FTINY)
443     vp->horiz = 180.;
444     else
445     vp->horiz = asin(vp->horiz) / (PI/180./2.);
446     vp->vert = sin(vp->vert*(PI/180./2.))/zf;
447     if (vp->vert >= 1.0-FTINY)
448     vp->vert = 180.;
449     else
450     vp->vert = asin(vp->vert) / (PI/180./2.);
451     return;
452     }
453 greg 1.1 }