#include "SamplingStrategy.h" #include "Ray.h" #include "Intersectable.h" #include "Preprocessor.h" #include "ViewCellsManager.h" #include "AxisAlignedBox3.h" #include "RssTree.h" #include "Vector2.h" #include "RndGauss.h" #include "Mutation.h" #ifdef GTP_INTERNAL #include "ArchModeler2MLRT.hxx" #endif namespace GtpVisibilityPreprocessor { #define MUTATION_USE_CDF 0 #define USE_SILHOUETTE_MUTATIONS 0 #define EVALUATE_MUTATION_STATS 1 void MutationBasedDistribution::Update(VssRayContainer &vssRays) { // for (int i=0; i < mRays.size(); i++) // cout<mPvsContribution) { // reset the counter of unsuccsseful mutation for a generating ray (if it exists) if (vssRays[i]->mDistribution == MUTATION_BASED_DISTRIBUTION && vssRays[i]->mGeneratorId != -1 ) { mRays[vssRays[i]->mGeneratorId].mUnsuccessfulMutations = 0; #if EVALUATE_MUTATION_STATS mutationRays++; Intersectable *newObject = mPreprocessor.mViewCellsManager->GetIntersectable( *vssRays[i], true); Intersectable *oldObject = mPreprocessor.mViewCellsManager->GetIntersectable( *mRays[vssRays[i]->mGeneratorId].mRay, true); if (oldObject == newObject) dummyCMutations++; #endif } contributingRays++; if (mRays.size() < mMaxRays) { VssRay *newRay = new VssRay(*vssRays[i]); // add this ray newRay->Ref(); mRays.push_back(RayEntry(newRay)); } else { // unref the old ray *mRays[mBufferStart].mRay = *vssRays[i]; mRays[mBufferStart].mMutations = 0; // mRays[mBufferStart] = RayEntry(newRay); mBufferStart++; if (mBufferStart >= mMaxRays) mBufferStart = 0; } } else { #if EVALUATE_MUTATION_STATS if (vssRays[i]->mDistribution == MUTATION_BASED_DISTRIBUTION && vssRays[i]->mGeneratorId != -1 ) { mutationRays++; Intersectable *newObject = mPreprocessor.mViewCellsManager->GetIntersectable( *vssRays[i], true); Intersectable *oldObject = mPreprocessor.mViewCellsManager->GetIntersectable( *mRays[vssRays[i]->mGeneratorId].mRay, true); if (oldObject == newObject) dummyNcMutations++; } #endif } } if (mutationRays) { cout<<"Mutated rays:"< Limits::Small) // nv = Normalize(v); // else // nv = v; // v = nv*size + v*size; return v*(4.0f*radius); #endif #if 0 return (U*(vr2.xx - 0.5f) + V*(vr2.yy - 0.5f))*(4.0f*radius); #endif Vector2 gaussvec2; #if 1 float sigma = radius; GaussianOn2D(vr2, sigma, // input gaussvec2); // output Vector3 shift = gaussvec2.xx * U + gaussvec2.yy * V; // cout<GetViewPoint(origin, Vector3(rr[0], rr[1], rr[2])); direction = UniformRandomVector(rr[3], rr[4]); const float pdf = 1.0f; sray = SimpleRay(origin, direction, MUTATION_BASED_DISTRIBUTION, pdf); sray.mGeneratorId = -1; return true; } int index; #if !MUTATION_USE_CDF // get tail of the buffer index = (mLastIndex+1)%mRays.size(); if (mRays[index].GetSamplingFactor() > mRays[mLastIndex].GetSamplingFactor()) { // search back for index where this is valid index = (mLastIndex - 1 + mRays.size())%mRays.size(); for (int i=0; i < mRays.size(); i++) { // if (mRays[index].mMutations > mRays[mLastIndex].mMutations) // break; if (mRays[index].GetSamplingFactor() > mRays[mLastIndex].GetSamplingFactor() ) break; index = (index - 1 + mRays.size())%mRays.size(); } // go one step back index = (index+1)%mRays.size(); } #else static HaltonSequence iHalton; iHalton.GetNext(1, rr); //rr[0] = RandomValue(0,1); // use binary search to find index with this cdf int l=0, r=mRays.size()-1; while(l= mRays[r].mCdf) // index = r; // else // index = l; #endif // cout<GetDir(); float objectRadius = 0.5f*Magnitude(box.Diagonal()); // cout<mOrigin; Vector3 termination = ray->mTermination; //box.Center(); //ray->mTermination; //box.Center(); float radiusExtension = 0.05f; // + mRays[index].mMutations/50.0f; origin += ComputeOriginMutation(*ray, U, V, Vector2(rr[0], rr[1]), objectRadius*radiusExtension); termination += ComputeTerminationMutation(*ray, U, V, Vector2(rr[2], rr[3]), objectRadius*radiusExtension); Vector3 direction = termination - origin; if (Magnitude(direction) < Limits::Small) return false; // shift the origin a little bit origin += direction*0.5f; direction.Normalize(); // $$ jb the pdf is yet not correct for all sampling methods! const float pdf = 1.0f; sray = SimpleRay(origin, direction, MUTATION_BASED_DISTRIBUTION, pdf); sray.mGeneratorId = index; } bool MutationBasedDistribution::GenerateMutation(const int index, SimpleRay &sray) { VssRay *ray = mRays[index].mRay; Intersectable *object = mPreprocessor.mViewCellsManager->GetIntersectable( *ray, true); AxisAlignedBox3 box = object->GetBox(); if (GenerateMutationCandidate(index, sray, object, box)) { mRays[index].mMutations++; return true; } return false; } bool MutationBasedDistribution::GenerateSilhouetteMutation(const int index, SimpleRay &sray) { #ifndef GTP_INTERNAL return GenerateMutation(index, sray); #else const int packetSize = 4; const int maxTries = 8; static int hit_triangles[16]; static float dist[16]; SimpleRay mutationCandidates[packetSize]; int candidates = 0; VssRay *ray = mRays[index].mRay; Intersectable *object = mPreprocessor.mViewCellsManager->GetIntersectable( *ray, true); AxisAlignedBox3 box = object->GetBox(); int id = 0; int silhouetteRays = 0; int tries = 0; while (silhouetteRays == 0 && tries < maxTries) { for (candidates = 0; candidates < packetSize && tries < maxTries; tries++) if (GenerateMutationCandidate(index, mutationCandidates[candidates], object, box)) candidates++; if (candidates < packetSize) break; // cout< // GetViewSpaceBox().Diagonal())*1e-3; } }