ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rv3.c
Revision: 2.13
Committed: Mon Jul 21 22:30:19 2003 UTC (20 years, 9 months ago) by schorsch
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R6, rad3R6P1
Changes since 2.12: +3 -3 lines
Log Message:
Eliminated copystruct() macro, which is unnecessary in ANSI.
Reduced ambiguity warnings for nested if/if/else clauses.

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: rv3.c,v 2.12 2003/06/30 14:59:13 schorsch Exp $";
3 #endif
4 /*
5 * rv3.c - miscellaneous routines for rview.
6 *
7 * External symbols declared in rpaint.h
8 */
9
10 #include "copyright.h"
11
12 #include <string.h>
13
14 #include "ray.h"
15 #include "rpaint.h"
16 #include "random.h"
17
18 #ifndef WFLUSH
19 #ifdef SPEED
20 #define WFLUSH (5*SPEED)
21 #else
22 #define WFLUSH 100 /* flush after this many rays */
23 #endif
24 #endif
25
26 #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
32
33 int
34 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 r->r = hresolu;
43 r->u = vresolu;
44 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 if (r->r > hresolu) r->r = hresolu;
73 if (r->u > vresolu) r->u = vresolu;
74 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 int
81 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 if (!sscanvec(sskip(s), vec)) {
100 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 if ((thisray.rmax = viewray(thisray.rorg, thisray.rdir,
106 &ourview, (x+.5)/hresolu, (y+.5)/vresolu)) < -FTINY) {
107 error(COMMAND, "not on image");
108 return(-1);
109 }
110 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
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 void
146 paint(p, xmin, ymin, xmax, ymax) /* compute and paint a rectangle */
147 register PNODE *p;
148 int xmin, ymin, xmax, ymax;
149 {
150 static unsigned long lastflush = 0;
151 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 h = xmin + (xmax-xmin)*frandom();
162 v = ymin + (ymax-ymin)*frandom();
163
164 if ((thisray.rmax = viewray(thisray.rorg, thisray.rdir, &ourview,
165 h/hresolu, v/vresolu)) < -FTINY) {
166 setcolor(thisray.rcol, 0.0, 0.0, 0.0);
167 } else {
168 rayorigin(&thisray, NULL, PRIMARY, 1.0);
169 samplendx++;
170 rayvalue(&thisray);
171 }
172
173 p->x = h;
174 p->y = v;
175 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
180 if (dev->flush != NULL && nrays - lastflush >= WFLUSH) {
181 lastflush = nrays;
182 (*dev->flush)();
183 }
184 }
185
186
187 void
188 newimage() /* start a new image */
189 {
190 /* free old image */
191 freepkids(&ptrunk);
192 /* save reserve memory */
193 fillreserves();
194 /* compute resolution */
195 hresolu = dev->xsiz;
196 vresolu = dev->ysiz;
197 normaspect(viewaspect(&ourview), &dev->pixaspect, &hresolu, &vresolu);
198 pframe.l = pframe.d = 0;
199 pframe.r = hresolu; pframe.u = vresolu;
200 pdepth = 0;
201 /* clear device */
202 (*dev->clear)(hresolu, vresolu);
203 /* get first value */
204 paint(&ptrunk, 0, 0, hresolu, vresolu);
205 }
206
207
208 void
209 redraw() /* redraw the image */
210 {
211 (*dev->clear)(hresolu, vresolu);
212 (*dev->comout)("redrawing...\n");
213 repaint(0, 0, hresolu, vresolu);
214 (*dev->comout)("\n");
215 }
216
217
218 void
219 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 paintrect(&ptrunk, 0, 0, hresolu, vresolu, &reg);
228 }
229
230
231 void
232 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 void
303 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 void
320 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 void
351 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 free((void *)p->kid);
361 p->kid = NULL;
362 }
363
364
365 void
366 newview(vp) /* change viewing parameters */
367 register VIEW *vp;
368 {
369 char *err;
370
371 if ((err = setview(vp)) != NULL) {
372 sprintf(errmsg, "view not set - %s", err);
373 error(COMMAND, errmsg);
374 } else if (memcmp((char *)vp, (char *)&ourview, sizeof(VIEW))) {
375 oldview = ourview;
376 ourview = *vp;
377 newimage();
378 }
379 }
380
381
382 void
383 moveview(angle, elev, mag, vc) /* move viewpoint */
384 double angle, elev, mag;
385 FVECT vc;
386 {
387 double d;
388 FVECT v1;
389 VIEW nv;
390 register int i;
391
392 VCOPY(nv.vup, ourview.vup);
393 nv.hoff = ourview.hoff; nv.voff = ourview.voff;
394 spinvector(nv.vdir, ourview.vdir, ourview.vup, angle*(PI/180.));
395 if (elev != 0.0) {
396 fcross(v1, ourview.vup, nv.vdir);
397 normalize(v1);
398 spinvector(nv.vdir, nv.vdir, v1, elev*(PI/180.));
399 }
400 if ((nv.type = ourview.type) == VT_PAR) {
401 nv.horiz = ourview.horiz / mag;
402 nv.vert = ourview.vert / mag;
403 d = 0.0; /* don't move closer */
404 for (i = 0; i < 3; i++)
405 d += (vc[i] - ourview.vp[i])*ourview.vdir[i];
406 nv.vfore = ourview.vfore;
407 nv.vaft = ourview.vaft;
408 } else {
409 nv.horiz = ourview.horiz;
410 nv.vert = ourview.vert;
411 d = sqrt(dist2(ourview.vp, vc)) / mag;
412 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 }
421 for (i = 0; i < 3; i++)
422 nv.vp[i] = vc[i] - d*nv.vdir[i];
423 newview(&nv);
424 }
425
426
427 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 zoomview(vp, zf) /* zoom in or out */
439 register VIEW *vp;
440 double zf;
441 {
442 switch (vp->type) {
443 case VT_PAR: /* parallel view */
444 vp->horiz /= zf;
445 vp->vert /= zf;
446 return;
447 case VT_ANG: /* angular fisheye */
448 vp->horiz /= zf;
449 if (vp->horiz > 360.)
450 vp->horiz = 360.;
451 vp->vert /= zf;
452 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 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 }