--- ray/src/rt/raytrace.c 1993/01/25 15:16:59 2.2 +++ ray/src/rt/raytrace.c 1993/07/21 15:36:13 2.7 @@ -18,13 +18,15 @@ static char SCCSid[] = "$SunId$ LBL"; #include "otspecial.h" +#define MAXCSET ((MAXSET+1)*2-1) /* maximum check set size */ + extern CUBE thescene; /* our scene */ extern int maxdepth; /* maximum recursion depth */ extern double minweight; /* minimum ray weight */ extern int do_irrad; /* compute irradiance? */ -long raynum = 0L; /* next unique ray number */ -long nrays = 0L; /* number of calls to localhit */ +unsigned long raynum = 0; /* next unique ray number */ +unsigned long nrays = 0; /* number of calls to localhit */ static FLOAT Lambfa[5] = {PI, PI, PI, 0.0, 0.0}; OBJREC Lamb = { @@ -32,6 +34,8 @@ OBJREC Lamb = { {0, 5, NULL, Lambfa}, NULL, }; /* a Lambertian surface */ +static int raymove(), checkset(), checkhit(); + #define MAXLOOP 128 /* modifier loop detection */ #define RAYHIT (-1) /* return value for intercepted ray */ @@ -73,7 +77,6 @@ rayclear(r) /* clear a ray for (re)evaluation */ register RAY *r; { r->rno = raynum++; - r->cxs[0] = 0; r->newcset = r->clipset; r->ro = NULL; r->rot = FHUGE; @@ -102,7 +105,8 @@ RAY *r; raycont(r) /* check for clipped object and continue */ register RAY *r; { - if (r->clipset != NULL && inset(r->clipset, r->ro->omod)) + if ((r->clipset != NULL && inset(r->clipset, r->ro->omod)) || + r->ro->omod == OVOID) raytrans(r); else rayshade(r, r->ro->omod); @@ -317,6 +321,7 @@ localhit(r, scene) /* check for hit in the octree */ register RAY *r; register CUBE *scene; { + OBJECT cxset[MAXCSET+1]; /* set of checked objects */ FVECT curpos; /* current cube position */ int sflags; /* sign flags */ double t, dt; @@ -357,13 +362,15 @@ register CUBE *scene; if (!incube(scene, curpos)) /* non-intersecting ray */ return(0); } - return(raymove(curpos, sflags, r, scene) == RAYHIT); + cxset[0] = 0; + return(raymove(curpos, cxset, sflags, r, scene) == RAYHIT); } static int -raymove(pos, dirf, r, cu) /* check for hit as we move */ -FVECT pos; /* modified */ +raymove(pos, cxs, dirf, r, cu) /* check for hit as we move */ +FVECT pos; /* current position, modified herein */ +OBJECT *cxs; /* checked objects, modified by checkhit */ int dirf; /* direction indicators to speed tests */ register RAY *r; register CUBE *cu; @@ -392,7 +399,7 @@ register CUBE *cu; } for ( ; ; ) { cukid.cutree = octkid(cu->cutree, br); - if ((ax = raymove(pos,dirf,r,&cukid)) == RAYHIT) + if ((ax = raymove(pos,cxs,dirf,r,&cukid)) == RAYHIT) return(RAYHIT); sgn = 1 << ax; if (sgn & dirf) /* positive axis? */ @@ -411,7 +418,7 @@ register CUBE *cu; } /*NOTREACHED*/ } - if (isfull(cu->cutree) && checkhit(r, cu)) + if (isfull(cu->cutree) && checkhit(r, cu, cxs)) return(RAYHIT); /* advance to next cube */ if (dirf&0x11) { @@ -444,16 +451,17 @@ register CUBE *cu; static -checkhit(r, cu) /* check for hit in full cube */ +checkhit(r, cu, cxs) /* check for hit in full cube */ register RAY *r; CUBE *cu; +OBJECT *cxs; { OBJECT oset[MAXSET+1]; register OBJREC *o; register int i; objset(oset, cu->cutree); - checkset(oset, r->cxs); /* eliminate double-checking */ + checkset(oset, cxs); /* eliminate double-checking */ for (i = oset[0]; i > 0; i--) { o = objptr(oset[i]); (*ofun[o->otype].funp)(o, r); @@ -467,11 +475,12 @@ CUBE *cu; static checkset(os, cs) /* modify checked set and set to check */ -register OBJECT os[MAXSET+1]; /* os' = os - cs */ -register OBJECT cs[MAXCSET+1]; /* cs' = cs + os */ +register OBJECT *os; /* os' = os - cs */ +register OBJECT *cs; /* cs' = cs + os */ { OBJECT cset[MAXCSET+MAXSET+1]; - register int i, j, k; + register int i, j; + int k; /* copy os in place, cset <- cs */ cset[0] = 0; k = 0; @@ -483,10 +492,14 @@ register OBJECT cs[MAXCSET+1]; /* cs' = cs + os */ cset[++cset[0]] = os[i]; } } + if (!(os[0] = k)) /* new "to check" set size */ + return; /* special case */ while (j <= cs[0]) /* get the rest of cs */ cset[++cset[0]] = cs[j++]; - if (cset[0] > MAXCSET) /* truncate if necessary */ + if (cset[0] > MAXCSET) /* truncate "checked" set if nec. */ cset[0] = MAXCSET; - setcopy(cs, cset); /* copy new "checked" set back */ - os[0] = k; /* new "to check" set size */ + /* setcopy(cs, cset); */ /* copy cset back to cs */ + os = cset; + for (i = os[0]; i-- >= 0; ) + *cs++ = *os++; }