--- ray/src/rt/srcobstr.c 2004/09/10 16:05:07 2.9 +++ ray/src/rt/srcobstr.c 2013/08/07 05:10:09 2.17 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: srcobstr.c,v 2.9 2004/09/10 16:05:07 greg Exp $"; +static const char RCSid[] = "$Id: srcobstr.c,v 2.17 2013/08/07 05:10:09 greg Exp $"; #endif /* * Source occlusion caching routines @@ -11,6 +11,8 @@ static const char RCSid[] = "$Id: srcobstr.c,v 2.9 200 #include "otspecial.h" +#include "rtotypes.h" + #include "source.h" #define ABS(x) ((x)>0 ? (x) : -(x)) @@ -19,6 +21,9 @@ static const char RCSid[] = "$Id: srcobstr.c,v 2.9 200 #if SHADCACHE /* preemptive shadow checking */ +OBJECT * antimodlist = NULL; /* set of clipped materials */ + + static int /* cast source ray to first blocker */ castshadow(int sn, FVECT rorg, FVECT rdir) { @@ -27,7 +32,7 @@ castshadow(int sn, FVECT rorg, FVECT rdir) VCOPY(rt.rorg, rorg); VCOPY(rt.rdir, rdir); rt.rmax = 0; - rayorigin(&rt, NULL, PRIMARY, 1.0); + rayorigin(&rt, PRIMARY, NULL, NULL); /* check for intersection */ while (localhit(&rt, &thescene)) { RAY rt1 = rt; /* pretend we were aimed at source */ @@ -58,7 +63,7 @@ initobscache(int sn) FVECT rorg, rdir; RREAL d; int i, j, k; - int ax, ax1, ax2; + int ax=0, ax1=1, ax2=2; if (srcp->sflags & (SSKIP|SPROX|SSPOT|SVIRTUAL)) return; /* don't cache these */ @@ -175,7 +180,7 @@ initobscache(int sn) static OBJECT * /* return occluder cache entry */ srcobstructp(register RAY *r) { - static unsigned long lastrno = ~0; + static RNUMBER lastrno = ~0; static OBJECT noobs; static OBJECT *lastobjp; SRCREC *srcp; @@ -195,7 +200,7 @@ srcobstructp(register RAY *r) initobscache(r->rsrc); /* compute cache index */ if (srcp->sflags & SDISTANT) { - int ax, ax1, ax2; + int ax=0, ax1=1, ax2=2; double t; ax = srcp->obscache->p.d.ax; if ((ax1 = ax+1) >= 3) ax1 -= 3; @@ -290,6 +295,10 @@ srcblocker(register RAY *r) if (r->robj == OVOID || objptr(r->robj) != r->ro || isvolume(r->ro->otype)) return(0); /* don't record complex blockers */ + if (r->rsrc < 0 || source[r->rsrc].so == r->ro) + return(0); /* just a mistake, that's all */ + if (antimodlist != NULL && inset(antimodlist, r->ro->omod)) + return(0); /* could be clipped */ m = findmaterial(r->ro); if (m == NULL) return(0); /* no material?! */ @@ -308,15 +317,55 @@ srcblocked(RAY *r) if (obs == OVOID) return(0); - op = objptr(obs); /* check for intersection */ + op = objptr(obs); /* check blocker intersection */ if (!(*ofun[op->otype].funp)(op, r)) return(0); - op = source[r->rsrc].so; /* check source really obstructed */ - if ((*ofun[op->otype].funp)(op, r)) { - rayclear(r); /* actually, source in front! */ - return(0); + if (source[r->rsrc].sflags & SDISTANT) + return(1); + op = source[r->rsrc].so; /* check source intersection */ + if (!(*ofun[op->otype].funp)(op, r)) + return(1); + rayclear(r); + return(0); /* source in front */ +} + + +void /* record potentially clipped materials */ +markclip(OBJREC *m) +{ + OBJECT *set2add, *oldset; + + if (m == NULL) { /* starting over */ + if (antimodlist != NULL) + free((void *)antimodlist); + antimodlist = NULL; + return; } - return(1); /* source truly blocked */ + m_clip(m, NULL); /* initialize modifier list */ + if ((set2add = (OBJECT *)m->os) == NULL || !set2add[0]) + return; + + if (antimodlist == NULL) { /* start of list */ + antimodlist = setsave(set2add); + return; + } + /* else add to previous list */ + oldset = antimodlist; + antimodlist = (OBJECT *)malloc((oldset[0]+set2add[0]+1)*sizeof(OBJECT)); + if (antimodlist == NULL) + error(SYSTEM, "out of memory in markclip"); + setunion(antimodlist, oldset, set2add); + free((void *)oldset); +} + + +#else /* SHADCACHE */ + + +void /* no-op also avoids linker warning */ +markclip(OBJREC *m) +{ + (void)m; }