ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rv3.c
Revision: 2.16
Committed: Fri Feb 18 17:47:53 2005 UTC (19 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.15: +2 -2 lines
Log Message:
Fixed bug in view distance adjustment with "move" command

File Contents

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