--- ray/src/rt/pmapkdt.c 2017/08/14 21:12:10 1.2 +++ ray/src/rt/pmapkdt.c 2020/04/08 15:14:21 1.6 @@ -8,13 +8,15 @@ supported by the Swiss National Science Foundation (SNSF, #147053) ====================================================================== - $Id: pmapkdt.c,v 1.2 2017/08/14 21:12:10 rschregle Exp $ + $Id: pmapkdt.c,v 1.6 2020/04/08 15:14:21 rschregle Exp $ */ #include "pmapdata.h" /* Includes pmapkdt.h */ #include "source.h" +#include "otspecial.h" +#include "random.h" @@ -346,20 +348,24 @@ static void kdT_FindNearest (PhotonMap *pmap, const fl if (norm && DOT(norm, p -> norm) <= PMAP_NORM_TOL * 127 * frandom()) return; - if (isContribPmap(pmap) && pmap -> srcContrib) { - /* Lookup in contribution photon map */ - OBJREC *srcMod; - const int srcIdx = photonSrcIdx(pmap, p); - - if (srcIdx < 0 || srcIdx >= nsources) - error(INTERNAL, "invalid light source index in photon map"); - - srcMod = findmaterial(source [srcIdx].so); + if (isContribPmap(pmap)) { + /* Lookup in contribution photon map; filter according to emitting + * light source if contrib list set, else accept all */ + + if (pmap -> srcContrib) { + OBJREC *srcMod; + const int srcIdx = photonSrcIdx(pmap, p); + + if (srcIdx < 0 || srcIdx >= nsources) + error(INTERNAL, "invalid light source index in photon map"); + + srcMod = findmaterial(source [srcIdx].so); - /* Reject photon if contributions from light source which emitted it - * are not sought */ - if (!lu_find(pmap -> srcContrib, srcMod -> oname) -> data) - return; + /* Reject photon if contributions from light source which emitted it + * are not sought */ + if (!lu_find(pmap -> srcContrib, srcMod -> oname) -> data) + return; + } /* Reject non-caustic photon if lookup for caustic contribs */ if (pmap -> lookupCaustic & !p -> caustic) @@ -413,15 +419,19 @@ static void kdT_FindNearest (PhotonMap *pmap, const fl -void kdT_FindPhotons (struct PhotonMap *pmap, const FVECT pos, - const FVECT norm) +int kdT_FindPhotons (struct PhotonMap *pmap, const FVECT pos, + const FVECT norm) { float p [3], n [3]; /* Photon pos & normal stored at lower precision */ VCOPY(p, pos); - VCOPY(n, norm); - kdT_FindNearest(pmap, p, n, 1); + if (norm) + VCOPY(n, norm); + kdT_FindNearest(pmap, p, norm ? n : NULL, 1); + + /* Return success or failure (empty queue => none found) */ + return pmap -> squeue.tail ? 0 : -1; } @@ -460,7 +470,7 @@ static void kdT_Find1Nearest (PhotonMap *pmap, const f d2 = DOT(dv, dv); if (d2 < pmap -> maxDist2 && - DOT(norm, p -> norm) > PMAP_NORM_TOL * 127 * frandom()) { + (!norm || DOT(norm, p -> norm) > PMAP_NORM_TOL * 127 * frandom())) { /* Closest photon so far with similar normal. We allow for tolerance * to account for perturbation in the latter; note the photon normal * is coded in the range [-127,127], hence we factor this in */ @@ -471,17 +481,25 @@ static void kdT_Find1Nearest (PhotonMap *pmap, const f -void kdT_Find1Photon (struct PhotonMap *pmap, const FVECT pos, - const FVECT norm, Photon *photon) +int kdT_Find1Photon (struct PhotonMap *pmap, const FVECT pos, + const FVECT norm, Photon *photon) { float p [3], n [3]; - Photon *pnn; + Photon *pnn = NULL; /* Photon pos & normal stored at lower precision */ VCOPY(p, pos); - VCOPY(n, norm); - kdT_Find1Nearest(pmap, p, n, &pnn, 1); - memcpy(photon, pnn, sizeof(Photon)); + if (norm) + VCOPY(n, norm); + kdT_Find1Nearest(pmap, p, norm ? n : NULL, &pnn, 1); + if (!pnn) + /* No photon found => failed */ + return -1; + else { + /* Copy found photon => successs */ + memcpy(photon, pnn, sizeof(Photon)); + return 0; + } }