ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rv3.c
(Generate patch)

Comparing ray/src/rt/rv3.c (file contents):
Revision 1.8 by greg, Wed Nov 1 16:12:20 1989 UTC vs.
Revision 2.43 by greg, Thu Jan 23 19:20:54 2020 UTC

# Line 1 | Line 1
1 /* Copyright (c) 1987 Regents of the University of California */
2
1   #ifndef lint
2 < static char SCCSid[] = "$SunId$ LBL";
2 > static const char       RCSid[] = "$Id$";
3   #endif
6
4   /*
5   *  rv3.c - miscellaneous routines for rview.
6   *
7 < *     5/11/87
7 > *  External symbols declared in rpaint.h
8   */
9  
10 < #include  "ray.h"
10 > #include "copyright.h"
11  
12 < #include  "octree.h"
12 > #include <string.h>
13  
14 + #include  "ray.h"
15   #include  "rpaint.h"
16 <
16 > #include  "otypes.h"
17 > #include  "otspecial.h"
18   #include  "random.h"
19  
20 + #ifndef WFLUSH
21 + #define WFLUSH          64              /* flush after this many primary rays */
22 + #endif
23 + #ifndef WFLUSH1
24 + #define WFLUSH1         512             /* or this many total rays */
25 + #endif
26  
27 < getrect(s, r)                           /* get a box */
28 < char  *s;
29 < register RECT  *r;
27 >
28 > #ifdef  SMLFLT
29 > #define  sscanvec(s,v)  (sscanf(s,"%f %f %f",v,v+1,v+2)==3)
30 > #else
31 > #define  sscanvec(s,v)  (sscanf(s,"%lf %lf %lf",v,v+1,v+2)==3)
32 > #endif
33 >
34 > extern int      ray_pnprocs;
35 >
36 > static RNUMBER  niflush;                /* flushes since newimage() */
37 >
38 > int
39 > getrect(                                /* get a box */
40 >        char  *s,
41 >        RECT  *r
42 > )
43   {
44          int  x0, y0, x1, y1;
45  
46          if (*s && !strncmp(s, "all", strlen(s))) {
47                  r->l = r->d = 0;
48 <                r->r = ourview.hresolu;
49 <                r->u = ourview.vresolu;
48 >                r->r = hresolu;
49 >                r->u = vresolu;
50                  return(0);
51          }
52          if (sscanf(s, "%d %d %d %d", &x0, &y0, &x1, &y1) != 4) {
# Line 57 | Line 75 | register RECT  *r;
75          }
76          if (r->l < 0) r->l = 0;
77          if (r->d < 0) r->d = 0;
78 <        if (r->r > ourview.hresolu) r->r = ourview.hresolu;
79 <        if (r->u > ourview.vresolu) r->u = ourview.vresolu;
78 >        if (r->r > hresolu) r->r = hresolu;
79 >        if (r->u > vresolu) r->u = vresolu;
80          if (r->l > r->r) r->l = r->r;
81          if (r->d > r->u) r->d = r->u;
82          return(0);
83   }
84  
85  
86 < getinterest(s, direc, vec, mp)          /* get area of interest */
87 < char  *s;
88 < int  direc;
89 < FVECT  vec;
90 < double  *mp;
86 > int
87 > getinterest(            /* get area of interest */
88 >        char  *s,
89 >        int  direc,
90 >        FVECT  vec,
91 >        double  *mp
92 > )
93   {
74        int  x, y;
75        RAY  thisray;
76        register int  i;
77
94          if (sscanf(s, "%lf", mp) != 1)
95                  *mp = 1.0;
96          else if (*mp < -FTINY)          /* negative zoom is reduction */
# Line 83 | Line 99 | double  *mp;
99                  error(COMMAND, "illegal magnification");
100                  return(-1);
101          }
102 <        if (sscanf(s, "%*lf %lf %lf %lf", &vec[0], &vec[1], &vec[2]) != 3) {
102 >        if (!sscanvec(sskip(s), vec)) {
103 >                RAY  thisray;
104 >                int  x, y;
105                  if (dev->getcur == NULL)
106                          return(-1);
107                  (*dev->comout)("Pick view center\n");
108                  if ((*dev->getcur)(&x, &y) == ABORT)
109                          return(-1);
110 <                rayview(thisray.rorg, thisray.rdir, &ourview, x+.5, y+.5);
110 >                if ((thisray.rmax = viewray(thisray.rorg, thisray.rdir,
111 >                        &ourview, (x+.5)/hresolu, (y+.5)/vresolu)) < -FTINY) {
112 >                        error(COMMAND, "not on image");
113 >                        return(-1);
114 >                }
115                  if (!direc || ourview.type == VT_PAR) {
116 <                        rayorigin(&thisray, NULL, PRIMARY, 1.0);
117 <                        if (!localhit(&thisray, &thescene)) {
118 <                                error(COMMAND, "not a local object");
119 <                                return(-1);
116 >                        int     weakhit = 0;
117 >                        FVECT   weakpt;
118 >                        rayorigin(&thisray, PRIMARY, NULL, NULL);
119 >                        while (localhit(&thisray, &thescene)) {
120 >                                OBJREC  *m = NULL;
121 >                                if (thisray.clipset == NULL ||
122 >                                                !inset(thisray.clipset,
123 >                                                            thisray.ro->omod))
124 >                                        m = findmaterial(thisray.ro);
125 >                                if ((m != NULL) & !weakhit &&
126 >                                                istransp(m->otype) &&
127 >                                                m->otype != MAT_MIST) {
128 >                                        weakhit = 1;
129 >                                        VCOPY(weakpt, thisray.rop);
130 >                                } else if (m != NULL && !istransp(m->otype) &&
131 >                                                !isBSDFproxy(m))
132 >                                        break;          /* something solid */
133 >                                VCOPY(thisray.rorg, thisray.rop);
134 >                                rayclear(&thisray);     /* skip invisible */
135                          }
136 +                        if ((thisray.ro == NULL) | (thisray.ro == &Aftplane)) {
137 +                                if (!weakhit) {
138 +                                        error(COMMAND, "not a local object");
139 +                                        return(-1);
140 +                                }                       /* else use weak obj. */
141 +                                VCOPY(thisray.rop, weakpt);
142 +                        }
143                  }
144                  if (direc)
145                          if (ourview.type == VT_PAR)
146 <                                for (i = 0; i < 3; i++)
103 <                                        vec[i] = thisray.rop[i] - ourview.vp[i];
146 >                                VSUB(vec, thisray.rop, ourview.vp);
147                          else
148                                  VCOPY(vec, thisray.rdir);
149                  else
150                          VCOPY(vec, thisray.rop);
151 <        } else if (direc)
152 <                        for (i = 0; i < 3; i++)
153 <                                vec[i] -= ourview.vp[i];
151 >        } else if (direc) {
152 >                VSUB(vec, vec, ourview.vp);
153 >                if (normalize(vec) == 0.0) {
154 >                        error(COMMAND, "point at view origin");
155 >                        return(-1);
156 >                }
157 >        }
158          return(0);
159   }
160  
161  
162 < float *         /* keep consistent with COLOR typedef */
163 < greyof(col)                             /* convert color to greyscale */
164 < register COLOR  col;
162 > COLORV *
163 > greyof(                         /* convert color to greyscale */
164 >        COLOR  col
165 > )
166   {
167          static COLOR  gcol;
168          double  b;
# Line 124 | Line 172 | register COLOR  col;
172          return(gcol);
173   }
174  
175 + static void
176 + recolor(                                        /* recolor the given node */
177 +        PNODE *p
178 + )
179 + {
180 +        while (p->kid != NULL) {                /* need to propogate down */
181 +                int  mx = (p->xmin + p->xmax) >> 1;
182 +                int  my = (p->ymin + p->ymax) >> 1;
183 +                int  ki;
184 +                if (p->x >= mx)
185 +                        ki = (p->y >= my) ? UR : DR;
186 +                else
187 +                        ki = (p->y >= my) ? UL : DL;
188 +                pcopy(p, p->kid+ki);
189 +                p = p->kid + ki;
190 +        }
191  
192 < paint(p, xmin, ymin, xmax, ymax)        /* compute and paint a rectangle */
193 < register PNODE  *p;
194 < int  xmin, ymin, xmax, ymax;
192 >        (*dev->paintr)(greyscale?greyof(p->v):p->v,
193 >                        p->xmin, p->ymin, p->xmax, p->ymax);
194 > }
195 >
196 > int
197 > paint(                  /* compute and paint a rectangle */
198 >        PNODE  *p
199 > )
200   {
201          static RAY  thisray;
202          double  h, v;
134        register int  i;
203  
204 <        if (xmax - xmin <= 0 || ymax - ymin <= 0) {     /* empty */
205 <                p->x = xmin;
206 <                p->y = ymin;
204 >        if ((p->xmax <= p->xmin) | (p->ymax <= p->ymin)) {      /* empty */
205 >                p->x = p->xmin;
206 >                p->y = p->ymin;
207                  setcolor(p->v, 0.0, 0.0, 0.0);
208 <                return;
208 >                return(0);
209          }
210                                                  /* jitter ray direction */
211 <        p->x = h = xmin + (xmax-xmin)*frandom();
212 <        p->y = v = ymin + (ymax-ymin)*frandom();
211 >        p->x = h = p->xmin + (p->xmax-p->xmin)*frandom();
212 >        p->y = v = p->ymin + (p->ymax-p->ymin)*frandom();
213          
214 <        rayview(thisray.rorg, thisray.rdir, &ourview, h, v);
214 >        if ((thisray.rmax = viewray(thisray.rorg, thisray.rdir, &ourview,
215 >                        h/hresolu, v/vresolu)) < -FTINY) {
216 >                setcolor(thisray.rcol, 0.0, 0.0, 0.0);
217 >        } else if (!ray_pnprocs) {              /* immediate mode */
218 >                ray_trace(&thisray);
219 >        } else {                                /* queuing mode */
220 >                int     rval;
221 >                rayorigin(&thisray, PRIMARY, NULL, NULL);
222 >                thisray.rno = (RNUMBER)p;
223 >                rval = ray_pqueue(&thisray);
224 >                if (!rval)
225 >                        return(0);
226 >                if (rval < 0)
227 >                        return(-1);
228 >                                                /* get node for returned ray */
229 >                p = (PNODE *)thisray.rno;
230 >        }
231  
148        rayorigin(&thisray, NULL, PRIMARY, 1.0);
149        
150        rayvalue(&thisray);
151
232          copycolor(p->v, thisray.rcol);
153
233          scalecolor(p->v, exposure);
234  
235 <        (*dev->paintr)(greyscale?greyof(p->v):p->v, xmin, ymin, xmax, ymax);
235 >        recolor(p);                             /* paint it */
236 >
237 >        if (dev->flush != NULL) {               /* shall we check for input? */
238 >                static RNUMBER  lastflush = 0;
239 >                RNUMBER         counter = raynum;
240 >                int             flushintvl;
241 >                if (!ray_pnprocs) {
242 >                        counter = nrays;
243 >                        flushintvl = WFLUSH1;
244 >                } else if (ambounce == 0)
245 >                        flushintvl = ray_pnprocs*WFLUSH;
246 >                else if (niflush < WFLUSH)
247 >                        flushintvl = ray_pnprocs*niflush/(ambounce*(ambounce>0)+1);
248 >                else
249 >                        flushintvl = ray_pnprocs*WFLUSH/(ambounce*(ambounce>0)+1);
250 >                if (lastflush > counter)
251 >                        lastflush = 0;          /* counter wrapped */
252 >
253 >                if (counter - lastflush >= flushintvl) {
254 >                        lastflush = counter;
255 >                        (*dev->flush)();
256 >                        niflush++;
257 >                }
258 >        }
259 >        return(1);
260   }
261  
262  
263 < newimage()                              /* start a new image */
263 > int
264 > waitrays(void)                                  /* finish up pending rays */
265   {
266 +        int     nwaited = 0;
267 +        int     rval;
268 +        RAY     raydone;
269 +
270 +        if (!ray_pnprocs)                       /* immediate mode? */
271 +                return(0);
272 +        while ((rval = ray_presult(&raydone, 0)) > 0) {
273 +                PNODE  *p = (PNODE *)raydone.rno;
274 +                copycolor(p->v, raydone.rcol);
275 +                scalecolor(p->v, exposure);
276 +                recolor(p);
277 +                nwaited++;
278 +        }
279 +        if (rval < 0)
280 +                return(-1);
281 +        return(nwaited);
282 + }
283 +
284 +
285 + void
286 + newimage(                                       /* start a new image */
287 +        char *s
288 + )
289 + {
290 +        int             newnp = 0;
291 +                                                /* # rendering procs arg? */
292 +        if (s != NULL)
293 +                sscanf(s, "%d", &newnp);
294                                                  /* free old image */
295          freepkids(&ptrunk);
296 <                                                /* set up frame */
297 <        if (ourview.hresolu > dev->xsiz || ourview.vresolu > dev->ysiz)
298 <                newview(&ourview);              /* beware recursive loop! */
299 <        pframe.l = pframe.d = 0;
300 <        pframe.r = ourview.hresolu; pframe.u = ourview.vresolu;
296 >                                                /* compute resolution */
297 >        hresolu = dev->xsiz;
298 >        vresolu = dev->ysiz;
299 >        normaspect(viewaspect(&ourview), &dev->pixaspect, &hresolu, &vresolu);
300 >        ptrunk.xmin = ptrunk.ymin = pframe.l = pframe.d = 0;
301 >        ptrunk.xmax = pframe.r = hresolu;
302 >        ptrunk.ymax = pframe.u = vresolu;
303          pdepth = 0;
304                                                  /* clear device */
305 <        (*dev->clear)(ourview.hresolu, ourview.vresolu);
306 <                                                /* get first value */
307 <        paint(&ptrunk, 0, 0, ourview.hresolu, ourview.vresolu);
305 >        (*dev->clear)(hresolu, vresolu);
306 >
307 >        if (newparam) {                         /* (re)start rendering procs */
308 >                if (ray_pnprocs)
309 >                        ray_pclose(0);          /* should already be closed */
310 >                if (newnp > 0)
311 >                        nproc = newnp;
312 >                if (nproc > 1)
313 >                        ray_popen(nproc);
314 >                newparam = 0;
315 >        } else if ((newnp > 0) & (newnp != nproc)) {
316 >                if (newnp == 1)                 /* change # rendering procs */
317 >                        ray_pclose(0);
318 >                else if (newnp < ray_pnprocs)
319 >                        ray_pclose(ray_pnprocs - newnp);
320 >                else
321 >                        ray_popen(newnp - ray_pnprocs);
322 >                nproc = newnp;
323 >        }
324 >        niflush = 0;                            /* get first value */
325 >        paint(&ptrunk);
326   }
327  
328  
329 < redraw()                                /* redraw the image */
329 > void
330 > redraw(void)                            /* redraw the image */
331   {
332 <        (*dev->clear)(ourview.hresolu, ourview.vresolu);
332 >        (*dev->clear)(hresolu, vresolu);
333          (*dev->comout)("redrawing...\n");
334 <        repaint(0, 0, ourview.hresolu, ourview.vresolu);
334 >        repaint(0, 0, hresolu, vresolu);
335          (*dev->comout)("\n");
336   }
337  
338  
339 < repaint(xmin, ymin, xmax, ymax)                 /* repaint a region */
340 < int  xmin, ymin, xmax, ymax;
339 > void
340 > repaint(                                /* repaint a region */
341 >        int  xmin,
342 >        int  ymin,
343 >        int  xmax,
344 >        int  ymax
345 > )
346   {
347          RECT  reg;
348  
349          reg.l = xmin; reg.r = xmax;
350          reg.d = ymin; reg.u = ymax;
351  
352 <        paintrect(&ptrunk, 0, 0, ourview.hresolu, ourview.vresolu, &reg);
352 >        paintrect(&ptrunk, &reg);
353   }
354  
355  
356 < paintrect(p, xmin, ymin, xmax, ymax, r)         /* paint picture rectangle */
357 < register PNODE  *p;
358 < int  xmin, ymin, xmax, ymax;
359 < register RECT  *r;
356 > void
357 > paintrect(                              /* paint picture rectangle */
358 >        PNODE  *p,
359 >        RECT  *r
360 > )
361   {
362          int  mx, my;
363  
364 <        if (xmax - xmin <= 0 || ymax - ymin <= 0)
364 >        if (p->xmax - p->xmin <= 0 || p->ymax - p->ymin <= 0)
365                  return;
366  
367          if (p->kid == NULL) {
368                  (*dev->paintr)(greyscale?greyof(p->v):p->v,
369 <                                xmin, ymin, xmax, ymax);        /* do this */
369 >                        p->xmin, p->ymin, p->xmax, p->ymax);    /* do this */
370                  return;
371          }
372 <        mx = (xmin + xmax) >> 1;                                /* do kids */
373 <        my = (ymin + ymax) >> 1;
372 >        mx = (p->xmin + p->xmax) >> 1;                          /* do kids */
373 >        my = (p->ymin + p->ymax) >> 1;
374          if (mx > r->l) {
375                  if (my > r->d)
376 <                        paintrect(p->kid+DL, xmin, ymin, mx, my, r);
376 >                        paintrect(p->kid+DL, r);
377                  if (my < r->u)
378 <                        paintrect(p->kid+UL, xmin, my, mx, ymax, r);
378 >                        paintrect(p->kid+UL, r);
379          }
380          if (mx < r->r) {
381                  if (my > r->d)
382 <                        paintrect(p->kid+DR, mx, ymin, xmax, my, r);
382 >                        paintrect(p->kid+DR, r);
383                  if (my < r->u)
384 <                        paintrect(p->kid+UR, mx, my, xmax, ymax, r);
384 >                        paintrect(p->kid+UR, r);
385          }
386   }
387  
388  
389   PNODE *
390 < findrect(x, y, p, r, pd)                /* find a rectangle */
391 < int  x, y;
392 < register PNODE  *p;
393 < register RECT  *r;
394 < int  pd;
390 > findrect(                               /* find a rectangle */
391 >        int  x,
392 >        int  y,
393 >        PNODE  *p,
394 >        int  pd
395 > )
396   {
397          int  mx, my;
398  
399          while (p->kid != NULL && pd--) {
400  
401 <                mx = (r->l + r->r) >> 1;
402 <                my = (r->d + r->u) >> 1;
401 >                mx = (p->xmin + p->xmax) >> 1;
402 >                my = (p->ymin + p->ymax) >> 1;
403  
404                  if (x < mx) {
245                        r->r = mx;
405                          if (y < my) {
247                                r->u = my;
406                                  p = p->kid+DL;
407                          } else {
250                                r->d = my;
408                                  p = p->kid+UL;
409                          }
410                  } else {
254                        r->l = mx;
411                          if (y < my) {
256                                r->u = my;
412                                  p = p->kid+DR;
413                          } else {
259                                r->d = my;
414                                  p = p->kid+UR;
415                          }
416                  }
# Line 265 | Line 419 | int  pd;
419   }
420  
421  
422 < scalepict(p, sf)                        /* scale picture values */
423 < register PNODE  *p;
424 < double  sf;
422 > void
423 > compavg(                                /* recompute averages */
424 >        PNODE   *p
425 > )
426   {
427 +        int     i, navg;
428 +        
429 +        if (p->kid == NULL)
430 +                return;
431 +
432 +        setcolor(p->v, .0, .0, .0);
433 +        navg = 0;
434 +        for (i = 0; i < 4; i++) {
435 +                if (p->kid[i].xmin >= p->kid[i].xmax) continue;
436 +                if (p->kid[i].ymin >= p->kid[i].ymax) continue;
437 +                compavg(p->kid+i);
438 +                addcolor(p->v, p->kid[i].v);
439 +                navg++;
440 +        }
441 +        if (navg > 1)
442 +                scalecolor(p->v, 1./navg);
443 + }
444 +
445 +
446 + void
447 + scalepict(                              /* scale picture values */
448 +        PNODE  *p,
449 +        double  sf
450 + )
451 + {
452          scalecolor(p->v, sf);           /* do this node */
453  
454          if (p->kid == NULL)
# Line 281 | Line 461 | double  sf;
461   }
462  
463  
464 < getpictcolrs(yoff, scan, p, xsiz, ysiz) /* get scanline from picture */
465 < int  yoff;
466 < register COLR  *scan;
467 < register PNODE  *p;
468 < int  xsiz, ysiz;
464 > void
465 > getpictcolrs(                           /* get scanline from picture */
466 >        int  yoff,
467 >        COLR  *scan,
468 >        PNODE  *p,
469 >        int  xsiz,
470 >        int  ysiz
471 > )
472   {
473 <        register int  mx;
473 >        int  mx;
474          int  my;
475  
476          if (p->kid == NULL) {                   /* do this node */
# Line 311 | Line 494 | int  xsiz, ysiz;
494   }
495  
496  
497 < pcopy(p1, p2)                           /* copy paint node p1 into p2 */
498 < register PNODE  *p1, *p2;
497 > void
498 > freepkids(                              /* free pnode's children */
499 >        PNODE  *p
500 > )
501   {
317        copycolor(p2->v, p1->v);
318        p2->x = p1->x;
319        p2->y = p1->y;
320 }
321
322
323 freepkids(p)                            /* free pnode's children */
324 register PNODE  *p;
325 {
502          if (p->kid == NULL)
503                  return;
504          freepkids(p->kid+DL);
505          freepkids(p->kid+DR);
506          freepkids(p->kid+UL);
507          freepkids(p->kid+UR);
508 <        free((char *)p->kid);
508 >        free((void *)p->kid);
509          p->kid = NULL;
510   }
511  
512  
513 < newview(vp)                             /* change viewing parameters */
514 < register VIEW  *vp;
513 > void
514 > newview(                                        /* change viewing parameters */
515 >        VIEW  *vp
516 > )
517   {
518          char  *err;
519  
342        if (vp->hresolu > dev->xsiz || vp->vresolu > dev->ysiz) /* shrink */
343                if (vp->vresolu * dev->xsiz < vp->hresolu * dev->ysiz) {
344                        vp->vresolu = dev->xsiz * vp->vresolu / vp->hresolu;
345                        vp->hresolu = dev->xsiz;
346                } else {
347                        vp->hresolu = dev->ysiz * vp->hresolu / vp->vresolu;
348                        vp->vresolu = dev->ysiz;
349                }
520          if ((err = setview(vp)) != NULL) {
521                  sprintf(errmsg, "view not set - %s", err);
522                  error(COMMAND, errmsg);
523 <        } else if (bcmp(vp, &ourview, sizeof(VIEW))) {
524 <                bcopy(&ourview, &oldview, sizeof(VIEW));
525 <                bcopy(vp, &ourview, sizeof(VIEW));
526 <                newimage();             /* newimage() calls with vp=&ourview! */
523 >        } else if (memcmp((char *)vp, (char *)&ourview, sizeof(VIEW))) {
524 >                oldview = ourview;
525 >                ourview = *vp;
526 >                newimage(NULL);
527          }
528   }
529  
530  
531 < moveview(angle, elev, mag, vc)                  /* move viewpoint */
532 < double  angle, elev, mag;
533 < FVECT  vc;
531 > void
532 > moveview(                                       /* move viewpoint */
533 >        double  angle,
534 >        double  elev,
535 >        double  mag,
536 >        FVECT  vc
537 > )
538   {
365        extern double  sqrt(), dist2();
539          double  d;
540 <        FVECT  v1;
541 <        VIEW  nv;
369 <        register int  i;
540 >        VIEW  nv = ourview;
541 >        int  i;
542  
371        VCOPY(nv.vup, ourview.vup);
372        nv.hresolu = ourview.hresolu; nv.vresolu = ourview.vresolu;
543          spinvector(nv.vdir, ourview.vdir, ourview.vup, angle*(PI/180.));
544 <        if (elev != 0.0) {
545 <                fcross(v1, ourview.vup, nv.vdir);
546 <                normalize(v1);
547 <                spinvector(nv.vdir, nv.vdir, v1, elev*(PI/180.));
548 <        }
549 <        if ((nv.type = ourview.type) == VT_PAR) {
380 <                nv.horiz = ourview.horiz / mag;
381 <                nv.vert = ourview.vert / mag;
544 >        if (elev != 0.0)
545 >                geodesic(nv.vdir, nv.vdir, nv.vup, elev*(-PI/180.), GEOD_RAD);
546 >
547 >        if (nv.type == VT_PAR) {
548 >                nv.horiz /= mag;
549 >                nv.vert /= mag;
550                  d = 0.0;                        /* don't move closer */
551                  for (i = 0; i < 3; i++)
552                          d += (vc[i] - ourview.vp[i])*ourview.vdir[i];
553          } else {
386                nv.horiz = ourview.horiz;
387                nv.vert = ourview.vert;
554                  d = sqrt(dist2(ourview.vp, vc)) / mag;
555 +                if (nv.vfore > FTINY) {
556 +                        nv.vfore += d - d*mag;
557 +                        if (nv.vfore < 0.0) nv.vfore = 0.0;
558 +                }
559 +                if (nv.vaft > FTINY) {
560 +                        nv.vaft += d - d*mag;
561 +                        if (nv.vaft <= nv.vfore) nv.vaft = 0.0;
562 +                }
563 +                nv.vdist /= mag;
564          }
565          for (i = 0; i < 3; i++)
566                  nv.vp[i] = vc[i] - d*nv.vdir[i];
# Line 393 | Line 568 | FVECT  vc;
568   }
569  
570  
571 < spinvector(vres, vorig, vnorm, theta)   /* rotate vector around normal */
572 < FVECT  vres, vorig, vnorm;
573 < double  theta;
571 > void
572 > pcopy(                                  /* copy paint node p1 into p2 */
573 >        PNODE  *p1,
574 >        PNODE  *p2
575 > )
576   {
577 <        extern double  sin(), cos();
578 <        double  sint, cost, dotp;
579 <        FVECT  vperp;
580 <        register int  i;
581 <        
582 <        if (theta == 0.0) {
583 <                VCOPY(vres, vorig);
577 >        copycolor(p2->v, p1->v);
578 >        p2->x = p1->x;
579 >        p2->y = p1->y;
580 > }
581 >
582 >
583 > void
584 > zoomview(                               /* zoom in or out */
585 >        VIEW  *vp,
586 >        double  zf
587 > )
588 > {
589 >        switch (vp->type) {
590 >        case VT_PAR:                            /* parallel view */
591 >                vp->horiz /= zf;
592 >                vp->vert /= zf;
593                  return;
594 +        case VT_ANG:                            /* angular fisheye */
595 +                vp->horiz /= zf;
596 +                if (vp->horiz > 360.)
597 +                        vp->horiz = 360.;
598 +                vp->vert /= zf;
599 +                if (vp->vert > 360.)
600 +                        vp->vert = 360.;
601 +                return;
602 +        case VT_PLS:                            /* planisphere fisheye */
603 +                vp->horiz = sin((PI/180./2.)*vp->horiz) /
604 +                                (1.0 + cos((PI/180./2.)*vp->horiz)) / zf;
605 +                vp->horiz *= vp->horiz;
606 +                vp->horiz = (2.*180./PI)*acos((1. - vp->horiz) /
607 +                                                (1. + vp->horiz));
608 +                vp->vert = sin((PI/180./2.)*vp->vert) /
609 +                                (1.0 + cos((PI/180./2.)*vp->vert)) / zf;
610 +                vp->vert *= vp->vert;
611 +                vp->vert = (2.*180./PI)*acos((1. - vp->vert) /
612 +                                                (1. + vp->vert));
613 +                return;
614 +        case VT_CYL:                            /* cylindrical panorama */
615 +                vp->horiz /= zf;
616 +                if (vp->horiz > 360.)
617 +                        vp->horiz = 360.;
618 +                vp->vert = atan(tan(vp->vert*(PI/180./2.))/zf) / (PI/180./2.);
619 +                return;
620 +        case VT_PER:                            /* perspective view */
621 +                vp->horiz = atan(tan(vp->horiz*(PI/180./2.))/zf) /
622 +                                (PI/180./2.);
623 +                vp->vert = atan(tan(vp->vert*(PI/180./2.))/zf) /
624 +                                (PI/180./2.);
625 +                return;
626 +        case VT_HEM:                            /* hemispherical fisheye */
627 +                vp->horiz = sin(vp->horiz*(PI/180./2.))/zf;
628 +                if (vp->horiz >= 1.0-FTINY)
629 +                        vp->horiz = 180.;
630 +                else
631 +                        vp->horiz = asin(vp->horiz) / (PI/180./2.);
632 +                vp->vert = sin(vp->vert*(PI/180./2.))/zf;
633 +                if (vp->vert >= 1.0-FTINY)
634 +                        vp->vert = 180.;
635 +                else
636 +                        vp->vert = asin(vp->vert) / (PI/180./2.);
637 +                return;
638          }
409        sint = sin(theta);
410        cost = cos(theta);
411        dotp = DOT(vorig, vnorm);
412        fcross(vperp, vnorm, vorig);
413        for (i = 0; i < 3; i++)
414                vres[i] = vnorm[i]*dotp*(1.-cost) +
415                                vorig[i]*cost + vperp[i]*sint;
639   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines