Changeset 1021 for GTP/trunk/Lib/Vis
- Timestamp:
- 06/19/06 16:14:40 (19 years ago)
- Location:
- GTP/trunk/Lib/Vis/Preprocessing/src
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp
r1020 r1021 706 706 case SPATIAL_BOX_BASED_DISTRIBUTION: 707 707 return new SpatialBoxBasedDistribution(*this); 708 case OBJECTS_INTERIOR_DISTRIBUTION:709 return new ObjectsInteriorDistribution(*this);708 //case OBJECTS_INTERIOR_DISTRIBUTION: 709 // return new ObjectsInteriorDistribution(*this); 710 710 default: // no valid strategy 711 711 return NULL; -
GTP/trunk/Lib/Vis/Preprocessing/src/SamplingStrategy.cpp
r1020 r1021 142 142 } 143 143 144 144 /* 145 145 bool ObjectsInteriorDistribution::GenerateSample(SimpleRay &ray) const 146 146 { … … 170 170 171 171 return true; 172 } 172 }*/ 173 173 174 174 } -
GTP/trunk/Lib/Vis/Preprocessing/src/SamplingStrategy.h
r1020 r1021 86 86 for sampling the inside of a colon. 87 87 */ 88 class ObjectsInteriorDistribution: public SamplingStrategy88 /*class ObjectsInteriorDistribution: public SamplingStrategy 89 89 { 90 90 public: … … 94 94 virtual bool GenerateSample(SimpleRay &ray) const; 95 95 }; 96 96 */ 97 97 }; 98 98 -
GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp
r1020 r1021 272 272 } 273 273 Debug << "empty view cells found: " << (int)mEmptyViewCells.size() << endl; 274 } 275 276 277 bool ViewCellsManager::EqualToSpatialNode(ViewCell *viewCell) const 278 { 279 return false; 274 280 } 275 281 … … 1175 1181 } 1176 1182 1183 1177 1184 bool ViewCellsManager::CheckValidity(ViewCell *vc, 1178 1185 int minPvsSize, … … 1190 1197 1191 1198 1192 bool ViewCellsManager::EqualToSpatialNode(ViewCell *viewCell) const1193 {1194 return false;1195 }1196 1197 1199 int ViewCellsManager::ComputeBoxIntersections(const AxisAlignedBox3 &box, 1198 1200 ViewCellContainer &viewCells) const … … 1200 1202 return 0; 1201 1203 }; 1204 1202 1205 1203 1206 AxisAlignedBox3 ViewCellsManager::GetFilterBBox(const Vector3 &viewPoint, … … 2196 2199 2197 2200 2198 /**********************************************************************/ 2199 /* BspViewCellsManager implementation */ 2200 /**********************************************************************/ 2201 2202 2203 BspViewCellsManager::BspViewCellsManager(BspTree *bspTree): 2204 ViewCellsManager(), mBspTree(bspTree) 2205 { 2206 Environment::GetSingleton()->GetIntValue("BspTree.Construction.samples", mInitialSamples); 2207 mBspTree->SetViewCellsManager(this); 2208 mBspTree->mViewCellsTree = mViewCellsTree; 2209 } 2210 2211 2212 bool BspViewCellsManager::ViewCellsConstructed() const 2213 { 2214 return mBspTree->GetRoot() != NULL; 2215 } 2216 2217 2218 ViewCell *BspViewCellsManager::GenerateViewCell(Mesh *mesh) const 2219 { 2220 return new BspViewCell(mesh); 2221 } 2222 2223 2224 int BspViewCellsManager::ConstructSubdivision(const ObjectContainer &objects, 2225 const VssRayContainer &rays) 2226 { 2227 // if view cells were already constructed 2228 if (ViewCellsConstructed()) 2229 return 0; 2230 2231 int sampleContributions = 0; 2232 2233 // construct view cells using the collected samples 2234 RayContainer constructionRays; 2235 VssRayContainer savedRays; 2236 2237 const int limit = min(mInitialSamples, (int)rays.size()); 2238 2239 VssRayContainer::const_iterator it, it_end = rays.end(); 2240 2241 const float prop = (float)limit / ((float)rays.size() + Limits::Small); 2242 2243 for (it = rays.begin(); it != it_end; ++ it) 2244 { 2245 if (Random(1.0f) < prop) 2246 constructionRays.push_back(new Ray(*(*it))); 2247 else 2248 savedRays.push_back(*it); 2249 } 2250 2251 if (mViewCells.empty()) 2252 { 2253 // no view cells loaded 2254 mBspTree->Construct(objects, constructionRays, &mViewSpaceBox); 2255 // collect final view cells 2256 mBspTree->CollectViewCells(mViewCells); 2257 } 2258 else 2259 { 2260 mBspTree->Construct(mViewCells); 2261 } 2262 2263 // destroy rays created only for construction 2264 CLEAR_CONTAINER(constructionRays); 2265 2266 Debug << mBspTree->GetStatistics() << endl; 2267 2268 //EvaluateViewCellsStats(); 2269 Debug << "\nView cells after construction:\n" << mCurrentViewCellsStats << endl; 2270 2271 // recast rest of the rays 2272 if (SAMPLE_AFTER_SUBDIVISION) 2273 ComputeSampleContributions(savedRays, true, false); 2274 2275 // real meshes are contructed at this stage 2276 if (0) 2277 { 2278 cout << "finalizing view cells ... "; 2279 FinalizeViewCells(true); 2280 cout << "finished" << endl; 2281 } 2282 2283 return sampleContributions; 2284 } 2285 2286 2287 void BspViewCellsManager::CollectViewCells() 2288 { 2289 // view cells tree constructed 2290 if (!ViewCellsTreeConstructed()) 2291 { 2292 mBspTree->CollectViewCells(mViewCells); 2293 } 2294 else 2295 { 2296 // we can use the view cells tree hierarchy to get the right set 2297 mViewCellsTree->CollectBestViewCellSet(mViewCells, 2298 mNumActiveViewCells); 2299 } 2300 } 2301 2302 2303 float BspViewCellsManager::GetProbability(ViewCell *viewCell) 2304 { 2305 // compute view cell area as subsititute for probability 2306 if (1) 2307 return GetVolume(viewCell) / GetViewSpaceBox().GetVolume(); 2308 else 2309 return GetArea(viewCell) / GetAccVcArea(); 2310 } 2311 2312 2313 2314 int BspViewCellsManager::CastLineSegment(const Vector3 &origin, 2315 const Vector3 &termination, 2316 ViewCellContainer &viewcells) 2317 { 2318 return mBspTree->CastLineSegment(origin, termination, viewcells); 2319 } 2320 2321 2322 int BspViewCellsManager::PostProcess(const ObjectContainer &objects, 2323 const VssRayContainer &rays) 2324 { 2325 if (!ViewCellsConstructed()) 2326 { 2327 Debug << "view cells not constructed" << endl; 2328 return 0; 2329 } 2330 2331 // view cells already finished before post processing step (i.e. because they were loaded) 2332 if (mViewCellsFinished) 2333 { 2334 FinalizeViewCells(true); 2335 EvaluateViewCellsStats(); 2336 2337 return 0; 2338 } 2339 2340 //-- post processing of bsp view cells 2341 2342 int vcSize = 0; 2343 int pvsSize = 0; 2344 2345 //-- merge view cells 2346 cout << "starting post processing using " << mPostProcessSamples << " samples ... "; 2347 long startTime = GetTime(); 2348 2349 VssRayContainer postProcessRays; 2350 GetRaySets(rays, mPostProcessSamples, postProcessRays); 2351 2352 if (mMergeViewCells) 2353 { 2354 cout << "constructing visibility based merge tree" << endl; 2355 mViewCellsTree->ConstructMergeTree(rays, objects); 2356 } 2357 else 2358 { 2359 cout << "constructing spatial merge tree" << endl; 2360 2361 // create spatial merge hierarchy 2362 ViewCell *root = ConstructSpatialMergeTree(mBspTree->GetRoot()); 2363 mViewCellsTree->SetRoot(root); 2364 2365 // compute pvs 2366 ObjectPvs pvs; 2367 UpdatePvsForEvaluation(root, pvs); 2368 } 2369 2370 // export statistics after merge 2371 if (1) 2372 { 2373 char mstats[100]; 2374 Environment::GetSingleton()->GetStringValue("ViewCells.mergeStats", mstats); 2375 mViewCellsTree->ExportStats(mstats); 2376 } 2377 2378 //-- stats and visualizations 2379 cout << "finished" << endl; 2380 cout << "merged view cells in " 2381 << TimeDiff(startTime, GetTime()) * 1e-3 << " secs" << endl; 2382 2383 Debug << "Postprocessing: Merged view cells in " 2384 << TimeDiff(startTime, GetTime()) * 1e-3 << " secs" << endl << endl; 2385 2386 2387 //-- visualization and statistics 2388 // reset view cells and stats 2389 ResetViewCells(); 2390 Debug << "\nView cells after merge:\n" << mCurrentViewCellsStats << endl; 2391 2392 2393 int savedColorCode = mColorCode; 2394 2395 //BspLeaf::NewMail(); 2396 if (1) // export merged view cells 2397 { 2398 mColorCode = 0; 2399 2400 Exporter *exporter = Exporter::GetExporter("merged_view_cells.wrl"); 2401 2402 2403 cout << "exporting view cells after merge ... "; 2404 2405 if (exporter) 2406 { 2407 if (mExportGeometry) 2408 exporter->ExportGeometry(objects); 2409 2410 //exporter->SetWireframe(); 2411 exporter->SetFilled(); 2412 ExportViewCellsForViz(exporter); 2413 2414 2415 delete exporter; 2416 } 2417 cout << "finished" << endl; 2418 } 2419 2420 if (1) // export merged view cells using pvs color coding 2421 { 2422 mColorCode = 1; 2423 2424 Exporter *exporter = Exporter::GetExporter("merged_view_cells_pvs.wrl"); 2425 2426 cout << "exporting view cells after merge (pvs size) ... "; 2427 2428 if (exporter) 2429 { 2430 //exporter->SetWireframe(); 2431 //exporter->SetForcedMaterial(RandomMaterial()); 2432 2433 if (mExportGeometry) 2434 exporter->ExportGeometry(objects); 2435 2436 //exporter->SetWireframe(); 2437 exporter->SetFilled(); 2438 ExportViewCellsForViz(exporter); 2439 2440 delete exporter; 2441 } 2442 cout << "finished" << endl; 2443 } 2444 2445 2446 // only for testing 2447 TestSubdivision(); 2448 2449 mColorCode = savedColorCode; 2450 2451 // compute final meshes and volume / area 2452 if (1) FinalizeViewCells(true); 2453 2454 // write view cells to disc 2455 if (mExportViewCells) 2456 { 2457 char filename[100]; 2458 Environment::GetSingleton()->GetStringValue("ViewCells.filename", filename); 2459 ExportViewCells(filename, mExportPvs, objects); 2460 } 2461 2462 // export bounding boxes 2463 if (0 && mExportBboxesForPvs) 2464 { 2465 char filename[100]; 2466 Environment::GetSingleton()->GetStringValue("ViewCells.boxesFilename", filename); 2467 ExportBoundingBoxes(filename, objects); 2468 } 2469 2470 2471 return 0; 2472 } 2473 2474 2475 BspViewCellsManager::~BspViewCellsManager() 2476 { 2477 } 2478 2479 2480 int BspViewCellsManager::GetType() const 2481 { 2482 return BSP; 2483 } 2484 2485 2486 void BspViewCellsManager::Visualize(const ObjectContainer &objects, 2487 const VssRayContainer &sampleRays) 2488 { 2201 2202 2203 void 2204 ViewCellsManager::ApplyFilter(ViewCell *viewCell, 2205 KdTree *kdTree, 2206 const float viewSpaceFilterSize, 2207 const float spatialFilterSize, 2208 ObjectPvs &pvs 2209 ) 2210 { 2211 // extend the pvs of the viewcell by pvs of its neighbors 2212 // and apply spatial filter by including all neighbors of the objects 2213 // in the pvs 2214 2215 // get all viewcells intersecting the viewSpaceFilterBox 2216 // and compute the pvs union 2217 2218 //Vector3 center = viewCell->GetBox().Center(); 2219 // Vector3 center = m->mBox.Center(); 2220 2221 // AxisAlignedBox3 box(center - Vector3(viewSpaceFilterSize/2), 2222 // center + Vector3(viewSpaceFilterSize/2)); 2489 2223 if (!ViewCellsConstructed()) 2490 2224 return; 2491 2492 int savedColorCode = mColorCode; 2493 2494 2495 if (1) // export final view cells 2496 { 2497 mColorCode = 1; // hack color code 2498 Exporter *exporter = Exporter::GetExporter("final_view_cells.x3d"); 2499 2500 cout << "exporting view cells after merge (pvs size) ... "; 2501 2502 if (exporter) 2503 { 2504 //exporter->SetWireframe(); 2505 2506 if (mExportGeometry) 2507 exporter->ExportGeometry(objects); 2508 2509 //exporter->SetFilled(); 2510 const bool b = mUseClipPlaneForViz; 2511 mUseClipPlaneForViz = false; 2512 2513 ExportViewCellsForViz(exporter); 2514 2515 mUseClipPlaneForViz = b; 2516 delete exporter; 2517 } 2518 cout << "finished" << endl; 2519 } 2520 2521 mColorCode = savedColorCode; 2522 2523 //-- visualization of the BSP splits 2524 bool exportSplits = false; 2525 Environment::GetSingleton()->GetBoolValue("BspTree.Visualization.exportSplits", exportSplits); 2526 2527 if (exportSplits) 2528 { 2529 cout << "exporting splits ... "; 2530 ExportSplits(objects); 2531 cout << "finished" << endl; 2532 } 2533 2534 // export single view cells 2535 ExportBspPvs(objects); 2536 } 2537 2538 2539 void BspViewCellsManager::ExportSplits(const ObjectContainer &objects) 2540 { 2541 Exporter *exporter = Exporter::GetExporter("bsp_splits.x3d"); 2542 2543 if (exporter) 2544 { 2545 //exporter->SetFilled(); 2546 2547 if (mExportGeometry) 2548 exporter->ExportGeometry(objects); 2549 2550 Material m; 2551 m.mDiffuseColor = RgbColor(1, 0, 0); 2552 exporter->SetForcedMaterial(m); 2553 exporter->SetWireframe(); 2554 2555 exporter->ExportBspSplits(*mBspTree, true); 2556 2557 //NOTE: take forced material, else big scenes cannot be viewed 2558 m.mDiffuseColor = RgbColor(0, 1, 0); 2559 exporter->SetForcedMaterial(m); 2560 //exporter->ResetForcedMaterial(); 2561 2562 delete exporter; 2563 } 2564 } 2565 2566 2567 void BspViewCellsManager::ExportBspPvs(const ObjectContainer &objects) 2568 { 2569 const int leafOut = 10; 2570 2571 ViewCell::NewMail(); 2572 2573 //-- some rays for output 2574 const int raysOut = min((int)mBspRays.size(), mVisualizationSamples); 2575 2576 cout << "visualization using " << mVisualizationSamples << " samples" << endl; 2577 Debug << "\nOutput view cells: " << endl; 2578 2579 // sort view cells in order to find the largest view cells 2580 if (0) 2581 stable_sort(mViewCells.begin(), mViewCells.end(), ViewCell::SmallerPvs); 2582 2583 int limit = min(leafOut, (int)mViewCells.size()); 2584 2585 for (int i = 0; i < limit; ++ i) 2586 { 2587 cout << "creating output for view cell " << i << " ... "; 2588 VssRayContainer vcRays; 2589 Intersectable::NewMail(); 2590 ViewCell *vc; 2591 2592 if (0) 2593 vc = mViewCells[i]; 2594 else 2595 vc = mViewCells[Random((int)mViewCells.size())]; 2596 2597 cout << "creating output for view cell " << i << " ... "; 2598 2599 if(0) 2600 { 2601 // check whether we can add the current ray to the output rays 2602 for (int k = 0; k < raysOut; ++ k) 2603 { 2604 BspRay *ray = mBspRays[k]; 2605 for (int j = 0; j < (int)ray->intersections.size(); ++ j) 2606 { 2607 BspLeaf *leaf = ray->intersections[j].mLeaf; 2608 if (vc == leaf->GetViewCell()) 2609 vcRays.push_back(ray->vssRay); 2610 } 2611 } 2612 } 2613 2614 //bspLeaves[j]->Mail(); 2615 char s[64]; sprintf(s, "bsp-pvs%04d.x3d", i); 2616 2617 Exporter *exporter = Exporter::GetExporter(s); 2618 2619 exporter->SetWireframe(); 2620 2621 Material m;//= RandomMaterial(); 2622 m.mDiffuseColor = RgbColor(0, 1, 0); 2623 exporter->SetForcedMaterial(m); 2624 2625 ExportViewCellGeometry(exporter, vc); 2626 2627 // export rays piercing this view cell 2628 exporter->ExportRays(vcRays, RgbColor(0, 1, 0)); 2629 2630 m.mDiffuseColor = RgbColor(1, 0, 0); 2631 exporter->SetForcedMaterial(m); 2632 2633 ObjectPvsMap::const_iterator it, 2634 it_end = vc->GetPvs().mEntries.end(); 2635 2636 exporter->SetFilled(); 2637 2638 // output PVS of view cell 2639 for (it = vc->GetPvs().mEntries.begin(); it != it_end; ++ it) 2640 { 2641 Intersectable *intersect = (*it).first; 2642 2643 if (!intersect->Mailed()) 2644 { 2645 Material m = RandomMaterial(); 2646 exporter->SetForcedMaterial(m); 2647 2648 exporter->ExportIntersectable(intersect); 2649 intersect->Mail(); 2650 } 2651 } 2652 2653 DEL_PTR(exporter); 2654 cout << "finished" << endl; 2655 } 2656 2657 Debug << endl; 2658 } 2659 2660 2661 void BspViewCellsManager::ExportColor(Exporter *exporter, 2662 ViewCell *vc) const 2663 { 2664 const bool vcValid = CheckValidity(vc, mMinPvsSize, mMaxPvsSize); 2665 2666 float importance = 0; 2667 static Material m; 2668 2669 switch (mColorCode) 2670 { 2671 case 0: // Random 2672 { 2673 if (vcValid) 2674 { 2675 m.mDiffuseColor.r = 0.5f + RandomValue(0.0f, 0.5f); 2676 m.mDiffuseColor.g = 0.5f + RandomValue(0.0f, 0.5f); 2677 m.mDiffuseColor.b = 0.5f + RandomValue(0.0f, 0.5f); 2678 } 2679 else 2680 { 2681 m.mDiffuseColor.r = 0.0f; 2682 m.mDiffuseColor.g = 1.0f; 2683 m.mDiffuseColor.b = 0.0f; 2684 } 2685 2686 exporter->SetForcedMaterial(m); 2687 return; 2688 } 2689 2690 case 1: // pvs 2691 { 2692 importance = (float)vc->GetPvs().GetSize() / 2693 (float)mCurrentViewCellsStats.maxPvs; 2694 2695 } 2696 break; 2697 case 2: // merges 2698 { 2699 int lSize = mViewCellsTree->GetNumInitialViewCells(vc); 2700 importance = (float)lSize / (float)mCurrentViewCellsStats.maxLeaves; 2701 } 2702 //break; 2703 case 3: // merge tree differene 2704 { 2705 // TODO 2706 //importance = (float)GetMaxTreeDiff(vc) / 2707 // (float)(mVspBspTree->GetStatistics().maxDepth * 2); 2708 2709 } 2710 break; 2711 default: 2712 break; 2713 } 2714 2715 // special color code for invalid view cells 2716 m.mDiffuseColor.r = importance; 2717 m.mDiffuseColor.g = 1.0f - m.mDiffuseColor.r; 2718 m.mDiffuseColor.b = vcValid ? 1.0f : 0.0f; 2719 2720 //Debug << "importance: " << importance << endl; 2721 exporter->SetForcedMaterial(m); 2722 } 2723 2724 2725 void BspViewCellsManager::TestSubdivision() 2726 { 2727 ViewCellContainer leaves; 2728 mViewCellsTree->CollectLeaves(mViewCellsTree->GetRoot(), leaves); 2729 2730 ViewCellContainer::const_iterator it, it_end = leaves.end(); 2731 2732 const float vol = mViewSpaceBox.GetVolume(); 2733 float subdivVol = 0; 2734 float newVol = 0; 2735 2736 for (it = leaves.begin(); it != it_end; ++ it) 2737 { 2738 BspNodeGeometry geom; 2739 BspLeaf *leaf = dynamic_cast<BspViewCell *>(*it)->mLeaf; 2740 mBspTree->ConstructGeometry(leaf, geom); 2741 2742 const float lVol = geom.GetVolume(); 2743 2744 newVol += lVol; 2745 subdivVol += (*it)->GetVolume(); 2746 2747 float thres = 0.9f; 2748 if ((lVol < ((*it)->GetVolume() * thres)) || 2749 (lVol * thres > ((*it)->GetVolume()))) 2750 Debug << "warning: " << lVol << " " << (*it)->GetVolume() << endl; 2751 } 2752 2753 Debug << "exact volume: " << vol << endl; 2754 Debug << "subdivision volume: " << subdivVol << endl; 2755 Debug << "new volume: " << newVol << endl; 2756 } 2757 2758 2759 void BspViewCellsManager::ExportViewCellGeometry(Exporter *exporter, 2760 ViewCell *vc, 2761 const Plane3 *clipPlane) const 2762 { 2763 if (vc->GetMesh()) 2764 { 2765 exporter->ExportMesh(vc->GetMesh()); 2766 2767 return; 2768 } 2769 2770 2771 if (clipPlane) 2772 { 2773 ViewCellContainer leaves; 2774 mViewCellsTree->CollectLeaves(vc, leaves); 2775 ViewCellContainer::const_iterator it, it_end = leaves.end(); 2776 2777 for (it = leaves.begin(); it != it_end; ++ it) 2778 { 2779 BspNodeGeometry geom; 2780 2781 BspNodeGeometry front; 2782 BspNodeGeometry back; 2783 2784 BspLeaf *leaf = dynamic_cast<BspViewCell *>(*it)->mLeaf; 2785 mBspTree->ConstructGeometry(leaf, geom); 2786 2787 const float eps = 0.00000001f; 2788 const int cf = geom.Side(*clipPlane, eps); 2789 2790 if (cf == -1) 2791 { 2792 exporter->ExportPolygons(geom.GetPolys()); 2793 } 2794 else if (cf == 0) 2795 { 2796 geom.SplitGeometry(front, 2797 back, 2798 *clipPlane, 2799 mViewSpaceBox, 2800 eps); 2801 2802 //Debug << "geo size: " << geom.Size() << endl; 2803 //Debug << "size b: " << back.Size() << " f: " << front.Size() << endl; 2804 if (back.Valid()) 2805 { 2806 exporter->ExportPolygons(back.GetPolys()); 2807 } 2808 } 2809 } 2810 } 2811 else 2812 { 2813 BspNodeGeometry geom; 2814 mBspTree->ConstructGeometry(vc, geom); 2815 2816 exporter->ExportPolygons(geom.GetPolys()); 2817 } 2818 } 2819 2820 2821 void BspViewCellsManager::CreateMesh(ViewCell *vc) 2822 { 2823 // delete previous mesh 2824 ///DEL_PTR(vc->GetMesh()); 2825 BspNodeGeometry geom; 2826 mBspTree->ConstructGeometry(vc, geom); 2827 2828 Mesh *mesh = MeshManager::GetSingleton()->CreateResource(); 2829 2830 IncludeNodeGeomInMesh(geom, *mesh); 2831 vc->SetMesh(mesh); 2832 } 2833 2834 2835 void BspViewCellsManager::Finalize(ViewCell *viewCell, 2836 const bool createMesh) 2837 { 2838 float area = 0; 2839 float volume = 0; 2840 2841 ViewCellContainer leaves; 2842 mViewCellsTree->CollectLeaves(viewCell, leaves); 2843 2844 ViewCellContainer::const_iterator it, it_end = leaves.end(); 2845 2846 for (it = leaves.begin(); it != it_end; ++ it) 2847 { 2848 BspNodeGeometry geom; 2849 BspLeaf *leaf = dynamic_cast<BspViewCell *>(*it)->mLeaf; 2850 mBspTree->ConstructGeometry(leaf, geom); 2851 2852 const float lVol = geom.GetVolume(); 2853 const float lArea = geom.GetArea(); 2854 2855 //(*it)->SetVolume(vol); 2856 //(*it)->SetArea(area); 2857 2858 area += lArea; 2859 volume += lVol; 2860 2861 CreateMesh(*it); 2862 } 2863 2864 viewCell->SetVolume(volume); 2865 viewCell->SetArea(area); 2866 } 2867 2868 2869 ViewCell *BspViewCellsManager::GetViewCell(const Vector3 &point, const bool active) const 2870 { 2871 if (!mBspTree) 2872 return NULL; 2873 2874 if (!mViewSpaceBox.IsInside(point)) 2875 return NULL; 2876 2877 return mBspTree->GetViewCell(point); 2878 } 2879 2880 2881 void BspViewCellsManager::CollectMergeCandidates(const VssRayContainer &rays, 2882 vector<MergeCandidate> &candidates) 2883 { 2884 cout << "collecting merge candidates ... " << endl; 2885 2886 if (mUseRaysForMerge) 2887 { 2888 mBspTree->CollectMergeCandidates(rays, candidates); 2889 } 2890 else 2891 { 2892 vector<BspLeaf *> leaves; 2893 mBspTree->CollectLeaves(leaves); 2894 mBspTree->CollectMergeCandidates(leaves, candidates); 2895 } 2896 2897 cout << "fininshed collecting candidates" << endl; 2898 } 2899 2900 2901 2902 bool BspViewCellsManager::ExportViewCells(const string filename, const bool exportPvs, const ObjectContainer &objects) 2903 { 2904 #if STILL_HAS_TODO 2905 cout << "exporting view cells to xml ... "; 2906 std::ofstream stream; 2907 2908 // for output we need unique ids for each view cell 2909 CreateUniqueViewCellIds(); 2910 2911 2912 stream.open(filename.c_str()); 2913 stream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"<<endl; 2914 stream << "<VisibilitySolution>" << endl; 2915 2916 //-- the view space bounding box 2917 stream << "<ViewSpaceBox" 2918 << " min=\"" << mViewSpaceBox.Min().x << " " << mViewSpaceBox.Min().y << " " << mViewSpaceBox.Min().z << "\"" 2919 << " max=\"" << mViewSpaceBox.Max().x << " " << mViewSpaceBox.Max().y << " " << mViewSpaceBox.Max().z << "\" />" << endl; 2920 2921 //-- the type of the view cells hierarchy 2922 2923 // NOTE: load in vsp bsp here because bsp and vsp bsp can use same tree and vsp bsp is bug free 2924 stream << "<Hierarchy name=\"vspBspTree\" >" << endl; 2925 2926 //-- load the view cells itself, i.e., the ids and the pvs 2927 stream << "<ViewCells>" << endl; 2928 2929 mViewCellsTree->Export(stream, exportPvs); 2930 2931 stream << "</ViewCells>" << endl; 2932 2933 //-- load the hierarchy 2934 stream << "<Hierarchy>" << endl; 2935 mBspTree->Export(stream); 2936 stream << endl << "</Hierarchy>" << endl; 2937 2938 stream << "</VisibilitySolution>" << endl; 2939 stream.close(); 2940 2941 cout << "finished" << endl; 2942 #endif 2943 return true; 2944 } 2945 2946 2947 ViewCell *BspViewCellsManager::ConstructSpatialMergeTree(BspNode *root) 2948 { 2949 // terminate recursion 2950 if (root->IsLeaf()) 2951 { 2952 BspLeaf *leaf = dynamic_cast<BspLeaf *>(root); 2953 leaf->GetViewCell()->SetMergeCost(0.0f); 2954 return leaf->GetViewCell(); 2955 } 2956 2957 BspInterior *interior = dynamic_cast<BspInterior *>(root); 2958 ViewCellInterior *viewCellInterior = new ViewCellInterior(); 2959 2960 // evaluate merge cost for priority traversal 2961 float mergeCost = 1.0f / (float)root->mTimeStamp; 2962 viewCellInterior->SetMergeCost(mergeCost); 2963 2964 float volume = 0; 2965 2966 BspNode *front = interior->GetFront(); 2967 BspNode *back = interior->GetBack(); 2968 2969 2970 //-- recursivly compute child hierarchies 2971 ViewCell *backVc = ConstructSpatialMergeTree(back); 2972 ViewCell *frontVc = ConstructSpatialMergeTree(front); 2973 2974 2975 viewCellInterior->SetupChildLink(backVc); 2976 viewCellInterior->SetupChildLink(frontVc); 2977 2978 volume += backVc->GetVolume(); 2979 volume += frontVc->GetVolume(); 2980 2981 viewCellInterior->SetVolume(volume); 2982 2983 return viewCellInterior; 2984 } 2985 2986 2987 void BspViewCellsManager::UpdatePvsForEvaluation(ViewCell *root, ObjectPvs &pvs) 2988 { 2989 // terminate traversal 2990 if (root->IsLeaf()) 2991 { 2992 pvs = root->GetPvs(); 2993 SetScalarPvsSize(root, pvs.GetSize()); 2994 2995 return; 2996 } 2997 2998 ViewCellInterior *interior = dynamic_cast<ViewCellInterior *>(root); 2999 ViewCellContainer::const_iterator vit, vit_end = interior->mChildren.end(); 3000 3001 vector<ObjectPvs> pvsList; 3002 3003 3004 for (vit = interior->mChildren.begin(); vit != vit_end; ++ vit) 3005 { 3006 ObjectPvs objPvs; 3007 3008 //-- recursivly compute child pvss 3009 UpdatePvsForEvaluation(*vit, objPvs); 3010 3011 // store pvs in vector 3012 pvsList.push_back(objPvs); 3013 } 3014 3015 #if 1 3016 Intersectable::NewMail(); 3017 3018 //-- faster way of computing pvs: 3019 // construct merged pvs by adding 3020 // and only those of the next pvs which were not mailed. 3021 // note: sumpdf is not correct!! 3022 vector<ObjectPvs>::iterator oit = pvsList.begin(); 3023 3024 for (vit = interior->mChildren.begin(); vit != vit_end; ++ vit, ++ oit) 3025 { 3026 3027 ObjectPvsMap::iterator pit, pit_end = (*oit).mEntries.end(); 3028 3029 for (pit = (*oit).mEntries.begin(); pit != pit_end; ++ pit) 3030 { 3031 3032 Intersectable *intersect = (*pit).first; 3033 3034 if (!intersect->Mailed()) 3035 { 3036 pvs.AddSample(intersect, (*pit).second.mSumPdf); 3037 intersect->Mail(); 3038 } 3039 } 3040 } 3041 3042 // store pvs in this node 3043 if (mViewCellsTree->ViewCellsStorage() == ViewCellsTree::PVS_IN_INTERIORS) 3044 { 3045 interior->SetPvs(pvs); 3046 } 3047 3048 // set new pvs size 3049 SetScalarPvsSize(interior, pvs.GetSize()); 3050 3051 #else 3052 // really merge cells: slow put sumpdf is correct 3053 ViewCellInterior *viewCellInterior = new ViewCellInterior(); 3054 3055 viewCellInterior->GetPvs().Merge(backVc->GetPvs()); 3056 viewCellInterior->GetPvs().Merge(frontVc->GetPvs()); 3057 #endif 3058 3059 } 3060 3061 /************************************************************************/ 3062 /* KdViewCellsManager implementation */ 3063 /************************************************************************/ 3064 3065 3066 3067 KdViewCellsManager::KdViewCellsManager(KdTree *kdTree): 3068 ViewCellsManager(), mKdTree(kdTree), mKdPvsDepth(100) 3069 { 3070 } 3071 3072 3073 float KdViewCellsManager::GetProbability(ViewCell *viewCell) 3074 { 3075 // compute view cell area / volume as subsititute for probability 3076 if (0) 3077 return GetArea(viewCell) / GetViewSpaceBox().SurfaceArea(); 3078 else 3079 return GetVolume(viewCell) / GetViewSpaceBox().GetVolume(); 3080 } 3081 3082 3083 3084 3085 void KdViewCellsManager::CollectViewCells() 3086 { 3087 //mKdTree->CollectViewCells(mViewCells); TODO 3088 } 3089 3090 3091 int KdViewCellsManager::ConstructSubdivision(const ObjectContainer &objects, 3092 const VssRayContainer &rays) 3093 { 3094 // if view cells already constructed 3095 if (ViewCellsConstructed()) 3096 return 0; 3097 3098 mKdTree->Construct(); 3099 3100 mTotalAreaValid = false; 3101 // create the view cells 3102 mKdTree->CreateAndCollectViewCells(mViewCells); 3103 3104 // cast rays 3105 ComputeSampleContributions(rays, true, false); 3106 3107 EvaluateViewCellsStats(); 3108 Debug << "\nView cells after construction:\n" << mCurrentViewCellsStats << endl; 3109 3110 return 0; 3111 } 3112 3113 3114 bool KdViewCellsManager::ViewCellsConstructed() const 3115 { 3116 return mKdTree->GetRoot() != NULL; 3117 } 3118 3119 3120 int KdViewCellsManager::PostProcess(const ObjectContainer &objects, 3121 const VssRayContainer &rays) 3122 { 3123 return 0; 3124 } 3125 3126 3127 void KdViewCellsManager::Visualize(const ObjectContainer &objects, 3128 const VssRayContainer &sampleRays) 3129 { 2225 2226 if (viewSpaceFilterSize >= 0.0f) { 2227 2228 bool usePrVS = false; 2229 2230 if (!usePrVS) { 2231 AxisAlignedBox3 box = GetViewCellBox(viewCell); 2232 box.Enlarge(Vector3(viewSpaceFilterSize/2)); 2233 2234 ViewCellContainer viewCells; 2235 ComputeBoxIntersections(box, viewCells); 2236 2237 // cout<<"box="<<box<<endl; 2238 ViewCellContainer::const_iterator it = viewCells.begin(), it_end = viewCells.end(); 2239 2240 int i; 2241 for (i=0; it != it_end; ++ it, ++ i) { 2242 //cout<<"v"<<i<<" pvs="<<(*it)->GetPvs().mEntries.size()<<endl; 2243 pvs.Merge((*it)->GetPvs()); 2244 } 2245 } else { 2246 PrVs prvs; 2247 AxisAlignedBox3 box = GetViewCellBox(viewCell); 2248 2249 // mViewCellsManager->SetMaxFilterSize(1); 2250 GetPrVS(box.Center(), prvs, viewSpaceFilterSize); 2251 pvs = prvs.mViewCell->GetPvs(); 2252 DeleteLocalMergeTree(prvs.mViewCell); 2253 } 2254 } else 2255 pvs = viewCell->GetPvs(); 2256 2257 if (spatialFilterSize >=0.0f) 2258 ApplySpatialFilter(kdTree, spatialFilterSize, pvs); 2259 2260 } 2261 2262 2263 2264 void 2265 ViewCellsManager::ApplyFilter(KdTree *kdTree, 2266 const float relViewSpaceFilterSize, 2267 const float relSpatialFilterSize 2268 ) 2269 { 2270 3130 2271 if (!ViewCellsConstructed()) 3131 2272 return; 3132 2273 3133 // using view cells instead of the kd PVS of objects 3134 const bool useViewCells = true; 3135 bool exportRays = false; 3136 3137 int limit = min(mVisualizationSamples, (int)sampleRays.size()); 3138 const int pvsOut = min((int)objects.size(), 10); 3139 VssRayContainer *rays = new VssRayContainer[pvsOut]; 3140 3141 if (useViewCells) 3142 { 3143 const int leafOut = 10; 3144 3145 ViewCell::NewMail(); 3146 3147 //-- some rays for output 3148 const int raysOut = min((int)sampleRays.size(), mVisualizationSamples); 3149 Debug << "visualization using " << raysOut << " samples" << endl; 3150 3151 //-- some random view cells and rays for output 3152 vector<KdLeaf *> kdLeaves; 3153 3154 for (int i = 0; i < leafOut; ++ i) 3155 kdLeaves.push_back(dynamic_cast<KdLeaf *>(mKdTree->GetRandomLeaf())); 3156 3157 for (int i = 0; i < kdLeaves.size(); ++ i) 3158 { 3159 KdLeaf *leaf = kdLeaves[i]; 3160 RayContainer vcRays; 3161 3162 cout << "creating output for view cell " << i << " ... "; 3163 #if 0 3164 // check whether we can add the current ray to the output rays 3165 for (int k = 0; k < raysOut; ++ k) 3166 { 3167 Ray *ray = sampleRays[k]; 3168 3169 for (int j = 0; j < (int)ray->bspIntersections.size(); ++ j) 3170 { 3171 BspLeaf *leaf2 = ray->bspIntersections[j].mLeaf; 3172 3173 if (leaf->GetViewCell() == leaf2->GetViewCell()) 3174 { 3175 vcRays.push_back(ray); 3176 } 3177 } 3178 } 3179 #endif 3180 Intersectable::NewMail(); 3181 3182 ViewCell *vc = leaf->mViewCell; 3183 3184 //bspLeaves[j]->Mail(); 3185 char s[64]; sprintf(s, "kd-pvs%04d.x3d", i); 3186 3187 Exporter *exporter = Exporter::GetExporter(s); 3188 exporter->SetFilled(); 3189 3190 exporter->SetWireframe(); 3191 //exporter->SetFilled(); 3192 3193 Material m;//= RandomMaterial(); 3194 m.mDiffuseColor = RgbColor(1, 1, 0); 3195 exporter->SetForcedMaterial(m); 3196 3197 AxisAlignedBox3 box = mKdTree->GetBox(leaf); 3198 exporter->ExportBox(box); 3199 3200 // export rays piercing this view cell 3201 exporter->ExportRays(vcRays, 1000, RgbColor(0, 1, 0)); 3202 3203 m.mDiffuseColor = RgbColor(1, 0, 0); 3204 exporter->SetForcedMaterial(m); 3205 3206 // exporter->SetWireframe(); 3207 exporter->SetFilled(); 3208 3209 ObjectPvsMap::iterator it, it_end = vc->GetPvs().mEntries.end(); 3210 // -- output PVS of view cell 3211 for (it = vc->GetPvs().mEntries.begin(); it != it_end; ++ it) 3212 { 3213 Intersectable *intersect = (*it).first; 3214 if (!intersect->Mailed()) 3215 { 3216 exporter->ExportIntersectable(intersect); 3217 intersect->Mail(); 3218 } 3219 } 3220 3221 DEL_PTR(exporter); 3222 cout << "finished" << endl; 3223 } 3224 3225 DEL_PTR(rays); 3226 } 3227 else // using kd PVS of objects 3228 { 3229 for (int i = 0; i < limit; ++ i) 3230 { 3231 VssRay *ray = sampleRays[i]; 3232 3233 // check whether we can add this to the rays 3234 for (int j = 0; j < pvsOut; j++) 3235 { 3236 if (objects[j] == ray->mTerminationObject) 3237 { 3238 rays[j].push_back(ray); 3239 } 3240 } 3241 } 3242 3243 if (exportRays) 3244 { 3245 Exporter *exporter = NULL; 3246 exporter = Exporter::GetExporter("sample-rays.x3d"); 3247 exporter->SetWireframe(); 3248 exporter->ExportKdTree(*mKdTree); 3249 3250 for (i = 0; i < pvsOut; i++) 3251 exporter->ExportRays(rays[i], RgbColor(1, 0, 0)); 3252 3253 exporter->SetFilled(); 3254 3255 delete exporter; 3256 } 3257 3258 for (int k=0; k < pvsOut; k++) 3259 { 3260 Intersectable *object = objects[k]; 3261 char s[64]; 3262 sprintf(s, "sample-pvs%04d.x3d", k); 3263 3264 Exporter *exporter = Exporter::GetExporter(s); 3265 exporter->SetWireframe(); 3266 3267 KdPvsMap::iterator i = object->mKdPvs.mEntries.begin(); 3268 Intersectable::NewMail(); 3269 3270 // avoid adding the object to the list 3271 object->Mail(); 3272 ObjectContainer visibleObjects; 3273 3274 for (; i != object->mKdPvs.mEntries.end(); i++) 3275 { 3276 KdNode *node = (*i).first; 3277 exporter->ExportBox(mKdTree->GetBox(node)); 3278 3279 mKdTree->CollectObjects(node, visibleObjects); 3280 } 3281 3282 exporter->ExportRays(rays[k], RgbColor(0, 1, 0)); 3283 exporter->SetFilled(); 3284 3285 for (int j = 0; j < visibleObjects.size(); j++) 3286 exporter->ExportIntersectable(visibleObjects[j]); 3287 3288 Material m; 3289 m.mDiffuseColor = RgbColor(1, 0, 0); 3290 exporter->SetForcedMaterial(m); 3291 exporter->ExportIntersectable(object); 3292 3293 delete exporter; 3294 } 3295 } 3296 } 3297 3298 3299 void KdViewCellsManager::ExportColor(Exporter *exporter, 3300 ViewCell *vc) const 3301 { 3302 // TODO 3303 } 3304 3305 3306 ViewCell *KdViewCellsManager::GenerateViewCell(Mesh *mesh) const 3307 { 3308 return new KdViewCell(mesh); 3309 } 3310 3311 3312 void KdViewCellsManager::ExportViewCellGeometry(Exporter *exporter, 3313 ViewCell *vc, 3314 const Plane3 *clipPlane) const 3315 { 3316 ViewCellContainer leaves; 3317 3318 mViewCellsTree->CollectLeaves(vc, leaves); 3319 ViewCellContainer::const_iterator it, it_end = leaves.end(); 3320 3321 for (it = leaves.begin(); it != it_end; ++ it) 3322 { 3323 KdViewCell *kdVc = dynamic_cast<KdViewCell *>(*it); 3324 3325 exporter->ExportBox(mKdTree->GetBox(kdVc->mLeaf)); 3326 } 3327 } 3328 3329 3330 int KdViewCellsManager::GetType() const 3331 { 3332 return ViewCellsManager::KD; 3333 } 3334 3335 3336 3337 KdNode *KdViewCellsManager::GetNodeForPvs(KdLeaf *leaf) 3338 { 3339 KdNode *node = leaf; 3340 3341 while (node->mParent && node->mDepth > mKdPvsDepth) 3342 node = node->mParent; 3343 return node; 3344 } 3345 3346 int KdViewCellsManager::CastLineSegment(const Vector3 &origin, 3347 const Vector3 &termination, 3348 ViewCellContainer &viewcells) 3349 { 3350 return mKdTree->CastLineSegment(origin, termination, viewcells); 3351 } 3352 3353 3354 void KdViewCellsManager::CreateMesh(ViewCell *vc) 3355 { 3356 // TODO 3357 } 3358 3359 3360 3361 void KdViewCellsManager::CollectMergeCandidates(const VssRayContainer &rays, 3362 vector<MergeCandidate> &candidates) 3363 { 3364 // TODO 3365 } 3366 3367 /**************************************************************************/ 3368 /* VspBspViewCellsManager implementation */ 3369 /**************************************************************************/ 3370 3371 3372 VspBspViewCellsManager::VspBspViewCellsManager(VspBspTree *vspBspTree): 3373 ViewCellsManager(), mVspBspTree(vspBspTree) 3374 { 3375 Environment::GetSingleton()->GetIntValue("VspBspTree.Construction.samples", mInitialSamples); 3376 mVspBspTree->SetViewCellsManager(this); 3377 mVspBspTree->mViewCellsTree = mViewCellsTree; 3378 } 3379 3380 3381 VspBspViewCellsManager::~VspBspViewCellsManager() 3382 { 3383 } 3384 3385 3386 float VspBspViewCellsManager::GetProbability(ViewCell *viewCell) 3387 { 3388 if (0 && mVspBspTree->mUseAreaForPvs) 3389 return GetArea(viewCell) / GetAccVcArea(); 3390 else 3391 return GetVolume(viewCell) / mViewSpaceBox.GetVolume(); 3392 } 3393 3394 3395 void VspBspViewCellsManager::CollectViewCells() 3396 { 3397 // view cells tree constructed 3398 if (!ViewCellsTreeConstructed()) 3399 { 3400 mVspBspTree->CollectViewCells(mViewCells, false); 3401 } 3402 else 3403 { // we can use the view cells tree hierarchy to get the right set 3404 mViewCellsTree->CollectBestViewCellSet(mViewCells, mNumActiveViewCells); 3405 } 3406 } 3407 3408 3409 bool VspBspViewCellsManager::ViewCellsConstructed() const 3410 { 3411 return mVspBspTree->GetRoot() != NULL; 3412 } 3413 3414 3415 ViewCell *VspBspViewCellsManager::GenerateViewCell(Mesh *mesh) const 3416 { 3417 return new BspViewCell(mesh); 3418 } 3419 3420 3421 int VspBspViewCellsManager::ConstructSubdivision(const ObjectContainer &objects, 3422 const VssRayContainer &rays) 3423 { 3424 mMaxPvsSize = (int)(mMaxPvsRatio * (float)objects.size()); 3425 3426 // if view cells were already constructed 3427 if (ViewCellsConstructed()) 3428 return 0; 3429 3430 int sampleContributions = 0; 3431 3432 VssRayContainer sampleRays; 3433 3434 int limit = min (mInitialSamples, (int)rays.size()); 3435 3436 VssRayContainer constructionRays; 3437 VssRayContainer savedRays; 3438 3439 Debug << "samples used for vsp bsp subdivision: " << mInitialSamples 3440 << ", actual rays: " << (int)rays.size() << endl; 3441 3442 GetRaySets(rays, mInitialSamples, constructionRays, &savedRays); 3443 3444 Debug << "initial rays: " << (int)constructionRays.size() << endl; 3445 Debug << "saved rays: " << (int)savedRays.size() << endl; 3446 3447 long startTime; 3448 3449 if (1) 3450 mVspBspTree->Construct(constructionRays, &mViewSpaceBox); 3451 else 3452 mVspBspTree->Construct(rays, &mViewSpaceBox); 3453 3454 // collapse invalid regions 3455 cout << "collapsing invalid tree regions ... "; 3456 startTime = GetTime(); 3457 const int collapsedLeaves = mVspBspTree->CollapseTree(); 3458 Debug << "collapsed in " << TimeDiff(startTime, GetTime()) * 1e-3 3459 << " seconds" << endl; 3460 3461 cout << "finished" << endl; 3462 3463 //-- stats 3464 Debug << mVspBspTree->GetStatistics() << endl; 3465 3466 ResetViewCells(); 3467 Debug << "\nView cells after construction:\n" << mCurrentViewCellsStats << endl; 3468 3469 3470 startTime = GetTime(); 3471 3472 cout << "Computing remaining ray contributions ... "; 3473 3474 // recast rest of rays 3475 if (SAMPLE_AFTER_SUBDIVISION) 3476 ComputeSampleContributions(savedRays, true, false); 3477 3478 cout << "finished" << endl; 3479 3480 Debug << "Computed remaining ray contribution in " << TimeDiff(startTime, GetTime()) * 1e-3 3481 << " secs" << endl; 3482 3483 cout << "construction finished" << endl; 3484 3485 // real meshes are contructed at this stage 3486 if (0) 3487 { 3488 cout << "finalizing view cells ... "; 3489 FinalizeViewCells(true); 3490 cout << "finished" << endl; 3491 } 3492 3493 return sampleContributions; 3494 } 3495 3496 3497 void VspBspViewCellsManager::MergeViewCells(const VssRayContainer &rays, 3498 const ObjectContainer &objects) 3499 { 3500 int vcSize = 0; 3501 int pvsSize = 0; 3502 3503 //-- merge view cells 3504 cout << "starting merge using " << mPostProcessSamples << " samples ... " << endl; 3505 long startTime = GetTime(); 3506 3507 3508 if (mMergeViewCells) 3509 { 3510 // TODO: should be done BEFORE the ray casting 3511 // compute tree by merging the nodes based on cost heuristics 3512 mViewCellsTree->ConstructMergeTree(rays, objects); 3513 } 3514 else 3515 { 3516 // compute tree by merging the nodes of the spatial hierarchy 3517 ViewCell *root = ConstructSpatialMergeTree(mVspBspTree->GetRoot()); 3518 mViewCellsTree->SetRoot(root); 3519 3520 // compute pvs 3521 ObjectPvs pvs; 3522 UpdatePvsForEvaluation(root, pvs); 3523 } 3524 3525 if (1) 3526 { 3527 char mstats[100]; 3528 ObjectPvs pvs; 3529 3530 Environment::GetSingleton()->GetStringValue("ViewCells.mergeStats", mstats); 3531 mViewCellsTree->ExportStats(mstats); 3532 } 3533 3534 //-- stats and visualizations 3535 cout << "finished merging" << endl; 3536 cout << "merged view cells in " 3537 << TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl; 3538 3539 Debug << "Postprocessing: Merged view cells in " 3540 << TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl << endl; 3541 3542 3543 int savedColorCode = mColorCode; 3544 3545 // get currently active view cell set 3546 ResetViewCells(); 3547 Debug << "\nView cells after merge:\n" << mCurrentViewCellsStats << endl; 3548 3549 //BspLeaf::NewMail(); 3550 if (1) // export merged view cells 3551 { 3552 mColorCode = 0; 3553 Exporter *exporter = Exporter::GetExporter("merged_view_cells.wrl"); 3554 3555 cout << "exporting view cells after merge ... "; 3556 3557 if (exporter) 3558 { 3559 if (0) 3560 exporter->SetWireframe(); 3561 else 3562 exporter->SetFilled(); 3563 3564 ExportViewCellsForViz(exporter); 3565 3566 if (mExportGeometry) 3567 { 3568 Material m; 3569 m.mDiffuseColor = RgbColor(0, 1, 0); 3570 exporter->SetForcedMaterial(m); 3571 exporter->SetFilled(); 3572 3573 exporter->ExportGeometry(objects); 3574 } 3575 3576 delete exporter; 3577 } 3578 cout << "finished" << endl; 3579 } 3580 3581 if (1) // export merged view cells using pvs coding 3582 { 3583 mColorCode = 1; 3584 3585 Exporter *exporter = Exporter::GetExporter("merged_view_cells_pvs.wrl"); 3586 3587 cout << "exporting view cells after merge (pvs size) ... "; 3588 3589 if (exporter) 3590 { 3591 if (0) 3592 exporter->SetWireframe(); 3593 else 3594 exporter->SetFilled(); 3595 3596 ExportViewCellsForViz(exporter); 3597 3598 if (mExportGeometry) 3599 { 3600 Material m; 3601 m.mDiffuseColor = RgbColor(0, 1, 0); 3602 exporter->SetForcedMaterial(m); 3603 exporter->SetFilled(); 3604 3605 exporter->ExportGeometry(objects); 3606 } 3607 3608 delete exporter; 3609 } 3610 cout << "finished" << endl; 3611 } 3612 3613 mColorCode = savedColorCode; 3614 3615 } 3616 3617 3618 bool VspBspViewCellsManager::EqualToSpatialNode(ViewCell *viewCell) const 3619 { 3620 return GetSpatialNode(viewCell) != NULL; 3621 } 3622 3623 3624 BspNode *VspBspViewCellsManager::GetSpatialNode(ViewCell *viewCell) const 3625 { 3626 if (!viewCell->IsLeaf()) 3627 { 3628 BspViewCell *bspVc = dynamic_cast<BspViewCell *>(viewCell); 3629 3630 return bspVc->mLeaf; 3631 } 3632 else 3633 { 3634 ViewCellInterior *interior = dynamic_cast<ViewCellInterior *>(viewCell); 3635 3636 // cannot be node of binary tree 3637 if (interior->mChildren.size() != 2) 3638 return NULL; 3639 3640 ViewCell *left = interior->mChildren[0]; 3641 ViewCell *right = interior->mChildren[1]; 3642 3643 BspNode *leftNode = GetSpatialNode(left); 3644 BspNode *rightNode = GetSpatialNode(right); 3645 3646 if (leftNode && rightNode && leftNode->IsSibling(rightNode)) 3647 { 3648 return leftNode->GetParent(); 3649 } 3650 } 3651 3652 return NULL; 3653 } 3654 3655 3656 void VspBspViewCellsManager::RefineViewCells(const VssRayContainer &rays, 3657 const ObjectContainer &objects) 3658 { 3659 Debug << "render time before refine:" << endl; 3660 mRenderer->RenderScene(); 3661 SimulationStatistics ss; 3662 dynamic_cast<RenderSimulator *>(mRenderer)->GetStatistics(ss); 3663 Debug << ss << endl; 3664 3665 cout << "Refining the merged view cells ... "; 3666 long startTime = GetTime(); 3667 3668 // refining the merged view cells 3669 const int refined = mViewCellsTree->RefineViewCells(rays, objects); 3670 3671 //-- stats and visualizations 3672 cout << "finished" << endl; 3673 cout << "refined " << refined << " view cells in " 3674 << TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl; 3675 3676 Debug << "Postprocessing: refined " << refined << " view cells in " 3677 << TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl << endl; 3678 } 3679 3680 3681 int VspBspViewCellsManager::PostProcess(const ObjectContainer &objects, 3682 const VssRayContainer &rays) 3683 { 3684 if (!ViewCellsConstructed()) 3685 { 3686 Debug << "postprocess error: no view cells constructed" << endl; 3687 return 0; 3688 } 3689 3690 3691 // view cells already finished before post processing step 3692 // (i.e. because they were loaded) 3693 if (mViewCellsFinished) 3694 { 3695 FinalizeViewCells(true); 3696 EvaluateViewCellsStats(); 3697 3698 return 0; 3699 } 3700 3701 // check if new view cells turned invalid 3702 int minPvs, maxPvs; 3703 3704 if (0) 3705 { 3706 minPvs = mMinPvsSize; 3707 maxPvs = mMaxPvsSize; 3708 } 3709 else 3710 { 3711 minPvs = mPruneEmptyViewCells ? 1 : 0; 3712 maxPvs = mMaxPvsSize; 3713 } 3714 3715 Debug << "setting validity, min: " << minPvs << " max: " << maxPvs << endl; 3716 cout << "setting validity, min: " << minPvs << " max: " << maxPvs << endl; 3717 3718 SetValidity(minPvs, maxPvs); 3719 3720 // update valid view space according to valid view cells 3721 if (0) mVspBspTree->ValidateTree(); 3722 3723 // area has to be recomputed 3724 mTotalAreaValid = false; 3725 VssRayContainer postProcessRays; 3726 GetRaySets(rays, mPostProcessSamples, postProcessRays); 3727 3728 Debug << "post processing using " << (int)postProcessRays.size() << " samples" << endl; 3729 3730 3731 // should maybe be done here to allow merge working with area or volume 3732 // and to correct the rendering statistics 3733 if (0) FinalizeViewCells(false); 3734 3735 //-- merge the individual view cells 3736 MergeViewCells(postProcessRays, objects); 3737 3738 3739 // only for debugging purpose: test if the subdivision is valid 3740 TestSubdivision(); 3741 3742 //-- refines the merged view cells 3743 if (0) RefineViewCells(postProcessRays, objects); 3744 3745 3746 //-- render simulation after merge + refine 3747 cout << "\nevaluating bsp view cells render time before compress ... "; 3748 dynamic_cast<RenderSimulator *>(mRenderer)->RenderScene(); 3749 SimulationStatistics ss; 3750 dynamic_cast<RenderSimulator *>(mRenderer)->GetStatistics(ss); 2274 ViewCellContainer::const_iterator it, it_end = mViewCells.end(); 2275 2276 ObjectPvs *newPvs; 2277 newPvs = new ObjectPvs[mViewCells.size()]; 2278 2279 float viewSpaceFilterSize = Magnitude(mViewSpaceBox.Size())*relViewSpaceFilterSize; 2280 float spatialFilterSize = Magnitude(kdTree->GetBox().Size())*relSpatialFilterSize; 3751 2281 3752 3753 cout << " finished" << endl; 3754 cout << ss << endl; 3755 Debug << ss << endl; 3756 3757 3758 //-- compression 3759 if (ViewCellsTreeConstructed() && mCompressViewCells) 3760 { 3761 int pvsEntries = mViewCellsTree->GetNumPvsEntries(mViewCellsTree->GetRoot()); 3762 Debug << "number of entries before compress: " << pvsEntries << endl; 3763 3764 mViewCellsTree->SetViewCellsStorage(ViewCellsTree::COMPRESSED); 3765 3766 pvsEntries = mViewCellsTree->GetNumPvsEntries(mViewCellsTree->GetRoot()); 3767 Debug << "number of entries after compress: " << pvsEntries << endl; 3768 } 3769 3770 3771 // collapse sibling leaves that share the same view cell 3772 if (0) mVspBspTree->CollapseTree(); 3773 3774 // recompute view cell list and statistics 3775 ResetViewCells(); 3776 3777 // compute final meshes and volume / area 3778 if (1) FinalizeViewCells(true); 3779 3780 // write view cells to disc 3781 if (mExportViewCells) 3782 { 3783 char filename[100]; 3784 Environment::GetSingleton()->GetStringValue("ViewCells.filename", filename); 3785 ExportViewCells(filename, mExportPvs, objects); 3786 } 3787 3788 3789 // export bounding boxes 3790 if (mExportBboxesForPvs) 3791 { 3792 char filename[100]; 3793 Environment::GetSingleton()->GetStringValue("ViewCells.boxesFilename", filename); 3794 3795 ExportBoundingBoxes(filename, objects); 3796 } 3797 3798 return 0; 3799 } 3800 3801 3802 int VspBspViewCellsManager::GetType() const 3803 { 3804 return VSP_BSP; 3805 } 3806 3807 3808 ViewCell *VspBspViewCellsManager::ConstructSpatialMergeTree(BspNode *root) 3809 { 3810 // terminate recursion 3811 if (root->IsLeaf()) 3812 { 3813 BspLeaf *leaf = dynamic_cast<BspLeaf *>(root); 3814 leaf->GetViewCell()->SetMergeCost(0.0f); 3815 return leaf->GetViewCell(); 3816 } 3817 3818 3819 BspInterior *interior = dynamic_cast<BspInterior *>(root); 3820 ViewCellInterior *viewCellInterior = new ViewCellInterior(); 3821 3822 // evaluate merge cost for priority traversal 3823 float mergeCost = 1.0f / (float)root->mTimeStamp; 3824 viewCellInterior->SetMergeCost(mergeCost); 3825 3826 float volume = 0; 3827 3828 BspNode *front = interior->GetFront(); 3829 BspNode *back = interior->GetBack(); 3830 3831 3832 ObjectPvs frontPvs, backPvs; 3833 3834 //-- recursivly compute child hierarchies 3835 ViewCell *backVc = ConstructSpatialMergeTree(back); 3836 ViewCell *frontVc = ConstructSpatialMergeTree(front); 3837 3838 3839 viewCellInterior->SetupChildLink(backVc); 3840 viewCellInterior->SetupChildLink(frontVc); 3841 3842 volume += backVc->GetVolume(); 3843 volume += frontVc->GetVolume(); 3844 3845 viewCellInterior->SetVolume(volume); 3846 3847 return viewCellInterior; 3848 } 3849 3850 3851 3852 void VspBspViewCellsManager::UpdatePvsForEvaluation(ViewCell *root, ObjectPvs &pvs) 3853 { 3854 // terminate traversal 3855 if (root->IsLeaf()) 3856 { 3857 pvs = root->GetPvs(); 3858 SetScalarPvsSize(root, root->GetPvs().GetSize()); 3859 3860 return; 3861 } 3862 3863 //-- interior node => propagate pvs up 3864 ViewCellInterior *interior = dynamic_cast<ViewCellInterior *>(root); 3865 interior->GetPvs().Clear(); 2282 int i; 2283 for (i=0, it = mViewCells.begin(); it != it_end; ++ it, ++ i) { 2284 ApplyFilter(*it, 2285 kdTree, 2286 viewSpaceFilterSize, 2287 spatialFilterSize, 2288 newPvs[i] 2289 ); 2290 } 2291 2292 // now replace all pvss 2293 for (i = 0, it = mViewCells.begin(); it != it_end; ++ it, ++ i) { 2294 2295 ObjectPvs &pvs = (*it)->GetPvs(); 3866 2296 pvs.Clear(); 3867 vector<ObjectPvs> pvsList; 3868 3869 ViewCellContainer::const_iterator vit, vit_end = interior->mChildren.end(); 3870 3871 for (vit = interior->mChildren.begin(); vit != vit_end; ++ vit) 3872 { 3873 ObjectPvs objPvs; 3874 3875 //-- recursivly compute child pvss 3876 UpdatePvsForEvaluation(*vit, objPvs); 3877 3878 // store pvs in vector 3879 pvsList.push_back(objPvs); 3880 } 3881 3882 #if 1 3883 3884 Intersectable::NewMail(); 3885 3886 //-- faster way of computing pvs: 3887 // construct merged pvs by adding 3888 // and only those of the next pvs which were not mailed. 3889 // note: sumpdf is not correct!! 3890 vector<ObjectPvs>::iterator oit = pvsList.begin(); 3891 3892 for (vit = interior->mChildren.begin(); vit != vit_end; ++ vit, ++ oit) 3893 { 3894 ObjectPvsMap::iterator pit, pit_end = (*oit).mEntries.end(); 3895 3896 for (pit = (*oit).mEntries.begin(); pit != pit_end; ++ pit) 3897 { 3898 Intersectable *intersect = (*pit).first; 3899 3900 if (!intersect->Mailed()) 3901 { 3902 pvs.AddSample(intersect, (*pit).second.mSumPdf); 3903 intersect->Mail(); 3904 } 3905 } 3906 } 3907 3908 // store pvs in this node 3909 if (mViewCellsTree->ViewCellsStorage() == ViewCellsTree::PVS_IN_INTERIORS) 3910 { 3911 interior->SetPvs(pvs); 3912 } 3913 3914 // set new pvs size 3915 SetScalarPvsSize(interior, pvs.GetSize()); 3916 3917 3918 #else 3919 3920 // really merge cells: slow put sumpdf is correct 3921 viewCellInterior->GetPvs().Merge(backVc->GetPvs()); 3922 viewCellInterior->GetPvs().Merge(frontVc->GetPvs()); 3923 #endif 3924 3925 } 3926 3927 3928 bool VspBspViewCellsManager::GetViewPoint(Vector3 &viewPoint) const 3929 { 3930 if (!ViewCellsConstructed()) 3931 return ViewCellsManager::GetViewPoint(viewPoint); 3932 3933 // TODO: set reasonable limit 3934 const int limit = 20; 3935 3936 for (int i = 0; i < limit; ++ i) 3937 { 3938 viewPoint = mViewSpaceBox.GetRandomPoint(); 3939 if (mVspBspTree->ViewPointValid(viewPoint)) 3940 { 3941 return true; 3942 } 3943 } 3944 3945 Debug << "failed to find valid view point, taking " << viewPoint << endl; 3946 return false; 3947 } 3948 3949 3950 bool VspBspViewCellsManager::ViewPointValid(const Vector3 &viewPoint) const 3951 { 3952 // $$JB -> implemented in viewcellsmanager (slower, but allows dynamic 3953 // validy update in preprocessor for all managers) 3954 return ViewCellsManager::ViewPointValid(viewPoint); 3955 3956 // return mViewSpaceBox.IsInside(viewPoint) && 3957 // mVspBspTree->ViewPointValid(viewPoint); 3958 } 3959 3960 3961 void VspBspViewCellsManager::Visualize(const ObjectContainer &objects, 3962 const VssRayContainer &sampleRays) 3963 { 3964 if (!ViewCellsConstructed()) 3965 return; 3966 3967 VssRayContainer visRays; 3968 GetRaySets(sampleRays, mVisualizationSamples, visRays); 3969 3970 //-- export view cells 3971 if (1) 3972 { // hack pvs 3973 const int savedColorCode = mColorCode; 3974 mColorCode = 1; 3975 3976 Exporter *exporter = Exporter::GetExporter("final_view_cells.wrl"); 3977 3978 if (exporter) 3979 { 3980 cout << "exporting view cells after post process ... "; 3981 3982 if (0) 3983 { 3984 // export view space box 3985 exporter->SetWireframe(); 3986 exporter->ExportBox(mViewSpaceBox); 3987 exporter->SetFilled(); 3988 } 3989 3990 if (mExportGeometry) 3991 { 3992 exporter->ExportGeometry(objects); 3993 } 3994 3995 // export rays 3996 if (1 && mExportRays) 3997 { 3998 exporter->ExportRays(visRays, RgbColor(0, 1, 0)); 3999 } 4000 4001 //exporter->SetFilled(); 4002 4003 // HACK: export without clip plane 4004 const bool b = mUseClipPlaneForViz; 4005 mUseClipPlaneForViz = false; 4006 4007 ExportViewCellsForViz(exporter); 4008 4009 mUseClipPlaneForViz = b; 4010 delete exporter; 4011 4012 cout << "finished" << endl; 4013 } 4014 4015 mColorCode = savedColorCode; 4016 } 4017 4018 4019 if (0) 4020 { 4021 cout << "exporting depth map ... "; 4022 4023 Exporter *exporter = Exporter::GetExporter("depth_map.x3d"); 4024 if (exporter) 4025 { 4026 if (1) 4027 { 4028 exporter->SetWireframe(); 4029 exporter->ExportBox(mViewSpaceBox); 4030 exporter->SetFilled(); 4031 } 4032 4033 if (mExportGeometry) 4034 { 4035 exporter->ExportGeometry(objects); 4036 } 4037 4038 const int maxDepth = mVspBspTree->mBspStats.maxDepth; 4039 4040 ViewCellContainer::const_iterator vit, vit_end = mViewCells.end(); 4041 4042 for (vit = mViewCells.begin(); vit != mViewCells.end(); ++ vit) 4043 { 4044 ViewCell *vc = *vit; 4045 4046 ViewCellContainer leaves; 4047 mViewCellsTree->CollectLeaves(vc, leaves); 4048 4049 ViewCellContainer::const_iterator lit, lit_end = leaves.end(); 4050 4051 for (lit = leaves.begin(); lit != lit_end; ++ lit) 4052 { 4053 BspLeaf *leaf = dynamic_cast<BspViewCell *>(*lit)->mLeaf; 4054 4055 Material m; 4056 4057 float relDepth = (float)leaf->GetDepth() / (float)maxDepth; 4058 m.mDiffuseColor.r = relDepth; 4059 m.mDiffuseColor.g = 0.0f; 4060 m.mDiffuseColor.b = 1.0f - relDepth; 4061 4062 exporter->SetForcedMaterial(m); 4063 4064 4065 BspNodeGeometry geom; 4066 mVspBspTree->ConstructGeometry(leaf, geom); 4067 exporter->ExportPolygons(geom.GetPolys()); 4068 } 4069 } 4070 4071 delete exporter; 4072 } 4073 4074 4075 cout << "finished" << endl; 4076 } 4077 4078 //-- visualization of the BSP splits 4079 bool exportSplits = false; 4080 Environment::GetSingleton()->GetBoolValue("VspBspTree.Visualization.exportSplits", exportSplits); 4081 4082 if (exportSplits) 4083 { 4084 cout << "exporting splits ... "; 4085 ExportSplits(objects, visRays); 4086 cout << "finished" << endl; 4087 } 4088 4089 //-- export single view cells 4090 ExportBspPvs(objects, visRays); 4091 } 4092 4093 4094 void VspBspViewCellsManager::ExportSplits(const ObjectContainer &objects, 4095 const VssRayContainer &rays) 4096 { 4097 Exporter *exporter = Exporter::GetExporter("bsp_splits.x3d"); 4098 4099 if (exporter) 4100 { 4101 Material m; 4102 m.mDiffuseColor = RgbColor(1, 0, 0); 4103 exporter->SetForcedMaterial(m); 4104 exporter->SetWireframe(); 4105 4106 exporter->ExportBspSplits(*mVspBspTree, true); 4107 4108 // take forced material, else big scenes cannot be viewed 4109 m.mDiffuseColor = RgbColor(0, 1, 0); 4110 exporter->SetForcedMaterial(m); 4111 exporter->SetFilled(); 4112 4113 exporter->ResetForcedMaterial(); 4114 4115 // export rays 4116 if (mExportRays) 4117 exporter->ExportRays(rays, RgbColor(1, 1, 0)); 4118 4119 if (mExportGeometry) 4120 exporter->ExportGeometry(objects); 4121 4122 delete exporter; 4123 } 4124 } 4125 4126 4127 void VspBspViewCellsManager::ExportBspPvs(const ObjectContainer &objects, 4128 const VssRayContainer &rays) 4129 { 4130 int leafOut; 4131 Environment::GetSingleton()->GetIntValue("ViewCells.Visualization.maxOutput", leafOut); 4132 4133 ViewCell::NewMail(); 4134 4135 cout << "visualization using " << (int)rays.size() << " samples" << endl; 4136 Debug << "visualization using " << (int)rays.size() << " samples" << endl; 4137 Debug << "\nOutput view cells: " << endl; 4138 4139 const bool sortViewCells = true; 4140 // sort view cells to visualize the largest view cells 4141 if (sortViewCells) 4142 { 4143 //stable_sort(mViewCells.begin(), mViewCells.end(), ViewCell::SmallerPvs); 4144 stable_sort(mViewCells.begin(), mViewCells.end(), ViewCell::LargerRenderCost); 4145 } 4146 4147 int limit = min(leafOut, (int)mViewCells.size()); 4148 4149 int raysOut = 0; 4150 4151 //-- some rays for output 4152 for (int i = 0; i < limit; ++ i) 4153 { 4154 cout << "creating output for view cell " << i << " ... "; 4155 4156 ViewCell *vc; 4157 4158 if (sortViewCells) // largest view cell pvs first 4159 vc = mViewCells[i]; 4160 else 4161 vc = mViewCells[(int)RandomValue(0, (float)mViewCells.size() - 1)]; 4162 4163 ObjectPvs pvs; 4164 mViewCellsTree->GetPvs(vc, pvs); 4165 4166 //bspLeaves[j]->Mail(); 4167 char s[64]; sprintf(s, "bsp-pvs%04d.wrl", i); 4168 Exporter *exporter = Exporter::GetExporter(s); 4169 4170 Debug << i << ": pvs size=" << (int)mViewCellsTree->GetPvsSize(vc) << endl; 4171 4172 //-- export the sample rays 4173 if (mExportRays) 4174 { 4175 // output rays stored with the view cells during subdivision 4176 if (0) 4177 { 4178 VssRayContainer vcRays; 4179 VssRayContainer collectRays; 4180 4181 raysOut = min((int)rays.size(), 100); 4182 4183 // collect intial view cells 4184 ViewCellContainer leaves; 4185 mViewCellsTree->CollectLeaves(vc, leaves); 4186 4187 ViewCellContainer::const_iterator vit, vit_end = leaves.end(); 4188 4189 for (vit = leaves.begin(); vit != vit_end; ++ vit) 4190 { 4191 BspLeaf *vcLeaf = dynamic_cast<BspViewCell *>(*vit)->mLeaf; 4192 4193 VssRayContainer::const_iterator rit, rit_end = vcLeaf->mVssRays.end(); 4194 4195 for (rit = vcLeaf->mVssRays.begin(); rit != rit_end; ++ rit) 4196 { 4197 collectRays.push_back(*rit); 4198 } 4199 } 4200 4201 VssRayContainer::const_iterator rit, rit_end = collectRays.end(); 4202 4203 for (rit = collectRays.begin(); rit != rit_end; ++ rit) 4204 { 4205 float p = RandomValue(0.0f, (float)collectRays.size()); 4206 4207 if (p < raysOut) 4208 vcRays.push_back(*rit); 4209 } 4210 4211 //-- export rays piercing this view cell 4212 exporter->ExportRays(vcRays, RgbColor(1, 1, 1)); 4213 } 4214 4215 // associate new rays with output view cell 4216 if (1) 4217 { 4218 VssRayContainer vcRays; 4219 raysOut = min((int)rays.size(), mVisualizationSamples); 4220 4221 // check whether we can add the current ray to the output rays 4222 for (int k = 0; k < raysOut; ++ k) 4223 { 4224 VssRay *ray = rays[k]; 4225 for (int j = 0; j < (int)ray->mViewCells.size(); ++ j) 4226 { 4227 ViewCell *rayvc = ray->mViewCells[j]; 4228 4229 if (rayvc == vc) 4230 vcRays.push_back(ray); 4231 } 4232 } 4233 4234 //-- export rays piercing this view cell 4235 exporter->ExportRays(vcRays, RgbColor(1, 1, 0)); 4236 } 4237 4238 } 4239 4240 4241 //-- export view cell geometry 4242 exporter->SetWireframe(); 4243 4244 Material m;//= RandomMaterial(); 4245 m.mDiffuseColor = RgbColor(0, 1, 0); 4246 exporter->SetForcedMaterial(m); 4247 4248 ExportViewCellGeometry(exporter, vc); 4249 4250 exporter->SetFilled(); 4251 4252 4253 //-- export pvs 4254 if (1) 4255 { 4256 ObjectPvsMap::const_iterator oit, 4257 oit_end = pvs.mEntries.end(); 4258 4259 Intersectable::NewMail(); 4260 4261 // output PVS of view cell 4262 for (oit = pvs.mEntries.begin(); oit != oit_end; ++ oit) 4263 { 4264 Intersectable *intersect = (*oit).first; 4265 4266 if (!intersect->Mailed()) 4267 { 4268 m = RandomMaterial(); 4269 exporter->SetForcedMaterial(m); 4270 4271 exporter->ExportIntersectable(intersect); 4272 intersect->Mail(); 4273 } 4274 } 4275 } 4276 4277 if (0) 4278 { // export scene geometry 4279 m.mDiffuseColor = RgbColor(1, 0, 0); 4280 exporter->SetForcedMaterial(m); 4281 4282 exporter->ExportGeometry(objects); 4283 } 4284 4285 DEL_PTR(exporter); 4286 cout << "finished" << endl; 4287 } 4288 4289 Debug << endl; 4290 } 4291 4292 4293 int VspBspViewCellsManager::ComputeBoxIntersections(const AxisAlignedBox3 &box, ViewCellContainer &viewCells) const 4294 { 4295 return mVspBspTree->ComputeBoxIntersections(box, viewCells); 4296 } 4297 4298 4299 int VspBspViewCellsManager::CastLineSegment(const Vector3 &origin, 4300 const Vector3 &termination, 4301 ViewCellContainer &viewcells) 4302 { 4303 return mVspBspTree->CastLineSegment(origin, termination, viewcells); 4304 } 4305 4306 4307 void VspBspViewCellsManager::ExportColor(Exporter *exporter, 4308 ViewCell *vc) const 2297 pvs = newPvs[i]; 2298 newPvs[i].Clear(); 2299 } 2300 2301 delete [] newPvs; 2302 } 2303 2304 2305 2306 2307 void 2308 ViewCellsManager::ApplySpatialFilter( 2309 KdTree *kdTree, 2310 const float spatialFilterSize, 2311 ObjectPvs &pvs 2312 ) 2313 { 2314 // now compute a new Pvs by including also objects intersecting the 2315 // extended boxes of visible objects 2316 2317 Intersectable::NewMail(); 2318 2319 std::map<Intersectable *, 2320 PvsData<Intersectable *>, 2321 LtSample<Intersectable *> >::const_iterator oi; 2322 2323 for (oi = pvs.mEntries.begin(); oi != pvs.mEntries.end(); ++oi) { 2324 Intersectable *object = (*oi).first; 2325 object->Mail(); 2326 } 2327 2328 ObjectPvs nPvs; 2329 int nPvsSize=0; 2330 // now go through the pvs again 2331 for (oi = pvs.mEntries.begin(); oi != pvs.mEntries.end(); ++oi) { 2332 Intersectable *object = (*oi).first; 2333 2334 // Vector3 center = object->GetBox().Center(); 2335 // AxisAlignedBox3 box(center - Vector3(spatialFilterSize/2), 2336 // center + Vector3(spatialFilterSize/2)); 2337 2338 AxisAlignedBox3 box = object->GetBox(); 2339 box.Enlarge(Vector3(spatialFilterSize/2)); 2340 2341 ObjectContainer objects; 2342 2343 // $$ warning collect objects takes only unmailed ones! 2344 kdTree->CollectObjects(box, 2345 objects); 2346 // cout<<"collected objects="<<objects.size()<<endl; 2347 ObjectContainer::const_iterator noi = objects.begin(); 2348 for (; noi != objects.end(); ++noi) { 2349 Intersectable *o = *noi; 2350 // $$ JB warning: pdfs are not correct at this point! 2351 nPvs.AddSample(o, Limits::Small); 2352 nPvsSize++; 2353 } 2354 } 2355 // cout<<"nPvs size = "<<nPvsSize<<endl; 2356 pvs.Merge(nPvs); 2357 } 2358 2359 2360 2361 2362 void ViewCellsManager::ExportColor(Exporter *exporter, ViewCell *vc) const 4309 2363 { 4310 2364 const bool vcValid = CheckValidity(vc, mMinPvsSize, mMaxPvsSize); … … 4342 2396 case 2: // merges 4343 2397 { 4344 int lSize = mViewCellsTree->GetNumInitialViewCells(vc);2398 const int lSize = mViewCellsTree->GetNumInitialViewCells(vc); 4345 2399 importance = (float)lSize / (float)mCurrentViewCellsStats.maxLeaves; 4346 2400 } 4347 2401 break; 2402 #if 0 4348 2403 case 3: // merge tree differene 4349 2404 { … … 4353 2408 } 4354 2409 break; 2410 #endif 4355 2411 default: 4356 2412 break; … … 4364 2420 //Debug << "importance: " << importance << endl; 4365 2421 exporter->SetForcedMaterial(m); 2422 } 2423 2424 2425 /**********************************************************************/ 2426 /* BspViewCellsManager implementation */ 2427 /**********************************************************************/ 2428 2429 2430 BspViewCellsManager::BspViewCellsManager(BspTree *bspTree): 2431 ViewCellsManager(), mBspTree(bspTree) 2432 { 2433 Environment::GetSingleton()->GetIntValue("BspTree.Construction.samples", mInitialSamples); 2434 mBspTree->SetViewCellsManager(this); 2435 mBspTree->mViewCellsTree = mViewCellsTree; 2436 } 2437 2438 2439 bool BspViewCellsManager::ViewCellsConstructed() const 2440 { 2441 return mBspTree->GetRoot() != NULL; 2442 } 2443 2444 2445 ViewCell *BspViewCellsManager::GenerateViewCell(Mesh *mesh) const 2446 { 2447 return new BspViewCell(mesh); 2448 } 2449 2450 2451 int BspViewCellsManager::ConstructSubdivision(const ObjectContainer &objects, 2452 const VssRayContainer &rays) 2453 { 2454 // if view cells were already constructed 2455 if (ViewCellsConstructed()) 2456 return 0; 2457 2458 int sampleContributions = 0; 2459 2460 // construct view cells using the collected samples 2461 RayContainer constructionRays; 2462 VssRayContainer savedRays; 2463 2464 const int limit = min(mInitialSamples, (int)rays.size()); 2465 2466 VssRayContainer::const_iterator it, it_end = rays.end(); 2467 2468 const float prop = (float)limit / ((float)rays.size() + Limits::Small); 2469 2470 for (it = rays.begin(); it != it_end; ++ it) 2471 { 2472 if (Random(1.0f) < prop) 2473 constructionRays.push_back(new Ray(*(*it))); 2474 else 2475 savedRays.push_back(*it); 2476 } 2477 2478 if (mViewCells.empty()) 2479 { 2480 // no view cells loaded 2481 mBspTree->Construct(objects, constructionRays, &mViewSpaceBox); 2482 // collect final view cells 2483 mBspTree->CollectViewCells(mViewCells); 2484 } 2485 else 2486 { 2487 mBspTree->Construct(mViewCells); 2488 } 2489 2490 // destroy rays created only for construction 2491 CLEAR_CONTAINER(constructionRays); 2492 2493 Debug << mBspTree->GetStatistics() << endl; 2494 2495 //EvaluateViewCellsStats(); 2496 Debug << "\nView cells after construction:\n" << mCurrentViewCellsStats << endl; 2497 2498 // recast rest of the rays 2499 if (SAMPLE_AFTER_SUBDIVISION) 2500 ComputeSampleContributions(savedRays, true, false); 2501 2502 // real meshes are contructed at this stage 2503 if (0) 2504 { 2505 cout << "finalizing view cells ... "; 2506 FinalizeViewCells(true); 2507 cout << "finished" << endl; 2508 } 2509 2510 return sampleContributions; 2511 } 2512 2513 2514 void BspViewCellsManager::CollectViewCells() 2515 { 2516 // view cells tree constructed 2517 if (!ViewCellsTreeConstructed()) 2518 { 2519 mBspTree->CollectViewCells(mViewCells); 2520 } 2521 else 2522 { 2523 // we can use the view cells tree hierarchy to get the right set 2524 mViewCellsTree->CollectBestViewCellSet(mViewCells, 2525 mNumActiveViewCells); 2526 } 2527 } 2528 2529 2530 float BspViewCellsManager::GetProbability(ViewCell *viewCell) 2531 { 2532 // compute view cell area as subsititute for probability 2533 if (1) 2534 return GetVolume(viewCell) / GetViewSpaceBox().GetVolume(); 2535 else 2536 return GetArea(viewCell) / GetAccVcArea(); 2537 } 2538 2539 2540 2541 int BspViewCellsManager::CastLineSegment(const Vector3 &origin, 2542 const Vector3 &termination, 2543 ViewCellContainer &viewcells) 2544 { 2545 return mBspTree->CastLineSegment(origin, termination, viewcells); 2546 } 2547 2548 2549 int BspViewCellsManager::PostProcess(const ObjectContainer &objects, 2550 const VssRayContainer &rays) 2551 { 2552 if (!ViewCellsConstructed()) 2553 { 2554 Debug << "view cells not constructed" << endl; 2555 return 0; 2556 } 2557 2558 // view cells already finished before post processing step (i.e. because they were loaded) 2559 if (mViewCellsFinished) 2560 { 2561 FinalizeViewCells(true); 2562 EvaluateViewCellsStats(); 2563 2564 return 0; 2565 } 2566 2567 //-- post processing of bsp view cells 2568 2569 int vcSize = 0; 2570 int pvsSize = 0; 2571 2572 //-- merge view cells 2573 cout << "starting post processing using " << mPostProcessSamples << " samples ... "; 2574 long startTime = GetTime(); 2575 2576 VssRayContainer postProcessRays; 2577 GetRaySets(rays, mPostProcessSamples, postProcessRays); 2578 2579 if (mMergeViewCells) 2580 { 2581 cout << "constructing visibility based merge tree" << endl; 2582 mViewCellsTree->ConstructMergeTree(rays, objects); 2583 } 2584 else 2585 { 2586 cout << "constructing spatial merge tree" << endl; 2587 2588 // create spatial merge hierarchy 2589 ViewCell *root = ConstructSpatialMergeTree(mBspTree->GetRoot()); 2590 mViewCellsTree->SetRoot(root); 2591 2592 // compute pvs 2593 ObjectPvs pvs; 2594 UpdatePvsForEvaluation(root, pvs); 2595 } 2596 2597 // export statistics after merge 2598 if (1) 2599 { 2600 char mstats[100]; 2601 Environment::GetSingleton()->GetStringValue("ViewCells.mergeStats", mstats); 2602 mViewCellsTree->ExportStats(mstats); 2603 } 2604 2605 //-- stats and visualizations 2606 cout << "finished" << endl; 2607 cout << "merged view cells in " 2608 << TimeDiff(startTime, GetTime()) * 1e-3 << " secs" << endl; 2609 2610 Debug << "Postprocessing: Merged view cells in " 2611 << TimeDiff(startTime, GetTime()) * 1e-3 << " secs" << endl << endl; 2612 2613 2614 //-- visualization and statistics 2615 // reset view cells and stats 2616 ResetViewCells(); 2617 Debug << "\nView cells after merge:\n" << mCurrentViewCellsStats << endl; 2618 2619 2620 int savedColorCode = mColorCode; 2621 2622 //BspLeaf::NewMail(); 2623 if (1) // export merged view cells 2624 { 2625 mColorCode = 0; 2626 2627 Exporter *exporter = Exporter::GetExporter("merged_view_cells.wrl"); 2628 2629 2630 cout << "exporting view cells after merge ... "; 2631 2632 if (exporter) 2633 { 2634 if (mExportGeometry) 2635 exporter->ExportGeometry(objects); 2636 2637 //exporter->SetWireframe(); 2638 exporter->SetFilled(); 2639 ExportViewCellsForViz(exporter); 2640 2641 2642 delete exporter; 2643 } 2644 cout << "finished" << endl; 2645 } 2646 2647 if (1) // export merged view cells using pvs color coding 2648 { 2649 mColorCode = 1; 2650 2651 Exporter *exporter = Exporter::GetExporter("merged_view_cells_pvs.wrl"); 2652 2653 cout << "exporting view cells after merge (pvs size) ... "; 2654 2655 if (exporter) 2656 { 2657 //exporter->SetWireframe(); 2658 //exporter->SetForcedMaterial(RandomMaterial()); 2659 2660 if (mExportGeometry) 2661 exporter->ExportGeometry(objects); 2662 2663 //exporter->SetWireframe(); 2664 exporter->SetFilled(); 2665 ExportViewCellsForViz(exporter); 2666 2667 delete exporter; 2668 } 2669 cout << "finished" << endl; 2670 } 2671 2672 2673 // only for testing 2674 TestSubdivision(); 2675 2676 mColorCode = savedColorCode; 2677 2678 // compute final meshes and volume / area 2679 if (1) FinalizeViewCells(true); 2680 2681 // write view cells to disc 2682 if (mExportViewCells) 2683 { 2684 char filename[100]; 2685 Environment::GetSingleton()->GetStringValue("ViewCells.filename", filename); 2686 ExportViewCells(filename, mExportPvs, objects); 2687 } 2688 2689 // export bounding boxes 2690 if (0 && mExportBboxesForPvs) 2691 { 2692 char filename[100]; 2693 Environment::GetSingleton()->GetStringValue("ViewCells.boxesFilename", filename); 2694 ExportBoundingBoxes(filename, objects); 2695 } 2696 2697 2698 return 0; 2699 } 2700 2701 2702 BspViewCellsManager::~BspViewCellsManager() 2703 { 2704 } 2705 2706 2707 int BspViewCellsManager::GetType() const 2708 { 2709 return BSP; 2710 } 2711 2712 2713 void BspViewCellsManager::Visualize(const ObjectContainer &objects, 2714 const VssRayContainer &sampleRays) 2715 { 2716 if (!ViewCellsConstructed()) 2717 return; 2718 2719 int savedColorCode = mColorCode; 2720 2721 2722 if (1) // export final view cells 2723 { 2724 mColorCode = 1; // hack color code 2725 Exporter *exporter = Exporter::GetExporter("final_view_cells.x3d"); 2726 2727 cout << "exporting view cells after merge (pvs size) ... "; 2728 2729 if (exporter) 2730 { 2731 //exporter->SetWireframe(); 2732 2733 if (mExportGeometry) 2734 exporter->ExportGeometry(objects); 2735 2736 //exporter->SetFilled(); 2737 const bool b = mUseClipPlaneForViz; 2738 mUseClipPlaneForViz = false; 2739 2740 ExportViewCellsForViz(exporter); 2741 2742 mUseClipPlaneForViz = b; 2743 delete exporter; 2744 } 2745 cout << "finished" << endl; 2746 } 2747 2748 mColorCode = savedColorCode; 2749 2750 //-- visualization of the BSP splits 2751 bool exportSplits = false; 2752 Environment::GetSingleton()->GetBoolValue("BspTree.Visualization.exportSplits", exportSplits); 2753 2754 if (exportSplits) 2755 { 2756 cout << "exporting splits ... "; 2757 ExportSplits(objects); 2758 cout << "finished" << endl; 2759 } 2760 2761 // export single view cells 2762 ExportBspPvs(objects); 2763 } 2764 2765 2766 void BspViewCellsManager::ExportSplits(const ObjectContainer &objects) 2767 { 2768 Exporter *exporter = Exporter::GetExporter("bsp_splits.x3d"); 2769 2770 if (exporter) 2771 { 2772 //exporter->SetFilled(); 2773 2774 if (mExportGeometry) 2775 exporter->ExportGeometry(objects); 2776 2777 Material m; 2778 m.mDiffuseColor = RgbColor(1, 0, 0); 2779 exporter->SetForcedMaterial(m); 2780 exporter->SetWireframe(); 2781 2782 exporter->ExportBspSplits(*mBspTree, true); 2783 2784 //NOTE: take forced material, else big scenes cannot be viewed 2785 m.mDiffuseColor = RgbColor(0, 1, 0); 2786 exporter->SetForcedMaterial(m); 2787 //exporter->ResetForcedMaterial(); 2788 2789 delete exporter; 2790 } 2791 } 2792 2793 2794 void BspViewCellsManager::ExportBspPvs(const ObjectContainer &objects) 2795 { 2796 const int leafOut = 10; 2797 2798 ViewCell::NewMail(); 2799 2800 //-- some rays for output 2801 const int raysOut = min((int)mBspRays.size(), mVisualizationSamples); 2802 2803 cout << "visualization using " << mVisualizationSamples << " samples" << endl; 2804 Debug << "\nOutput view cells: " << endl; 2805 2806 // sort view cells in order to find the largest view cells 2807 if (0) 2808 stable_sort(mViewCells.begin(), mViewCells.end(), ViewCell::SmallerPvs); 2809 2810 int limit = min(leafOut, (int)mViewCells.size()); 2811 2812 for (int i = 0; i < limit; ++ i) 2813 { 2814 cout << "creating output for view cell " << i << " ... "; 2815 VssRayContainer vcRays; 2816 Intersectable::NewMail(); 2817 ViewCell *vc; 2818 2819 if (0) 2820 vc = mViewCells[i]; 2821 else 2822 vc = mViewCells[Random((int)mViewCells.size())]; 2823 2824 cout << "creating output for view cell " << i << " ... "; 2825 2826 if(0) 2827 { 2828 // check whether we can add the current ray to the output rays 2829 for (int k = 0; k < raysOut; ++ k) 2830 { 2831 BspRay *ray = mBspRays[k]; 2832 for (int j = 0; j < (int)ray->intersections.size(); ++ j) 2833 { 2834 BspLeaf *leaf = ray->intersections[j].mLeaf; 2835 if (vc == leaf->GetViewCell()) 2836 vcRays.push_back(ray->vssRay); 2837 } 2838 } 2839 } 2840 2841 //bspLeaves[j]->Mail(); 2842 char s[64]; sprintf(s, "bsp-pvs%04d.x3d", i); 2843 2844 Exporter *exporter = Exporter::GetExporter(s); 2845 2846 exporter->SetWireframe(); 2847 2848 Material m;//= RandomMaterial(); 2849 m.mDiffuseColor = RgbColor(0, 1, 0); 2850 exporter->SetForcedMaterial(m); 2851 2852 ExportViewCellGeometry(exporter, vc); 2853 2854 // export rays piercing this view cell 2855 exporter->ExportRays(vcRays, RgbColor(0, 1, 0)); 2856 2857 m.mDiffuseColor = RgbColor(1, 0, 0); 2858 exporter->SetForcedMaterial(m); 2859 2860 ObjectPvsMap::const_iterator it, 2861 it_end = vc->GetPvs().mEntries.end(); 2862 2863 exporter->SetFilled(); 2864 2865 // output PVS of view cell 2866 for (it = vc->GetPvs().mEntries.begin(); it != it_end; ++ it) 2867 { 2868 Intersectable *intersect = (*it).first; 2869 2870 if (!intersect->Mailed()) 2871 { 2872 Material m = RandomMaterial(); 2873 exporter->SetForcedMaterial(m); 2874 2875 exporter->ExportIntersectable(intersect); 2876 intersect->Mail(); 2877 } 2878 } 2879 2880 DEL_PTR(exporter); 2881 cout << "finished" << endl; 2882 } 2883 2884 Debug << endl; 2885 } 2886 2887 2888 void BspViewCellsManager::TestSubdivision() 2889 { 2890 ViewCellContainer leaves; 2891 mViewCellsTree->CollectLeaves(mViewCellsTree->GetRoot(), leaves); 2892 2893 ViewCellContainer::const_iterator it, it_end = leaves.end(); 2894 2895 const float vol = mViewSpaceBox.GetVolume(); 2896 float subdivVol = 0; 2897 float newVol = 0; 2898 2899 for (it = leaves.begin(); it != it_end; ++ it) 2900 { 2901 BspNodeGeometry geom; 2902 BspLeaf *leaf = dynamic_cast<BspViewCell *>(*it)->mLeaf; 2903 mBspTree->ConstructGeometry(leaf, geom); 2904 2905 const float lVol = geom.GetVolume(); 2906 2907 newVol += lVol; 2908 subdivVol += (*it)->GetVolume(); 2909 2910 float thres = 0.9f; 2911 if ((lVol < ((*it)->GetVolume() * thres)) || 2912 (lVol * thres > ((*it)->GetVolume()))) 2913 Debug << "warning: " << lVol << " " << (*it)->GetVolume() << endl; 2914 } 2915 2916 Debug << "exact volume: " << vol << endl; 2917 Debug << "subdivision volume: " << subdivVol << endl; 2918 Debug << "new volume: " << newVol << endl; 2919 } 2920 2921 2922 void BspViewCellsManager::ExportViewCellGeometry(Exporter *exporter, 2923 ViewCell *vc, 2924 const Plane3 *clipPlane) const 2925 { 2926 if (vc->GetMesh()) 2927 { 2928 exporter->ExportMesh(vc->GetMesh()); 2929 2930 return; 2931 } 2932 2933 2934 if (clipPlane) 2935 { 2936 ViewCellContainer leaves; 2937 mViewCellsTree->CollectLeaves(vc, leaves); 2938 ViewCellContainer::const_iterator it, it_end = leaves.end(); 2939 2940 for (it = leaves.begin(); it != it_end; ++ it) 2941 { 2942 BspNodeGeometry geom; 2943 2944 BspNodeGeometry front; 2945 BspNodeGeometry back; 2946 2947 BspLeaf *leaf = dynamic_cast<BspViewCell *>(*it)->mLeaf; 2948 mBspTree->ConstructGeometry(leaf, geom); 2949 2950 const float eps = 0.00000001f; 2951 const int cf = geom.Side(*clipPlane, eps); 2952 2953 if (cf == -1) 2954 { 2955 exporter->ExportPolygons(geom.GetPolys()); 2956 } 2957 else if (cf == 0) 2958 { 2959 geom.SplitGeometry(front, 2960 back, 2961 *clipPlane, 2962 mViewSpaceBox, 2963 eps); 2964 2965 //Debug << "geo size: " << geom.Size() << endl; 2966 //Debug << "size b: " << back.Size() << " f: " << front.Size() << endl; 2967 if (back.Valid()) 2968 { 2969 exporter->ExportPolygons(back.GetPolys()); 2970 } 2971 } 2972 } 2973 } 2974 else 2975 { 2976 BspNodeGeometry geom; 2977 mBspTree->ConstructGeometry(vc, geom); 2978 2979 exporter->ExportPolygons(geom.GetPolys()); 2980 } 2981 } 2982 2983 2984 void BspViewCellsManager::CreateMesh(ViewCell *vc) 2985 { 2986 // delete previous mesh 2987 ///DEL_PTR(vc->GetMesh()); 2988 BspNodeGeometry geom; 2989 mBspTree->ConstructGeometry(vc, geom); 2990 2991 Mesh *mesh = MeshManager::GetSingleton()->CreateResource(); 2992 2993 IncludeNodeGeomInMesh(geom, *mesh); 2994 vc->SetMesh(mesh); 2995 } 2996 2997 2998 void BspViewCellsManager::Finalize(ViewCell *viewCell, 2999 const bool createMesh) 3000 { 3001 float area = 0; 3002 float volume = 0; 3003 3004 ViewCellContainer leaves; 3005 mViewCellsTree->CollectLeaves(viewCell, leaves); 3006 3007 ViewCellContainer::const_iterator it, it_end = leaves.end(); 3008 3009 for (it = leaves.begin(); it != it_end; ++ it) 3010 { 3011 BspNodeGeometry geom; 3012 BspLeaf *leaf = dynamic_cast<BspViewCell *>(*it)->mLeaf; 3013 mBspTree->ConstructGeometry(leaf, geom); 3014 3015 const float lVol = geom.GetVolume(); 3016 const float lArea = geom.GetArea(); 3017 3018 //(*it)->SetVolume(vol); 3019 //(*it)->SetArea(area); 3020 3021 area += lArea; 3022 volume += lVol; 3023 3024 CreateMesh(*it); 3025 } 3026 3027 viewCell->SetVolume(volume); 3028 viewCell->SetArea(area); 3029 } 3030 3031 3032 ViewCell *BspViewCellsManager::GetViewCell(const Vector3 &point, const bool active) const 3033 { 3034 if (!ViewCellsConstructed()) 3035 return NULL; 3036 3037 if (!mViewSpaceBox.IsInside(point)) 3038 return NULL; 3039 3040 return mBspTree->GetViewCell(point); 3041 } 3042 3043 3044 void BspViewCellsManager::CollectMergeCandidates(const VssRayContainer &rays, 3045 vector<MergeCandidate> &candidates) 3046 { 3047 cout << "collecting merge candidates ... " << endl; 3048 3049 if (mUseRaysForMerge) 3050 { 3051 mBspTree->CollectMergeCandidates(rays, candidates); 3052 } 3053 else 3054 { 3055 vector<BspLeaf *> leaves; 3056 mBspTree->CollectLeaves(leaves); 3057 mBspTree->CollectMergeCandidates(leaves, candidates); 3058 } 3059 3060 cout << "fininshed collecting candidates" << endl; 3061 } 3062 3063 3064 3065 bool BspViewCellsManager::ExportViewCells(const string filename, const bool exportPvs, const ObjectContainer &objects) 3066 { 3067 #if STILL_HAS_TODO 3068 cout << "exporting view cells to xml ... "; 3069 std::ofstream stream; 3070 3071 // for output we need unique ids for each view cell 3072 CreateUniqueViewCellIds(); 3073 3074 3075 stream.open(filename.c_str()); 3076 stream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"<<endl; 3077 stream << "<VisibilitySolution>" << endl; 3078 3079 //-- the view space bounding box 3080 stream << "<ViewSpaceBox" 3081 << " min=\"" << mViewSpaceBox.Min().x << " " << mViewSpaceBox.Min().y << " " << mViewSpaceBox.Min().z << "\"" 3082 << " max=\"" << mViewSpaceBox.Max().x << " " << mViewSpaceBox.Max().y << " " << mViewSpaceBox.Max().z << "\" />" << endl; 3083 3084 //-- the type of the view cells hierarchy 3085 3086 // NOTE: load in vsp bsp here because bsp and vsp bsp can use same tree and vsp bsp is bug free 3087 stream << "<Hierarchy name=\"vspBspTree\" >" << endl; 3088 3089 //-- load the view cells itself, i.e., the ids and the pvs 3090 stream << "<ViewCells>" << endl; 3091 3092 mViewCellsTree->Export(stream, exportPvs); 3093 3094 stream << "</ViewCells>" << endl; 3095 3096 //-- load the hierarchy 3097 stream << "<Hierarchy>" << endl; 3098 mBspTree->Export(stream); 3099 stream << endl << "</Hierarchy>" << endl; 3100 3101 stream << "</VisibilitySolution>" << endl; 3102 stream.close(); 3103 3104 cout << "finished" << endl; 3105 #endif 3106 return true; 3107 } 3108 3109 3110 ViewCell *BspViewCellsManager::ConstructSpatialMergeTree(BspNode *root) 3111 { 3112 // terminate recursion 3113 if (root->IsLeaf()) 3114 { 3115 BspLeaf *leaf = dynamic_cast<BspLeaf *>(root); 3116 leaf->GetViewCell()->SetMergeCost(0.0f); 3117 return leaf->GetViewCell(); 3118 } 3119 3120 BspInterior *interior = dynamic_cast<BspInterior *>(root); 3121 ViewCellInterior *viewCellInterior = new ViewCellInterior(); 3122 3123 // evaluate merge cost for priority traversal 3124 float mergeCost = 1.0f / (float)root->mTimeStamp; 3125 viewCellInterior->SetMergeCost(mergeCost); 3126 3127 float volume = 0; 3128 3129 BspNode *front = interior->GetFront(); 3130 BspNode *back = interior->GetBack(); 3131 3132 3133 //-- recursivly compute child hierarchies 3134 ViewCell *backVc = ConstructSpatialMergeTree(back); 3135 ViewCell *frontVc = ConstructSpatialMergeTree(front); 3136 3137 3138 viewCellInterior->SetupChildLink(backVc); 3139 viewCellInterior->SetupChildLink(frontVc); 3140 3141 volume += backVc->GetVolume(); 3142 volume += frontVc->GetVolume(); 3143 3144 viewCellInterior->SetVolume(volume); 3145 3146 return viewCellInterior; 3147 } 3148 3149 3150 void BspViewCellsManager::UpdatePvsForEvaluation(ViewCell *root, ObjectPvs &pvs) 3151 { 3152 // terminate traversal 3153 if (root->IsLeaf()) 3154 { 3155 pvs = root->GetPvs(); 3156 SetScalarPvsSize(root, pvs.GetSize()); 3157 3158 return; 3159 } 3160 3161 ViewCellInterior *interior = dynamic_cast<ViewCellInterior *>(root); 3162 ViewCellContainer::const_iterator vit, vit_end = interior->mChildren.end(); 3163 3164 vector<ObjectPvs> pvsList; 3165 3166 3167 for (vit = interior->mChildren.begin(); vit != vit_end; ++ vit) 3168 { 3169 ObjectPvs objPvs; 3170 3171 //-- recursivly compute child pvss 3172 UpdatePvsForEvaluation(*vit, objPvs); 3173 3174 // store pvs in vector 3175 pvsList.push_back(objPvs); 3176 } 3177 3178 #if 1 3179 Intersectable::NewMail(); 3180 3181 //-- faster way of computing pvs: 3182 // construct merged pvs by adding 3183 // and only those of the next pvs which were not mailed. 3184 // note: sumpdf is not correct!! 3185 vector<ObjectPvs>::iterator oit = pvsList.begin(); 3186 3187 for (vit = interior->mChildren.begin(); vit != vit_end; ++ vit, ++ oit) 3188 { 3189 3190 ObjectPvsMap::iterator pit, pit_end = (*oit).mEntries.end(); 3191 3192 for (pit = (*oit).mEntries.begin(); pit != pit_end; ++ pit) 3193 { 3194 3195 Intersectable *intersect = (*pit).first; 3196 3197 if (!intersect->Mailed()) 3198 { 3199 pvs.AddSample(intersect, (*pit).second.mSumPdf); 3200 intersect->Mail(); 3201 } 3202 } 3203 } 3204 3205 // store pvs in this node 3206 if (mViewCellsTree->ViewCellsStorage() == ViewCellsTree::PVS_IN_INTERIORS) 3207 { 3208 interior->SetPvs(pvs); 3209 } 3210 3211 // set new pvs size 3212 SetScalarPvsSize(interior, pvs.GetSize()); 3213 3214 #else 3215 // really merge cells: slow nut sumpdf is correct 3216 ViewCellInterior *viewCellInterior = new ViewCellInterior(); 3217 3218 viewCellInterior->GetPvs().Merge(backVc->GetPvs()); 3219 viewCellInterior->GetPvs().Merge(frontVc->GetPvs()); 3220 #endif 3221 3222 } 3223 3224 /************************************************************************/ 3225 /* KdViewCellsManager implementation */ 3226 /************************************************************************/ 3227 3228 3229 3230 KdViewCellsManager::KdViewCellsManager(KdTree *kdTree): 3231 ViewCellsManager(), mKdTree(kdTree), mKdPvsDepth(100) 3232 { 3233 } 3234 3235 3236 float KdViewCellsManager::GetProbability(ViewCell *viewCell) 3237 { 3238 // compute view cell area / volume as subsititute for probability 3239 if (0) 3240 return GetArea(viewCell) / GetViewSpaceBox().SurfaceArea(); 3241 else 3242 return GetVolume(viewCell) / GetViewSpaceBox().GetVolume(); 3243 } 3244 3245 3246 3247 3248 void KdViewCellsManager::CollectViewCells() 3249 { 3250 //mKdTree->CollectViewCells(mViewCells); TODO 3251 } 3252 3253 3254 int KdViewCellsManager::ConstructSubdivision(const ObjectContainer &objects, 3255 const VssRayContainer &rays) 3256 { 3257 // if view cells already constructed 3258 if (ViewCellsConstructed()) 3259 return 0; 3260 3261 mKdTree->Construct(); 3262 3263 mTotalAreaValid = false; 3264 // create the view cells 3265 mKdTree->CreateAndCollectViewCells(mViewCells); 3266 3267 // cast rays 3268 ComputeSampleContributions(rays, true, false); 3269 3270 EvaluateViewCellsStats(); 3271 Debug << "\nView cells after construction:\n" << mCurrentViewCellsStats << endl; 3272 3273 return 0; 3274 } 3275 3276 3277 bool KdViewCellsManager::ViewCellsConstructed() const 3278 { 3279 return mKdTree->GetRoot() != NULL; 3280 } 3281 3282 3283 int KdViewCellsManager::PostProcess(const ObjectContainer &objects, 3284 const VssRayContainer &rays) 3285 { 3286 return 0; 3287 } 3288 3289 3290 void KdViewCellsManager::Visualize(const ObjectContainer &objects, 3291 const VssRayContainer &sampleRays) 3292 { 3293 if (!ViewCellsConstructed()) 3294 return; 3295 3296 // using view cells instead of the kd PVS of objects 3297 const bool useViewCells = true; 3298 bool exportRays = false; 3299 3300 int limit = min(mVisualizationSamples, (int)sampleRays.size()); 3301 const int pvsOut = min((int)objects.size(), 10); 3302 VssRayContainer *rays = new VssRayContainer[pvsOut]; 3303 3304 if (useViewCells) 3305 { 3306 const int leafOut = 10; 3307 3308 ViewCell::NewMail(); 3309 3310 //-- some rays for output 3311 const int raysOut = min((int)sampleRays.size(), mVisualizationSamples); 3312 Debug << "visualization using " << raysOut << " samples" << endl; 3313 3314 //-- some random view cells and rays for output 3315 vector<KdLeaf *> kdLeaves; 3316 3317 for (int i = 0; i < leafOut; ++ i) 3318 kdLeaves.push_back(dynamic_cast<KdLeaf *>(mKdTree->GetRandomLeaf())); 3319 3320 for (int i = 0; i < kdLeaves.size(); ++ i) 3321 { 3322 KdLeaf *leaf = kdLeaves[i]; 3323 RayContainer vcRays; 3324 3325 cout << "creating output for view cell " << i << " ... "; 3326 #if 0 3327 // check whether we can add the current ray to the output rays 3328 for (int k = 0; k < raysOut; ++ k) 3329 { 3330 Ray *ray = sampleRays[k]; 3331 3332 for (int j = 0; j < (int)ray->bspIntersections.size(); ++ j) 3333 { 3334 BspLeaf *leaf2 = ray->bspIntersections[j].mLeaf; 3335 3336 if (leaf->GetViewCell() == leaf2->GetViewCell()) 3337 { 3338 vcRays.push_back(ray); 3339 } 3340 } 3341 } 3342 #endif 3343 Intersectable::NewMail(); 3344 3345 ViewCell *vc = leaf->mViewCell; 3346 3347 //bspLeaves[j]->Mail(); 3348 char s[64]; sprintf(s, "kd-pvs%04d.x3d", i); 3349 3350 Exporter *exporter = Exporter::GetExporter(s); 3351 exporter->SetFilled(); 3352 3353 exporter->SetWireframe(); 3354 //exporter->SetFilled(); 3355 3356 Material m;//= RandomMaterial(); 3357 m.mDiffuseColor = RgbColor(1, 1, 0); 3358 exporter->SetForcedMaterial(m); 3359 3360 AxisAlignedBox3 box = mKdTree->GetBox(leaf); 3361 exporter->ExportBox(box); 3362 3363 // export rays piercing this view cell 3364 exporter->ExportRays(vcRays, 1000, RgbColor(0, 1, 0)); 3365 3366 m.mDiffuseColor = RgbColor(1, 0, 0); 3367 exporter->SetForcedMaterial(m); 3368 3369 // exporter->SetWireframe(); 3370 exporter->SetFilled(); 3371 3372 ObjectPvsMap::iterator it, it_end = vc->GetPvs().mEntries.end(); 3373 // -- output PVS of view cell 3374 for (it = vc->GetPvs().mEntries.begin(); it != it_end; ++ it) 3375 { 3376 Intersectable *intersect = (*it).first; 3377 if (!intersect->Mailed()) 3378 { 3379 exporter->ExportIntersectable(intersect); 3380 intersect->Mail(); 3381 } 3382 } 3383 3384 DEL_PTR(exporter); 3385 cout << "finished" << endl; 3386 } 3387 3388 DEL_PTR(rays); 3389 } 3390 else // using kd PVS of objects 3391 { 3392 for (int i = 0; i < limit; ++ i) 3393 { 3394 VssRay *ray = sampleRays[i]; 3395 3396 // check whether we can add this to the rays 3397 for (int j = 0; j < pvsOut; j++) 3398 { 3399 if (objects[j] == ray->mTerminationObject) 3400 { 3401 rays[j].push_back(ray); 3402 } 3403 } 3404 } 3405 3406 if (exportRays) 3407 { 3408 Exporter *exporter = NULL; 3409 exporter = Exporter::GetExporter("sample-rays.x3d"); 3410 exporter->SetWireframe(); 3411 exporter->ExportKdTree(*mKdTree); 3412 3413 for (i = 0; i < pvsOut; i++) 3414 exporter->ExportRays(rays[i], RgbColor(1, 0, 0)); 3415 3416 exporter->SetFilled(); 3417 3418 delete exporter; 3419 } 3420 3421 for (int k=0; k < pvsOut; k++) 3422 { 3423 Intersectable *object = objects[k]; 3424 char s[64]; 3425 sprintf(s, "sample-pvs%04d.x3d", k); 3426 3427 Exporter *exporter = Exporter::GetExporter(s); 3428 exporter->SetWireframe(); 3429 3430 KdPvsMap::iterator i = object->mKdPvs.mEntries.begin(); 3431 Intersectable::NewMail(); 3432 3433 // avoid adding the object to the list 3434 object->Mail(); 3435 ObjectContainer visibleObjects; 3436 3437 for (; i != object->mKdPvs.mEntries.end(); i++) 3438 { 3439 KdNode *node = (*i).first; 3440 exporter->ExportBox(mKdTree->GetBox(node)); 3441 3442 mKdTree->CollectObjects(node, visibleObjects); 3443 } 3444 3445 exporter->ExportRays(rays[k], RgbColor(0, 1, 0)); 3446 exporter->SetFilled(); 3447 3448 for (int j = 0; j < visibleObjects.size(); j++) 3449 exporter->ExportIntersectable(visibleObjects[j]); 3450 3451 Material m; 3452 m.mDiffuseColor = RgbColor(1, 0, 0); 3453 exporter->SetForcedMaterial(m); 3454 exporter->ExportIntersectable(object); 3455 3456 delete exporter; 3457 } 3458 } 3459 } 3460 3461 3462 ViewCell *KdViewCellsManager::GenerateViewCell(Mesh *mesh) const 3463 { 3464 return new KdViewCell(mesh); 3465 } 3466 3467 3468 void KdViewCellsManager::ExportViewCellGeometry(Exporter *exporter, 3469 ViewCell *vc, 3470 const Plane3 *clipPlane) const 3471 { 3472 ViewCellContainer leaves; 3473 3474 mViewCellsTree->CollectLeaves(vc, leaves); 3475 ViewCellContainer::const_iterator it, it_end = leaves.end(); 3476 3477 for (it = leaves.begin(); it != it_end; ++ it) 3478 { 3479 KdViewCell *kdVc = dynamic_cast<KdViewCell *>(*it); 3480 3481 exporter->ExportBox(mKdTree->GetBox(kdVc->mLeaf)); 3482 } 3483 } 3484 3485 3486 int KdViewCellsManager::GetType() const 3487 { 3488 return ViewCellsManager::KD; 3489 } 3490 3491 3492 3493 KdNode *KdViewCellsManager::GetNodeForPvs(KdLeaf *leaf) 3494 { 3495 KdNode *node = leaf; 3496 3497 while (node->mParent && node->mDepth > mKdPvsDepth) 3498 node = node->mParent; 3499 return node; 3500 } 3501 3502 int KdViewCellsManager::CastLineSegment(const Vector3 &origin, 3503 const Vector3 &termination, 3504 ViewCellContainer &viewcells) 3505 { 3506 return mKdTree->CastLineSegment(origin, termination, viewcells); 3507 } 3508 3509 3510 void KdViewCellsManager::CreateMesh(ViewCell *vc) 3511 { 3512 // TODO 3513 } 3514 3515 3516 3517 void KdViewCellsManager::CollectMergeCandidates(const VssRayContainer &rays, 3518 vector<MergeCandidate> &candidates) 3519 { 3520 // TODO 3521 } 3522 3523 3524 3525 3526 /**************************************************************************/ 3527 /* VspBspViewCellsManager implementation */ 3528 /**************************************************************************/ 3529 3530 3531 VspBspViewCellsManager::VspBspViewCellsManager(VspBspTree *vspBspTree): 3532 ViewCellsManager(), mVspBspTree(vspBspTree) 3533 { 3534 Environment::GetSingleton()->GetIntValue("VspBspTree.Construction.samples", mInitialSamples); 3535 mVspBspTree->SetViewCellsManager(this); 3536 mVspBspTree->mViewCellsTree = mViewCellsTree; 3537 } 3538 3539 3540 VspBspViewCellsManager::~VspBspViewCellsManager() 3541 { 3542 } 3543 3544 3545 float VspBspViewCellsManager::GetProbability(ViewCell *viewCell) 3546 { 3547 if (0 && mVspBspTree->mUseAreaForPvs) 3548 return GetArea(viewCell) / GetAccVcArea(); 3549 else 3550 return GetVolume(viewCell) / mViewSpaceBox.GetVolume(); 3551 } 3552 3553 3554 void VspBspViewCellsManager::CollectViewCells() 3555 { 3556 // view cells tree constructed 3557 if (!ViewCellsTreeConstructed()) 3558 { 3559 mVspBspTree->CollectViewCells(mViewCells, false); 3560 } 3561 else 3562 { // we can use the view cells tree hierarchy to get the right set 3563 mViewCellsTree->CollectBestViewCellSet(mViewCells, mNumActiveViewCells); 3564 } 3565 } 3566 3567 3568 void VspBspViewCellsManager::CollectMergeCandidates(const VssRayContainer &rays, 3569 vector<MergeCandidate> &candidates) 3570 { 3571 cout << "collecting merge candidates ... " << endl; 3572 3573 if (mUseRaysForMerge) 3574 { 3575 mVspBspTree->CollectMergeCandidates(rays, candidates); 3576 } 3577 else 3578 { 3579 vector<BspLeaf *> leaves; 3580 mVspBspTree->CollectLeaves(leaves); 3581 3582 mVspBspTree->CollectMergeCandidates(leaves, candidates); 3583 } 3584 3585 cout << "fininshed collecting candidates" << endl; 3586 } 3587 3588 3589 bool VspBspViewCellsManager::ViewCellsConstructed() const 3590 { 3591 return mVspBspTree->GetRoot() != NULL; 3592 } 3593 3594 3595 ViewCell *VspBspViewCellsManager::GenerateViewCell(Mesh *mesh) const 3596 { 3597 return new BspViewCell(mesh); 3598 } 3599 3600 3601 int VspBspViewCellsManager::ConstructSubdivision(const ObjectContainer &objects, 3602 const VssRayContainer &rays) 3603 { 3604 mMaxPvsSize = (int)(mMaxPvsRatio * (float)objects.size()); 3605 3606 // if view cells were already constructed 3607 if (ViewCellsConstructed()) 3608 return 0; 3609 3610 int sampleContributions = 0; 3611 3612 VssRayContainer sampleRays; 3613 3614 int limit = min (mInitialSamples, (int)rays.size()); 3615 3616 VssRayContainer constructionRays; 3617 VssRayContainer savedRays; 3618 3619 Debug << "samples used for vsp bsp subdivision: " << mInitialSamples 3620 << ", actual rays: " << (int)rays.size() << endl; 3621 3622 GetRaySets(rays, mInitialSamples, constructionRays, &savedRays); 3623 3624 Debug << "initial rays: " << (int)constructionRays.size() << endl; 3625 Debug << "saved rays: " << (int)savedRays.size() << endl; 3626 3627 long startTime; 3628 3629 if (1) 3630 mVspBspTree->Construct(constructionRays, &mViewSpaceBox); 3631 else 3632 mVspBspTree->Construct(rays, &mViewSpaceBox); 3633 3634 // collapse invalid regions 3635 cout << "collapsing invalid tree regions ... "; 3636 startTime = GetTime(); 3637 const int collapsedLeaves = mVspBspTree->CollapseTree(); 3638 Debug << "collapsed in " << TimeDiff(startTime, GetTime()) * 1e-3 3639 << " seconds" << endl; 3640 3641 cout << "finished" << endl; 3642 3643 //-- stats 3644 Debug << mVspBspTree->GetStatistics() << endl; 3645 3646 ResetViewCells(); 3647 Debug << "\nView cells after construction:\n" << mCurrentViewCellsStats << endl; 3648 3649 3650 startTime = GetTime(); 3651 3652 cout << "Computing remaining ray contributions ... "; 3653 3654 // recast rest of rays 3655 if (SAMPLE_AFTER_SUBDIVISION) 3656 ComputeSampleContributions(savedRays, true, false); 3657 3658 cout << "finished" << endl; 3659 3660 Debug << "Computed remaining ray contribution in " << TimeDiff(startTime, GetTime()) * 1e-3 3661 << " secs" << endl; 3662 3663 cout << "construction finished" << endl; 3664 3665 // real meshes are contructed at this stage 3666 if (0) 3667 { 3668 cout << "finalizing view cells ... "; 3669 FinalizeViewCells(true); 3670 cout << "finished" << endl; 3671 } 3672 3673 return sampleContributions; 3674 } 3675 3676 3677 void VspBspViewCellsManager::MergeViewCells(const VssRayContainer &rays, 3678 const ObjectContainer &objects) 3679 { 3680 int vcSize = 0; 3681 int pvsSize = 0; 3682 3683 //-- merge view cells 3684 cout << "starting merge using " << mPostProcessSamples << " samples ... " << endl; 3685 long startTime = GetTime(); 3686 3687 3688 if (mMergeViewCells) 3689 { 3690 // TODO: should be done BEFORE the ray casting 3691 // compute tree by merging the nodes based on cost heuristics 3692 mViewCellsTree->ConstructMergeTree(rays, objects); 3693 } 3694 else 3695 { 3696 // compute tree by merging the nodes of the spatial hierarchy 3697 ViewCell *root = ConstructSpatialMergeTree(mVspBspTree->GetRoot()); 3698 mViewCellsTree->SetRoot(root); 3699 3700 // compute pvs 3701 ObjectPvs pvs; 3702 UpdatePvsForEvaluation(root, pvs); 3703 } 3704 3705 if (1) 3706 { 3707 char mstats[100]; 3708 ObjectPvs pvs; 3709 3710 Environment::GetSingleton()->GetStringValue("ViewCells.mergeStats", mstats); 3711 mViewCellsTree->ExportStats(mstats); 3712 } 3713 3714 //-- stats and visualizations 3715 cout << "finished merging" << endl; 3716 cout << "merged view cells in " 3717 << TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl; 3718 3719 Debug << "Postprocessing: Merged view cells in " 3720 << TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl << endl; 3721 3722 3723 int savedColorCode = mColorCode; 3724 3725 // get currently active view cell set 3726 ResetViewCells(); 3727 Debug << "\nView cells after merge:\n" << mCurrentViewCellsStats << endl; 3728 3729 //BspLeaf::NewMail(); 3730 if (1) // export merged view cells 3731 { 3732 mColorCode = 0; 3733 Exporter *exporter = Exporter::GetExporter("merged_view_cells.wrl"); 3734 3735 cout << "exporting view cells after merge ... "; 3736 3737 if (exporter) 3738 { 3739 if (0) 3740 exporter->SetWireframe(); 3741 else 3742 exporter->SetFilled(); 3743 3744 ExportViewCellsForViz(exporter); 3745 3746 if (mExportGeometry) 3747 { 3748 Material m; 3749 m.mDiffuseColor = RgbColor(0, 1, 0); 3750 exporter->SetForcedMaterial(m); 3751 exporter->SetFilled(); 3752 3753 exporter->ExportGeometry(objects); 3754 } 3755 3756 delete exporter; 3757 } 3758 cout << "finished" << endl; 3759 } 3760 3761 if (1) // export merged view cells using pvs coding 3762 { 3763 mColorCode = 1; 3764 3765 Exporter *exporter = Exporter::GetExporter("merged_view_cells_pvs.wrl"); 3766 3767 cout << "exporting view cells after merge (pvs size) ... "; 3768 3769 if (exporter) 3770 { 3771 if (0) 3772 exporter->SetWireframe(); 3773 else 3774 exporter->SetFilled(); 3775 3776 ExportViewCellsForViz(exporter); 3777 3778 if (mExportGeometry) 3779 { 3780 Material m; 3781 m.mDiffuseColor = RgbColor(0, 1, 0); 3782 exporter->SetForcedMaterial(m); 3783 exporter->SetFilled(); 3784 3785 exporter->ExportGeometry(objects); 3786 } 3787 3788 delete exporter; 3789 } 3790 cout << "finished" << endl; 3791 } 3792 3793 mColorCode = savedColorCode; 3794 3795 } 3796 3797 3798 bool VspBspViewCellsManager::EqualToSpatialNode(ViewCell *viewCell) const 3799 { 3800 return GetSpatialNode(viewCell) != NULL; 3801 } 3802 3803 3804 BspNode *VspBspViewCellsManager::GetSpatialNode(ViewCell *viewCell) const 3805 { 3806 if (!viewCell->IsLeaf()) 3807 { 3808 BspViewCell *bspVc = dynamic_cast<BspViewCell *>(viewCell); 3809 3810 return bspVc->mLeaf; 3811 } 3812 else 3813 { 3814 ViewCellInterior *interior = dynamic_cast<ViewCellInterior *>(viewCell); 3815 3816 // cannot be node of binary tree 3817 if (interior->mChildren.size() != 2) 3818 return NULL; 3819 3820 ViewCell *left = interior->mChildren[0]; 3821 ViewCell *right = interior->mChildren[1]; 3822 3823 BspNode *leftNode = GetSpatialNode(left); 3824 BspNode *rightNode = GetSpatialNode(right); 3825 3826 if (leftNode && rightNode && leftNode->IsSibling(rightNode)) 3827 { 3828 return leftNode->GetParent(); 3829 } 3830 } 3831 3832 return NULL; 3833 } 3834 3835 3836 void VspBspViewCellsManager::RefineViewCells(const VssRayContainer &rays, 3837 const ObjectContainer &objects) 3838 { 3839 Debug << "render time before refine:" << endl; 3840 mRenderer->RenderScene(); 3841 SimulationStatistics ss; 3842 dynamic_cast<RenderSimulator *>(mRenderer)->GetStatistics(ss); 3843 Debug << ss << endl; 3844 3845 cout << "Refining the merged view cells ... "; 3846 long startTime = GetTime(); 3847 3848 // refining the merged view cells 3849 const int refined = mViewCellsTree->RefineViewCells(rays, objects); 3850 3851 //-- stats and visualizations 3852 cout << "finished" << endl; 3853 cout << "refined " << refined << " view cells in " 3854 << TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl; 3855 3856 Debug << "Postprocessing: refined " << refined << " view cells in " 3857 << TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl << endl; 3858 } 3859 3860 3861 int VspBspViewCellsManager::PostProcess(const ObjectContainer &objects, 3862 const VssRayContainer &rays) 3863 { 3864 if (!ViewCellsConstructed()) 3865 { 3866 Debug << "postprocess error: no view cells constructed" << endl; 3867 return 0; 3868 } 3869 3870 3871 // view cells already finished before post processing step 3872 // (i.e. because they were loaded) 3873 if (mViewCellsFinished) 3874 { 3875 FinalizeViewCells(true); 3876 EvaluateViewCellsStats(); 3877 3878 return 0; 3879 } 3880 3881 // check if new view cells turned invalid 3882 int minPvs, maxPvs; 3883 3884 if (0) 3885 { 3886 minPvs = mMinPvsSize; 3887 maxPvs = mMaxPvsSize; 3888 } 3889 else 3890 { 3891 minPvs = mPruneEmptyViewCells ? 1 : 0; 3892 maxPvs = mMaxPvsSize; 3893 } 3894 3895 Debug << "setting validity, min: " << minPvs << " max: " << maxPvs << endl; 3896 cout << "setting validity, min: " << minPvs << " max: " << maxPvs << endl; 3897 3898 SetValidity(minPvs, maxPvs); 3899 3900 // update valid view space according to valid view cells 3901 if (0) mVspBspTree->ValidateTree(); 3902 3903 // area has to be recomputed 3904 mTotalAreaValid = false; 3905 VssRayContainer postProcessRays; 3906 GetRaySets(rays, mPostProcessSamples, postProcessRays); 3907 3908 Debug << "post processing using " << (int)postProcessRays.size() << " samples" << endl; 3909 3910 3911 // should maybe be done here to allow merge working with area or volume 3912 // and to correct the rendering statistics 3913 if (0) FinalizeViewCells(false); 3914 3915 //-- merge the individual view cells 3916 MergeViewCells(postProcessRays, objects); 3917 3918 3919 // only for debugging purpose: test if the subdivision is valid 3920 TestSubdivision(); 3921 3922 //-- refines the merged view cells 3923 if (0) RefineViewCells(postProcessRays, objects); 3924 3925 3926 //-- render simulation after merge + refine 3927 cout << "\nevaluating bsp view cells render time before compress ... "; 3928 dynamic_cast<RenderSimulator *>(mRenderer)->RenderScene(); 3929 SimulationStatistics ss; 3930 dynamic_cast<RenderSimulator *>(mRenderer)->GetStatistics(ss); 3931 3932 3933 cout << " finished" << endl; 3934 cout << ss << endl; 3935 Debug << ss << endl; 3936 3937 3938 //-- compression 3939 if (ViewCellsTreeConstructed() && mCompressViewCells) 3940 { 3941 int pvsEntries = mViewCellsTree->GetNumPvsEntries(mViewCellsTree->GetRoot()); 3942 Debug << "number of entries before compress: " << pvsEntries << endl; 3943 3944 mViewCellsTree->SetViewCellsStorage(ViewCellsTree::COMPRESSED); 3945 3946 pvsEntries = mViewCellsTree->GetNumPvsEntries(mViewCellsTree->GetRoot()); 3947 Debug << "number of entries after compress: " << pvsEntries << endl; 3948 } 3949 3950 3951 // collapse sibling leaves that share the same view cell 3952 if (0) mVspBspTree->CollapseTree(); 3953 3954 // recompute view cell list and statistics 3955 ResetViewCells(); 3956 3957 // compute final meshes and volume / area 3958 if (1) FinalizeViewCells(true); 3959 3960 // write view cells to disc 3961 if (mExportViewCells) 3962 { 3963 char filename[100]; 3964 Environment::GetSingleton()->GetStringValue("ViewCells.filename", filename); 3965 ExportViewCells(filename, mExportPvs, objects); 3966 } 3967 3968 3969 // export bounding boxes 3970 if (mExportBboxesForPvs) 3971 { 3972 char filename[100]; 3973 Environment::GetSingleton()->GetStringValue("ViewCells.boxesFilename", filename); 3974 3975 ExportBoundingBoxes(filename, objects); 3976 } 3977 3978 return 0; 3979 } 3980 3981 3982 int VspBspViewCellsManager::GetType() const 3983 { 3984 return VSP_BSP; 3985 } 3986 3987 3988 ViewCell *VspBspViewCellsManager::ConstructSpatialMergeTree(BspNode *root) 3989 { 3990 // terminate recursion 3991 if (root->IsLeaf()) 3992 { 3993 BspLeaf *leaf = dynamic_cast<BspLeaf *>(root); 3994 leaf->GetViewCell()->SetMergeCost(0.0f); 3995 return leaf->GetViewCell(); 3996 } 3997 3998 3999 BspInterior *interior = dynamic_cast<BspInterior *>(root); 4000 ViewCellInterior *viewCellInterior = new ViewCellInterior(); 4001 4002 // evaluate merge cost for priority traversal 4003 float mergeCost = 1.0f / (float)root->mTimeStamp; 4004 viewCellInterior->SetMergeCost(mergeCost); 4005 4006 float volume = 0; 4007 4008 BspNode *front = interior->GetFront(); 4009 BspNode *back = interior->GetBack(); 4010 4011 4012 ObjectPvs frontPvs, backPvs; 4013 4014 //-- recursivly compute child hierarchies 4015 ViewCell *backVc = ConstructSpatialMergeTree(back); 4016 ViewCell *frontVc = ConstructSpatialMergeTree(front); 4017 4018 4019 viewCellInterior->SetupChildLink(backVc); 4020 viewCellInterior->SetupChildLink(frontVc); 4021 4022 volume += backVc->GetVolume(); 4023 volume += frontVc->GetVolume(); 4024 4025 viewCellInterior->SetVolume(volume); 4026 4027 return viewCellInterior; 4028 } 4029 4030 4031 4032 void VspBspViewCellsManager::UpdatePvsForEvaluation(ViewCell *root, ObjectPvs &pvs) 4033 { 4034 // terminate traversal 4035 if (root->IsLeaf()) 4036 { 4037 pvs = root->GetPvs(); 4038 SetScalarPvsSize(root, root->GetPvs().GetSize()); 4039 4040 return; 4041 } 4042 4043 //-- interior node => propagate pvs up 4044 ViewCellInterior *interior = dynamic_cast<ViewCellInterior *>(root); 4045 interior->GetPvs().Clear(); 4046 pvs.Clear(); 4047 vector<ObjectPvs> pvsList; 4048 4049 ViewCellContainer::const_iterator vit, vit_end = interior->mChildren.end(); 4050 4051 for (vit = interior->mChildren.begin(); vit != vit_end; ++ vit) 4052 { 4053 ObjectPvs objPvs; 4054 4055 //-- recursivly compute child pvss 4056 UpdatePvsForEvaluation(*vit, objPvs); 4057 4058 // store pvs in vector 4059 pvsList.push_back(objPvs); 4060 } 4061 4062 #if 1 4063 4064 Intersectable::NewMail(); 4065 4066 //-- faster way of computing pvs: 4067 // construct merged pvs by adding 4068 // and only those of the next pvs which were not mailed. 4069 // note: sumpdf is not correct!! 4070 vector<ObjectPvs>::iterator oit = pvsList.begin(); 4071 4072 for (vit = interior->mChildren.begin(); vit != vit_end; ++ vit, ++ oit) 4073 { 4074 ObjectPvsMap::iterator pit, pit_end = (*oit).mEntries.end(); 4075 4076 for (pit = (*oit).mEntries.begin(); pit != pit_end; ++ pit) 4077 { 4078 Intersectable *intersect = (*pit).first; 4079 4080 if (!intersect->Mailed()) 4081 { 4082 pvs.AddSample(intersect, (*pit).second.mSumPdf); 4083 intersect->Mail(); 4084 } 4085 } 4086 } 4087 4088 // store pvs in this node 4089 if (mViewCellsTree->ViewCellsStorage() == ViewCellsTree::PVS_IN_INTERIORS) 4090 { 4091 interior->SetPvs(pvs); 4092 } 4093 4094 // set new pvs size 4095 SetScalarPvsSize(interior, pvs.GetSize()); 4096 4097 4098 #else 4099 4100 // really merge cells: slow but sumpdf is correct 4101 viewCellInterior->GetPvs().Merge(backVc->GetPvs()); 4102 viewCellInterior->GetPvs().Merge(frontVc->GetPvs()); 4103 #endif 4104 4105 } 4106 4107 4108 bool VspBspViewCellsManager::GetViewPoint(Vector3 &viewPoint) const 4109 { 4110 if (!ViewCellsConstructed()) 4111 return ViewCellsManager::GetViewPoint(viewPoint); 4112 4113 // TODO: set reasonable limit 4114 const int limit = 20; 4115 4116 for (int i = 0; i < limit; ++ i) 4117 { 4118 viewPoint = mViewSpaceBox.GetRandomPoint(); 4119 if (mVspBspTree->ViewPointValid(viewPoint)) 4120 { 4121 return true; 4122 } 4123 } 4124 4125 Debug << "failed to find valid view point, taking " << viewPoint << endl; 4126 return false; 4127 } 4128 4129 4130 bool VspBspViewCellsManager::ViewPointValid(const Vector3 &viewPoint) const 4131 { 4132 // $$JB -> implemented in viewcellsmanager (slower, but allows dynamic 4133 // validy update in preprocessor for all managers) 4134 return ViewCellsManager::ViewPointValid(viewPoint); 4135 4136 // return mViewSpaceBox.IsInside(viewPoint) && 4137 // mVspBspTree->ViewPointValid(viewPoint); 4138 } 4139 4140 4141 void VspBspViewCellsManager::Visualize(const ObjectContainer &objects, 4142 const VssRayContainer &sampleRays) 4143 { 4144 if (!ViewCellsConstructed()) 4145 return; 4146 4147 VssRayContainer visRays; 4148 GetRaySets(sampleRays, mVisualizationSamples, visRays); 4149 4150 //-- export view cells 4151 if (1) 4152 { // hack pvs 4153 const int savedColorCode = mColorCode; 4154 mColorCode = 1; 4155 4156 Exporter *exporter = Exporter::GetExporter("final_view_cells.wrl"); 4157 4158 if (exporter) 4159 { 4160 cout << "exporting view cells after post process ... "; 4161 4162 if (0) 4163 { 4164 // export view space box 4165 exporter->SetWireframe(); 4166 exporter->ExportBox(mViewSpaceBox); 4167 exporter->SetFilled(); 4168 } 4169 4170 if (mExportGeometry) 4171 { 4172 exporter->ExportGeometry(objects); 4173 } 4174 4175 // export rays 4176 if (1 && mExportRays) 4177 { 4178 exporter->ExportRays(visRays, RgbColor(0, 1, 0)); 4179 } 4180 4181 //exporter->SetFilled(); 4182 4183 // HACK: export without clip plane 4184 const bool b = mUseClipPlaneForViz; 4185 mUseClipPlaneForViz = false; 4186 4187 ExportViewCellsForViz(exporter); 4188 4189 mUseClipPlaneForViz = b; 4190 delete exporter; 4191 4192 cout << "finished" << endl; 4193 } 4194 4195 mColorCode = savedColorCode; 4196 } 4197 4198 4199 if (0) 4200 { 4201 cout << "exporting depth map ... "; 4202 4203 Exporter *exporter = Exporter::GetExporter("depth_map.x3d"); 4204 if (exporter) 4205 { 4206 if (1) 4207 { 4208 exporter->SetWireframe(); 4209 exporter->ExportBox(mViewSpaceBox); 4210 exporter->SetFilled(); 4211 } 4212 4213 if (mExportGeometry) 4214 { 4215 exporter->ExportGeometry(objects); 4216 } 4217 4218 const int maxDepth = mVspBspTree->mBspStats.maxDepth; 4219 4220 ViewCellContainer::const_iterator vit, vit_end = mViewCells.end(); 4221 4222 for (vit = mViewCells.begin(); vit != mViewCells.end(); ++ vit) 4223 { 4224 ViewCell *vc = *vit; 4225 4226 ViewCellContainer leaves; 4227 mViewCellsTree->CollectLeaves(vc, leaves); 4228 4229 ViewCellContainer::const_iterator lit, lit_end = leaves.end(); 4230 4231 for (lit = leaves.begin(); lit != lit_end; ++ lit) 4232 { 4233 BspLeaf *leaf = dynamic_cast<BspViewCell *>(*lit)->mLeaf; 4234 4235 Material m; 4236 4237 float relDepth = (float)leaf->GetDepth() / (float)maxDepth; 4238 m.mDiffuseColor.r = relDepth; 4239 m.mDiffuseColor.g = 0.0f; 4240 m.mDiffuseColor.b = 1.0f - relDepth; 4241 4242 exporter->SetForcedMaterial(m); 4243 4244 4245 BspNodeGeometry geom; 4246 mVspBspTree->ConstructGeometry(leaf, geom); 4247 exporter->ExportPolygons(geom.GetPolys()); 4248 } 4249 } 4250 4251 delete exporter; 4252 } 4253 4254 4255 cout << "finished" << endl; 4256 } 4257 4258 //-- visualization of the BSP splits 4259 bool exportSplits = false; 4260 Environment::GetSingleton()->GetBoolValue("VspBspTree.Visualization.exportSplits", exportSplits); 4261 4262 if (exportSplits) 4263 { 4264 cout << "exporting splits ... "; 4265 ExportSplits(objects, visRays); 4266 cout << "finished" << endl; 4267 } 4268 4269 //-- export single view cells 4270 ExportBspPvs(objects, visRays); 4271 } 4272 4273 4274 void VspBspViewCellsManager::ExportSplits(const ObjectContainer &objects, 4275 const VssRayContainer &rays) 4276 { 4277 Exporter *exporter = Exporter::GetExporter("bsp_splits.x3d"); 4278 4279 if (exporter) 4280 { 4281 Material m; 4282 m.mDiffuseColor = RgbColor(1, 0, 0); 4283 exporter->SetForcedMaterial(m); 4284 exporter->SetWireframe(); 4285 4286 exporter->ExportBspSplits(*mVspBspTree, true); 4287 4288 // take forced material, else big scenes cannot be viewed 4289 m.mDiffuseColor = RgbColor(0, 1, 0); 4290 exporter->SetForcedMaterial(m); 4291 exporter->SetFilled(); 4292 4293 exporter->ResetForcedMaterial(); 4294 4295 // export rays 4296 if (mExportRays) 4297 exporter->ExportRays(rays, RgbColor(1, 1, 0)); 4298 4299 if (mExportGeometry) 4300 exporter->ExportGeometry(objects); 4301 4302 delete exporter; 4303 } 4304 } 4305 4306 4307 void VspBspViewCellsManager::ExportBspPvs(const ObjectContainer &objects, 4308 const VssRayContainer &rays) 4309 { 4310 int leafOut; 4311 Environment::GetSingleton()->GetIntValue("ViewCells.Visualization.maxOutput", leafOut); 4312 4313 ViewCell::NewMail(); 4314 4315 cout << "visualization using " << (int)rays.size() << " samples" << endl; 4316 Debug << "visualization using " << (int)rays.size() << " samples" << endl; 4317 Debug << "\nOutput view cells: " << endl; 4318 4319 const bool sortViewCells = true; 4320 4321 // sort view cells to visualize the largest view cells 4322 if (sortViewCells) 4323 { 4324 //stable_sort(mViewCells.begin(), mViewCells.end(), ViewCell::SmallerPvs); 4325 stable_sort(mViewCells.begin(), mViewCells.end(), ViewCell::LargerRenderCost); 4326 } 4327 4328 int limit = min(leafOut, (int)mViewCells.size()); 4329 4330 int raysOut = 0; 4331 4332 //-- some rays for output 4333 for (int i = 0; i < limit; ++ i) 4334 { 4335 cout << "creating output for view cell " << i << " ... "; 4336 4337 ViewCell *vc; 4338 4339 if (sortViewCells) // largest view cell pvs first 4340 vc = mViewCells[i]; 4341 else 4342 vc = mViewCells[(int)RandomValue(0, (float)mViewCells.size() - 1)]; 4343 4344 ObjectPvs pvs; 4345 mViewCellsTree->GetPvs(vc, pvs); 4346 4347 //bspLeaves[j]->Mail(); 4348 char s[64]; sprintf(s, "bsp-pvs%04d.wrl", i); 4349 Exporter *exporter = Exporter::GetExporter(s); 4350 4351 Debug << i << ": pvs size=" << (int)mViewCellsTree->GetPvsSize(vc) << endl; 4352 4353 //-- export the sample rays 4354 if (mExportRays) 4355 { 4356 // output rays stored with the view cells during subdivision 4357 if (0) 4358 { 4359 VssRayContainer vcRays; 4360 VssRayContainer collectRays; 4361 4362 raysOut = min((int)rays.size(), 100); 4363 4364 // collect intial view cells 4365 ViewCellContainer leaves; 4366 mViewCellsTree->CollectLeaves(vc, leaves); 4367 4368 ViewCellContainer::const_iterator vit, vit_end = leaves.end(); 4369 4370 for (vit = leaves.begin(); vit != vit_end; ++ vit) 4371 { 4372 BspLeaf *vcLeaf = dynamic_cast<BspViewCell *>(*vit)->mLeaf; 4373 4374 VssRayContainer::const_iterator rit, rit_end = vcLeaf->mVssRays.end(); 4375 4376 for (rit = vcLeaf->mVssRays.begin(); rit != rit_end; ++ rit) 4377 { 4378 collectRays.push_back(*rit); 4379 } 4380 } 4381 4382 VssRayContainer::const_iterator rit, rit_end = collectRays.end(); 4383 4384 for (rit = collectRays.begin(); rit != rit_end; ++ rit) 4385 { 4386 float p = RandomValue(0.0f, (float)collectRays.size()); 4387 4388 if (p < raysOut) 4389 vcRays.push_back(*rit); 4390 } 4391 4392 //-- export rays piercing this view cell 4393 exporter->ExportRays(vcRays, RgbColor(1, 1, 1)); 4394 } 4395 4396 // associate new rays with output view cell 4397 if (1) 4398 { 4399 VssRayContainer vcRays; 4400 raysOut = min((int)rays.size(), mVisualizationSamples); 4401 4402 // check whether we can add the current ray to the output rays 4403 for (int k = 0; k < raysOut; ++ k) 4404 { 4405 VssRay *ray = rays[k]; 4406 for (int j = 0; j < (int)ray->mViewCells.size(); ++ j) 4407 { 4408 ViewCell *rayvc = ray->mViewCells[j]; 4409 4410 if (rayvc == vc) 4411 vcRays.push_back(ray); 4412 } 4413 } 4414 4415 //-- export rays piercing this view cell 4416 exporter->ExportRays(vcRays, RgbColor(1, 1, 0)); 4417 } 4418 4419 } 4420 4421 4422 //-- export view cell geometry 4423 exporter->SetWireframe(); 4424 4425 Material m;//= RandomMaterial(); 4426 m.mDiffuseColor = RgbColor(0, 1, 0); 4427 exporter->SetForcedMaterial(m); 4428 4429 ExportViewCellGeometry(exporter, vc); 4430 4431 exporter->SetFilled(); 4432 4433 4434 //-- export pvs 4435 if (1) 4436 { 4437 ObjectPvsMap::const_iterator oit, 4438 oit_end = pvs.mEntries.end(); 4439 4440 Intersectable::NewMail(); 4441 4442 // output PVS of view cell 4443 for (oit = pvs.mEntries.begin(); oit != oit_end; ++ oit) 4444 { 4445 Intersectable *intersect = (*oit).first; 4446 4447 if (!intersect->Mailed()) 4448 { 4449 m = RandomMaterial(); 4450 exporter->SetForcedMaterial(m); 4451 4452 exporter->ExportIntersectable(intersect); 4453 intersect->Mail(); 4454 } 4455 } 4456 } 4457 4458 if (0) 4459 { // export scene geometry 4460 m.mDiffuseColor = RgbColor(1, 0, 0); 4461 exporter->SetForcedMaterial(m); 4462 4463 exporter->ExportGeometry(objects); 4464 } 4465 4466 DEL_PTR(exporter); 4467 cout << "finished" << endl; 4468 } 4469 4470 Debug << endl; 4471 } 4472 4473 4474 void VspBspViewCellsManager::TestFilter(const ObjectContainer &objects) 4475 { 4476 Exporter *exporter = Exporter::GetExporter("filter.x3d"); 4477 4478 Vector3 bsize = mViewSpaceBox.Size(); 4479 const Vector3 viewPoint(mViewSpaceBox.Center()); 4480 float w = Magnitude(mViewSpaceBox.Size()) * mFilterWidth; 4481 const Vector3 width = Vector3(w); 4482 4483 PrVs testPrVs; 4484 4485 if (exporter) 4486 { 4487 ViewCellContainer viewCells; 4488 4489 const AxisAlignedBox3 tbox = GetFilterBBox(viewPoint, mFilterWidth); 4490 4491 GetPrVS(viewPoint, testPrVs, GetFilterWidth()); 4492 4493 exporter->SetWireframe(); 4494 4495 exporter->SetForcedMaterial(RgbColor(1,1,1)); 4496 exporter->ExportBox(tbox); 4497 4498 exporter->SetFilled(); 4499 4500 exporter->SetForcedMaterial(RgbColor(0,1,0)); 4501 ExportViewCellGeometry(exporter, GetViewCell(viewPoint)); 4502 4503 //exporter->ResetForcedMaterial(); 4504 exporter->SetForcedMaterial(RgbColor(0,0,1)); 4505 ExportViewCellGeometry(exporter, testPrVs.mViewCell); 4506 4507 exporter->SetForcedMaterial(RgbColor(1,0,0)); 4508 exporter->ExportGeometry(objects); 4509 4510 delete exporter; 4511 } 4512 } 4513 4514 4515 int VspBspViewCellsManager::ComputeBoxIntersections(const AxisAlignedBox3 &box, 4516 ViewCellContainer &viewCells) const 4517 { 4518 return mVspBspTree->ComputeBoxIntersections(box, viewCells); 4519 } 4520 4521 4522 int VspBspViewCellsManager::CastLineSegment(const Vector3 &origin, 4523 const Vector3 &termination, 4524 ViewCellContainer &viewcells) 4525 { 4526 return mVspBspTree->CastLineSegment(origin, termination, viewcells); 4366 4527 } 4367 4528 … … 4508 4669 ViewCell *VspBspViewCellsManager::GetViewCell(const Vector3 &point, const bool active) const 4509 4670 { 4510 if (! mVspBspTree)4671 if (!ViewCellsConstructed()) 4511 4672 return NULL; 4512 4673 … … 4612 4773 } 4613 4774 4614 void 4615 ViewCellsManager::ApplySpatialFilter( 4616 KdTree *kdTree, 4617 const float spatialFilterSize, 4618 ObjectPvs &pvs 4619 ) 4620 { 4621 4622 // now compute a new Pvs by including also objects intersecting the extended boxes of 4623 // visible objects 4624 4625 Intersectable::NewMail(); 4775 4776 4777 /**************************************************************************/ 4778 /* VspBspViewCellsManager implementation */ 4779 /**************************************************************************/ 4780 4781 4782 VspOspViewCellsManager::VspOspViewCellsManager(VspTree *vspTree, OspTree *ospTree): 4783 ViewCellsManager(), mVspTree(vspTree), mOspTree(ospTree) 4784 { 4785 Environment::GetSingleton()->GetIntValue("VspBspTree.Construction.samples", mInitialSamples); 4786 mVspTree->SetViewCellsManager(this); 4787 mVspTree->mViewCellsTree = mViewCellsTree; 4788 } 4789 4790 4791 VspOspViewCellsManager::~VspOspViewCellsManager() 4792 { 4793 } 4794 4795 4796 float VspOspViewCellsManager::GetProbability(ViewCell *viewCell) 4797 { 4798 return GetVolume(viewCell) / mViewSpaceBox.GetVolume(); 4799 } 4800 4801 4802 void VspOspViewCellsManager::CollectViewCells() 4803 { 4804 // view cells tree constructed 4805 if (!ViewCellsTreeConstructed()) 4806 { 4807 mVspTree->CollectViewCells(mViewCells, false); 4808 } 4809 else 4810 { // we can use the view cells tree hierarchy to get the right set 4811 mViewCellsTree->CollectBestViewCellSet(mViewCells, mNumActiveViewCells); 4812 } 4813 } 4814 4815 4816 bool VspOspViewCellsManager::ViewCellsConstructed() const 4817 { 4818 return mVspTree->GetRoot() != NULL; 4819 } 4820 4821 4822 ViewCell *VspOspViewCellsManager::GenerateViewCell(Mesh *mesh) const 4823 { 4824 return new VspViewCell(mesh); 4825 } 4826 4827 4828 int VspOspViewCellsManager::ConstructSubdivision(const ObjectContainer &objects, 4829 const VssRayContainer &rays) 4830 { 4831 mMaxPvsSize = (int)(mMaxPvsRatio * (float)objects.size()); 4832 4833 // if view cells were already constructed 4834 if (ViewCellsConstructed()) 4835 return 0; 4836 4837 int sampleContributions = 0; 4838 4839 VssRayContainer sampleRays; 4840 4841 int limit = min (mInitialSamples, (int)rays.size()); 4842 4843 VssRayContainer constructionRays; 4844 VssRayContainer savedRays; 4845 4846 Debug << "samples used for vsp bsp subdivision: " << mInitialSamples 4847 << ", actual rays: " << (int)rays.size() << endl; 4848 4849 GetRaySets(rays, mInitialSamples, constructionRays, &savedRays); 4850 4851 Debug << "initial rays: " << (int)constructionRays.size() << endl; 4852 Debug << "saved rays: " << (int)savedRays.size() << endl; 4853 4854 long startTime; 4855 4856 #if TODO 4857 if (1) 4858 mVspTree->Construct(constructionRays, &mViewSpaceBox); 4859 else 4860 mVspTree->Construct(rays, &mViewSpaceBox); 4861 #endif 4862 // collapse invalid regions 4863 cout << "collapsing invalid tree regions ... "; 4864 startTime = GetTime(); 4865 const int collapsedLeaves = mVspTree->CollapseTree(); 4866 Debug << "collapsed in " << TimeDiff(startTime, GetTime()) * 1e-3 4867 << " seconds" << endl; 4868 4869 cout << "finished" << endl; 4870 4871 //-- stats 4872 Debug << mVspTree->GetStatistics() << endl; 4873 4874 ResetViewCells(); 4875 Debug << "\nView cells after construction:\n" << mCurrentViewCellsStats << endl; 4876 4877 4878 startTime = GetTime(); 4879 4880 cout << "Computing remaining ray contributions ... "; 4881 4882 // recast rest of rays 4883 if (SAMPLE_AFTER_SUBDIVISION) 4884 ComputeSampleContributions(savedRays, true, false); 4885 4886 cout << "finished" << endl; 4887 4888 Debug << "Computed remaining ray contribution in " << TimeDiff(startTime, GetTime()) * 1e-3 4889 << " secs" << endl; 4890 4891 cout << "construction finished" << endl; 4892 4893 // real meshes are contructed at this stage 4894 if (0) 4895 { 4896 cout << "finalizing view cells ... "; 4897 FinalizeViewCells(true); 4898 cout << "finished" << endl; 4899 } 4900 4901 return sampleContributions; 4902 } 4903 4904 4905 int VspOspViewCellsManager::PostProcess(const ObjectContainer &objects, 4906 const VssRayContainer &rays) 4907 { 4908 if (!ViewCellsConstructed()) 4909 { 4910 Debug << "postprocess error: no view cells constructed" << endl; 4911 return 0; 4912 } 4913 4914 4915 // view cells already finished before post processing step 4916 // (i.e. because they were loaded) 4917 if (mViewCellsFinished) 4918 { 4919 FinalizeViewCells(true); 4920 EvaluateViewCellsStats(); 4921 4922 return 0; 4923 } 4924 4925 // check if new view cells turned invalid 4926 int minPvs, maxPvs; 4927 4928 if (0) 4929 { 4930 minPvs = mMinPvsSize; 4931 maxPvs = mMaxPvsSize; 4932 } 4933 else 4934 { 4935 minPvs = mPruneEmptyViewCells ? 1 : 0; 4936 maxPvs = mMaxPvsSize; 4937 } 4938 4939 Debug << "setting validity, min: " << minPvs << " max: " << maxPvs << endl; 4940 cout << "setting validity, min: " << minPvs << " max: " << maxPvs << endl; 4941 4942 SetValidity(minPvs, maxPvs); 4943 4944 4945 // area has to be recomputed 4946 mTotalAreaValid = false; 4947 VssRayContainer postProcessRays; 4948 GetRaySets(rays, mPostProcessSamples, postProcessRays); 4949 4950 Debug << "post processing using " << (int)postProcessRays.size() << " samples" << endl; 4951 4952 4953 // should maybe be done here to allow merge working with area or volume 4954 // and to correct the rendering statistics 4955 if (0) FinalizeViewCells(false); 4956 4957 // compute tree by merging the nodes of the spatial hierarchy 4958 ViewCell *root = ConstructSpatialMergeTree(mVspTree->GetRoot()); 4959 mViewCellsTree->SetRoot(root); 4960 4961 // compute pvs 4962 ObjectPvs pvs; 4963 UpdatePvsForEvaluation(root, pvs); 4964 4965 4966 //-- render simulation after merge + refine 4967 cout << "\nevaluating bsp view cells render time before compress ... "; 4968 dynamic_cast<RenderSimulator *>(mRenderer)->RenderScene(); 4969 SimulationStatistics ss; 4970 dynamic_cast<RenderSimulator *>(mRenderer)->GetStatistics(ss); 4626 4971 4627 std::map<Intersectable *, 4628 PvsData<Intersectable *>, 4629 LtSample<Intersectable *> >::const_iterator oi; 4630 4631 for (oi = pvs.mEntries.begin(); oi != pvs.mEntries.end(); ++oi) { 4632 Intersectable *object = (*oi).first; 4633 object->Mail(); 4634 } 4635 4636 ObjectPvs nPvs; 4637 int nPvsSize=0; 4638 // now go through the pvs again 4639 for (oi = pvs.mEntries.begin(); oi != pvs.mEntries.end(); ++oi) { 4640 Intersectable *object = (*oi).first; 4641 4642 // Vector3 center = object->GetBox().Center(); 4643 // AxisAlignedBox3 box(center - Vector3(spatialFilterSize/2), 4644 // center + Vector3(spatialFilterSize/2)); 4645 4646 AxisAlignedBox3 box = object->GetBox(); 4647 box.Enlarge(Vector3(spatialFilterSize/2)); 4648 4649 ObjectContainer objects; 4650 4651 // $$ warning collect objects takes only unmailed ones! 4652 kdTree->CollectObjects(box, 4653 objects); 4654 // cout<<"collected objects="<<objects.size()<<endl; 4655 ObjectContainer::const_iterator noi = objects.begin(); 4656 for (; noi != objects.end(); ++noi) { 4657 Intersectable *o = *noi; 4658 // $$ JB warning: pdfs are not correct at this point! 4659 nPvs.AddSample(o, Limits::Small); 4660 nPvsSize++; 4661 } 4662 } 4663 // cout<<"nPvs size = "<<nPvsSize<<endl; 4664 pvs.Merge(nPvs); 4665 } 4666 4667 void 4668 ViewCellsManager::ApplyFilter(ViewCell *viewCell, 4669 KdTree *kdTree, 4670 const float viewSpaceFilterSize, 4671 const float spatialFilterSize, 4672 ObjectPvs &pvs 4673 ) 4674 { 4675 // extend the pvs of the viewcell by pvs of its neighbors 4676 // and apply spatial filter by including all neighbors of the objects 4677 // in the pvs 4678 4679 // get all viewcells intersecting the viewSpaceFilterBox 4680 // and compute the pvs union 4681 4682 //Vector3 center = viewCell->GetBox().Center(); 4683 // Vector3 center = m->mBox.Center(); 4684 4685 // AxisAlignedBox3 box(center - Vector3(viewSpaceFilterSize/2), 4686 // center + Vector3(viewSpaceFilterSize/2)); 4972 4973 cout << " finished" << endl; 4974 cout << ss << endl; 4975 Debug << ss << endl; 4976 4977 4978 //-- compression 4979 if (ViewCellsTreeConstructed() && mCompressViewCells) 4980 { 4981 int pvsEntries = mViewCellsTree->GetNumPvsEntries(mViewCellsTree->GetRoot()); 4982 Debug << "number of entries before compress: " << pvsEntries << endl; 4983 4984 mViewCellsTree->SetViewCellsStorage(ViewCellsTree::COMPRESSED); 4985 4986 pvsEntries = mViewCellsTree->GetNumPvsEntries(mViewCellsTree->GetRoot()); 4987 Debug << "number of entries after compress: " << pvsEntries << endl; 4988 } 4989 4990 // compute final meshes and volume / area 4991 if (1) FinalizeViewCells(true); 4992 4993 // write view cells to disc 4994 if (mExportViewCells) 4995 { 4996 char filename[100]; 4997 Environment::GetSingleton()->GetStringValue("ViewCells.filename", filename); 4998 ExportViewCells(filename, mExportPvs, objects); 4999 } 5000 5001 5002 return 0; 5003 } 5004 5005 5006 int VspOspViewCellsManager::GetType() const 5007 { 5008 return VSP_OSP; 5009 } 5010 5011 5012 ViewCell *VspOspViewCellsManager::ConstructSpatialMergeTree(VspNode *root) 5013 { 5014 // terminate recursion 5015 if (root->IsLeaf()) 5016 { 5017 VspLeaf *leaf = dynamic_cast<VspLeaf *>(root); 5018 leaf->GetViewCell()->SetMergeCost(0.0f); 5019 return leaf->GetViewCell(); 5020 } 5021 5022 5023 VspInterior *interior = dynamic_cast<VspInterior *>(root); 5024 ViewCellInterior *viewCellInterior = new ViewCellInterior(); 5025 5026 // evaluate merge cost for priority traversal 5027 float mergeCost = 1.0f / (float)root->mTimeStamp; 5028 viewCellInterior->SetMergeCost(mergeCost); 5029 5030 float volume = 0; 5031 5032 VspNode *front = interior->GetFront(); 5033 VspNode *back = interior->GetBack(); 5034 5035 5036 ObjectPvs frontPvs, backPvs; 5037 5038 //-- recursivly compute child hierarchies 5039 ViewCell *backVc = ConstructSpatialMergeTree(back); 5040 ViewCell *frontVc = ConstructSpatialMergeTree(front); 5041 5042 5043 viewCellInterior->SetupChildLink(backVc); 5044 viewCellInterior->SetupChildLink(frontVc); 5045 5046 volume += backVc->GetVolume(); 5047 volume += frontVc->GetVolume(); 5048 5049 viewCellInterior->SetVolume(volume); 5050 5051 return viewCellInterior; 5052 } 5053 5054 5055 5056 void VspOspViewCellsManager::UpdatePvsForEvaluation(ViewCell *root, ObjectPvs &pvs) 5057 { 5058 // terminate traversal 5059 if (root->IsLeaf()) 5060 { 5061 pvs = root->GetPvs(); 5062 SetScalarPvsSize(root, root->GetPvs().GetSize()); 5063 5064 return; 5065 } 5066 5067 //-- interior node => propagate pvs up 5068 ViewCellInterior *interior = dynamic_cast<ViewCellInterior *>(root); 5069 interior->GetPvs().Clear(); 5070 pvs.Clear(); 5071 vector<ObjectPvs> pvsList; 5072 5073 ViewCellContainer::const_iterator vit, vit_end = interior->mChildren.end(); 5074 5075 for (vit = interior->mChildren.begin(); vit != vit_end; ++ vit) 5076 { 5077 ObjectPvs objPvs; 5078 5079 //-- recursivly compute child pvss 5080 UpdatePvsForEvaluation(*vit, objPvs); 5081 5082 // store pvs in vector 5083 pvsList.push_back(objPvs); 5084 } 5085 5086 #if 1 5087 Intersectable::NewMail(); 5088 5089 //-- faster way of computing pvs: 5090 // construct merged pvs by adding 5091 // and only those of the next pvs which were not mailed. 5092 // note: sumpdf is not correct!! 5093 vector<ObjectPvs>::iterator oit = pvsList.begin(); 5094 5095 for (vit = interior->mChildren.begin(); vit != vit_end; ++ vit, ++ oit) 5096 { 5097 ObjectPvsMap::iterator pit, pit_end = (*oit).mEntries.end(); 5098 5099 for (pit = (*oit).mEntries.begin(); pit != pit_end; ++ pit) 5100 { 5101 Intersectable *intersect = (*pit).first; 5102 5103 if (!intersect->Mailed()) 5104 { 5105 pvs.AddSample(intersect, (*pit).second.mSumPdf); 5106 intersect->Mail(); 5107 } 5108 } 5109 } 5110 5111 // store pvs in this node 5112 if (mViewCellsTree->ViewCellsStorage() == ViewCellsTree::PVS_IN_INTERIORS) 5113 { 5114 interior->SetPvs(pvs); 5115 } 5116 5117 // set new pvs size 5118 SetScalarPvsSize(interior, pvs.GetSize()); 5119 5120 5121 #else 5122 5123 // really merge cells: slow put sumpdf is correct 5124 viewCellInterior->GetPvs().Merge(backVc->GetPvs()); 5125 viewCellInterior->GetPvs().Merge(frontVc->GetPvs()); 5126 #endif 5127 } 5128 5129 5130 bool VspOspViewCellsManager::GetViewPoint(Vector3 &viewPoint) const 5131 { 5132 if (!ViewCellsConstructed()) 5133 return ViewCellsManager::GetViewPoint(viewPoint); 5134 5135 // TODO: set reasonable limit 5136 const int limit = 20; 5137 5138 for (int i = 0; i < limit; ++ i) 5139 { 5140 viewPoint = mViewSpaceBox.GetRandomPoint(); 5141 if (mVspTree->ViewPointValid(viewPoint)) 5142 { 5143 return true; 5144 } 5145 } 5146 5147 Debug << "failed to find valid view point, taking " << viewPoint << endl; 5148 return false; 5149 } 5150 5151 5152 bool VspOspViewCellsManager::ViewPointValid(const Vector3 &viewPoint) const 5153 { 5154 // $$JB -> implemented in viewcellsmanager (slower, but allows dynamic 5155 // validy update in preprocessor for all managers) 5156 return ViewCellsManager::ViewPointValid(viewPoint); 5157 5158 // return mViewSpaceBox.IsInside(viewPoint) && 5159 // mVspBspTree->ViewPointValid(viewPoint); 5160 } 5161 5162 5163 void VspOspViewCellsManager::Visualize(const ObjectContainer &objects, 5164 const VssRayContainer &sampleRays) 5165 { 4687 5166 if (!ViewCellsConstructed()) 4688 5167 return; 4689 4690 if (viewSpaceFilterSize >= 0.0f) { 4691 4692 bool usePrVS = false; 4693 4694 if (!usePrVS) { 4695 AxisAlignedBox3 box = GetViewCellBox(viewCell); 4696 box.Enlarge(Vector3(viewSpaceFilterSize/2)); 4697 4698 ViewCellContainer viewCells; 4699 ComputeBoxIntersections(box, viewCells); 4700 4701 // cout<<"box="<<box<<endl; 4702 ViewCellContainer::const_iterator it = viewCells.begin(), it_end = viewCells.end(); 4703 4704 int i; 4705 for (i=0; it != it_end; ++ it, ++ i) { 4706 //cout<<"v"<<i<<" pvs="<<(*it)->GetPvs().mEntries.size()<<endl; 4707 pvs.Merge((*it)->GetPvs()); 4708 } 4709 } else { 4710 PrVs prvs; 4711 AxisAlignedBox3 box = GetViewCellBox(viewCell); 4712 4713 // mViewCellsManager->SetMaxFilterSize(1); 4714 GetPrVS(box.Center(), prvs, viewSpaceFilterSize); 4715 pvs = prvs.mViewCell->GetPvs(); 4716 DeleteLocalMergeTree(prvs.mViewCell); 4717 } 4718 } else 4719 pvs = viewCell->GetPvs(); 4720 4721 if (spatialFilterSize >=0.0f) 4722 ApplySpatialFilter(kdTree, spatialFilterSize, pvs); 4723 4724 } 4725 4726 4727 4728 void 4729 ViewCellsManager::ApplyFilter(KdTree *kdTree, 4730 const float relViewSpaceFilterSize, 4731 const float relSpatialFilterSize 4732 ) 4733 { 4734 5168 #if TODO 5169 VssRayContainer visRays; 5170 GetRaySets(sampleRays, mVisualizationSamples, visRays); 5171 5172 //-- export view cells 5173 if (1) 5174 { // hack pvs 5175 const int savedColorCode = mColorCode; 5176 mColorCode = 1; 5177 5178 Exporter *exporter = Exporter::GetExporter("final_view_cells.wrl"); 5179 5180 if (exporter) 5181 { 5182 cout << "exporting view cells after post process ... "; 5183 5184 if (0) 5185 { 5186 // export view space box 5187 exporter->SetWireframe(); 5188 exporter->ExportBox(mViewSpaceBox); 5189 exporter->SetFilled(); 5190 } 5191 5192 if (mExportGeometry) 5193 { 5194 exporter->ExportGeometry(objects); 5195 } 5196 5197 // export rays 5198 if (1 && mExportRays) 5199 { 5200 exporter->ExportRays(visRays, RgbColor(0, 1, 0)); 5201 } 5202 5203 //exporter->SetFilled(); 5204 5205 // HACK: export without clip plane 5206 const bool b = mUseClipPlaneForViz; 5207 mUseClipPlaneForViz = false; 5208 5209 ExportViewCellsForViz(exporter); 5210 5211 mUseClipPlaneForViz = b; 5212 delete exporter; 5213 5214 cout << "finished" << endl; 5215 } 5216 5217 mColorCode = savedColorCode; 5218 } 5219 5220 5221 if (0) 5222 { 5223 cout << "exporting depth map ... "; 5224 5225 Exporter *exporter = Exporter::GetExporter("depth_map.x3d"); 5226 if (exporter) 5227 { 5228 if (1) 5229 { 5230 exporter->SetWireframe(); 5231 exporter->ExportBox(mViewSpaceBox); 5232 exporter->SetFilled(); 5233 } 5234 5235 if (mExportGeometry) 5236 { 5237 exporter->ExportGeometry(objects); 5238 } 5239 5240 const int maxDepth = mVspBspTree->mBspStats.maxDepth; 5241 5242 ViewCellContainer::const_iterator vit, vit_end = mViewCells.end(); 5243 5244 for (vit = mViewCells.begin(); vit != mViewCells.end(); ++ vit) 5245 { 5246 ViewCell *vc = *vit; 5247 5248 ViewCellContainer leaves; 5249 mViewCellsTree->CollectLeaves(vc, leaves); 5250 5251 ViewCellContainer::const_iterator lit, lit_end = leaves.end(); 5252 5253 for (lit = leaves.begin(); lit != lit_end; ++ lit) 5254 { 5255 BspLeaf *leaf = dynamic_cast<BspViewCell *>(*lit)->mLeaf; 5256 5257 Material m; 5258 5259 float relDepth = (float)leaf->GetDepth() / (float)maxDepth; 5260 m.mDiffuseColor.r = relDepth; 5261 m.mDiffuseColor.g = 0.0f; 5262 m.mDiffuseColor.b = 1.0f - relDepth; 5263 5264 exporter->SetForcedMaterial(m); 5265 5266 5267 BspNodeGeometry geom; 5268 mVspBspTree->ConstructGeometry(leaf, geom); 5269 exporter->ExportPolygons(geom.GetPolys()); 5270 } 5271 } 5272 5273 delete exporter; 5274 } 5275 5276 5277 cout << "finished" << endl; 5278 } 5279 5280 //-- visualization of the BSP splits 5281 5282 bool exportSplits = false; 5283 Environment::GetSingleton()->GetBoolValue("VspBspTree.Visualization.exportSplits", exportSplits); 5284 5285 if (exportSplits) 5286 { 5287 cout << "exporting splits ... "; 5288 ExportSplits(objects, visRays); 5289 cout << "finished" << endl; 5290 } 5291 5292 //-- export single view cells 5293 ExportBspPvs(objects, visRays); 5294 #endif 5295 } 5296 5297 5298 void VspOspViewCellsManager::ExportBspPvs(const ObjectContainer &objects, 5299 const VssRayContainer &rays) 5300 { 5301 int leafOut; 5302 Environment::GetSingleton()->GetIntValue("ViewCells.Visualization.maxOutput", leafOut); 5303 5304 ViewCell::NewMail(); 5305 5306 cout << "visualization using " << (int)rays.size() << " samples" << endl; 5307 Debug << "visualization using " << (int)rays.size() << " samples" << endl; 5308 Debug << "\nOutput view cells: " << endl; 5309 5310 const bool sortViewCells = true; 5311 5312 // sort view cells to visualize the largest view cells 5313 if (sortViewCells) 5314 { 5315 //stable_sort(mViewCells.begin(), mViewCells.end(), ViewCell::SmallerPvs); 5316 stable_sort(mViewCells.begin(), mViewCells.end(), ViewCell::LargerRenderCost); 5317 } 5318 5319 int limit = min(leafOut, (int)mViewCells.size()); 5320 5321 int raysOut = 0; 5322 5323 //-- some rays for output 5324 for (int i = 0; i < limit; ++ i) 5325 { 5326 cout << "creating output for view cell " << i << " ... "; 5327 5328 ViewCell *vc; 5329 5330 if (sortViewCells) // largest view cell pvs first 5331 vc = mViewCells[i]; 5332 else 5333 vc = mViewCells[(int)RandomValue(0, (float)mViewCells.size() - 1)]; 5334 5335 ObjectPvs pvs; 5336 mViewCellsTree->GetPvs(vc, pvs); 5337 5338 //bspLeaves[j]->Mail(); 5339 char s[64]; sprintf(s, "bsp-pvs%04d.wrl", i); 5340 Exporter *exporter = Exporter::GetExporter(s); 5341 5342 Debug << i << ": pvs size=" << (int)mViewCellsTree->GetPvsSize(vc) << endl; 5343 5344 //-- export the sample rays 5345 if (mExportRays) 5346 { 5347 // output rays stored with the view cells during subdivision 5348 if (0) 5349 { 5350 VssRayContainer vcRays; 5351 VssRayContainer collectRays; 5352 5353 raysOut = min((int)rays.size(), 100); 5354 5355 // collect intial view cells 5356 ViewCellContainer leaves; 5357 mViewCellsTree->CollectLeaves(vc, leaves); 5358 5359 ViewCellContainer::const_iterator vit, vit_end = leaves.end(); 5360 5361 for (vit = leaves.begin(); vit != vit_end; ++ vit) 5362 { 5363 BspLeaf *vcLeaf = dynamic_cast<BspViewCell *>(*vit)->mLeaf; 5364 5365 VssRayContainer::const_iterator rit, rit_end = vcLeaf->mVssRays.end(); 5366 5367 for (rit = vcLeaf->mVssRays.begin(); rit != rit_end; ++ rit) 5368 { 5369 collectRays.push_back(*rit); 5370 } 5371 } 5372 5373 VssRayContainer::const_iterator rit, rit_end = collectRays.end(); 5374 5375 for (rit = collectRays.begin(); rit != rit_end; ++ rit) 5376 { 5377 float p = RandomValue(0.0f, (float)collectRays.size()); 5378 5379 if (p < raysOut) 5380 vcRays.push_back(*rit); 5381 } 5382 5383 //-- export rays piercing this view cell 5384 exporter->ExportRays(vcRays, RgbColor(1, 1, 1)); 5385 } 5386 5387 // associate new rays with output view cell 5388 if (1) 5389 { 5390 VssRayContainer vcRays; 5391 raysOut = min((int)rays.size(), mVisualizationSamples); 5392 5393 // check whether we can add the current ray to the output rays 5394 for (int k = 0; k < raysOut; ++ k) 5395 { 5396 VssRay *ray = rays[k]; 5397 for (int j = 0; j < (int)ray->mViewCells.size(); ++ j) 5398 { 5399 ViewCell *rayvc = ray->mViewCells[j]; 5400 5401 if (rayvc == vc) 5402 vcRays.push_back(ray); 5403 } 5404 } 5405 5406 //-- export rays piercing this view cell 5407 exporter->ExportRays(vcRays, RgbColor(1, 1, 0)); 5408 } 5409 5410 } 5411 5412 5413 //-- export view cell geometry 5414 exporter->SetWireframe(); 5415 5416 Material m;//= RandomMaterial(); 5417 m.mDiffuseColor = RgbColor(0, 1, 0); 5418 exporter->SetForcedMaterial(m); 5419 5420 ExportViewCellGeometry(exporter, vc); 5421 5422 exporter->SetFilled(); 5423 5424 5425 //-- export pvs 5426 if (1) 5427 { 5428 ObjectPvsMap::const_iterator oit, 5429 oit_end = pvs.mEntries.end(); 5430 5431 Intersectable::NewMail(); 5432 5433 // output PVS of view cell 5434 for (oit = pvs.mEntries.begin(); oit != oit_end; ++ oit) 5435 { 5436 Intersectable *intersect = (*oit).first; 5437 5438 if (!intersect->Mailed()) 5439 { 5440 m = RandomMaterial(); 5441 exporter->SetForcedMaterial(m); 5442 5443 exporter->ExportIntersectable(intersect); 5444 intersect->Mail(); 5445 } 5446 } 5447 } 5448 5449 if (0) 5450 { // export scene geometry 5451 m.mDiffuseColor = RgbColor(1, 0, 0); 5452 exporter->SetForcedMaterial(m); 5453 5454 exporter->ExportGeometry(objects); 5455 } 5456 5457 DEL_PTR(exporter); 5458 cout << "finished" << endl; 5459 } 5460 5461 Debug << endl; 5462 } 5463 5464 5465 int VspOspViewCellsManager::ComputeBoxIntersections(const AxisAlignedBox3 &box, 5466 ViewCellContainer &viewCells) const 5467 { 5468 return mVspTree->ComputeBoxIntersections(box, viewCells); 5469 } 5470 5471 5472 int VspOspViewCellsManager::CastLineSegment(const Vector3 &origin, 5473 const Vector3 &termination, 5474 ViewCellContainer &viewcells) 5475 { 5476 return mVspTree->CastLineSegment(origin, termination, viewcells); 5477 } 5478 5479 5480 void VspOspViewCellsManager::ExportViewCellGeometry(Exporter *exporter, 5481 ViewCell *vc, 5482 const Plane3 *clipPlane) const 5483 { 5484 // matt: TODO 5485 } 5486 5487 5488 bool VspOspViewCellsManager::ExportViewCells(const string filename, 5489 const bool exportPvs, 5490 const ObjectContainer &objects) 5491 { 5492 if (!ViewCellsConstructed() || !ViewCellsTreeConstructed()) 5493 return false; 5494 5495 cout << "exporting view cells to xml ... "; 5496 5497 #if ZIPPED_VIEWCELLS 5498 ogzstream stream(filename.c_str()); 5499 #else 5500 std::ofstream stream(filename.c_str()); 5501 #endif 5502 5503 // for output we need unique ids for each view cell 5504 CreateUniqueViewCellIds(); 5505 5506 stream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"<<endl; 5507 stream << "<VisibilitySolution>" << endl; 5508 5509 //-- the view space bounding box 5510 stream << "<ViewSpaceBox" 5511 << " min=\"" << mViewSpaceBox.Min().x << " " << mViewSpaceBox.Min().y << " " << mViewSpaceBox.Min().z << "\"" 5512 << " max=\"" << mViewSpaceBox.Max().x << " " << mViewSpaceBox.Max().y << " " << mViewSpaceBox.Max().z << "\" />" << endl; 5513 5514 5515 //-- export bounding boxes 5516 stream << "<BoundingBoxes>" << endl; 5517 5518 ObjectContainer::const_iterator oit, oit_end = objects.end(); 5519 5520 for (oit = objects.begin(); oit != oit_end; ++ oit) 5521 { 5522 MeshInstance *mi = dynamic_cast<MeshInstance *>(*oit); 5523 const AxisAlignedBox3 box = mi->GetBox(); 5524 5525 //-- the bounding boxes 5526 stream << "<BoundingBox" << " id=\"" << mi->GetId() << "\"" 5527 << " min=\"" << box.Min().x << " " << box.Min().y << " " << box.Min().z << "\"" 5528 << " max=\"" << box.Max().x << " " << box.Max().y << " " << box.Max().z << "\" />" << endl; 5529 } 5530 5531 stream << "</BoundingBoxes>" << endl; 5532 5533 5534 //-- export the view cells and the pvs 5535 stream << "<HierarchyType name=\"vspBspTree\" />" << endl; 5536 5537 const int numViewCells = mCurrentViewCellsStats.viewCells; 5538 5539 stream << "<ViewCells number=\"" << numViewCells << "\" >" << endl; 5540 5541 mViewCellsTree->Export(stream, exportPvs); 5542 5543 stream << "</ViewCells>" << endl; 5544 5545 5546 //-- export the spatial hierarchy 5547 5548 // the type of the view cells hierarchy 5549 stream << "<Hierarchy>" << endl; 5550 mVspTree->Export(stream); 5551 stream << endl << "</Hierarchy>" << endl; 5552 5553 stream << "</VisibilitySolution>" << endl; 5554 5555 5556 stream.close(); 5557 cout << "finished" << endl; 5558 5559 return true; 5560 } 5561 5562 5563 5564 ViewCell *VspOspViewCellsManager::GetViewCell(const Vector3 &point, const bool active) const 5565 { 4735 5566 if (!ViewCellsConstructed()) 4736 return; 4737 4738 ViewCellContainer::const_iterator it, it_end = mViewCells.end(); 4739 4740 ObjectPvs *newPvs; 4741 newPvs = new ObjectPvs[mViewCells.size()]; 4742 4743 float viewSpaceFilterSize = Magnitude(mViewSpaceBox.Size())*relViewSpaceFilterSize; 4744 float spatialFilterSize = Magnitude(kdTree->GetBox().Size())*relSpatialFilterSize; 4745 4746 int i; 4747 for (i=0, it = mViewCells.begin(); it != it_end; ++ it, ++ i) { 4748 ApplyFilter(*it, 4749 kdTree, 4750 viewSpaceFilterSize, 4751 spatialFilterSize, 4752 newPvs[i] 4753 ); 4754 } 4755 4756 // now replace all pvss 4757 for (i = 0, it = mViewCells.begin(); it != it_end; ++ it, ++ i) { 4758 4759 ObjectPvs &pvs = (*it)->GetPvs(); 4760 pvs.Clear(); 4761 pvs = newPvs[i]; 4762 newPvs[i].Clear(); 4763 } 4764 4765 delete [] newPvs; 4766 } 4767 4768 void VspBspViewCellsManager::TestFilter(const ObjectContainer &objects) 4769 { 4770 Exporter *exporter = Exporter::GetExporter("filter.x3d"); 4771 4772 Vector3 bsize = mViewSpaceBox.Size(); 4773 const Vector3 viewPoint(mViewSpaceBox.Center()); 4774 float w = Magnitude(mViewSpaceBox.Size()) * mFilterWidth; 4775 const Vector3 width = Vector3(w); 4776 4777 PrVs testPrVs; 4778 4779 if (exporter) 4780 { 4781 ViewCellContainer viewCells; 4782 4783 const AxisAlignedBox3 tbox = GetFilterBBox(viewPoint, mFilterWidth); 4784 4785 GetPrVS(viewPoint, testPrVs, GetFilterWidth()); 4786 4787 exporter->SetWireframe(); 4788 4789 exporter->SetForcedMaterial(RgbColor(1,1,1)); 4790 exporter->ExportBox(tbox); 4791 4792 exporter->SetFilled(); 4793 4794 exporter->SetForcedMaterial(RgbColor(0,1,0)); 4795 ExportViewCellGeometry(exporter, GetViewCell(viewPoint)); 4796 4797 //exporter->ResetForcedMaterial(); 4798 exporter->SetForcedMaterial(RgbColor(0,0,1)); 4799 ExportViewCellGeometry(exporter, testPrVs.mViewCell); 4800 4801 exporter->SetForcedMaterial(RgbColor(1,0,0)); 4802 exporter->ExportGeometry(objects); 4803 4804 delete exporter; 4805 } 4806 } 4807 4808 4809 void VspBspViewCellsManager::CollectMergeCandidates(const VssRayContainer &rays, 4810 vector<MergeCandidate> &candidates) 4811 { 4812 cout << "collecting merge candidates ... " << endl; 4813 4814 if (mUseRaysForMerge) 4815 { 4816 mVspBspTree->CollectMergeCandidates(rays, candidates); 4817 } 4818 else 4819 { 4820 vector<BspLeaf *> leaves; 4821 mVspBspTree->CollectLeaves(leaves); 4822 4823 mVspBspTree->CollectMergeCandidates(leaves, candidates); 4824 } 4825 4826 cout << "fininshed collecting candidates" << endl; 5567 return NULL; 5568 5569 if (!mViewSpaceBox.IsInside(point)) 5570 return NULL; 5571 5572 return mVspTree->GetViewCell(point, active); 5573 } 5574 5575 5576 void VspOspViewCellsManager::CreateMesh(ViewCell *vc) 5577 { 5578 // matt: TODO 5579 Mesh *mesh = MeshManager::GetSingleton()->CreateResource(); 5580 vc->SetMesh(mesh); 5581 } 5582 5583 5584 int VspOspViewCellsManager::CastBeam(Beam &beam) 5585 { 5586 // matt: TODO 5587 return 0; 5588 } 5589 5590 5591 void VspOspViewCellsManager::Finalize(ViewCell *viewCell, 5592 const bool createMesh) 5593 { 5594 #if TODO 5595 float area = 0; 5596 float volume = 0; 5597 5598 ViewCellContainer leaves; 5599 mViewCellsTree->CollectLeaves(viewCell, leaves); 5600 5601 ViewCellContainer::const_iterator it, it_end = leaves.end(); 5602 5603 for (it = leaves.begin(); it != it_end; ++ it) 5604 { 5605 BspNodeGeometry geom; 5606 BspLeaf *leaf = dynamic_cast<BspViewCell *>(*it)->mLeaf; 5607 mVspBspTree->ConstructGeometry(leaf, geom); 5608 5609 const float lVol = geom.GetVolume(); 5610 const float lArea = geom.GetArea(); 5611 5612 //(*it)->SetVolume(vol); 5613 //(*it)->SetArea(area); 5614 5615 area += lArea; 5616 volume += lVol; 5617 5618 CreateMesh(*it); 5619 } 5620 5621 viewCell->SetVolume(volume); 5622 viewCell->SetArea(area); 5623 #endif 5624 } 5625 5626 5627 void VspOspViewCellsManager::PrepareLoadedViewCells() 5628 { 5629 // TODO 4827 5630 } 4828 5631 -
GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h
r1006 r1021 32 32 class MergeCandidate; 33 33 class BoundingBoxConverter; 34 class VspTree; 35 class OspTree; 36 class VspNode; 34 37 35 38 … … 66 69 67 70 /// view cell container types 68 enum {BSP, KD, VSP_KD, VSP_BSP };71 enum {BSP, KD, VSP_KD, VSP_BSP, VSP_OSP}; 69 72 70 73 /// render cost evaluation type … … 369 372 void CollectViewCells(const int n); 370 373 371 /** Returns true if this (logical) view cell is equal to a spatial node.372 */373 virtual bool EqualToSpatialNode(ViewCell *viewCell) const;374 375 374 /** Sets current view cells set to active, i.e., the sampling is done in this view cell set. 376 375 */ … … 472 471 473 472 473 /** Returns true if this view cell is equivalent to a node of the spatial hierarchy. 474 */ 475 virtual bool EqualToSpatialNode(ViewCell *viewCell) const; 476 474 477 protected: 475 478 /** Exports bounding boxes as xml stream … … 528 531 /** Sets exporter color. 529 532 */ 530 virtual void ExportColor(Exporter *exporter, ViewCell *vc) const = 0;533 virtual void ExportColor(Exporter *exporter, ViewCell *vc) const; 531 534 532 535 /** Returns volume of the view space. … … 619 622 /// if rays should be used to collect merge candidates 620 623 bool mUseRaysForMerge; 624 621 625 /// if there should be an additional merge step after the subdivision 622 626 bool mMergeViewCells; … … 718 722 protected: 719 723 720 721 724 void CollectViewCells(); 722 725 723 void ExportColor(Exporter *exporter, ViewCell *vc) const;724 726 725 727 /// the BSP tree. … … 799 801 KdNode *GetNodeForPvs(KdLeaf *leaf); 800 802 801 void ExportColor(Exporter *exporter, ViewCell *vc) const;802 803 803 804 804 /// the BSP tree. … … 880 880 BspNode *GetSpatialNode(ViewCell *viewCell) const; 881 881 882 /** Merges the view cells.882 /** Merges view cells according to some criteria 883 883 */ 884 884 void MergeViewCells(const VssRayContainer &rays, … … 895 895 896 896 897 void ExportColor(Exporter *exporter, ViewCell *vc) const;898 899 897 /** Prepare view cells for use after loading them from disc. 900 898 */ … … 921 919 void EvalFromPointQueries(); 922 920 921 /** Exports visualization of the BSP splits. 922 */ 923 void ExportSplits(const ObjectContainer &objects, 924 const VssRayContainer &rays); 925 926 /** Exports visualization of the BSP PVS. 927 */ 928 void ExportBspPvs(const ObjectContainer &objects, 929 const VssRayContainer &rays); 930 923 931 924 932 /// the view space partition BSP tree. … … 928 936 private: 929 937 930 /** Exports visualization of the BSP splits. 931 */ 932 void ExportSplits(const ObjectContainer &objects, 933 const VssRayContainer &rays); 938 /** test if subdivision is valid in terms of volume / area. 939 */ 940 void TestSubdivision(); 941 }; 942 943 944 /** 945 Manages different higher order operations on the view cells. 946 */ 947 class VspOspViewCellsManager: public ViewCellsManager 948 { 949 950 public: 951 952 VspOspViewCellsManager(VspTree *tree, OspTree *ospTree); 953 ~VspOspViewCellsManager(); 954 955 int ConstructSubdivision(const ObjectContainer &objects, 956 const VssRayContainer &rays); 957 958 int PostProcess(const ObjectContainer &objects, 959 const VssRayContainer &rays); 960 961 void Visualize(const ObjectContainer &objects, 962 const VssRayContainer &sampleRays); 963 964 int GetType() const; 965 966 ViewCell *GenerateViewCell(Mesh *mesh = NULL) const; 967 968 bool ViewCellsConstructed() const; 969 970 971 int CastLineSegment(const Vector3 &origin, 972 const Vector3 &termination, 973 ViewCellContainer &viewcells); 974 975 float GetProbability(ViewCell *viewCell); 976 977 ViewCell *GetViewCell(const Vector3 &point, const bool active = false) const; 978 979 bool GetViewPoint(Vector3 &viewPoint) const; 980 981 bool ViewPointValid(const Vector3 &viewPoint) const; 982 983 void CreateMesh(ViewCell *vc); 984 985 bool ExportViewCells(const string filename, const bool exportPvs, const ObjectContainer &objects); 986 987 int CastBeam(Beam &beam); 988 989 void ExportViewCellGeometry(Exporter *exporter, 990 ViewCell *vc, 991 const Plane3 *clipPlane = NULL) const; 992 993 void Finalize(ViewCell *viewCell, const bool createMesh); 994 995 996 protected: 997 998 int ComputeBoxIntersections(const AxisAlignedBox3 &box, ViewCellContainer &viewCells) const; 999 1000 void CollectViewCells(); 1001 1002 1003 /** Prepare view cells for use after loading them from disc. 1004 */ 1005 void PrepareLoadedViewCells(); 1006 1007 /** Constructs merge hierarchy which corresponds to the spatial hierarchy. 1008 */ 1009 ViewCell *ConstructSpatialMergeTree(VspNode *root); 1010 1011 void UpdatePvsForEvaluation(ViewCell *root, ObjectPvs &pvs); 934 1012 935 1013 /** Exports visualization of the BSP PVS. … … 938 1016 const VssRayContainer &rays); 939 1017 940 /** test if subdivision is valid in terms of volume / area. 941 */ 942 void TestSubdivision(); 1018 1019 /// the view space partition tree. 1020 VspTree *mVspTree; 1021 OspTree *mOspTree; 943 1022 }; 944 1023 -
GTP/trunk/Lib/Vis/Preprocessing/src/VspOspTree.cpp
r1020 r1021 50 50 51 51 52 53 void VspTreeStatistics::Print(ostream &app) const 54 { 55 #if TODO 56 app << "===== BspTree statistics ===============\n"; 57 58 app << setprecision(4); 59 60 app << "#N_CTIME ( Construction time [s] )\n" << Time() << " \n"; 61 62 app << "#N_NODES ( Number of nodes )\n" << nodes << "\n"; 63 64 app << "#N_INTERIORS ( Number of interior nodes )\n" << Interior() << "\n"; 65 66 app << "#N_LEAVES ( Number of leaves )\n" << Leaves() << "\n"; 67 68 app << "#N_POLYSPLITS ( Number of polygon splits )\n" << polySplits << "\n"; 69 70 app << "#AXIS_ALIGNED_SPLITS (number of axis aligned splits)\n" << splits[0] + splits[1] + splits[2] << endl; 71 72 app << "#N_SPLITS ( Number of splits in axes x y z)\n"; 73 74 for (int i = 0; i < 3; ++ i) 75 app << splits[i] << " "; 76 app << endl; 77 78 app << "#N_PMAXDEPTHLEAVES ( Percentage of leaves at maximum depth )\n" 79 << maxDepthNodes * 100 / (double)Leaves() << endl; 80 81 app << "#N_PMINPVSLEAVES ( Percentage of leaves with mininimal PVS )\n" 82 << minPvsNodes * 100 / (double)Leaves() << endl; 83 84 app << "#N_PMINRAYSLEAVES ( Percentage of leaves with minimal number of rays)\n" 85 << minRaysNodes * 100 / (double)Leaves() << endl; 86 87 app << "#N_MAXCOSTNODES ( Percentage of leaves with terminated because of max cost ratio )\n" 88 << maxCostNodes * 100 / (double)Leaves() << endl; 89 90 app << "#N_PMINPROBABILITYLEAVES ( Percentage of leaves with mininum probability )\n" 91 << minProbabilityNodes * 100 / (double)Leaves() << endl; 92 93 app << "#N_PMAXRAYCONTRIBLEAVES ( Percentage of leaves with maximal ray contribution )\n" 94 << maxRayContribNodes * 100 / (double)Leaves() << endl; 95 96 app << "#N_PMAXDEPTH ( Maximal reached depth )\n" << maxDepth << endl; 97 98 app << "#N_PMINDEPTH ( Minimal reached depth )\n" << minDepth << endl; 99 100 app << "#AVGDEPTH ( average depth )\n" << AvgDepth() << endl; 101 102 app << "#N_INPUTPOLYGONS (number of input polygons )\n" << polys << endl; 103 104 app << "#N_INVALIDLEAVES (number of invalid leaves )\n" << invalidLeaves << endl; 105 106 app << "#N_RAYS (number of rays / leaf)\n" << AvgRays() << endl; 107 //app << "#N_PVS: " << pvs << endl; 108 109 app << "#N_ROUTPUT_INPUT_POLYGONS ( ratio polygons after subdivision / input polygons )\n" << 110 (polys + polySplits) / (double)polys << endl; 111 112 app << "===== END OF BspTree statistics ==========\n"; 113 #endif 114 } 115 116 52 117 /******************************************************************/ 53 118 /* class VspNode implementation */ … … 218 283 } 219 284 285 220 286 int VspLeaf::Type() const 221 287 { 222 288 return Leaf; 223 289 } 224 225 290 226 291 … … 1383 1448 1384 1449 1450 void VspTree::SetViewCellsManager(ViewCellsManager *vcm) 1451 { 1452 mViewCellsManager = vcm; 1453 } 1454 1455 1385 1456 void VspTree::ValidateTree() 1386 1457 { … … 2160 2231 2161 2232 2233 2234 int VspTree::ComputeBoxIntersections(const AxisAlignedBox3 &box, 2235 ViewCellContainer &viewCells) const 2236 { 2237 #if TODO 2238 stack<bspNodePair> nodeStack; 2239 BspNodeGeometry *rgeom = new BspNodeGeometry(); 2240 2241 ConstructGeometry(mRoot, *rgeom); 2242 2243 nodeStack.push(bspNodePair(mRoot, rgeom)); 2244 2245 ViewCell::NewMail(); 2246 2247 while (!nodeStack.empty()) 2248 { 2249 BspNode *node = nodeStack.top().first; 2250 BspNodeGeometry *geom = nodeStack.top().second; 2251 nodeStack.pop(); 2252 2253 const int side = geom->ComputeIntersection(box); 2254 2255 switch (side) 2256 { 2257 case -1: 2258 // node geometry is contained in box 2259 CollectViewCells(node, true, viewCells, true); 2260 break; 2261 2262 case 0: 2263 if (node->IsLeaf()) 2264 { 2265 BspLeaf *leaf = dynamic_cast<BspLeaf *>(node); 2266 2267 if (!leaf->GetViewCell()->Mailed() && leaf->TreeValid()) 2268 { 2269 leaf->GetViewCell()->Mail(); 2270 viewCells.push_back(leaf->GetViewCell()); 2271 } 2272 } 2273 else 2274 { 2275 BspInterior *interior = dynamic_cast<BspInterior *>(node); 2276 2277 BspNode *first = interior->GetFront(); 2278 BspNode *second = interior->GetBack(); 2279 2280 BspNodeGeometry *firstGeom = new BspNodeGeometry(); 2281 BspNodeGeometry *secondGeom = new BspNodeGeometry(); 2282 2283 geom->SplitGeometry(*firstGeom, 2284 *secondGeom, 2285 interior->GetPlane(), 2286 mBox, 2287 //0.0000001f); 2288 mEpsilon); 2289 2290 nodeStack.push(bspNodePair(first, firstGeom)); 2291 nodeStack.push(bspNodePair(second, secondGeom)); 2292 } 2293 2294 break; 2295 default: 2296 // default: cull 2297 break; 2298 } 2299 DEL_PTR(geom); 2300 } 2301 2302 #endif 2303 return (int)viewCells.size(); 2304 } 2305 2306 2307 2162 2308 /*****************************************************************/ 2163 /* class O psTree implementation */2309 /* class OspTree implementation */ 2164 2310 /*****************************************************************/ 2165 2311 … … 2333 2479 2334 2480 2335 /*****************************************************************/ 2336 /* class HierarchyManager implementation */ 2337 /*****************************************************************/ 2481 bool OspTree::LocalTerminationCriteriaMet(const OspTraversalData &data) const 2482 { 2483 // matt: TODO 2484 return true; 2485 /* (((int)data.mRays->size() <= mTermMinRays) || 2486 (data.mPvs <= mTermMinPvs) || 2487 (data.mProbability <= mTermMinProbability) || 2488 (data.GetAvgRayContribution() > mTermMaxRayContribution) || 2489 (data.mDepth >= mTermMaxDepth));*/ 2490 } 2491 2492 2493 bool OspTree::GlobalTerminationCriteriaMet(const OspTraversalData &data) const 2494 { 2495 // matt: TODO 2496 return true; 2497 /*(mOutOfMemory || 2498 (mVspStats.Leaves() >= mMaxViewCells) || 2499 (mGlobalCostMisses >= mTermGlobalCostMissTolerance));*/ 2500 } 2501 2502 2503 void OspTree::EvaluateLeafStats(const OspTraversalData &data) 2504 { 2505 #if TODO 2506 // the node became a leaf -> evaluate stats for leafs 2507 VspLeaf *leaf = dynamic_cast<VspLeaf *>(data.mNode); 2508 2509 if (data.mPvs > mVspStats.maxPvs) 2510 { 2511 mVspStats.maxPvs = data.mPvs; 2512 } 2513 2514 mVspStats.pvs += data.mPvs; 2515 2516 if (data.mDepth < mVspStats.minDepth) 2517 { 2518 mVspStats.minDepth = data.mDepth; 2519 } 2520 2521 if (data.mDepth >= mTermMaxDepth) 2522 { 2523 ++ mVspStats.maxDepthNodes; 2524 //Debug << "new max depth: " << mVspStats.maxDepthNodes << endl; 2525 } 2526 2527 // accumulate rays to compute rays / leaf 2528 mVspStats.accumRays += (int)data.mRays->size(); 2529 2530 if (data.mPvs < mTermMinPvs) 2531 ++ mVspStats.minPvsNodes; 2532 2533 if ((int)data.mRays->size() < mTermMinRays) 2534 ++ mVspStats.minRaysNodes; 2535 2536 if (data.GetAvgRayContribution() > mTermMaxRayContribution) 2537 ++ mVspStats.maxRayContribNodes; 2538 2539 if (data.mProbability <= mTermMinProbability) 2540 ++ mVspStats.minProbabilityNodes; 2541 2542 // accumulate depth to compute average depth 2543 mVspStats.accumDepth += data.mDepth; 2544 2545 ++ mCreatedViewCells; 2546 2547 #ifdef _DEBUG 2548 Debug << "BSP stats: " 2549 << "Depth: " << data.mDepth << " (max: " << mTermMaxDepth << "), " 2550 << "PVS: " << data.mPvs << " (min: " << mTermMinPvs << "), " 2551 // << "Area: " << data.mProbability << " (min: " << mTermMinProbability << "), " 2552 << "#rays: " << (int)data.mRays->size() << " (max: " << mTermMinRays << "), " 2553 << "#pvs: " << leaf->GetViewCell()->GetPvs().GetSize() << "=, " 2554 << "#avg ray contrib (pvs): " << (float)data.mPvs / (float)data.mRays->size() << endl; 2555 #endif 2556 2557 #endif 2558 } 2559 2560 2561 /*********************************************************************/ 2562 /* class HierarchyManager implementation */ 2563 /*********************************************************************/ 2338 2564 2339 2565 HierarchyManager::HierarchyManager() -
GTP/trunk/Lib/Vis/Preprocessing/src/VspOspTree.h
r1020 r1021 309 309 virtual bool IsLeaf() const = 0; 310 310 311 virtual int Type() const ;311 virtual int Type() const = 0; 312 312 313 313 /** Determines whether this node is a root … … 435 435 bool IsLeaf() const; 436 436 437 virtualint Type() const;437 int Type() const; 438 438 439 439 /** Returns pointer of view cell.
Note: See TracChangeset
for help on using the changeset viewer.