--- ray/src/rt/raytrace.c 1996/04/17 14:06:35 2.26 +++ ray/src/rt/raytrace.c 1998/09/15 09:52:39 2.33 @@ -1,7 +1,7 @@ -/* Copyright (c) 1996 Regents of the University of California */ +/* Copyright (c) 1998 Silicon Graphics, Inc. */ #ifndef lint -static char SCCSid[] = "$SunId$ LBL"; +static char SCCSid[] = "$SunId$ SGI"; #endif /* @@ -44,7 +44,9 @@ OBJREC Aftplane; /* aft clipping plane object */ static int raymove(), checkset(), checkhit(); -#define MAXLOOP 128 /* modifier loop detection */ +#ifndef MAXLOOP +#define MAXLOOP 0 /* modifier loop detection */ +#endif #define RAYHIT (-1) /* return value for intercepted ray */ @@ -54,6 +56,8 @@ register RAY *r, *ro; int rt; double rw; { + double re; + if ((r->parent = ro) == NULL) { /* primary ray */ r->rlvl = 0; r->rweight = rw; @@ -82,9 +86,15 @@ double rw; copycolor(r->albedo, ro->albedo); r->gecc = ro->gecc; r->slights = ro->slights; - r->rweight = ro->rweight * rw; r->crtype = ro->crtype | (r->rtype = rt); VCOPY(r->rorg, ro->rop); + r->rweight = ro->rweight * rw; + /* estimate absorption */ + re = colval(ro->cext,RED) < colval(ro->cext,GRN) ? + colval(ro->cext,RED) : colval(ro->cext,GRN); + if (colval(ro->cext,BLU) < re) re = colval(ro->cext,BLU); + if (re > 0.) + r->rweight *= exp(-re*ro->rot); } rayclear(r); return(r->rlvl <= maxdepth && r->rweight >= minweight ? 0 : -1); @@ -96,12 +106,12 @@ register RAY *r; { r->rno = raynum++; r->newcset = r->clipset; + r->robj = OVOID; r->ro = NULL; - r->rot = FHUGE; + r->rt = r->rot = FHUGE; r->pert[0] = r->pert[1] = r->pert[2] = 0.0; setcolor(r->pcol, 1.0, 1.0, 1.0); setcolor(r->rcol, 0.0, 0.0, 0.0); - r->rt = 0.0; } @@ -152,12 +162,14 @@ rayshade(r, mod) /* shade ray r with material mod */ register RAY *r; int mod; { - static int depth = 0; int gotmat; register OBJREC *m; +#if MAXLOOP + static int depth = 0; /* check for infinite loop */ if (depth++ >= MAXLOOP) objerror(r->ro, USER, "possible modifier loop"); +#endif r->rt = r->rot; /* set effective ray length */ for (gotmat = 0; !gotmat && mod != OVOID; mod = m->omod) { m = objptr(mod); @@ -170,7 +182,9 @@ int mod; /* hack for irradiance calculation */ if (do_irrad && !(r->crtype & ~(PRIMARY|TRANS))) { if (irr_ignore(m->otype)) { +#if MAXLOOP depth--; +#endif raytrans(r); return(1); } @@ -180,7 +194,9 @@ int mod; /* materials call raytexture */ gotmat = (*ofun[m->otype].funp)(m, r); } +#if MAXLOOP depth--; +#endif return(gotmat); } @@ -189,16 +205,13 @@ rayparticipate(r) /* compute ray medium participatio register RAY *r; { COLOR ce, ca; - double dist; double re, ge, be; if (intens(r->cext) <= 1./FHUGE) return; /* no medium */ - if ((dist = r->rot) >= FHUGE) - dist = 2.*thescene.cusize; /* what to use for infinity? */ - re = dist*colval(r->cext,RED); - ge = dist*colval(r->cext,GRN); - be = dist*colval(r->cext,BLU); + re = r->rot*colval(r->cext,RED); + ge = r->rot*colval(r->cext,GRN); + be = r->rot*colval(r->cext,BLU); if (r->crtype & SHADOW) { /* no scattering for sources */ re *= 1. - colval(r->albedo,RED); ge *= 1. - colval(r->albedo,GRN); @@ -223,11 +236,13 @@ raytexture(r, mod) /* get material modifiers */ RAY *r; int mod; { - static int depth = 0; register OBJREC *m; +#if MAXLOOP + static int depth = 0; /* check for infinite loop */ if (depth++ >= MAXLOOP) objerror(r->ro, USER, "modifier loop"); +#endif /* execute textures and patterns */ for ( ; mod != OVOID; mod = m->omod) { m = objptr(mod); @@ -243,7 +258,9 @@ int mod; objerror(r->ro, USER, errmsg); } } +#if MAXLOOP depth--; /* end here */ +#endif } @@ -272,9 +289,9 @@ double coef; backmat = rayshade(&br, back); /* check for transparency */ if (backmat ^ foremat) - if (backmat) + if (backmat && coef > FTINY) raytrans(&fr); - else + else if (foremat && coef < 1.0-FTINY) raytrans(&br); /* mix perturbations */ for (i = 0; i < 3; i++) @@ -557,7 +574,8 @@ OBJECT *cxs; checkset(oset, cxs); /* eliminate double-checking */ for (i = oset[0]; i > 0; i--) { o = objptr(oset[i]); - (*ofun[o->otype].funp)(o, r); + if ((*ofun[o->otype].funp)(o, r)) + r->robj = oset[i]; } if (r->ro == NULL) return(0); /* no scores yet */