ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rv3.c
Revision: 1.12
Committed: Fri Jan 19 00:00:31 1990 UTC (34 years, 3 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.11: +3 -3 lines
Log Message:
improved portability and speed of bcopy()

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