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

# Content
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 #include "octree.h"
16
17 #include "rpaint.h"
18
19 #include "random.h"
20
21 #ifndef WFLUSH
22 #define WFLUSH 30 /* flush after this many rays */
23 #endif
24
25 #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
31
32 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 r->r = hresolu;
41 r->u = vresolu;
42 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 if (r->r > hresolu) r->r = hresolu;
71 if (r->u > vresolu) r->u = vresolu;
72 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 if (!sscanvec(sskip(s), vec)) {
97 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 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 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
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 extern long nrays;
147 static long lastflush = 0;
148 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 h = xmin + (xmax-xmin)*frandom();
159 v = ymin + (ymax-ymin)*frandom();
160
161 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 samplendx++;
167 rayvalue(&thisray);
168 }
169
170 p->x = h;
171 p->y = v;
172 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
177 if (dev->flush != NULL && nrays - lastflush >= WFLUSH) {
178 lastflush = nrays;
179 (*dev->flush)();
180 }
181 }
182
183
184 newimage() /* start a new image */
185 {
186 /* free old image */
187 freepkids(&ptrunk);
188 /* save reserve memory */
189 fillreserves();
190 /* compute resolution */
191 hresolu = dev->xsiz;
192 vresolu = dev->ysiz;
193 normaspect(viewaspect(&ourview), &dev->pixaspect, &hresolu, &vresolu);
194 pframe.l = pframe.d = 0;
195 pframe.r = hresolu; pframe.u = vresolu;
196 pdepth = 0;
197 /* clear device */
198 (*dev->clear)(hresolu, vresolu);
199 /* get first value */
200 paint(&ptrunk, 0, 0, hresolu, vresolu);
201 }
202
203
204 redraw() /* redraw the image */
205 {
206 (*dev->clear)(hresolu, vresolu);
207 (*dev->comout)("redrawing...\n");
208 repaint(0, 0, hresolu, vresolu);
209 (*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 paintrect(&ptrunk, 0, 0, hresolu, vresolu, &reg);
222 }
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 if ((err = setview(vp)) != NULL) {
370 sprintf(errmsg, "view not set - %s", err);
371 error(COMMAND, errmsg);
372 } else if (bcmp((char *)vp, (char *)&ourview, sizeof(VIEW))) {
373 copystruct(&oldview, &ourview);
374 copystruct(&ourview, vp);
375 newimage();
376 }
377 }
378
379
380 moveview(angle, elev, mag, vc) /* move viewpoint */
381 double angle, elev, mag;
382 FVECT vc;
383 {
384 extern double sqrt(), dist2();
385 double d;
386 FVECT v1;
387 VIEW nv;
388 register int i;
389
390 VCOPY(nv.vup, ourview.vup);
391 nv.hoff = ourview.hoff; nv.voff = ourview.voff;
392 spinvector(nv.vdir, ourview.vdir, ourview.vup, angle*(PI/180.));
393 if (elev != 0.0) {
394 fcross(v1, ourview.vup, nv.vdir);
395 normalize(v1);
396 spinvector(nv.vdir, nv.vdir, v1, elev*(PI/180.));
397 }
398 if ((nv.type = ourview.type) == VT_PAR) {
399 nv.horiz = ourview.horiz / mag;
400 nv.vert = ourview.vert / mag;
401 d = 0.0; /* don't move closer */
402 for (i = 0; i < 3; i++)
403 d += (vc[i] - ourview.vp[i])*ourview.vdir[i];
404 } else {
405 nv.horiz = ourview.horiz;
406 nv.vert = ourview.vert;
407 d = sqrt(dist2(ourview.vp, vc)) / mag;
408 }
409 for (i = 0; i < 3; i++)
410 nv.vp[i] = vc[i] - d*nv.vdir[i];
411 newview(&nv);
412 }
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 }