#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" #include "ViewCellsManager.h" #include "RenderSimulator.h" bool useViewSpaceBox = true;//true; bool use2dSampling = false; bool useViewspacePlane = true;//true; VssPreprocessor::VssPreprocessor(): mPass(0), mVssRays() { // this should increase coherence of the samples environment->GetIntValue("VssPreprocessor.samplesPerPass", mSamplesPerPass); environment->GetIntValue("VssPreprocessor.initialSamples", mInitialSamples); environment->GetIntValue("VssPreprocessor.vssSamples", mVssSamples); environment->GetIntValue("VssPreprocessor.vssSamplesPerPass", mVssSamplesPerPass); environment->GetBoolValue("VssPreprocessor.useImportanceSampling", mUseImportanceSampling); environment->GetIntValue("BspTree.Construction.samples", mBspConstructionSamples); 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(); AxisAlignedBox3 sbox = box; sbox.Enlarge(Vector3(-Limits::Small)); if (!sbox.IsInside(viewPoint)) return 0; 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, AxisAlignedBox3 *viewSpaceBox ) { Vector3 point; if (!use2dSampling) { Vector3 normal; int i = RandomValue(0, mObjects.size()-1); Intersectable *object = mObjects[i]; object->GetRandomSurfacePoint(point, normal); } else { AxisAlignedBox3 box; if (viewSpaceBox) box =*viewSpaceBox; else box = mKdTree->GetBox(); point = box.GetRandomPoint(); point.y = viewpoint.y; } return point - viewpoint; } int VssPreprocessor::GenerateImportanceRays(VssTree *vssTree, const int desiredSamples, SimpleRayContainer &rays ) { int num; if (0) { float minRayContribution; float maxRayContribution; float avgRayContribution; vssTree->GetRayContributionStatistics(minRayContribution, maxRayContribution, avgRayContribution); cout<< "#MIN_RAY_CONTRIB\n"<stat.Leaves()); num = vssTree->GenerateRays(p, rays); } else { int leaves = vssTree->stat.Leaves()/2; num = vssTree->GenerateRays(desiredSamples, leaves, rays); } cout<<"Generated "<SetWireframe(); // exporter->ExportKdTree(*mKdTree); exporter->SetFilled(); exporter->ExportScene(mSceneGraph->mRoot); exporter->SetWireframe(); if (mViewSpaceBox) { exporter->SetForcedMaterial(RgbColor(1,0,1)); exporter->ExportBox(*mViewSpaceBox); exporter->ResetForcedMaterial(); } VssRayContainer rays; for (int i=0; i < vssRays.size(); i++) if (RandomValue(0,1) < prob) rays.push_back(vssRays[i]); exporter->ExportRays(rays, RgbColor(1, 0, 0)); delete exporter; cout<<"done."<SetFilled(); exporter->ExportScene(mSceneGraph->mRoot); // exporter->SetWireframe(); bool result = exporter->ExportVssTree2( *tree, dir ); delete exporter; return result; } bool VssPreprocessor::ExportVssTreeLeaf(char *filename, VssTree *tree, VssTreeLeaf *leaf) { Exporter *exporter = NULL; exporter = Exporter::GetExporter(filename); exporter->SetWireframe(); exporter->ExportKdTree(*mKdTree); if (mViewSpaceBox) { exporter->SetForcedMaterial(RgbColor(1,0,0)); exporter->ExportBox(*mViewSpaceBox); exporter->ResetForcedMaterial(); } exporter->SetForcedMaterial(RgbColor(0,0,1)); exporter->ExportBox(tree->GetBBox(leaf)); exporter->ResetForcedMaterial(); VssRayContainer rays[4]; for (int i=0; i < leaf->rays.size(); i++) { int k = leaf->rays[i].GetRayClass(); rays[k].push_back(leaf->rays[i].mRay); } // SOURCE RAY exporter->ExportRays(rays[0], RgbColor(1, 0, 0)); // TERMINATION RAY exporter->ExportRays(rays[1], RgbColor(1, 1, 1)); // PASSING_RAY exporter->ExportRays(rays[2], RgbColor(1, 1, 0)); // CONTAINED_RAY exporter->ExportRays(rays[3], RgbColor(0, 0, 1)); delete exporter; return true; } void VssPreprocessor::ExportVssTreeLeaves(VssTree *tree, const int number) { vector leaves; tree->CollectLeaves(leaves); int num = 0; int i; float p = number / (float)leaves.size(); for (i=0; i < leaves.size(); i++) { if (RandomValue(0,1) < p) { char filename[64]; sprintf(filename, "vss-leaf-%04d.x3d", num); ExportVssTreeLeaf(filename, tree, leaves[i]); num++; } if (num >= number) break; } } float VssPreprocessor::GetAvgPvsSize(VssTree *tree, const vector &viewcells ) { vector::const_iterator it, it_end = viewcells.end(); int sum = 0; for (it = viewcells.begin(); it != it_end; ++ it) sum += tree->GetPvsSize(*it); return sum/(float)viewcells.size(); } bool VssPreprocessor::ComputeVisibility() { mSceneGraph->CollectObjects(&mObjects); long startTime = GetTime(); int totalSamples = 0; AxisAlignedBox3 *box = new AxisAlignedBox3(mKdTree->GetBox()); if (!useViewspacePlane) { float size = 0.05f; float s = 0.5f - size; float olds = Magnitude(box->Size()); box->Enlarge(box->Size()*Vector3(-s)); Vector3 translation = Vector3(-olds*0.1f, 0, 0); box->SetMin(box->Min() + translation); box->SetMax(box->Max() + translation); } else { // sample city like heights box->SetMin(1, box->Min(1) + box->Size(1)*0.2); box->SetMax(1, box->Min(1) + box->Size(1)*0.3); } if (use2dSampling) box->SetMax(1, box->Min(1)); if (useViewSpaceBox) mViewSpaceBox = box; else mViewSpaceBox = NULL; VssTree *vssTree = NULL; while (totalSamples < mInitialSamples) { int passContributingSamples = 0; int passSampleContributions = 0; int passSamples = 0; int index = 0; int sampleContributions; int s = Min(mSamplesPerPass, mInitialSamples); for (int k=0; k < s; k++) { Vector3 viewpoint = GetViewpoint(mViewSpaceBox); Vector3 direction = GetDirection(viewpoint, mViewSpaceBox); 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" <CollectObjects(&objects); // construct view cells mViewCellsManager->Construct(objects, mVssRays, mViewSpaceBox); vssTree = new VssTree; // viewcells = Construct(mVssRays); vssTree->Construct(mVssRays, mViewSpaceBox); cout<<"VssTree root PVS size = "<GetRootPvsSize()<UpdatePVS(newVssRays); // get viewcells as kd tree boxes vector kdViewcells; if (0) { vector leaves; mKdTree->CollectLeaves(leaves); vector::const_iterator it; int targetLeaves = 50; float prob = targetLeaves/(float)leaves.size(); for (it = leaves.begin(); it != leaves.end(); ++it) if (RandomValue(0.0f,1.0f) < prob) kdViewcells.push_back(mKdTree->GetBox(*it)); float avgPvs = GetAvgPvsSize(vssTree, kdViewcells); cout<<"Initial average PVS size = "<AddRays(vssRays); if (0) { int subdivided = vssTree->UpdateSubdivision(); cout<<"subdivided leafs = "<ComputeSampleContributions(passRays, sampleContributions, contributingSamples); //-- save rays for post processing if (((int)storedRays.size() < mViewCellsManager->GetPostProcessSamples()) || ((int)storedRays.size() < mViewCellsManager->GetVisualizationSamples())) { RayContainer::const_iterator it, it_end = passRays.end(); for (it = passRays.begin(); it != it_end; ++ it) storedRays.push_back(new Ray(*(*it))); } else { CLEAR_CONTAINER(passRays); } */ samples+=num; float pvs = vssTree->GetAvgPvsSize(); cout<<"*****************************\n"; cout<= mVssSamples) break; pass++; } cout << "here" << endl; //-- post process view cells mViewCellsManager->PostProcess(objects, storedRays); //-- several visualizations and statistics mViewCellsManager->PrintStatistics(Debug); //-- render simulation after merge cout << "\nevaluating bsp view cells render time after merge ... "; const SimulationStatistics ss = mViewCellsManager->SimulateRendering(); cout << " finished" << endl; cout << ss << endl; Debug << ss << endl; mViewCellsManager->Visualize(objects, storedRays); CLEAR_CONTAINER(storedRays); delete vssTree; return true; }