ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rv3.c
Revision: 2.20
Committed: Wed Apr 5 06:22:57 2006 UTC (18 years ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R8
Changes since 2.19: +2 -2 lines
Log Message:
Made -u+ option truly random

File Contents

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