#include "SceneGraph.h" #include "KdTree.h" #include "SamplingPreprocessor.h" #include "X3dExporter.h" SamplingPreprocessor::SamplingPreprocessor() { // this should increase coherence of the samples mSamplesPerPass = 1; mTotalSamples = 1e8; mKdPvsDepth = 10; } void SamplingPreprocessor::SetupRay(Ray &ray, const Vector3 &point, const Vector3 &direction) { ray.intersections.clear(); ray.leaves.clear(); ray.meshes.clear(); // cout<mParent && node->mDepth > mKdPvsDepth) node = node->mParent; return node; } int SamplingPreprocessor::AddNodeSamples(Intersectable *object, const Ray &ray) { int contributingSamples = 0; for (int j=0; j < ray.leaves.size(); j++) { KdNode *node = GetNodeForPvs( ray.leaves[j] ); contributingSamples += object->mKdPvs.AddNodeSample(node); } return contributingSamples; } bool SamplingPreprocessor::ComputeVisibility() { // pickup an object ObjectContainer objects; mSceneGraph->CollectObjects(&objects); Vector3 point, normal, direction; Ray ray; long startTime = GetTime(); int i; int pass = 0; int totalSamples = 0; int pvsOut = Min((int)objects.size(), 10); vector rays[10]; while (totalSamples < mTotalSamples) { int passContributingSamples = 0; int passSampleContributions = 0; int passSamples = 0; for (i =0; i < objects.size(); i++) { for (int k=0; k < mSamplesPerPass; k++) { Intersectable *object = objects[i]; object->GetRandomSurfacePoint(point, normal); direction = UniformRandomVector(normal); // construct a ray SetupRay(ray, point, direction); mKdTree->CastRay(ray); if (i < pvsOut) rays[i].push_back(ray); int sampleContributions = 0; if (ray.leaves.size()) { sampleContributions += AddNodeSamples(object, ray); if (ray.intersections.size()) { sampleContributions += AddNodeSamples(ray.intersections[0].mObject, ray); // check whether we can add this to the rays for (int j = 0; j < pvsOut; j++) { if (objects[j] == ray.intersections[0].mObject) { rays[j].push_back(ray); } } } passSamples++; if (sampleContributions) { passContributingSamples++; passSampleContributions += sampleContributions; } } } } totalSamples += passSamples; pass++; int pvsSize = 0; for (i=0; i < objects.size(); i++) { Intersectable *object = objects[i]; pvsSize += object->mKdPvs.mEntries.size(); } cout<<"pass "<SetWireframe(); exporter->ExportKdTree(*mKdTree); for (i=0; i < pvsOut; i++) exporter->ExportRays(rays[i], 1000, RgbColor(1, 0, 0)); exporter->SetFilled(); delete exporter; } if (1) { for (int k=0; k < pvsOut; k++) { Intersectable *object = objects[k]; char s[64]; sprintf(s, "sample-pvs%04d.x3d", k); Exporter *exporter = Exporter::GetExporter(s); exporter->SetWireframe(); KdPvsMap::iterator i = object->mKdPvs.mEntries.begin(); Intersectable::NewMail(); // avoid adding the object to the list object->Mail(); ObjectContainer visibleObjects; for (; i != object->mKdPvs.mEntries.end(); i++) { KdNode *node = (*i).first; exporter->ExportBox(mKdTree->GetBox(node)); mKdTree->CollectObjects(node, visibleObjects); } exporter->ExportRays(rays[k], 1000, RgbColor(0, 1, 0)); exporter->SetFilled(); for (int j = 0; j < visibleObjects.size(); j++) exporter->ExportIntersectable(visibleObjects[j]); Material m; m.mDiffuseColor = RgbColor(1, 0, 0); exporter->SetForcedMaterial(m); exporter->ExportIntersectable(object); delete exporter; } } return true; }