void HitPoints::Init() { // Not using UpdateBBox() because hp->accumPhotonRadius2 is not yet set BBox hpBBox = BBox(); for (u_int i = 0; i < (*hitPoints).size(); ++i) { HitPoint *hp = &(*hitPoints)[i]; if (hp->IsSurface()) hpBBox = Union(hpBBox, hp->GetPosition()); } // Calculate initial radius Vector ssize = hpBBox.pMax - hpBBox.pMin; initialPhotonRadius = renderer->sppmi->photonStartRadiusScale * ((ssize.x + ssize.y + ssize.z) / 3.f) / sqrtf(nSamplePerPass) * 2.f; const float photonRadius2 = initialPhotonRadius * initialPhotonRadius; // Expand the bounding box by used radius hpBBox.Expand(initialPhotonRadius); // Update hit points information hitPointBBox = hpBBox; maxHitPointRadius2 = photonRadius2; LOG(LUX_DEBUG, LUX_NOERROR) << "Hit points bounding box: " << hitPointBBox; LOG(LUX_DEBUG, LUX_NOERROR) << "Hit points max. radius: " << sqrtf(maxHitPointRadius2); // Initialize hit points field for (u_int i = 0; i < (*hitPoints).size(); ++i) { HitPoint *hp = &(*hitPoints)[i]; hp->accumPhotonRadius2 = photonRadius2; } // Allocate hit points lookup accelerator switch (renderer->sppmi->lookupAccelType) { case HASH_GRID: lookUpAccel = new HashGrid(this); break; case KD_TREE: lookUpAccel = new KdTree(this); break; case HYBRID_HASH_GRID: lookUpAccel = new HybridHashGrid(this); break; case PARALLEL_HASH_GRID: lookUpAccel = new ParallelHashGrid(this, renderer->sppmi->parallelHashGridSpare); break; default: assert (false); } }
void HitPoints::UpdatePointsInformation() { // Calculate hit points bounding box BBox bbox; float maxr2, minr2, meanr2; u_int minp, maxp, meanp; u_int surfaceHits, constantHits, zeroHits; assert((*hitPoints).size() > 0); HitPoint *hp = &(*hitPoints)[0]; if (hp->IsSurface()) { surfaceHits = 1; constantHits = 0; u_int pc = hp->GetPhotonCount(); zeroHits = pc == 0 ? 1 : 0; bbox = hp->GetPosition(); maxr2 = minr2 = meanr2 = hp->accumPhotonRadius2; minp = maxp = meanp = pc; } else { constantHits = 1; surfaceHits = 0; zeroHits = 0; maxr2 = 0.f; minr2 = INFINITY; meanr2 = 0.f; minp = maxp = meanp = 0; } for (u_int i = 1; i < (*hitPoints).size(); ++i) { hp = &(*hitPoints)[i]; if (hp->IsSurface()) { u_int pc = hp->GetPhotonCount(); if(pc == 0) ++zeroHits; bbox = Union(bbox, hp->GetPosition()); maxr2 = max<float>(maxr2, hp->accumPhotonRadius2); minr2 = min<float>(minr2, hp->accumPhotonRadius2); meanr2 += hp->accumPhotonRadius2; maxp = max<float>(maxp, pc); minp = min<float>(minp, pc); meanp += pc; ++surfaceHits; } else ++constantHits; } LOG(LUX_DEBUG, LUX_NOERROR) << "Hit points stats:"; if (surfaceHits > 0) { LOG(LUX_DEBUG, LUX_NOERROR) << "\tbounding box: " << bbox; LOG(LUX_DEBUG, LUX_NOERROR) << "\tmin/max radius: " << sqrtf(minr2) << "/" << sqrtf(maxr2); LOG(LUX_DEBUG, LUX_NOERROR) << "\tmin/max photonCount: " << minp << "/" << maxp; LOG(LUX_DEBUG, LUX_NOERROR) << "\tmean radius/photonCount: " << sqrtf(meanr2 / surfaceHits) << "/" << meanp / surfaceHits; } LOG(LUX_DEBUG, LUX_NOERROR) << "\tconstant/zero hits: " << constantHits << "/" << zeroHits; hitPointBBox = bbox; maxHitPointRadius2 = maxr2; }