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

Comparing ray/src/rt/srcobstr.c (file contents):
Revision 2.2 by greg, Thu Jan 1 19:31:46 2004 UTC vs.
Revision 2.9 by greg, Fri Sep 10 16:05:07 2004 UTC

# Line 19 | Line 19 | static const char RCSid[] = "$Id$";
19   #if  SHADCACHE                  /* preemptive shadow checking */
20  
21  
22 < static void                             /* cast source ray to first blocker */
22 > static int                              /* cast source ray to first blocker */
23   castshadow(int sn, FVECT rorg, FVECT rdir)
24   {
25          RAY     rt;
# Line 28 | Line 28 | castshadow(int sn, FVECT rorg, FVECT rdir)
28          VCOPY(rt.rdir, rdir);
29          rt.rmax = 0;
30          rayorigin(&rt, NULL, PRIMARY, 1.0);
31 <        if (!localhit(&rt, &thescene))
32 <                return;
33 <                                        /* pretend we were aimed at source */
34 <        rt.crtype |= rt.rtype = SHADOW;
35 <        rt.rdir[0] = -rt.rdir[0];
36 <        rt.rdir[1] = -rt.rdir[1];
37 <        rt.rdir[2] = -rt.rdir[2];
38 <        rt.rod = -rt.rod;
39 <        VSUB(rt.rorg, rt.rop, rt.rdir);
40 <        rt.rot = 1.;
41 <        rt.rsrc = sn;
31 >                                        /* check for intersection */
32 >        while (localhit(&rt, &thescene)) {
33 >                RAY     rt1 = rt;       /* pretend we were aimed at source */
34 >                rt1.crtype |= rt1.rtype = SHADOW;
35 >                rt1.rdir[0] = -rt.rdir[0];
36 >                rt1.rdir[1] = -rt.rdir[1];
37 >                rt1.rdir[2] = -rt.rdir[2];
38 >                rt1.rod = -rt.rod;
39 >                VSUB(rt1.rorg, rt.rop, rt.rdir);
40 >                rt1.rot = 1.;
41 >                rt1.rsrc = sn;
42                                          /* record blocker */
43 <        srcblocker(&rt);
43 >                if (srcblocker(&rt1))
44 >                        return(1);
45 >                                        /* move past failed blocker */
46 >                VSUM(rt.rorg, rt.rop, rt.rdir, FTINY);
47 >                rayclear(&rt);          /* & try again... */
48 >        }
49 >        return(0);                      /* found no blockers */
50   }
51  
52  
53 < static void                             /* initialize occlusion cache */
53 > void                                    /* initialize occlusion cache */
54   initobscache(int sn)
55   {
56          register SRCREC *srcp = &source[sn];
# Line 54 | Line 60 | initobscache(int sn)
60          int             i, j, k;
61          int             ax, ax1, ax2;
62  
63 +        if (srcp->sflags & (SSKIP|SPROX|SSPOT|SVIRTUAL))
64 +                return;                 /* don't cache these */
65          if (srcp->sflags & SDISTANT)
66                  cachelen = 4*SHADCACHE*SHADCACHE;
67          else if (srcp->sflags & SFLAT)
# Line 61 | Line 69 | initobscache(int sn)
69          else /* spherical distribution */
70                  cachelen = SHADCACHE*SHADCACHE*6;
71                                          /* allocate cache */
64        DCHECK(srcp->obscache != NULL,
65                        CONSISTENCY, "initobscache() called twice");
72          srcp->obscache = (OBSCACHE *)malloc(sizeof(OBSCACHE) +
73                                                  sizeof(OBJECT)*(cachelen-1));
74          if (srcp->obscache == NULL)
# Line 136 | Line 142 | initobscache(int sn)
142                                  else
143                                          VSUM(rdir, srcp->obscache->p.f.v,
144                                                  srcp->obscache->p.f.u, d);
145 <                                d = 2./SHADCACHE*(j+.5);
145 >                                d = 1. - 2./SHADCACHE*(j+.5);
146                                  VSUM(rdir, rdir, srcp->snorm, d);
147                                  normalize(rdir);
148                                  castshadow(sn, rorg, rdir);
# Line 169 | Line 175 | initobscache(int sn)
175   static OBJECT *                 /* return occluder cache entry */
176   srcobstructp(register RAY *r)
177   {
178 +        static unsigned long    lastrno = ~0;
179          static OBJECT   noobs;
180 +        static OBJECT   *lastobjp;
181          SRCREC          *srcp;
182          int             ondx;
183  
184 +        noobs = OVOID;
185 +        if (r->rno == lastrno)
186 +                return lastobjp;        /* just recall last pointer */
187          DCHECK(r->rsrc < 0, CONSISTENCY,
188                          "srcobstructp() called with unaimed ray");
189 <        noobs = OVOID;
189 >        lastrno = r->rno;
190 >        lastobjp = &noobs;
191          srcp = &source[r->rsrc];
192          if (srcp->sflags & (SSKIP|SPROX|SSPOT|SVIRTUAL))
193                  return(&noobs);         /* don't cache these */
# Line 197 | Line 209 | srcobstructp(register RAY *r)
209                  ondx += (int)(2*SHADCACHE*srcp->obscache->p.d.e2 *
210                                  (r->rorg[ax2] + t*srcp->sloc[ax2] -
211                                          srcp->obscache->p.d.o[ax2]));
212 <                if (ondx < 0 | ondx >= 4*SHADCACHE*SHADCACHE)
212 >                if ((ondx < 0) | (ondx >= 4*SHADCACHE*SHADCACHE))
213                          return(&noobs); /* could happen if ray is outside */
214          } else if (srcp->sflags & SFLAT) {
215                  FVECT   sd;
# Line 219 | Line 231 | srcobstructp(register RAY *r)
231                          if (sd[0] < 0)
232                                  ondx += ((SHADCACHE+1)>>1)*SHADCACHE;
233                          ondx += SHADCACHE*(int)(SHADCACHE*(.5-FTINY) *
234 <                                        sd[2]/sd0m);
234 >                                        (1. - sd[2]/sd0m));
235                          ondx += (int)(SHADCACHE*(.5-FTINY) *
236                                          (1. + sd[1]/sd0m));
237                  } else /* sd1m > sd0m */ {
# Line 228 | Line 240 | srcobstructp(register RAY *r)
240                          if (sd[1] < 0)
241                                  ondx += ((SHADCACHE+1)>>1)*SHADCACHE;
242                          ondx += SHADCACHE*(int)(SHADCACHE*(.5-FTINY) *
243 <                                        sd[2]/sd1m);
243 >                                        (1. - sd[2]/sd1m));
244                          ondx += (int)(SHADCACHE*(.5-FTINY) *
245                                          (1. + sd[0]/sd1m));
246                  }
247 +                DCHECK((ondx < 0) | (ondx >= SHADCACHE*SHADCACHE*3 +
248 +                                (SHADCACHE&1)*SHADCACHE*4), CONSISTENCY,
249 +                                "flat source cache index out of bounds");
250          } else /* spherical distribution */ {
251                  int     ax, ax1, ax2;
252                  RREAL   amax = 0;
# Line 249 | Line 264 | srcobstructp(register RAY *r)
264                                          (1. + r->rdir[ax1]/amax));
265                  ondx += (int)(SHADCACHE*(.5-FTINY) *
266                                  (1. + r->rdir[ax2]/amax));
267 +                DCHECK((ondx < 0) | (ondx >= SHADCACHE*SHADCACHE*6), CONSISTENCY,
268 +                                "radial source cache index out of bounds");
269          }
270                                          /* return cache pointer */
271 <        return(&srcp->obscache->obs[ondx]);
271 >        return(lastobjp = &srcp->obscache->obs[ondx]);
272   }
273  
274  
# Line 265 | Line 282 | freeobscache(SRCREC *srcp)
282   }
283  
284          
285 < void                            /* record a source blocker */
285 > int                             /* record a source blocker */
286   srcblocker(register RAY *r)
287   {
288          OBJREC  *m;
289  
290          if (r->robj == OVOID || objptr(r->robj) != r->ro ||
291                          isvolume(r->ro->otype))
292 <                return;                 /* don't record complex blockers */
292 >                return(0);              /* don't record complex blockers */
293          m = findmaterial(r->ro);
294          if (m == NULL)
295 <                return;                 /* no material?! */
296 <        if (!(ofun[m->otype].flags & T_OPAQUE))
297 <                return;                 /* material not a reliable blocker */
295 >                return(0);              /* no material?! */
296 >        if (!isopaque(m->otype))
297 >                return(0);              /* material not a reliable blocker */
298          *srcobstructp(r) = r->robj;     /* else record obstructor */
299 +        return(1);
300   }
301  
302  
# Line 291 | Line 309 | srcblocked(RAY *r)
309          if (obs == OVOID)
310                  return(0);
311          op = objptr(obs);               /* check for intersection */
312 <        return((*ofun[op->otype].funp)(op, r));
312 >        if (!(*ofun[op->otype].funp)(op, r))
313 >                return(0);
314 >        op = source[r->rsrc].so;        /* check source really obstructed */
315 >        if ((*ofun[op->otype].funp)(op, r)) {
316 >                rayclear(r);            /* actually, source in front! */
317 >                return(0);
318 >        }
319 >        return(1);                      /* source truly blocked */
320   }
321  
322  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines