--- ray/src/rt/pmapmat.c 2015/09/01 16:27:52 2.9 +++ ray/src/rt/pmapmat.c 2016/05/17 17:39:47 2.13 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: pmapmat.c,v 2.9 2015/09/01 16:27:52 greg Exp $"; +static const char RCSid[] = "$Id: pmapmat.c,v 2.13 2016/05/17 17:39:47 rschregle Exp $"; #endif /* ================================================================== @@ -106,23 +106,25 @@ void photonRay (const RAY *rayIn, RAY *rayOut, { rayorigin(rayOut, rayOutType, rayIn, NULL); - /* Transfer flux */ - copycolor(rayOut -> rcol, rayIn -> rcol); - - /* Copy caustic flag & direction for transferred rays */ - if (rayOutType == PMAP_XFER) { - /* rayOut -> rtype |= rayIn -> rtype & SPECULAR; */ - rayOut -> rtype |= rayIn -> rtype; - VCOPY(rayOut -> rdir, rayIn -> rdir); - } - else if (fluxAtten) { - /* Attenuate and normalise flux for scattered rays */ - multcolor(rayOut -> rcol, fluxAtten); - colorNorm(rayOut -> rcol); - } + if (rayIn) { + /* Transfer flux */ + copycolor(rayOut -> rcol, rayIn -> rcol); + + /* Copy caustic flag & direction for transferred rays */ + if (rayOutType == PMAP_XFER) { + /* rayOut -> rtype |= rayIn -> rtype & SPECULAR; */ + rayOut -> rtype |= rayIn -> rtype; + VCOPY(rayOut -> rdir, rayIn -> rdir); + } + else if (fluxAtten) { + /* Attenuate and normalise flux for scattered rays */ + multcolor(rayOut -> rcol, fluxAtten); + colorNorm(rayOut -> rcol); + } - /* Propagate index of emitting light source */ - rayOut -> rsrc = rayIn -> rsrc; + /* Propagate index of emitting light source */ + rayOut -> rsrc = rayIn -> rsrc; + } } @@ -132,17 +134,17 @@ static void addPhotons (const RAY *r) { if (!r -> rlvl) /* Add direct photon map at primary hitpoint */ - addPhoton(directPmap, r); + newPhoton(directPmap, r); else { /* Add global or precomputed photon map at indirect hitpoint */ - addPhoton(preCompPmap ? preCompPmap : globalPmap, r); + newPhoton(preCompPmap ? preCompPmap : globalPmap, r); /* Store caustic photon if specular flag set */ if (PMAP_CAUSTICRAY(r)) - addPhoton(causticPmap, r); + newPhoton(causticPmap, r); /* Store in contribution photon map */ - addPhoton(contribPmap, r); + newPhoton(contribPmap, r); } } @@ -978,8 +980,11 @@ static int aliasPhotonScatter (OBJREC *mat, RAY *rayIn /* Straight replacement? */ if (!mat -> oargs.nsargs) { - mat = objptr(mat -> omod); - photonScatter [mat -> otype] (mat, rayIn); + /* Skip void modifier! */ + if (mat -> omod != OVOID) { + mat = objptr(mat -> omod); + photonScatter [mat -> otype] (mat, rayIn); + } return 0; } @@ -1250,8 +1255,19 @@ static int mx_dataPhotonScatter (OBJREC *mat, RAY *ray if (errno) objerror(mat, WARNING, "compute error"); else { - mat = objptr(mod [pmapRandom(rouletteState) < coef ? 0 : 1]); - photonScatter [mat -> otype] (mat, rayIn); + OBJECT mxMod = mod [pmapRandom(rouletteState) < coef ? 0 : 1]; + + if (mxMod != OVOID) { + mat = objptr(mxMod); + photonScatter [mat -> otype] (mat, rayIn); + } + else { + /* Transfer ray if no modifier */ + RAY rayOut; + + photonRay(rayIn, &rayOut, PMAP_XFER, NULL); + tracePhoton(&rayOut); + } } return 0; @@ -1303,8 +1319,19 @@ static int mx_pdataPhotonScatter (OBJREC *mat, RAY *ra if (errno) objerror(mat, WARNING, "compute error"); else { - mat = objptr(mod [pmapRandom(rouletteState) < coef ? 0 : 1]); - photonScatter [mat -> otype] (mat, rayIn); + OBJECT mxMod = mod [pmapRandom(rouletteState) < coef ? 0 : 1]; + + if (mxMod != OVOID) { + mat = objptr(mxMod); + photonScatter [mat -> otype] (mat, rayIn); + } + else { + /* Transfer ray if no modifier */ + RAY rayOut; + + photonRay(rayIn, &rayOut, PMAP_XFER, NULL); + tracePhoton(&rayOut); + } } return 0; @@ -1343,8 +1370,19 @@ static int mx_funcPhotonScatter (OBJREC *mat, RAY *ray if (errno) objerror(mat, WARNING, "compute error"); else { - mat = objptr(mod [pmapRandom(rouletteState) < coef ? 0 : 1]); - photonScatter [mat -> otype] (mat, rayIn); + OBJECT mxMod = mod [pmapRandom(rouletteState) < coef ? 0 : 1]; + + if (mxMod != OVOID) { + mat = objptr(mxMod); + photonScatter [mat -> otype] (mat, rayIn); + } + else { + /* Transfer ray if no modifier */ + RAY rayOut; + + photonRay(rayIn, &rayOut, PMAP_XFER, NULL); + tracePhoton(&rayOut); + } } return 0;