ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rv3.c
Revision: 2.11
Committed: Tue Feb 25 02:47:23 2003 UTC (21 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R5
Changes since 2.10: +1 -56 lines
Log Message:
Replaced inline copyright notice with #include "copyright.h"

File Contents

# User Rev Content
1 greg 1.1 #ifndef lint
2 greg 2.10 static const char RCSid[] = "$Id$";
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     #include "ray.h"
13    
14     #include "rpaint.h"
15    
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     } else if (direc)
126     for (i = 0; i < 3; i++)
127     vec[i] -= ourview.vp[i];
128     return(0);
129     }
130 greg 1.1
131    
132     float * /* keep consistent with COLOR typedef */
133     greyof(col) /* convert color to greyscale */
134     register COLOR col;
135     {
136     static COLOR gcol;
137     double b;
138    
139     b = bright(col);
140     setcolor(gcol, b, b, b);
141     return(gcol);
142     }
143    
144    
145 greg 2.10 void
146 greg 1.1 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 static unsigned long lastflush = 0;
151 greg 1.1 static RAY thisray;
152     double h, v;
153    
154     if (xmax - xmin <= 0 || ymax - ymin <= 0) { /* empty */
155     p->x = xmin;
156     p->y = ymin;
157     setcolor(p->v, 0.0, 0.0, 0.0);
158     return;
159     }
160     /* jitter ray direction */
161 greg 1.15 h = xmin + (xmax-xmin)*frandom();
162     v = ymin + (ymax-ymin)*frandom();
163 greg 1.1
164 greg 2.6 if ((thisray.rmax = viewray(thisray.rorg, thisray.rdir, &ourview,
165     h/hresolu, v/vresolu)) < -FTINY) {
166 greg 1.17 setcolor(thisray.rcol, 0.0, 0.0, 0.0);
167     } else {
168     rayorigin(&thisray, NULL, PRIMARY, 1.0);
169 greg 1.20 samplendx++;
170 greg 1.17 rayvalue(&thisray);
171     }
172 greg 1.1
173 greg 1.15 p->x = h;
174     p->y = v;
175 greg 1.1 copycolor(p->v, thisray.rcol);
176     scalecolor(p->v, exposure);
177    
178     (*dev->paintr)(greyscale?greyof(p->v):p->v, xmin, ymin, xmax, ymax);
179 greg 1.13
180     if (dev->flush != NULL && nrays - lastflush >= WFLUSH) {
181     lastflush = nrays;
182     (*dev->flush)();
183     }
184 greg 1.1 }
185    
186    
187 greg 2.10 void
188 greg 1.1 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 greg 2.10 void
209 greg 1.1 redraw() /* redraw the image */
210     {
211 greg 1.9 (*dev->clear)(hresolu, vresolu);
212 greg 1.1 (*dev->comout)("redrawing...\n");
213 greg 1.9 repaint(0, 0, hresolu, vresolu);
214 greg 1.1 (*dev->comout)("\n");
215     }
216    
217    
218 greg 2.10 void
219 greg 1.1 repaint(xmin, ymin, xmax, ymax) /* repaint a region */
220     int xmin, ymin, xmax, ymax;
221     {
222     RECT reg;
223    
224     reg.l = xmin; reg.r = xmax;
225     reg.d = ymin; reg.u = ymax;
226    
227 greg 1.9 paintrect(&ptrunk, 0, 0, hresolu, vresolu, &reg);
228 greg 1.1 }
229    
230    
231 greg 2.10 void
232 greg 1.1 paintrect(p, xmin, ymin, xmax, ymax, r) /* paint picture rectangle */
233     register PNODE *p;
234     int xmin, ymin, xmax, ymax;
235     register RECT *r;
236     {
237     int mx, my;
238    
239     if (xmax - xmin <= 0 || ymax - ymin <= 0)
240     return;
241    
242     if (p->kid == NULL) {
243     (*dev->paintr)(greyscale?greyof(p->v):p->v,
244     xmin, ymin, xmax, ymax); /* do this */
245     return;
246     }
247     mx = (xmin + xmax) >> 1; /* do kids */
248     my = (ymin + ymax) >> 1;
249     if (mx > r->l) {
250     if (my > r->d)
251     paintrect(p->kid+DL, xmin, ymin, mx, my, r);
252     if (my < r->u)
253     paintrect(p->kid+UL, xmin, my, mx, ymax, r);
254     }
255     if (mx < r->r) {
256     if (my > r->d)
257     paintrect(p->kid+DR, mx, ymin, xmax, my, r);
258     if (my < r->u)
259     paintrect(p->kid+UR, mx, my, xmax, ymax, r);
260     }
261     }
262    
263    
264     PNODE *
265     findrect(x, y, p, r, pd) /* find a rectangle */
266     int x, y;
267     register PNODE *p;
268     register RECT *r;
269     int pd;
270     {
271     int mx, my;
272    
273     while (p->kid != NULL && pd--) {
274    
275     mx = (r->l + r->r) >> 1;
276     my = (r->d + r->u) >> 1;
277    
278     if (x < mx) {
279     r->r = mx;
280     if (y < my) {
281     r->u = my;
282     p = p->kid+DL;
283     } else {
284     r->d = my;
285     p = p->kid+UL;
286     }
287     } else {
288     r->l = mx;
289     if (y < my) {
290     r->u = my;
291     p = p->kid+DR;
292     } else {
293     r->d = my;
294     p = p->kid+UR;
295     }
296     }
297     }
298     return(p);
299     }
300    
301    
302 greg 2.10 void
303 greg 1.1 scalepict(p, sf) /* scale picture values */
304     register PNODE *p;
305     double sf;
306     {
307     scalecolor(p->v, sf); /* do this node */
308    
309     if (p->kid == NULL)
310     return;
311     /* do children */
312     scalepict(p->kid+DL, sf);
313     scalepict(p->kid+DR, sf);
314     scalepict(p->kid+UL, sf);
315     scalepict(p->kid+UR, sf);
316     }
317    
318    
319 greg 2.10 void
320 greg 1.1 getpictcolrs(yoff, scan, p, xsiz, ysiz) /* get scanline from picture */
321     int yoff;
322     register COLR *scan;
323     register PNODE *p;
324     int xsiz, ysiz;
325     {
326     register int mx;
327     int my;
328    
329     if (p->kid == NULL) { /* do this node */
330     setcolr(scan[0], colval(p->v,RED),
331     colval(p->v,GRN),
332     colval(p->v,BLU));
333     for (mx = 1; mx < xsiz; mx++)
334     copycolr(scan[mx], scan[0]);
335     return;
336     }
337     /* do kids */
338     mx = xsiz >> 1;
339     my = ysiz >> 1;
340     if (yoff < my) {
341     getpictcolrs(yoff, scan, p->kid+DL, mx, my);
342     getpictcolrs(yoff, scan+mx, p->kid+DR, xsiz-mx, my);
343     } else {
344     getpictcolrs(yoff-my, scan, p->kid+UL, mx, ysiz-my);
345     getpictcolrs(yoff-my, scan+mx, p->kid+UR, xsiz-mx, ysiz-my);
346     }
347     }
348    
349    
350 greg 2.10 void
351 greg 1.1 freepkids(p) /* free pnode's children */
352     register PNODE *p;
353     {
354     if (p->kid == NULL)
355     return;
356     freepkids(p->kid+DL);
357     freepkids(p->kid+DR);
358     freepkids(p->kid+UL);
359     freepkids(p->kid+UR);
360 greg 2.10 free((void *)p->kid);
361 greg 1.1 p->kid = NULL;
362     }
363    
364    
365 greg 2.10 void
366 greg 1.1 newview(vp) /* change viewing parameters */
367     register VIEW *vp;
368     {
369     char *err;
370    
371 greg 1.6 if ((err = setview(vp)) != NULL) {
372 greg 1.1 sprintf(errmsg, "view not set - %s", err);
373     error(COMMAND, errmsg);
374 greg 1.12 } else if (bcmp((char *)vp, (char *)&ourview, sizeof(VIEW))) {
375     copystruct(&oldview, &ourview);
376     copystruct(&ourview, vp);
377 greg 1.14 newimage();
378 greg 1.1 }
379     }
380    
381    
382 greg 2.10 void
383 greg 1.4 moveview(angle, elev, mag, vc) /* move viewpoint */
384     double angle, elev, mag;
385 greg 1.1 FVECT vc;
386     {
387     double d;
388 greg 1.4 FVECT v1;
389 greg 1.1 VIEW nv;
390     register int i;
391    
392     VCOPY(nv.vup, ourview.vup);
393 greg 1.9 nv.hoff = ourview.hoff; nv.voff = ourview.voff;
394 greg 1.1 spinvector(nv.vdir, ourview.vdir, ourview.vup, angle*(PI/180.));
395 greg 1.4 if (elev != 0.0) {
396 greg 1.5 fcross(v1, ourview.vup, nv.vdir);
397 greg 1.4 normalize(v1);
398     spinvector(nv.vdir, nv.vdir, v1, elev*(PI/180.));
399     }
400 greg 1.1 if ((nv.type = ourview.type) == VT_PAR) {
401     nv.horiz = ourview.horiz / mag;
402     nv.vert = ourview.vert / mag;
403 greg 1.3 d = 0.0; /* don't move closer */
404 greg 1.2 for (i = 0; i < 3; i++)
405 greg 1.3 d += (vc[i] - ourview.vp[i])*ourview.vdir[i];
406 greg 2.7 nv.vfore = ourview.vfore;
407     nv.vaft = ourview.vaft;
408 greg 1.1 } else {
409     nv.horiz = ourview.horiz;
410     nv.vert = ourview.vert;
411 greg 1.2 d = sqrt(dist2(ourview.vp, vc)) / mag;
412 greg 2.8 if ((nv.vfore = ourview.vfore) > FTINY) {
413     nv.vfore += d - d*mag;
414     if (nv.vfore < 0.0) nv.vfore = 0.0;
415     }
416     if ((nv.vaft = ourview.vaft) > FTINY) {
417     nv.vaft += d - d*mag;
418     if (nv.vaft <= nv.vfore) nv.vaft = 0.0;
419     }
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 }