ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rv3.c
Revision: 2.2
Committed: Fri Jan 17 09:27:21 1992 UTC (32 years, 3 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.1: +7 -1 lines
Log Message:
fixed bug in use of scanf() with SMLFLT defined

File Contents

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