#include "SceneGraph.h" #include "KdTree.h" #include "VssPreprocessor.h" #include "X3dExporter.h" #include "Environment.h" #include "MutualVisibility.h" #include "Polygon3.h" #include "ViewCell.h" #include "VssRay.h" #include "VssTree.h" VssPreprocessor::VssPreprocessor(): mPass(0), mVssRays() { // this should increase coherence of the samples environment->GetIntValue("VssPreprocessor.samplesPerPass", mSamplesPerPass); environment->GetIntValue("VssPreprocessor.totalSamples", mTotalSamples); mStats.open("stats.log"); } VssPreprocessor::~VssPreprocessor() { CLEAR_CONTAINER(mVssRays); } void VssPreprocessor::SetupRay(Ray &ray, const Vector3 &point, const Vector3 &direction ) { ray.intersections.clear(); // do not store anything else then intersections at the ray ray.Init(point, direction, Ray::LOCAL_RAY); } int VssPreprocessor::CastRay( Vector3 &viewPoint, Vector3 &direction, VssRayContainer &vssRays ) { int hits = 0; static Ray ray; AxisAlignedBox3 box = mKdTree->GetBox(); SetupRay(ray, viewPoint, direction); // cast ray to KD tree to find intersection with other objects Intersectable *objectA, *objectB; Vector3 pointA, pointB; float bsize = Magnitude(box.Size()); if (mKdTree->CastRay(ray)) { objectA = ray.intersections[0].mObject; pointA = ray.Extrap(ray.intersections[0].mT); } else { objectA = NULL; // compute intersection with the scene bounding box float tmin, tmax; box.ComputeMinMaxT(ray, &tmin, &tmax); if (tmax > bsize) { // cerr<<"Warning: tmax > box size tmax="<CastRay(ray)) { objectB = ray.intersections[0].mObject; pointB = ray.Extrap(ray.intersections[0].mT); } else { objectB = NULL; float tmin, tmax; box.ComputeMinMaxT(ray, &tmin, &tmax); if (tmax > bsize) { // cerr<<"Warning: tmax > box size tmax="<GetBox(); // shrink the box in the y direction return box.GetRandomPoint(); } Vector3 VssPreprocessor::GetDirection(const Vector3 &viewpoint) { int i = RandomValue(0, mObjects.size()-1); Intersectable *object = mObjects[i]; Vector3 point, normal; object->GetRandomSurfacePoint(point, normal); return point - viewpoint; } int VssPreprocessor::RandomizedImportanceSampling(VssTree *vssTree, const int desiredSamples) { float minRayContribution; float maxRayContribution; float avgRayContribution; vssTree->GetRayContributionStatistics(minRayContribution, maxRayContribution, avgRayContribution); cout<< "#MIN_RAY_CONTRIB\n"<stat.Leaves()); SimpleRayContainer rays; int num = vssTree->GenerateRays(p, rays); cout<<"Generated "<AddRays(vssRays); return num; } bool VssPreprocessor::ComputeVisibility() { mSceneGraph->CollectObjects(&mObjects); long startTime = GetTime(); int totalSamples = 0; AxisAlignedBox3 *viewSpaceBox = NULL; AxisAlignedBox3 box = mKdTree->GetBox(); if (1) box.Enlarge(box.Size()*-Vector3(0.45, 0.45, 0.45)); else { // sample city like heights box.SetMin(1, box.Min(1) + box.Size(1)*0.1); box.SetMax(1, box.Min(1) + box.Size(1)*0.2); } bool useViewSpaceBox = false; if (useViewSpaceBox) viewSpaceBox = &box; VssTree *vssTree = NULL; while (totalSamples < mTotalSamples) { int passContributingSamples = 0; int passSampleContributions = 0; int passSamples = 0; int index = 0; int sampleContributions; for (int k=0; k < mSamplesPerPass; k++) { Vector3 viewpoint = GetViewpoint(viewSpaceBox); Vector3 direction = GetDirection(viewpoint); sampleContributions = CastRay(viewpoint, direction, mVssRays); //-- CORR matt: put block inside loop if (sampleContributions) { passContributingSamples ++; passSampleContributions += sampleContributions; } passSamples++; totalSamples++; } mPass++; int pvsSize = 0; float avgRayContrib = (passContributingSamples > 0) ? passSampleContributions/(float)passContributingSamples : 0; cout << "#Pass " << mPass << " : t = " << TimeDiff(startTime, GetTime())*1e-3 << "s" << endl; cout << "#TotalSamples=" << totalSamples/1000 << "k #SampleContributions=" << passSampleContributions << " (" << 100*passContributingSamples/(float)passSamples<<"%)" << " avgPVS=" << pvsSize/(float)mObjects.size() << endl << "avg ray contrib=" << avgRayContrib << endl; mStats << "#Pass\n" <SetWireframe(); exporter->ExportKdTree(*mKdTree); if (viewSpaceBox) { exporter->SetForcedMaterial(RgbColor(1,0,0)); exporter->ExportBox(*viewSpaceBox); exporter->ResetForcedMaterial(); } VssRayContainer rays; for (int i=0; i < mVssRays.size(); i++) if (RandomValue(0,1) < prob) rays.push_back(mVssRays[i]); exporter->ExportRays(rays, RgbColor(1, 0, 0)); delete exporter; } cout<<"done."<Construct(mVssRays, viewSpaceBox); cout<<"VssTree root PVS size = "<GetRootPvsSize()<AddRays(vssRays); } else { num = RandomizedImportanceSampling(vssTree, num); } samples+=num; float pvs = vssTree->GetAvgPvsSize(); cout<