--- ray/src/rt/srcobstr.c 2003/12/31 19:38:27 2.1 +++ ray/src/rt/srcobstr.c 2004/09/08 01:48:50 2.6 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: srcobstr.c,v 2.1 2003/12/31 19:38:27 greg Exp $"; +static const char RCSid[] = "$Id: srcobstr.c,v 2.6 2004/09/08 01:48:50 greg Exp $"; #endif /* * Source occlusion caching routines @@ -136,7 +136,7 @@ initobscache(int sn) else VSUM(rdir, srcp->obscache->p.f.v, srcp->obscache->p.f.u, d); - d = 2./SHADCACHE*(j+.5); + d = 1. - 2./SHADCACHE*(j+.5); VSUM(rdir, rdir, srcp->snorm, d); normalize(rdir); castshadow(sn, rorg, rdir); @@ -169,13 +169,19 @@ initobscache(int sn) static OBJECT * /* return occluder cache entry */ srcobstructp(register RAY *r) { + static unsigned long lastrno = ~0; static OBJECT noobs; + static OBJECT *lastobjp; SRCREC *srcp; int ondx; + noobs = OVOID; + if (r->rno == lastrno) + return lastobjp; /* just recall last pointer */ DCHECK(r->rsrc < 0, CONSISTENCY, "srcobstructp() called with unaimed ray"); - noobs = OVOID; + lastrno = r->rno; + lastobjp = &noobs; srcp = &source[r->rsrc]; if (srcp->sflags & (SSKIP|SPROX|SSPOT|SVIRTUAL)) return(&noobs); /* don't cache these */ @@ -197,7 +203,7 @@ srcobstructp(register RAY *r) ondx += (int)(2*SHADCACHE*srcp->obscache->p.d.e2 * (r->rorg[ax2] + t*srcp->sloc[ax2] - srcp->obscache->p.d.o[ax2])); - if (ondx < 0 | ondx >= 4*SHADCACHE*SHADCACHE) + if ((ondx < 0) | (ondx >= 4*SHADCACHE*SHADCACHE)) return(&noobs); /* could happen if ray is outside */ } else if (srcp->sflags & SFLAT) { FVECT sd; @@ -219,7 +225,7 @@ srcobstructp(register RAY *r) if (sd[0] < 0) ondx += ((SHADCACHE+1)>>1)*SHADCACHE; ondx += SHADCACHE*(int)(SHADCACHE*(.5-FTINY) * - sd[2]/sd0m); + (1. - sd[2]/sd0m)); ondx += (int)(SHADCACHE*(.5-FTINY) * (1. + sd[1]/sd0m)); } else /* sd1m > sd0m */ { @@ -228,10 +234,13 @@ srcobstructp(register RAY *r) if (sd[1] < 0) ondx += ((SHADCACHE+1)>>1)*SHADCACHE; ondx += SHADCACHE*(int)(SHADCACHE*(.5-FTINY) * - sd[2]/sd1m); + (1. - sd[2]/sd1m)); ondx += (int)(SHADCACHE*(.5-FTINY) * (1. + sd[0]/sd1m)); } + DCHECK((ondx < 0) | (ondx >= SHADCACHE*SHADCACHE*3 + + (SHADCACHE&1)*SHADCACHE*4), CONSISTENCY, + "flat source cache index out of bounds"); } else /* spherical distribution */ { int ax, ax1, ax2; RREAL amax = 0; @@ -249,9 +258,11 @@ srcobstructp(register RAY *r) (1. + r->rdir[ax1]/amax)); ondx += (int)(SHADCACHE*(.5-FTINY) * (1. + r->rdir[ax2]/amax)); + DCHECK((ondx < 0) | (ondx >= SHADCACHE*SHADCACHE*6), CONSISTENCY, + "radial source cache index out of bounds"); } /* return cache pointer */ - return(&srcp->obscache->obs[ondx]); + return(lastobjp = &srcp->obscache->obs[ondx]); } @@ -276,7 +287,7 @@ srcblocker(register RAY *r) m = findmaterial(r->ro); if (m == NULL) return; /* no material?! */ - if (!(ofun[m->otype].flags & T_OPAQUE)) + if (!isopaque(m->otype)) return; /* material not a reliable blocker */ *srcobstructp(r) = r->robj; /* else record obstructor */ } @@ -291,7 +302,7 @@ srcblocked(RAY *r) if (obs == OVOID) return(0); op = objptr(obs); /* check for intersection */ - return ((*ofun[op->otype].funp)(op, r)); + return((*ofun[op->otype].funp)(op, r)); }