--- ray/src/rt/dielectric.c 2010/09/26 15:51:15 2.21 +++ ray/src/rt/dielectric.c 2015/05/20 13:12:06 2.26 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: dielectric.c,v 2.21 2010/09/26 15:51:15 greg Exp $"; +static const char RCSid[] = "$Id: dielectric.c,v 2.26 2015/05/20 13:12:06 rschregle Exp $"; #endif /* * dielectric.c - shading function for transparent materials. @@ -10,6 +10,7 @@ static const char RCSid[] = "$Id: dielectric.c,v 2.21 #include "ray.h" #include "otypes.h" #include "rtotypes.h" +#include "pmapmat.h" #ifdef DISPERSE #include "source.h" @@ -50,8 +51,8 @@ static double mylog(double x); #define MINCOS 0.997 /* minimum dot product for dispersion */ - -static double +static +double mylog( /* special log for extinction coefficients */ double x ) @@ -64,25 +65,30 @@ mylog( /* special log for extinction coefficients */ } -extern int +int m_dielectric( /* color a ray which hit a dielectric interface */ OBJREC *m, - register RAY *r + RAY *r ) { double cos1, cos2, nratio; COLOR ctrans; COLOR talb; int hastexture; - double transdist, transtest=0; - double mirdist, mirtest=0; + double transdist=0, transtest=0; + double mirdist=0, mirtest=0; int flatsurface; double refl, trans; FVECT dnorm; double d1, d2; RAY p; - register int i; + int i; + /* PMAP: skip refracted shadow or ambient ray if accounted for in + photon map */ + if (shadowRayInPmap(r) || ambRayInPmap(r)) + return(1); + if (m->oargs.nfargs != (m->otype==MAT_DIELECTRIC ? 5 : 8)) objerror(m, USER, "bad arguments"); @@ -94,7 +100,8 @@ m_dielectric( /* color a ray which hit a dielectric in VCOPY(dnorm, r->ron); cos1 = r->rod; } - flatsurface = !hastexture && r->ro != NULL && isflat(r->ro->otype); + flatsurface = r->ro != NULL && isflat(r->ro->otype) && + !hastexture | (r->crtype & AMBIENT); /* index of refraction */ if (m->otype == MAT_DIELECTRIC) @@ -199,8 +206,8 @@ m_dielectric( /* color a ray which hit a dielectric in addcolor(r->rcol, p.rcol); /* virtual distance */ if (flatsurface || - (1.-FTINY <= nratio && - nratio <= 1.+FTINY)) { + (1.-FTINY <= nratio) & + (nratio <= 1.+FTINY)) { transtest = 2*bright(p.rcol); transdist = r->rot + p.rt; } @@ -213,12 +220,10 @@ m_dielectric( /* color a ray which hit a dielectric in rayorigin(&p, REFLECTED, r, p.rcoef) == 0) { /* compute reflected ray */ - for (i = 0; i < 3; i++) - p.rdir[i] = r->rdir[i] + 2.0*cos1*dnorm[i]; + VSUM(p.rdir, r->rdir, dnorm, 2.*cos1); /* accidental penetration? */ if (hastexture && DOT(p.rdir,r->ron)*hastexture <= FTINY) - for (i = 0; i < 3; i++) /* ignore texture */ - p.rdir[i] = r->rdir[i] + 2.0*r->rod*r->ron[i]; + VSUM(p.rdir, r->rdir, r->ron, 2.*r->rod); checknorm(p.rdir); rayvalue(&p); /* reflected ray value */ @@ -309,10 +314,10 @@ disperse( /* check light sources for dispersion */ VCOPY(n2, r->ron); /* first order dispersion approx. */ - dtmp1 = DOT(n1, v1); - dtmp2 = DOT(n2, v2); + dtmp1 = 1./DOT(n1, v1); + dtmp2 = 1./DOT(n2, v2); for (i = 0; i < 3; i++) - dv[i] = v1[i] + v2[i] - n1[i]/dtmp1 - n2[i]/dtmp2; + dv[i] = v1[i] + v2[i] - n1[i]*dtmp1 - n2[i]*dtmp2; if (DOT(dv, dv) <= FTINY) /* null effect */ return(0); @@ -355,15 +360,13 @@ disperse( /* check light sources for dispersion */ dtmp1 = sqrt(si.dom / v2Xdvv2Xdv / PI); /* compute first ray */ - for (i = 0; i < 3; i++) - vtmp2[i] = sray.rdir[i] + dtmp1*vtmp1[i]; + VSUM(vtmp2, sray.rdir, vtmp1, dtmp1); l1 = lambda(m, v2, dv, vtmp2); /* first lambda */ if (l1 < 0) continue; /* compute second ray */ - for (i = 0; i < 3; i++) - vtmp2[i] = sray.rdir[i] - dtmp1*vtmp1[i]; + VSUM(vtmp2, sray.rdir, vtmp1, -dtmp1); l2 = lambda(m, v2, dv, vtmp2); /* second lambda */ if (l2 < 0) @@ -384,7 +387,7 @@ disperse( /* check light sources for dispersion */ static int lambda( /* compute lambda for material */ - register OBJREC *m, + OBJREC *m, FVECT v2, FVECT dv, FVECT lr @@ -396,7 +399,7 @@ lambda( /* compute lambda for material */ fcross(lrXdv, lr, dv); for (i = 0; i < 3; i++) - if (lrXdv[i] > FTINY || lrXdv[i] < -FTINY) + if ((lrXdv[i] > FTINY) | (lrXdv[i] < -FTINY)) break; if (i >= 3) return(-1);