ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rv3.c
Revision: 2.14
Committed: Tue Jan 18 00:33:16 2005 UTC (19 years, 3 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.13: +4 -8 lines
Log Message:
Added -pd option for depth-of-field sampling and -vd focal distance entry

File Contents

# User Rev Content
1 greg 1.1 #ifndef lint
2 greg 2.14 static const char RCSid[] = "$Id: rv3.c,v 2.13 2003/07/21 22:30:19 schorsch 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     } else if (direc)
126     for (i = 0; i < 3; i++)
127     vec[i] -= ourview.vp[i];
128 greg 2.14 if (normalize(vec) == 0.0)
129     return(-1);
130 greg 1.7 return(0);
131     }
132 greg 1.1
133    
134     float * /* keep consistent with COLOR typedef */
135     greyof(col) /* convert color to greyscale */
136     register COLOR col;
137     {
138     static COLOR gcol;
139     double b;
140    
141     b = bright(col);
142     setcolor(gcol, b, b, b);
143     return(gcol);
144     }
145    
146    
147 greg 2.10 void
148 greg 1.1 paint(p, xmin, ymin, xmax, ymax) /* compute and paint a rectangle */
149     register PNODE *p;
150     int xmin, ymin, xmax, ymax;
151     {
152 greg 2.5 static unsigned long lastflush = 0;
153 greg 1.1 static RAY thisray;
154     double h, v;
155    
156     if (xmax - xmin <= 0 || ymax - ymin <= 0) { /* empty */
157     p->x = xmin;
158     p->y = ymin;
159     setcolor(p->v, 0.0, 0.0, 0.0);
160     return;
161     }
162     /* jitter ray direction */
163 greg 1.15 h = xmin + (xmax-xmin)*frandom();
164     v = ymin + (ymax-ymin)*frandom();
165 greg 1.1
166 greg 2.6 if ((thisray.rmax = viewray(thisray.rorg, thisray.rdir, &ourview,
167     h/hresolu, v/vresolu)) < -FTINY) {
168 greg 1.17 setcolor(thisray.rcol, 0.0, 0.0, 0.0);
169     } else {
170     rayorigin(&thisray, NULL, PRIMARY, 1.0);
171 greg 1.20 samplendx++;
172 greg 1.17 rayvalue(&thisray);
173     }
174 greg 1.1
175 greg 1.15 p->x = h;
176     p->y = v;
177 greg 1.1 copycolor(p->v, thisray.rcol);
178     scalecolor(p->v, exposure);
179    
180     (*dev->paintr)(greyscale?greyof(p->v):p->v, xmin, ymin, xmax, ymax);
181 greg 1.13
182     if (dev->flush != NULL && nrays - lastflush >= WFLUSH) {
183     lastflush = nrays;
184     (*dev->flush)();
185     }
186 greg 1.1 }
187    
188    
189 greg 2.10 void
190 greg 1.1 newimage() /* start a new image */
191     {
192     /* free old image */
193     freepkids(&ptrunk);
194 greg 1.19 /* save reserve memory */
195     fillreserves();
196 greg 1.9 /* compute resolution */
197 greg 1.10 hresolu = dev->xsiz;
198     vresolu = dev->ysiz;
199 greg 1.11 normaspect(viewaspect(&ourview), &dev->pixaspect, &hresolu, &vresolu);
200 greg 1.1 pframe.l = pframe.d = 0;
201 greg 1.9 pframe.r = hresolu; pframe.u = vresolu;
202 greg 1.1 pdepth = 0;
203     /* clear device */
204 greg 1.9 (*dev->clear)(hresolu, vresolu);
205 greg 1.1 /* get first value */
206 greg 1.9 paint(&ptrunk, 0, 0, hresolu, vresolu);
207 greg 1.1 }
208    
209    
210 greg 2.10 void
211 greg 1.1 redraw() /* redraw the image */
212     {
213 greg 1.9 (*dev->clear)(hresolu, vresolu);
214 greg 1.1 (*dev->comout)("redrawing...\n");
215 greg 1.9 repaint(0, 0, hresolu, vresolu);
216 greg 1.1 (*dev->comout)("\n");
217     }
218    
219    
220 greg 2.10 void
221 greg 1.1 repaint(xmin, ymin, xmax, ymax) /* repaint a region */
222     int xmin, ymin, xmax, ymax;
223     {
224     RECT reg;
225    
226     reg.l = xmin; reg.r = xmax;
227     reg.d = ymin; reg.u = ymax;
228    
229 greg 1.9 paintrect(&ptrunk, 0, 0, hresolu, vresolu, &reg);
230 greg 1.1 }
231    
232    
233 greg 2.10 void
234 greg 1.1 paintrect(p, xmin, ymin, xmax, ymax, r) /* paint picture rectangle */
235     register PNODE *p;
236     int xmin, ymin, xmax, ymax;
237     register RECT *r;
238     {
239     int mx, my;
240    
241     if (xmax - xmin <= 0 || ymax - ymin <= 0)
242     return;
243    
244     if (p->kid == NULL) {
245     (*dev->paintr)(greyscale?greyof(p->v):p->v,
246     xmin, ymin, xmax, ymax); /* do this */
247     return;
248     }
249     mx = (xmin + xmax) >> 1; /* do kids */
250     my = (ymin + ymax) >> 1;
251     if (mx > r->l) {
252     if (my > r->d)
253     paintrect(p->kid+DL, xmin, ymin, mx, my, r);
254     if (my < r->u)
255     paintrect(p->kid+UL, xmin, my, mx, ymax, r);
256     }
257     if (mx < r->r) {
258     if (my > r->d)
259     paintrect(p->kid+DR, mx, ymin, xmax, my, r);
260     if (my < r->u)
261     paintrect(p->kid+UR, mx, my, xmax, ymax, r);
262     }
263     }
264    
265    
266     PNODE *
267     findrect(x, y, p, r, pd) /* find a rectangle */
268     int x, y;
269     register PNODE *p;
270     register RECT *r;
271     int pd;
272     {
273     int mx, my;
274    
275     while (p->kid != NULL && pd--) {
276    
277     mx = (r->l + r->r) >> 1;
278     my = (r->d + r->u) >> 1;
279    
280     if (x < mx) {
281     r->r = mx;
282     if (y < my) {
283     r->u = my;
284     p = p->kid+DL;
285     } else {
286     r->d = my;
287     p = p->kid+UL;
288     }
289     } else {
290     r->l = mx;
291     if (y < my) {
292     r->u = my;
293     p = p->kid+DR;
294     } else {
295     r->d = my;
296     p = p->kid+UR;
297     }
298     }
299     }
300     return(p);
301     }
302    
303    
304 greg 2.10 void
305 greg 1.1 scalepict(p, sf) /* scale picture values */
306     register PNODE *p;
307     double sf;
308     {
309     scalecolor(p->v, sf); /* do this node */
310    
311     if (p->kid == NULL)
312     return;
313     /* do children */
314     scalepict(p->kid+DL, sf);
315     scalepict(p->kid+DR, sf);
316     scalepict(p->kid+UL, sf);
317     scalepict(p->kid+UR, sf);
318     }
319    
320    
321 greg 2.10 void
322 greg 1.1 getpictcolrs(yoff, scan, p, xsiz, ysiz) /* get scanline from picture */
323     int yoff;
324     register COLR *scan;
325     register PNODE *p;
326     int xsiz, ysiz;
327     {
328     register int mx;
329     int my;
330    
331     if (p->kid == NULL) { /* do this node */
332     setcolr(scan[0], colval(p->v,RED),
333     colval(p->v,GRN),
334     colval(p->v,BLU));
335     for (mx = 1; mx < xsiz; mx++)
336     copycolr(scan[mx], scan[0]);
337     return;
338     }
339     /* do kids */
340     mx = xsiz >> 1;
341     my = ysiz >> 1;
342     if (yoff < my) {
343     getpictcolrs(yoff, scan, p->kid+DL, mx, my);
344     getpictcolrs(yoff, scan+mx, p->kid+DR, xsiz-mx, my);
345     } else {
346     getpictcolrs(yoff-my, scan, p->kid+UL, mx, ysiz-my);
347     getpictcolrs(yoff-my, scan+mx, p->kid+UR, xsiz-mx, ysiz-my);
348     }
349     }
350    
351    
352 greg 2.10 void
353 greg 1.1 freepkids(p) /* free pnode's children */
354     register PNODE *p;
355     {
356     if (p->kid == NULL)
357     return;
358     freepkids(p->kid+DL);
359     freepkids(p->kid+DR);
360     freepkids(p->kid+UL);
361     freepkids(p->kid+UR);
362 greg 2.10 free((void *)p->kid);
363 greg 1.1 p->kid = NULL;
364     }
365    
366    
367 greg 2.10 void
368 greg 1.1 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 schorsch 2.12 } else if (memcmp((char *)vp, (char *)&ourview, sizeof(VIEW))) {
377 schorsch 2.13 oldview = ourview;
378     ourview = *vp;
379 greg 1.14 newimage();
380 greg 1.1 }
381     }
382    
383    
384 greg 2.10 void
385 greg 1.4 moveview(angle, elev, mag, vc) /* move viewpoint */
386     double angle, elev, mag;
387 greg 1.1 FVECT vc;
388     {
389     double d;
390 greg 1.4 FVECT v1;
391 greg 2.14 VIEW nv = ourview;
392 greg 1.1 register int i;
393    
394     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 1.1 } else {
407 greg 1.2 d = sqrt(dist2(ourview.vp, vc)) / mag;
408 greg 2.8 if ((nv.vfore = ourview.vfore) > FTINY) {
409     nv.vfore += d - d*mag;
410     if (nv.vfore < 0.0) nv.vfore = 0.0;
411     }
412     if ((nv.vaft = ourview.vaft) > FTINY) {
413     nv.vaft += d - d*mag;
414     if (nv.vaft <= nv.vfore) nv.vaft = 0.0;
415     }
416 greg 1.1 }
417 greg 1.2 for (i = 0; i < 3; i++)
418     nv.vp[i] = vc[i] - d*nv.vdir[i];
419 greg 1.1 newview(&nv);
420 greg 1.17 }
421    
422    
423 greg 2.10 void
424     pcopy(p1, p2) /* copy paint node p1 into p2 */
425     register PNODE *p1, *p2;
426     {
427     copycolor(p2->v, p1->v);
428     p2->x = p1->x;
429     p2->y = p1->y;
430     }
431    
432    
433     void
434 greg 2.9 zoomview(vp, zf) /* zoom in or out */
435 greg 1.17 register VIEW *vp;
436     double zf;
437     {
438     switch (vp->type) {
439     case VT_PAR: /* parallel view */
440 greg 2.9 vp->horiz /= zf;
441     vp->vert /= zf;
442     return;
443 greg 1.17 case VT_ANG: /* angular fisheye */
444     vp->horiz /= zf;
445 greg 2.9 if (vp->horiz > 360.)
446     vp->horiz = 360.;
447 greg 1.17 vp->vert /= zf;
448 greg 2.9 if (vp->vert > 360.)
449     vp->vert = 360.;
450     return;
451     case VT_CYL: /* cylindrical panorama */
452     vp->horiz /= zf;
453     if (vp->horiz > 360.)
454     vp->horiz = 360.;
455     vp->vert = atan(tan(vp->vert*(PI/180./2.))/zf) / (PI/180./2.);
456 greg 1.17 return;
457     case VT_PER: /* perspective view */
458     vp->horiz = atan(tan(vp->horiz*(PI/180./2.))/zf) /
459     (PI/180./2.);
460     vp->vert = atan(tan(vp->vert*(PI/180./2.))/zf) /
461     (PI/180./2.);
462     return;
463     case VT_HEM: /* hemispherical fisheye */
464     vp->horiz = sin(vp->horiz*(PI/180./2.))/zf;
465     if (vp->horiz >= 1.0-FTINY)
466     vp->horiz = 180.;
467     else
468     vp->horiz = asin(vp->horiz) / (PI/180./2.);
469     vp->vert = sin(vp->vert*(PI/180./2.))/zf;
470     if (vp->vert >= 1.0-FTINY)
471     vp->vert = 180.;
472     else
473     vp->vert = asin(vp->vert) / (PI/180./2.);
474     return;
475     }
476 greg 1.1 }