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.1 by greg, Wed Dec 31 19:38:27 2003 UTC vs.
Revision 2.13 by greg, Wed Jul 25 04:12:36 2007 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 > OBJECT *        antimodlist = NULL;     /* set of clipped materials */
23 >
24 >
25 > static int                              /* cast source ray to first blocker */
26   castshadow(int sn, FVECT rorg, FVECT rdir)
27   {
28          RAY     rt;
# Line 27 | Line 30 | castshadow(int sn, FVECT rorg, FVECT rdir)
30          VCOPY(rt.rorg, rorg);
31          VCOPY(rt.rdir, rdir);
32          rt.rmax = 0;
33 <        rayorigin(&rt, NULL, PRIMARY, 1.0);
34 <        if (!localhit(&rt, &thescene))
35 <                return;
36 <                                        /* pretend we were aimed at source */
37 <        rt.crtype |= rt.rtype = SHADOW;
38 <        rt.rdir[0] = -rt.rdir[0];
39 <        rt.rdir[1] = -rt.rdir[1];
40 <        rt.rdir[2] = -rt.rdir[2];
41 <        rt.rod = -rt.rod;
42 <        VSUB(rt.rorg, rt.rop, rt.rdir);
43 <        rt.rot = 1.;
44 <        rt.rsrc = sn;
33 >        rayorigin(&rt, PRIMARY, NULL, NULL);
34 >                                        /* check for intersection */
35 >        while (localhit(&rt, &thescene)) {
36 >                RAY     rt1 = rt;       /* pretend we were aimed at source */
37 >                rt1.crtype |= rt1.rtype = SHADOW;
38 >                rt1.rdir[0] = -rt.rdir[0];
39 >                rt1.rdir[1] = -rt.rdir[1];
40 >                rt1.rdir[2] = -rt.rdir[2];
41 >                rt1.rod = -rt.rod;
42 >                VSUB(rt1.rorg, rt.rop, rt.rdir);
43 >                rt1.rot = 1.;
44 >                rt1.rsrc = sn;
45                                          /* record blocker */
46 <        srcblocker(&rt);
46 >                if (srcblocker(&rt1))
47 >                        return(1);
48 >                                        /* move past failed blocker */
49 >                VSUM(rt.rorg, rt.rop, rt.rdir, FTINY);
50 >                rayclear(&rt);          /* & try again... */
51 >        }
52 >        return(0);                      /* found no blockers */
53   }
54  
55  
56 < static void                             /* initialize occlusion cache */
56 > void                                    /* initialize occlusion cache */
57   initobscache(int sn)
58   {
59          register SRCREC *srcp = &source[sn];
# Line 54 | Line 63 | initobscache(int sn)
63          int             i, j, k;
64          int             ax, ax1, ax2;
65  
66 +        if (srcp->sflags & (SSKIP|SPROX|SSPOT|SVIRTUAL))
67 +                return;                 /* don't cache these */
68          if (srcp->sflags & SDISTANT)
69                  cachelen = 4*SHADCACHE*SHADCACHE;
70          else if (srcp->sflags & SFLAT)
# Line 61 | Line 72 | initobscache(int sn)
72          else /* spherical distribution */
73                  cachelen = SHADCACHE*SHADCACHE*6;
74                                          /* allocate cache */
64        DCHECK(srcp->obscache != NULL,
65                        CONSISTENCY, "initobscache() called twice");
75          srcp->obscache = (OBSCACHE *)malloc(sizeof(OBSCACHE) +
76                                                  sizeof(OBJECT)*(cachelen-1));
77          if (srcp->obscache == NULL)
# Line 136 | Line 145 | initobscache(int sn)
145                                  else
146                                          VSUM(rdir, srcp->obscache->p.f.v,
147                                                  srcp->obscache->p.f.u, d);
148 <                                d = 2./SHADCACHE*(j+.5);
148 >                                d = 1. - 2./SHADCACHE*(j+.5);
149                                  VSUM(rdir, rdir, srcp->snorm, d);
150                                  normalize(rdir);
151                                  castshadow(sn, rorg, rdir);
# Line 169 | Line 178 | initobscache(int sn)
178   static OBJECT *                 /* return occluder cache entry */
179   srcobstructp(register RAY *r)
180   {
181 +        static unsigned long    lastrno = ~0;
182          static OBJECT   noobs;
183 +        static OBJECT   *lastobjp;
184          SRCREC          *srcp;
185          int             ondx;
186  
187 +        noobs = OVOID;
188 +        if (r->rno == lastrno)
189 +                return lastobjp;        /* just recall last pointer */
190          DCHECK(r->rsrc < 0, CONSISTENCY,
191                          "srcobstructp() called with unaimed ray");
192 <        noobs = OVOID;
192 >        lastrno = r->rno;
193 >        lastobjp = &noobs;
194          srcp = &source[r->rsrc];
195          if (srcp->sflags & (SSKIP|SPROX|SSPOT|SVIRTUAL))
196                  return(&noobs);         /* don't cache these */
# Line 197 | Line 212 | srcobstructp(register RAY *r)
212                  ondx += (int)(2*SHADCACHE*srcp->obscache->p.d.e2 *
213                                  (r->rorg[ax2] + t*srcp->sloc[ax2] -
214                                          srcp->obscache->p.d.o[ax2]));
215 <                if (ondx < 0 | ondx >= 4*SHADCACHE*SHADCACHE)
215 >                if ((ondx < 0) | (ondx >= 4*SHADCACHE*SHADCACHE))
216                          return(&noobs); /* could happen if ray is outside */
217          } else if (srcp->sflags & SFLAT) {
218                  FVECT   sd;
# Line 219 | Line 234 | srcobstructp(register RAY *r)
234                          if (sd[0] < 0)
235                                  ondx += ((SHADCACHE+1)>>1)*SHADCACHE;
236                          ondx += SHADCACHE*(int)(SHADCACHE*(.5-FTINY) *
237 <                                        sd[2]/sd0m);
237 >                                        (1. - sd[2]/sd0m));
238                          ondx += (int)(SHADCACHE*(.5-FTINY) *
239                                          (1. + sd[1]/sd0m));
240                  } else /* sd1m > sd0m */ {
# Line 228 | Line 243 | srcobstructp(register RAY *r)
243                          if (sd[1] < 0)
244                                  ondx += ((SHADCACHE+1)>>1)*SHADCACHE;
245                          ondx += SHADCACHE*(int)(SHADCACHE*(.5-FTINY) *
246 <                                        sd[2]/sd1m);
246 >                                        (1. - sd[2]/sd1m));
247                          ondx += (int)(SHADCACHE*(.5-FTINY) *
248                                          (1. + sd[0]/sd1m));
249                  }
250 +                DCHECK((ondx < 0) | (ondx >= SHADCACHE*SHADCACHE*3 +
251 +                                (SHADCACHE&1)*SHADCACHE*4), CONSISTENCY,
252 +                                "flat source cache index out of bounds");
253          } else /* spherical distribution */ {
254                  int     ax, ax1, ax2;
255                  RREAL   amax = 0;
# Line 249 | Line 267 | srcobstructp(register RAY *r)
267                                          (1. + r->rdir[ax1]/amax));
268                  ondx += (int)(SHADCACHE*(.5-FTINY) *
269                                  (1. + r->rdir[ax2]/amax));
270 +                DCHECK((ondx < 0) | (ondx >= SHADCACHE*SHADCACHE*6), CONSISTENCY,
271 +                                "radial source cache index out of bounds");
272          }
273                                          /* return cache pointer */
274 <        return(&srcp->obscache->obs[ondx]);
274 >        return(lastobjp = &srcp->obscache->obs[ondx]);
275   }
276  
277  
# Line 265 | Line 285 | freeobscache(SRCREC *srcp)
285   }
286  
287          
288 < void                            /* record a source blocker */
288 > int                             /* record a source blocker */
289   srcblocker(register RAY *r)
290   {
291          OBJREC  *m;
292  
293          if (r->robj == OVOID || objptr(r->robj) != r->ro ||
294                          isvolume(r->ro->otype))
295 <                return;                 /* don't record complex blockers */
295 >                return(0);              /* don't record complex blockers */
296 >        if (r->rsrc < 0 || source[r->rsrc].so == r->ro)
297 >                return(0);              /* just a mistake, that's all */
298 >        if (antimodlist != NULL && inset(antimodlist, r->ro->omod))
299 >                return(0);              /* could be clipped */
300          m = findmaterial(r->ro);
301          if (m == NULL)
302 <                return;                 /* no material?! */
303 <        if (!(ofun[m->otype].flags & T_OPAQUE))
304 <                return;                 /* material not a reliable blocker */
302 >                return(0);              /* no material?! */
303 >        if (!isopaque(m->otype))
304 >                return(0);              /* material not a reliable blocker */
305          *srcobstructp(r) = r->robj;     /* else record obstructor */
306 +        return(1);
307   }
308  
309  
# Line 290 | Line 315 | srcblocked(RAY *r)
315  
316          if (obs == OVOID)
317                  return(0);
318 <        op = objptr(obs);               /* check for intersection */
319 <        return ((*ofun[op->otype].funp)(op, r));
318 >        op = objptr(obs);               /* check blocker intersection */
319 >        if (!(*ofun[op->otype].funp)(op, r))
320 >                return(0);
321 >        if (source[r->rsrc].sflags & SDISTANT)
322 >                return(1);
323 >        op = source[r->rsrc].so;        /* check source intersection */
324 >        if (!(*ofun[op->otype].funp)(op, r))
325 >                return(1);
326 >        rayclear(r);
327 >        return(0);                      /* source in front */
328 > }
329 >
330 >
331 > void                            /* record potentially clipped materials */
332 > markclip(OBJREC *m)
333 > {
334 >        OBJECT  *set2add, *oldset;
335 >
336 >        m_clip(m, NULL);                /* initialize modifier list */
337 >        if ((set2add = (OBJECT *)m->os) == NULL || !set2add[0])
338 >                return;
339 >
340 >        if (antimodlist == NULL) {      /* start of list */
341 >                antimodlist = setsave(set2add);
342 >                return;
343 >        }
344 >                                        /* else add to previous list */
345 >        oldset = antimodlist;
346 >        antimodlist = (OBJECT *)malloc((oldset[0]+set2add[0]+1)*sizeof(OBJECT));
347 >        if (antimodlist == NULL)
348 >                error(SYSTEM, "out of memory in markclip");
349 >        setunion(antimodlist, oldset, set2add);
350 >        free((void *)oldset);
351 > }
352 >
353 >
354 > #else   /* SHADCACHE */
355 >
356 >
357 > void                            /* no-op also avoids linker warning */
358 > markclip(OBJREC *m)
359 > {
360 >        (void)m;
361   }
362  
363  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines