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 2.13 by schorsch, Mon Jul 21 22:30:19 2003 UTC vs.
Revision 2.43 by greg, Thu Jan 23 19:20:54 2020 UTC

# Line 13 | Line 13 | static const char      RCSid[] = "$Id$";
13  
14   #include  "ray.h"
15   #include  "rpaint.h"
16 + #include  "otypes.h"
17 + #include  "otspecial.h"
18   #include  "random.h"
19  
20   #ifndef WFLUSH
21 < #ifdef SPEED
20 < #define WFLUSH          (5*SPEED)
21 < #else
22 < #define WFLUSH          100             /* flush after this many rays */
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 +
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(s, r)                           /* get a box */
40 < char  *s;
41 < register RECT  *r;
39 > getrect(                                /* get a box */
40 >        char  *s,
41 >        RECT  *r
42 > )
43   {
44          int  x0, y0, x1, y1;
45  
# Line 78 | Line 84 | register RECT  *r;
84  
85  
86   int
87 < getinterest(s, direc, vec, mp)          /* get area of interest */
88 < char  *s;
89 < int  direc;
90 < FVECT  vec;
91 < double  *mp;
87 > getinterest(            /* get area of interest */
88 >        char  *s,
89 >        int  direc,
90 >        FVECT  vec,
91 >        double  *mp
92 > )
93   {
87        int  x, y;
88        RAY  thisray;
89        register int  i;
90
94          if (sscanf(s, "%lf", mp) != 1)
95                  *mp = 1.0;
96          else if (*mp < -FTINY)          /* negative zoom is reduction */
# Line 97 | Line 100 | double  *mp;
100                  return(-1);
101          }
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");
# Line 108 | Line 113 | double  *mp;
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++)
120 <                                        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 141 | 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 < void
193 < paint(p, xmin, ymin, xmax, ymax)        /* compute and paint a rectangle */
194 < register PNODE  *p;
195 < 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   {
150        static unsigned long  lastflush = 0;
201          static RAY  thisray;
202          double  h, v;
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 <        h = xmin + (xmax-xmin)*frandom();
212 <        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          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 {
218 <                rayorigin(&thisray, NULL, PRIMARY, 1.0);
219 <                samplendx++;
220 <                rayvalue(&thisray);
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  
173        p->x = h;
174        p->y = v;
232          copycolor(p->v, thisray.rcol);
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 && nrays - lastflush >= WFLUSH) {
238 <                lastflush = nrays;
239 <                (*dev->flush)();
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 + 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 */
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);
192                                                /* save reserve memory */
193        fillreserves();
296                                                  /* compute resolution */
297          hresolu = dev->xsiz;
298          vresolu = dev->ysiz;
299          normaspect(viewaspect(&ourview), &dev->pixaspect, &hresolu, &vresolu);
300 <        pframe.l = pframe.d = 0;
301 <        pframe.r = hresolu; pframe.u = 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)(hresolu, vresolu);
306 <                                                /* get first value */
307 <        paint(&ptrunk, 0, 0, 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   void
330 < redraw()                                /* redraw the image */
330 > redraw(void)                            /* redraw the image */
331   {
332          (*dev->clear)(hresolu, vresolu);
333          (*dev->comout)("redrawing...\n");
# Line 216 | Line 337 | redraw()                               /* redraw the image */
337  
338  
339   void
340 < repaint(xmin, ymin, xmax, ymax)                 /* repaint a region */
341 < int  xmin, ymin, xmax, ymax;
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, hresolu, vresolu, &reg);
352 >        paintrect(&ptrunk, &reg);
353   }
354  
355  
356   void
357 < paintrect(p, xmin, ymin, xmax, ymax, r)         /* paint picture rectangle */
358 < register PNODE  *p;
359 < int  xmin, ymin, xmax, ymax;
360 < register RECT  *r;
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) {
279                        r->r = mx;
405                          if (y < my) {
281                                r->u = my;
406                                  p = p->kid+DL;
407                          } else {
284                                r->d = my;
408                                  p = p->kid+UL;
409                          }
410                  } else {
288                        r->l = mx;
411                          if (y < my) {
290                                r->u = my;
412                                  p = p->kid+DR;
413                          } else {
293                                r->d = my;
414                                  p = p->kid+UR;
415                          }
416                  }
# Line 300 | Line 420 | int  pd;
420  
421  
422   void
423 < scalepict(p, sf)                        /* scale picture values */
424 < register PNODE  *p;
425 < double  sf;
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 317 | Line 462 | double  sf;
462  
463  
464   void
465 < getpictcolrs(yoff, scan, p, xsiz, ysiz) /* get scanline from picture */
466 < int  yoff;
467 < register COLR  *scan;
468 < register PNODE  *p;
469 < int  xsiz, ysiz;
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 348 | Line 495 | int  xsiz, ysiz;
495  
496  
497   void
498 < freepkids(p)                            /* free pnode's children */
499 < register PNODE  *p;
498 > freepkids(                              /* free pnode's children */
499 >        PNODE  *p
500 > )
501   {
502          if (p->kid == NULL)
503                  return;
# Line 363 | Line 511 | register PNODE  *p;
511  
512  
513   void
514 < newview(vp)                             /* change viewing parameters */
515 < register VIEW  *vp;
514 > newview(                                        /* change viewing parameters */
515 >        VIEW  *vp
516 > )
517   {
518          char  *err;
519  
# Line 374 | Line 523 | register VIEW  *vp;
523          } else if (memcmp((char *)vp, (char *)&ourview, sizeof(VIEW))) {
524                  oldview = ourview;
525                  ourview = *vp;
526 <                newimage();
526 >                newimage(NULL);
527          }
528   }
529  
530  
531   void
532 < moveview(angle, elev, mag, vc)                  /* move viewpoint */
533 < double  angle, elev, mag;
534 < FVECT  vc;
532 > moveview(                                       /* move viewpoint */
533 >        double  angle,
534 >        double  elev,
535 >        double  mag,
536 >        FVECT  vc
537 > )
538   {
539          double  d;
540 <        FVECT  v1;
541 <        VIEW  nv;
390 <        register int  i;
540 >        VIEW  nv = ourview;
541 >        int  i;
542  
392        VCOPY(nv.vup, ourview.vup);
393        nv.hoff = ourview.hoff; nv.voff = ourview.voff;
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) {
401 <                nv.horiz = ourview.horiz / mag;
402 <                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];
406                nv.vfore = ourview.vfore;
407                nv.vaft = ourview.vaft;
553          } else {
409                nv.horiz = ourview.horiz;
410                nv.vert = ourview.vert;
554                  d = sqrt(dist2(ourview.vp, vc)) / mag;
555 <                if ((nv.vfore = ourview.vfore) > FTINY) {
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 = ourview.vaft) > FTINY) {
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 425 | Line 569 | FVECT  vc;
569  
570  
571   void
572 < pcopy(p1, p2)                           /* copy paint node p1 into p2 */
573 < register PNODE  *p1, *p2;
572 > pcopy(                                  /* copy paint node p1 into p2 */
573 >        PNODE  *p1,
574 >        PNODE  *p2
575 > )
576   {
577          copycolor(p2->v, p1->v);
578          p2->x = p1->x;
# Line 435 | Line 581 | register PNODE  *p1, *p2;
581  
582  
583   void
584 < zoomview(vp, zf)                        /* zoom in or out */
585 < register VIEW  *vp;
586 < double  zf;
584 > zoomview(                               /* zoom in or out */
585 >        VIEW  *vp,
586 >        double  zf
587 > )
588   {
589          switch (vp->type) {
590          case VT_PAR:                            /* parallel view */
# Line 451 | Line 598 | double  zf;
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;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines