#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" 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); } VssRay * VssPreprocessor::CastRay( Vector3 &viewPoint, Vector3 &direction ) { 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; 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); pointA = ray.Extrap(tmax); } SetupRay(ray, viewPoint, -direction); if (mKdTree->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); pointB = ray.Extrap(tmax); } VssRay *vssRay = NULL; if (objectA || objectB) { vssRay = new VssRay(pointA, pointB, objectA, objectB); } return vssRay; } Vector3 VssPreprocessor::GetViewpoint() { AxisAlignedBox3 box = mKdTree->GetBox(); // shrink the box in the y direction Vector3 diff(0, -box.Size().y*0.4f, 0); box.Enlarge(diff); return box.GetRandomPoint(); } Vector3 VssPreprocessor::GetDirection(const Vector3 &viewpoint) { int i = RandomValue(0, mObjects.size()); Intersectable *object = mObjects[i]; Vector3 point, normal; object->GetRandomSurfacePoint(point, normal); return point - viewpoint; } bool VssPreprocessor::ComputeVisibility() { mSceneGraph->CollectObjects(&mObjects); long startTime = GetTime(); int i; int totalSamples = 0; 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(); Vector3 direction = GetDirection(viewpoint); VssRay *vssRay = CastRay(viewpoint, direction); if (vssRay) { sampleContributions = vssRay->HitCount(); mVssRays.push_back(vssRay); } //-- 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" <