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.19 by greg, Wed Feb 22 03:16:20 2017 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 + #if  SHADCACHE                  /* preemptive shadow checking */
19 +
20 + #ifndef MAX2SHADE
21 + #define MAX2SHADE       200             /* limit # of sources to precheck */
22 + #endif
23 +
24   #define ABS(x)  ((x)>0 ? (x) : -(x))
25  
26  
27 < #if  SHADCACHE                  /* preemptive shadow checking */
27 > OBJECT *        antimodlist = NULL;     /* set of clipped materials */
28  
29  
30 < static void                             /* cast source ray to first blocker */
30 > static int                              /* cast source ray to first blocker */
31   castshadow(int sn, FVECT rorg, FVECT rdir)
32   {
33          RAY     rt;
# Line 27 | Line 35 | castshadow(int sn, FVECT rorg, FVECT rdir)
35          VCOPY(rt.rorg, rorg);
36          VCOPY(rt.rdir, rdir);
37          rt.rmax = 0;
38 <        rayorigin(&rt, NULL, PRIMARY, 1.0);
39 <        if (!localhit(&rt, &thescene))
40 <                return;
41 <                                        /* pretend we were aimed at source */
42 <        rt.crtype |= rt.rtype = SHADOW;
43 <        rt.rdir[0] = -rt.rdir[0];
44 <        rt.rdir[1] = -rt.rdir[1];
45 <        rt.rdir[2] = -rt.rdir[2];
46 <        rt.rod = -rt.rod;
47 <        VSUB(rt.rorg, rt.rop, rt.rdir);
48 <        rt.rot = 1.;
49 <        rt.rsrc = sn;
38 >        rayorigin(&rt, PRIMARY, NULL, NULL);
39 >                                        /* check for intersection */
40 >        while (localhit(&rt, &thescene)) {
41 >                RAY     rt1 = rt;       /* pretend we were aimed at source */
42 >                rt1.crtype |= rt1.rtype = SHADOW;
43 >                rt1.rdir[0] = -rt.rdir[0];
44 >                rt1.rdir[1] = -rt.rdir[1];
45 >                rt1.rdir[2] = -rt.rdir[2];
46 >                rt1.rod = -rt.rod;
47 >                VSUB(rt1.rorg, rt.rop, rt.rdir);
48 >                rt1.rot = 1.;
49 >                rt1.rsrc = sn;
50                                          /* record blocker */
51 <        srcblocker(&rt);
51 >                if (srcblocker(&rt1))
52 >                        return(1);
53 >                                        /* move past failed blocker */
54 >                VSUM(rt.rorg, rt.rop, rt.rdir, FTINY);
55 >                rayclear(&rt);          /* & try again... */
56 >        }
57 >        return(0);                      /* found no blockers */
58   }
59  
60  
61 < static void                             /* initialize occlusion cache */
61 > void                                    /* initialize occlusion cache */
62   initobscache(int sn)
63   {
64 <        register SRCREC *srcp = &source[sn];
65 <        int             cachelen;
66 <        FVECT           rorg, rdir;
67 <        RREAL           d;
68 <        int             i, j, k;
69 <        int             ax, ax1, ax2;
64 >        SRCREC  *srcp = &source[sn];
65 >        int     cachelen;
66 >        FVECT   rorg, rdir;
67 >        RREAL   d;
68 >        int     i, j, k;
69 >        int     ax=0, ax1=1, ax2=2;
70  
71 +        if (srcp->sflags & (SSKIP|SPROX|SSPOT|SVIRTUAL))
72 +                return;                 /* don't cache these */
73          if (srcp->sflags & SDISTANT)
74                  cachelen = 4*SHADCACHE*SHADCACHE;
75          else if (srcp->sflags & SFLAT)
# Line 61 | Line 77 | initobscache(int sn)
77          else /* spherical distribution */
78                  cachelen = SHADCACHE*SHADCACHE*6;
79                                          /* allocate cache */
64        DCHECK(srcp->obscache != NULL,
65                        CONSISTENCY, "initobscache() called twice");
80          srcp->obscache = (OBSCACHE *)malloc(sizeof(OBSCACHE) +
81                                                  sizeof(OBJECT)*(cachelen-1));
82          if (srcp->obscache == NULL)
# Line 100 | Line 114 | initobscache(int sn)
114                                          /* clear cache */
115          for (i = cachelen; i--; )
116                  srcp->obscache->obs[i] = OVOID;
117 + #if (MAX2SHADE >= 0)
118 +        if (sn >= MAX2SHADE)            /* limit on prechecking */
119 +                return;
120 + #endif
121                                          /* cast shadow rays */
122          if (srcp->sflags & SDISTANT) {
123                  for (k = 3; k--; )
# Line 167 | Line 185 | initobscache(int sn)
185  
186  
187   static OBJECT *                 /* return occluder cache entry */
188 < srcobstructp(register RAY *r)
188 > srcobstructp(RAY *r)
189   {
190 +        static RNUMBER  lastrno = ~0;
191          static OBJECT   noobs;
192 +        static OBJECT   *lastobjp;
193          SRCREC          *srcp;
194          int             ondx;
195  
196 +        noobs = OVOID;
197 +        if (r->rno == lastrno)
198 +                return lastobjp;        /* just recall last pointer */
199          DCHECK(r->rsrc < 0, CONSISTENCY,
200                          "srcobstructp() called with unaimed ray");
201 <        noobs = OVOID;
201 >        lastrno = r->rno;
202 >        lastobjp = &noobs;
203          srcp = &source[r->rsrc];
204          if (srcp->sflags & (SSKIP|SPROX|SSPOT|SVIRTUAL))
205                  return(&noobs);         /* don't cache these */
# Line 183 | Line 207 | srcobstructp(register RAY *r)
207                  initobscache(r->rsrc);
208                                          /* compute cache index */
209          if (srcp->sflags & SDISTANT) {
210 <                int     ax, ax1, ax2;
210 >                int     ax=0, ax1=1, ax2=2;
211                  double  t;
212                  ax = srcp->obscache->p.d.ax;
213                  if ((ax1 = ax+1) >= 3) ax1 -= 3;
# Line 197 | Line 221 | srcobstructp(register RAY *r)
221                  ondx += (int)(2*SHADCACHE*srcp->obscache->p.d.e2 *
222                                  (r->rorg[ax2] + t*srcp->sloc[ax2] -
223                                          srcp->obscache->p.d.o[ax2]));
224 <                if (ondx < 0 | ondx >= 4*SHADCACHE*SHADCACHE)
224 >                if ((ondx < 0) | (ondx >= 4*SHADCACHE*SHADCACHE))
225                          return(&noobs); /* could happen if ray is outside */
226          } else if (srcp->sflags & SFLAT) {
227                  FVECT   sd;
# Line 232 | Line 256 | srcobstructp(register RAY *r)
256                          ondx += (int)(SHADCACHE*(.5-FTINY) *
257                                          (1. + sd[0]/sd1m));
258                  }
259 <                DCHECK(ondx < 0 | ondx >= SHADCACHE*SHADCACHE*3 +
260 <                                (SHADCACHE&1)*SHADCACHE*4, CONSISTENCY,
259 >                DCHECK((ondx < 0) | (ondx >= SHADCACHE*SHADCACHE*3 +
260 >                                (SHADCACHE&1)*SHADCACHE*4), CONSISTENCY,
261                                  "flat source cache index out of bounds");
262          } else /* spherical distribution */ {
263                  int     ax, ax1, ax2;
# Line 252 | Line 276 | srcobstructp(register RAY *r)
276                                          (1. + r->rdir[ax1]/amax));
277                  ondx += (int)(SHADCACHE*(.5-FTINY) *
278                                  (1. + r->rdir[ax2]/amax));
279 <                DCHECK(ondx < 0 | ondx >= SHADCACHE*SHADCACHE*6, CONSISTENCY,
279 >                DCHECK((ondx < 0) | (ondx >= SHADCACHE*SHADCACHE*6), CONSISTENCY,
280                                  "radial source cache index out of bounds");
281          }
282                                          /* return cache pointer */
283 <        return(&srcp->obscache->obs[ondx]);
283 >        return(lastobjp = &srcp->obscache->obs[ondx]);
284   }
285  
286  
# Line 270 | Line 294 | freeobscache(SRCREC *srcp)
294   }
295  
296          
297 < void                            /* record a source blocker */
298 < srcblocker(register RAY *r)
297 > int                             /* record a source blocker */
298 > srcblocker(RAY *r)
299   {
300          OBJREC  *m;
301  
302          if (r->robj == OVOID || objptr(r->robj) != r->ro ||
303                          isvolume(r->ro->otype))
304 <                return;                 /* don't record complex blockers */
304 >                return(0);              /* don't record complex blockers */
305 >        if (r->rsrc < 0 || source[r->rsrc].so == r->ro)
306 >                return(0);              /* just a mistake, that's all */
307 >        if (antimodlist != NULL && inset(antimodlist, r->ro->omod))
308 >                return(0);              /* could be clipped */
309          m = findmaterial(r->ro);
310          if (m == NULL)
311 <                return;                 /* no material?! */
312 <        if (!(ofun[m->otype].flags & T_OPAQUE))
313 <                return;                 /* material not a reliable blocker */
311 >                return(0);              /* no material?! */
312 >        if (!isopaque(m->otype))
313 >                return(0);              /* material not a reliable blocker */
314          *srcobstructp(r) = r->robj;     /* else record obstructor */
315 +        return(1);
316   }
317  
318  
# Line 295 | Line 324 | srcblocked(RAY *r)
324  
325          if (obs == OVOID)
326                  return(0);
327 <        op = objptr(obs);               /* check for intersection */
328 <        return((*ofun[op->otype].funp)(op, r));
327 >        op = objptr(obs);               /* check blocker intersection */
328 >        if (!(*ofun[op->otype].funp)(op, r))
329 >                return(0);
330 >        if (source[r->rsrc].sflags & SDISTANT)
331 >                return(1);
332 >        op = source[r->rsrc].so;        /* check source intersection */
333 >        if (!(*ofun[op->otype].funp)(op, r))
334 >                return(1);
335 >        rayclear(r);
336 >        return(0);                      /* source in front */
337 > }
338 >
339 >
340 > void                            /* record potentially clipped materials */
341 > markclip(OBJREC *m)
342 > {
343 >        OBJECT  *set2add, *oldset;
344 >
345 >        if (m == NULL) {                /* starting over */
346 >                if (antimodlist != NULL)
347 >                        free((void *)antimodlist);
348 >                antimodlist = NULL;
349 >                return;
350 >        }
351 >        m_clip(m, NULL);                /* initialize modifier list */
352 >        if ((set2add = (OBJECT *)m->os) == NULL || !set2add[0])
353 >                return;
354 >
355 >        if (antimodlist == NULL) {      /* start of list */
356 >                antimodlist = setsave(set2add);
357 >                return;
358 >        }
359 >                                        /* else add to previous list */
360 >        oldset = antimodlist;
361 >        antimodlist = (OBJECT *)malloc((oldset[0]+set2add[0]+1)*sizeof(OBJECT));
362 >        if (antimodlist == NULL)
363 >                error(SYSTEM, "out of memory in markclip");
364 >        setunion(antimodlist, oldset, set2add);
365 >        free((void *)oldset);
366 > }
367 >
368 >
369 > #else   /* SHADCACHE */
370 >
371 >
372 > void                            /* no-op also avoids linker warning */
373 > markclip(OBJREC *m)
374 > {
375 >        (void)m;
376   }
377  
378  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines