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.3 by greg, Fri Jan 9 05:37:12 2004 UTC vs.
Revision 2.15 by greg, Sat Dec 12 00:03:42 2009 UTC

# Line 11 | Line 11 | static const char RCSid[] = "$Id$";
11  
12   #include  "otspecial.h"
13  
14 + #include  "rtotypes.h"
15 +
16   #include  "source.h"
17  
18   #define ABS(x)  ((x)>0 ? (x) : -(x))
# Line 19 | Line 21 | static const char RCSid[] = "$Id$";
21   #if  SHADCACHE                  /* preemptive shadow checking */
22  
23  
24 < static void                             /* cast source ray to first blocker */
24 > OBJECT *        antimodlist = NULL;     /* set of clipped materials */
25 >
26 >
27 > static int                              /* cast source ray to first blocker */
28   castshadow(int sn, FVECT rorg, FVECT rdir)
29   {
30          RAY     rt;
# Line 27 | Line 32 | castshadow(int sn, FVECT rorg, FVECT rdir)
32          VCOPY(rt.rorg, rorg);
33          VCOPY(rt.rdir, rdir);
34          rt.rmax = 0;
35 <        rayorigin(&rt, NULL, PRIMARY, 1.0);
36 <        if (!localhit(&rt, &thescene))
37 <                return;
38 <                                        /* pretend we were aimed at source */
39 <        rt.crtype |= rt.rtype = SHADOW;
40 <        rt.rdir[0] = -rt.rdir[0];
41 <        rt.rdir[1] = -rt.rdir[1];
42 <        rt.rdir[2] = -rt.rdir[2];
43 <        rt.rod = -rt.rod;
44 <        VSUB(rt.rorg, rt.rop, rt.rdir);
45 <        rt.rot = 1.;
46 <        rt.rsrc = sn;
35 >        rayorigin(&rt, PRIMARY, NULL, NULL);
36 >                                        /* check for intersection */
37 >        while (localhit(&rt, &thescene)) {
38 >                RAY     rt1 = rt;       /* pretend we were aimed at source */
39 >                rt1.crtype |= rt1.rtype = SHADOW;
40 >                rt1.rdir[0] = -rt.rdir[0];
41 >                rt1.rdir[1] = -rt.rdir[1];
42 >                rt1.rdir[2] = -rt.rdir[2];
43 >                rt1.rod = -rt.rod;
44 >                VSUB(rt1.rorg, rt.rop, rt.rdir);
45 >                rt1.rot = 1.;
46 >                rt1.rsrc = sn;
47                                          /* record blocker */
48 <        srcblocker(&rt);
48 >                if (srcblocker(&rt1))
49 >                        return(1);
50 >                                        /* move past failed blocker */
51 >                VSUM(rt.rorg, rt.rop, rt.rdir, FTINY);
52 >                rayclear(&rt);          /* & try again... */
53 >        }
54 >        return(0);                      /* found no blockers */
55   }
56  
57  
58 < static void                             /* initialize occlusion cache */
58 > void                                    /* initialize occlusion cache */
59   initobscache(int sn)
60   {
61          register SRCREC *srcp = &source[sn];
# Line 54 | Line 65 | initobscache(int sn)
65          int             i, j, k;
66          int             ax, ax1, ax2;
67  
68 +        if (srcp->sflags & (SSKIP|SPROX|SSPOT|SVIRTUAL))
69 +                return;                 /* don't cache these */
70          if (srcp->sflags & SDISTANT)
71                  cachelen = 4*SHADCACHE*SHADCACHE;
72          else if (srcp->sflags & SFLAT)
# Line 61 | Line 74 | initobscache(int sn)
74          else /* spherical distribution */
75                  cachelen = SHADCACHE*SHADCACHE*6;
76                                          /* allocate cache */
64        DCHECK(srcp->obscache != NULL,
65                        CONSISTENCY, "initobscache() called twice");
77          srcp->obscache = (OBSCACHE *)malloc(sizeof(OBSCACHE) +
78                                                  sizeof(OBJECT)*(cachelen-1));
79          if (srcp->obscache == NULL)
# Line 169 | Line 180 | initobscache(int sn)
180   static OBJECT *                 /* return occluder cache entry */
181   srcobstructp(register RAY *r)
182   {
183 +        static RNUMBER  lastrno = ~0;
184          static OBJECT   noobs;
185 +        static OBJECT   *lastobjp;
186          SRCREC          *srcp;
187          int             ondx;
188  
189 +        noobs = OVOID;
190 +        if (r->rno == lastrno)
191 +                return lastobjp;        /* just recall last pointer */
192          DCHECK(r->rsrc < 0, CONSISTENCY,
193                          "srcobstructp() called with unaimed ray");
194 <        noobs = OVOID;
194 >        lastrno = r->rno;
195 >        lastobjp = &noobs;
196          srcp = &source[r->rsrc];
197          if (srcp->sflags & (SSKIP|SPROX|SSPOT|SVIRTUAL))
198                  return(&noobs);         /* don't cache these */
# Line 197 | Line 214 | srcobstructp(register RAY *r)
214                  ondx += (int)(2*SHADCACHE*srcp->obscache->p.d.e2 *
215                                  (r->rorg[ax2] + t*srcp->sloc[ax2] -
216                                          srcp->obscache->p.d.o[ax2]));
217 <                if (ondx < 0 | ondx >= 4*SHADCACHE*SHADCACHE)
217 >                if ((ondx < 0) | (ondx >= 4*SHADCACHE*SHADCACHE))
218                          return(&noobs); /* could happen if ray is outside */
219          } else if (srcp->sflags & SFLAT) {
220                  FVECT   sd;
# Line 232 | Line 249 | srcobstructp(register RAY *r)
249                          ondx += (int)(SHADCACHE*(.5-FTINY) *
250                                          (1. + sd[0]/sd1m));
251                  }
252 <                DCHECK(ondx < 0 | ondx >= SHADCACHE*SHADCACHE*3 +
253 <                                (SHADCACHE&1)*SHADCACHE*4, CONSISTENCY,
252 >                DCHECK((ondx < 0) | (ondx >= SHADCACHE*SHADCACHE*3 +
253 >                                (SHADCACHE&1)*SHADCACHE*4), CONSISTENCY,
254                                  "flat source cache index out of bounds");
255          } else /* spherical distribution */ {
256                  int     ax, ax1, ax2;
# Line 252 | Line 269 | srcobstructp(register RAY *r)
269                                          (1. + r->rdir[ax1]/amax));
270                  ondx += (int)(SHADCACHE*(.5-FTINY) *
271                                  (1. + r->rdir[ax2]/amax));
272 <                DCHECK(ondx < 0 | ondx >= SHADCACHE*SHADCACHE*6, CONSISTENCY,
272 >                DCHECK((ondx < 0) | (ondx >= SHADCACHE*SHADCACHE*6), CONSISTENCY,
273                                  "radial source cache index out of bounds");
274          }
275                                          /* return cache pointer */
276 <        return(&srcp->obscache->obs[ondx]);
276 >        return(lastobjp = &srcp->obscache->obs[ondx]);
277   }
278  
279  
# Line 270 | Line 287 | freeobscache(SRCREC *srcp)
287   }
288  
289          
290 < void                            /* record a source blocker */
290 > int                             /* record a source blocker */
291   srcblocker(register RAY *r)
292   {
293          OBJREC  *m;
294  
295          if (r->robj == OVOID || objptr(r->robj) != r->ro ||
296                          isvolume(r->ro->otype))
297 <                return;                 /* don't record complex blockers */
297 >                return(0);              /* don't record complex blockers */
298 >        if (r->rsrc < 0 || source[r->rsrc].so == r->ro)
299 >                return(0);              /* just a mistake, that's all */
300 >        if (antimodlist != NULL && inset(antimodlist, r->ro->omod))
301 >                return(0);              /* could be clipped */
302          m = findmaterial(r->ro);
303          if (m == NULL)
304 <                return;                 /* no material?! */
305 <        if (!(ofun[m->otype].flags & T_OPAQUE))
306 <                return;                 /* material not a reliable blocker */
304 >                return(0);              /* no material?! */
305 >        if (!isopaque(m->otype))
306 >                return(0);              /* material not a reliable blocker */
307          *srcobstructp(r) = r->robj;     /* else record obstructor */
308 +        return(1);
309   }
310  
311  
# Line 295 | Line 317 | srcblocked(RAY *r)
317  
318          if (obs == OVOID)
319                  return(0);
320 <        op = objptr(obs);               /* check for intersection */
321 <        return((*ofun[op->otype].funp)(op, r));
320 >        op = objptr(obs);               /* check blocker intersection */
321 >        if (!(*ofun[op->otype].funp)(op, r))
322 >                return(0);
323 >        if (source[r->rsrc].sflags & SDISTANT)
324 >                return(1);
325 >        op = source[r->rsrc].so;        /* check source intersection */
326 >        if (!(*ofun[op->otype].funp)(op, r))
327 >                return(1);
328 >        rayclear(r);
329 >        return(0);                      /* source in front */
330 > }
331 >
332 >
333 > void                            /* record potentially clipped materials */
334 > markclip(OBJREC *m)
335 > {
336 >        OBJECT  *set2add, *oldset;
337 >
338 >        m_clip(m, NULL);                /* initialize modifier list */
339 >        if ((set2add = (OBJECT *)m->os) == NULL || !set2add[0])
340 >                return;
341 >
342 >        if (antimodlist == NULL) {      /* start of list */
343 >                antimodlist = setsave(set2add);
344 >                return;
345 >        }
346 >                                        /* else add to previous list */
347 >        oldset = antimodlist;
348 >        antimodlist = (OBJECT *)malloc((oldset[0]+set2add[0]+1)*sizeof(OBJECT));
349 >        if (antimodlist == NULL)
350 >                error(SYSTEM, "out of memory in markclip");
351 >        setunion(antimodlist, oldset, set2add);
352 >        free((void *)oldset);
353 > }
354 >
355 >
356 > #else   /* SHADCACHE */
357 >
358 >
359 > void                            /* no-op also avoids linker warning */
360 > markclip(OBJREC *m)
361 > {
362 >        (void)m;
363   }
364  
365  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines