#include "SamplingStrategy.h" #include "Intersectable.h" #include "DifferenceSampling.h" #include "ViewCell.h" #include "ViewCellsManager.h" #include "Preprocessor.h" #ifdef GTP_INTERNAL #include "ArchModeler2MLRT.hxx" #endif namespace GtpVisibilityPreprocessor { /** Collects the pvs of the objects which are in the first but not in the second pvs. */ static void GetPvsDifference(const ObjectPvs &largerPvs, const ObjectPvs &smallerPvs, ObjectContainer &pvsDifference) { Intersectable::NewMail(); Intersectable *obj; ObjectPvsIterator bit = smallerPvs.GetIterator(); // mail smaller pvs while (bit.HasMoreEntries()) { obj = bit.Next(); obj->Mail(); } ObjectPvsIterator ait = largerPvs.GetIterator(); // write differece pvs while (ait.HasMoreEntries()) { obj = ait.Next(); pvsDifference.push_back(obj); //if (!obj->Mailed()) // c.AddSampleDirty(obj, 0); } } DifferenceSampling::DifferenceSampling(Preprocessor &preprocessor): SamplingStrategy(preprocessor), mCurrentViewCell(0), mNumSamples(0) {} void DifferenceSampling::ComputeDifferenceSet(ViewCell *vc, ObjectContainer &differenceSet) { const ObjectPvs &pvs = vc->GetPvs(); const float filterSize = 100; ObjectPvs filteredPvs; PvsFilterStatistics pvsStats = mPreprocessor. mViewCellsManager->ApplyFilter2(vc, false, filterSize, filteredPvs); //mDifferencePvs.Clear(false); //mDifferencePvs.Reserve(filteredPvs.GetSize()); mPvsDifference.clear(); mPvsDifference.reserve(filteredPvs.GetSize()); GetPvsDifference(filteredPvs, pvs, mPvsDifference); } bool DifferenceSampling::GenerateSample(SimpleRay &ray) { if (mNumSamples -- <= 0) { ViewCellContainer &viewCells = mPreprocessor.mViewCellsManager->GetViewCells(); const int vcIdx = (int)RandomValue(0, (float)viewCells.size() - 0.5f); mCurrentViewCell = viewCells[vcIdx]; ComputeDifferenceSet(mCurrentViewCell, mPvsDifference); // n samples per object const int n = 50; mNumSamples = mPvsDifference.size() * n; } Vector3 origin, direction; Vector3 point; Vector3 normal, vcnormal; // get a new object from the difference set const int objIdx = (int)RandomValue(0, (float)mPvsDifference.size() - 0.5f); Intersectable *object = mPvsDifference[objIdx]; // cast a ray from the view cells border towards the object object->GetRandomSurfacePoint(point, normal); mCurrentViewCell->GetRandomEdgePoint(origin, vcnormal); direction = point - origin; // $$ jb the pdf is yet not correct for all sampling methods! const float c = Magnitude(direction); if ((c <= Limits::Small) /*|| (DotProd(direction, normal) < 0)*/) { return false; } // $$ jb the pdf is yet not correct for all sampling methods! const float pdf = 1.0f; //cout << "p: " << point << " "; direction *= 1.0f / c; ray = SimpleRay(origin, direction, DIFFERENCE_SAMPLING_BASED_DISTRIBUTION, pdf); //cout << "ray: " << ray.mOrigin << " " << ray.mDirection << endl; return true; } }