Changeset 1021 for GTP/trunk/Lib/Vis


Ignore:
Timestamp:
06/19/06 16:14:40 (19 years ago)
Author:
mattausch
Message:

added view cells manager for vsposptree

Location:
GTP/trunk/Lib/Vis/Preprocessing/src
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp

    r1020 r1021  
    706706        case SPATIAL_BOX_BASED_DISTRIBUTION: 
    707707                return new SpatialBoxBasedDistribution(*this); 
    708         case OBJECTS_INTERIOR_DISTRIBUTION: 
    709                 return new ObjectsInteriorDistribution(*this); 
     708        //case OBJECTS_INTERIOR_DISTRIBUTION: 
     709        //      return new ObjectsInteriorDistribution(*this); 
    710710        default: // no valid strategy 
    711711                return NULL; 
  • GTP/trunk/Lib/Vis/Preprocessing/src/SamplingStrategy.cpp

    r1020 r1021  
    142142} 
    143143 
    144  
     144/* 
    145145bool ObjectsInteriorDistribution::GenerateSample(SimpleRay &ray) const 
    146146{ 
     
    170170 
    171171        return true; 
    172 } 
     172}*/ 
    173173 
    174174} 
  • GTP/trunk/Lib/Vis/Preprocessing/src/SamplingStrategy.h

    r1020 r1021  
    8686        for sampling the inside of a colon. 
    8787*/ 
    88 class ObjectsInteriorDistribution: public SamplingStrategy 
     88/*class ObjectsInteriorDistribution: public SamplingStrategy 
    8989{ 
    9090 public: 
     
    9494         virtual bool GenerateSample(SimpleRay &ray) const; 
    9595}; 
    96  
     96*/ 
    9797}; 
    9898 
  • GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp

    r1020 r1021  
    272272        } 
    273273        Debug << "empty view cells found: " << (int)mEmptyViewCells.size() << endl; 
     274} 
     275 
     276 
     277bool ViewCellsManager::EqualToSpatialNode(ViewCell *viewCell) const  
     278{  
     279        return false; 
    274280} 
    275281 
     
    11751181} 
    11761182 
     1183 
    11771184bool ViewCellsManager::CheckValidity(ViewCell *vc, 
    11781185                                                                         int minPvsSize, 
     
    11901197 
    11911198 
    1192 bool ViewCellsManager::EqualToSpatialNode(ViewCell *viewCell) const  
    1193 {  
    1194         return false; 
    1195 } 
    1196  
    11971199int ViewCellsManager::ComputeBoxIntersections(const AxisAlignedBox3 &box,  
    11981200                                                                                          ViewCellContainer &viewCells) const 
     
    12001202        return 0; 
    12011203}; 
     1204 
    12021205 
    12031206AxisAlignedBox3 ViewCellsManager::GetFilterBBox(const Vector3 &viewPoint,  
     
    21962199 
    21972200 
    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 
     2203void 
     2204ViewCellsManager::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)); 
    24892223        if (!ViewCellsConstructed()) 
    24902224                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 
     2264void 
     2265ViewCellsManager::ApplyFilter(KdTree *kdTree, 
     2266                                                          const float relViewSpaceFilterSize, 
     2267                                                          const float relSpatialFilterSize 
     2268                                                          ) 
     2269{ 
     2270 
    31302271        if (!ViewCellsConstructed()) 
    31312272                return; 
    31322273 
    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; 
    37512281   
    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(); 
    38662296        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 
     2307void 
     2308ViewCellsManager::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 
     2362void ViewCellsManager::ExportColor(Exporter *exporter, ViewCell *vc) const 
    43092363{ 
    43102364        const bool vcValid = CheckValidity(vc, mMinPvsSize, mMaxPvsSize); 
     
    43422396        case 2: // merges 
    43432397                { 
    4344             int lSize = mViewCellsTree->GetNumInitialViewCells(vc); 
     2398            const int lSize = mViewCellsTree->GetNumInitialViewCells(vc); 
    43452399                        importance = (float)lSize / (float)mCurrentViewCellsStats.maxLeaves; 
    43462400                } 
    43472401                break; 
     2402#if 0 
    43482403        case 3: // merge tree differene 
    43492404                { 
     
    43532408                } 
    43542409                break; 
     2410#endif 
    43552411        default: 
    43562412                break; 
     
    43642420        //Debug << "importance: " << importance << endl; 
    43652421        exporter->SetForcedMaterial(m); 
     2422} 
     2423 
     2424 
     2425/**********************************************************************/ 
     2426/*                 BspViewCellsManager implementation                 */ 
     2427/**********************************************************************/ 
     2428 
     2429 
     2430BspViewCellsManager::BspViewCellsManager(BspTree *bspTree): 
     2431ViewCellsManager(), mBspTree(bspTree) 
     2432{ 
     2433        Environment::GetSingleton()->GetIntValue("BspTree.Construction.samples", mInitialSamples); 
     2434        mBspTree->SetViewCellsManager(this); 
     2435        mBspTree->mViewCellsTree = mViewCellsTree; 
     2436} 
     2437 
     2438 
     2439bool BspViewCellsManager::ViewCellsConstructed() const 
     2440{ 
     2441        return mBspTree->GetRoot() != NULL; 
     2442} 
     2443 
     2444 
     2445ViewCell *BspViewCellsManager::GenerateViewCell(Mesh *mesh) const 
     2446{ 
     2447        return new BspViewCell(mesh); 
     2448} 
     2449 
     2450 
     2451int 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 
     2514void 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 
     2530float 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 
     2541int BspViewCellsManager::CastLineSegment(const Vector3 &origin, 
     2542                                                                                 const Vector3 &termination, 
     2543                                                                                 ViewCellContainer &viewcells) 
     2544{ 
     2545        return mBspTree->CastLineSegment(origin, termination, viewcells); 
     2546} 
     2547 
     2548 
     2549int 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 
     2702BspViewCellsManager::~BspViewCellsManager() 
     2703{ 
     2704} 
     2705 
     2706 
     2707int BspViewCellsManager::GetType() const 
     2708{ 
     2709        return BSP; 
     2710} 
     2711 
     2712 
     2713void 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 
     2766void 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 
     2794void 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 
     2888void 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 
     2922void 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 
     2984void 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 
     2998void 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 
     3032ViewCell *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 
     3044void 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 
     3065bool 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 
     3110ViewCell *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 
     3150void 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 
     3230KdViewCellsManager::KdViewCellsManager(KdTree *kdTree): 
     3231ViewCellsManager(), mKdTree(kdTree), mKdPvsDepth(100) 
     3232{ 
     3233} 
     3234 
     3235 
     3236float 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 
     3248void KdViewCellsManager::CollectViewCells() 
     3249{ 
     3250        //mKdTree->CollectViewCells(mViewCells); TODO 
     3251} 
     3252 
     3253 
     3254int 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 
     3277bool KdViewCellsManager::ViewCellsConstructed() const 
     3278{ 
     3279        return mKdTree->GetRoot() != NULL; 
     3280} 
     3281 
     3282 
     3283int KdViewCellsManager::PostProcess(const ObjectContainer &objects, 
     3284                                                                        const VssRayContainer &rays) 
     3285{ 
     3286        return 0; 
     3287} 
     3288 
     3289 
     3290void 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 
     3462ViewCell *KdViewCellsManager::GenerateViewCell(Mesh *mesh) const 
     3463{ 
     3464        return new KdViewCell(mesh); 
     3465} 
     3466 
     3467 
     3468void 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 
     3486int KdViewCellsManager::GetType() const 
     3487{ 
     3488        return ViewCellsManager::KD; 
     3489} 
     3490 
     3491 
     3492 
     3493KdNode *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 
     3502int KdViewCellsManager::CastLineSegment(const Vector3 &origin, 
     3503                                                                                const Vector3 &termination, 
     3504                                                                                ViewCellContainer &viewcells) 
     3505{ 
     3506        return mKdTree->CastLineSegment(origin, termination, viewcells); 
     3507} 
     3508 
     3509 
     3510void KdViewCellsManager::CreateMesh(ViewCell *vc) 
     3511{ 
     3512        // TODO 
     3513} 
     3514 
     3515 
     3516 
     3517void KdViewCellsManager::CollectMergeCandidates(const VssRayContainer &rays,  
     3518                                                                                                vector<MergeCandidate> &candidates) 
     3519{ 
     3520        // TODO 
     3521} 
     3522 
     3523 
     3524 
     3525 
     3526/**************************************************************************/ 
     3527/*                   VspBspViewCellsManager implementation                */ 
     3528/**************************************************************************/ 
     3529 
     3530 
     3531VspBspViewCellsManager::VspBspViewCellsManager(VspBspTree *vspBspTree): 
     3532ViewCellsManager(), mVspBspTree(vspBspTree) 
     3533{ 
     3534        Environment::GetSingleton()->GetIntValue("VspBspTree.Construction.samples", mInitialSamples); 
     3535        mVspBspTree->SetViewCellsManager(this); 
     3536        mVspBspTree->mViewCellsTree = mViewCellsTree; 
     3537} 
     3538 
     3539 
     3540VspBspViewCellsManager::~VspBspViewCellsManager() 
     3541{ 
     3542} 
     3543 
     3544 
     3545float 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 
     3554void 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 
     3568void 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 
     3589bool VspBspViewCellsManager::ViewCellsConstructed() const 
     3590{ 
     3591        return mVspBspTree->GetRoot() != NULL; 
     3592} 
     3593 
     3594 
     3595ViewCell *VspBspViewCellsManager::GenerateViewCell(Mesh *mesh) const 
     3596{ 
     3597        return new BspViewCell(mesh); 
     3598} 
     3599 
     3600 
     3601int 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 
     3677void 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 
     3798bool VspBspViewCellsManager::EqualToSpatialNode(ViewCell *viewCell) const 
     3799{ 
     3800        return GetSpatialNode(viewCell) != NULL; 
     3801} 
     3802 
     3803 
     3804BspNode *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 
     3836void 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 
     3861int 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 
     3982int VspBspViewCellsManager::GetType() const 
     3983{ 
     3984        return VSP_BSP; 
     3985} 
     3986 
     3987 
     3988ViewCell *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 
     4032void 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 
     4108bool 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 
     4130bool 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 
     4141void 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 
     4274void 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 
     4307void 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 
     4474void 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 
     4515int VspBspViewCellsManager::ComputeBoxIntersections(const AxisAlignedBox3 &box,  
     4516                                                                                                        ViewCellContainer &viewCells) const 
     4517{ 
     4518        return mVspBspTree->ComputeBoxIntersections(box, viewCells); 
     4519} 
     4520 
     4521 
     4522int VspBspViewCellsManager::CastLineSegment(const Vector3 &origin, 
     4523                                                                                        const Vector3 &termination, 
     4524                                                                                        ViewCellContainer &viewcells) 
     4525{ 
     4526        return mVspBspTree->CastLineSegment(origin, termination, viewcells); 
    43664527} 
    43674528 
     
    45084669ViewCell *VspBspViewCellsManager::GetViewCell(const Vector3 &point, const bool active) const 
    45094670{ 
    4510         if (!mVspBspTree) 
     4671        if (!ViewCellsConstructed()) 
    45114672                return NULL; 
    45124673 
     
    46124773} 
    46134774 
    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 
     4782VspOspViewCellsManager::VspOspViewCellsManager(VspTree *vspTree, OspTree *ospTree): 
     4783ViewCellsManager(), mVspTree(vspTree), mOspTree(ospTree) 
     4784{ 
     4785        Environment::GetSingleton()->GetIntValue("VspBspTree.Construction.samples", mInitialSamples); 
     4786        mVspTree->SetViewCellsManager(this); 
     4787        mVspTree->mViewCellsTree = mViewCellsTree; 
     4788} 
     4789 
     4790 
     4791VspOspViewCellsManager::~VspOspViewCellsManager() 
     4792{ 
     4793} 
     4794 
     4795 
     4796float VspOspViewCellsManager::GetProbability(ViewCell *viewCell) 
     4797{ 
     4798        return GetVolume(viewCell) / mViewSpaceBox.GetVolume(); 
     4799} 
     4800 
     4801 
     4802void 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 
     4816bool VspOspViewCellsManager::ViewCellsConstructed() const 
     4817{ 
     4818        return mVspTree->GetRoot() != NULL; 
     4819} 
     4820 
     4821 
     4822ViewCell *VspOspViewCellsManager::GenerateViewCell(Mesh *mesh) const 
     4823{ 
     4824        return new VspViewCell(mesh); 
     4825} 
     4826 
     4827 
     4828int 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 
     4905int 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); 
    46264971   
    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 
     5006int VspOspViewCellsManager::GetType() const 
     5007{ 
     5008        return VSP_OSP; 
     5009} 
     5010 
     5011 
     5012ViewCell *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 
     5056void 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 
     5130bool 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 
     5152bool 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 
     5163void VspOspViewCellsManager::Visualize(const ObjectContainer &objects, 
     5164                                                                           const VssRayContainer &sampleRays) 
     5165{ 
    46875166        if (!ViewCellsConstructed()) 
    46885167                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 
     5298void 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 
     5465int VspOspViewCellsManager::ComputeBoxIntersections(const AxisAlignedBox3 &box,  
     5466                                                                                                        ViewCellContainer &viewCells) const 
     5467{ 
     5468        return mVspTree->ComputeBoxIntersections(box, viewCells); 
     5469} 
     5470 
     5471 
     5472int VspOspViewCellsManager::CastLineSegment(const Vector3 &origin, 
     5473                                                                                        const Vector3 &termination, 
     5474                                                                                        ViewCellContainer &viewcells) 
     5475{ 
     5476        return mVspTree->CastLineSegment(origin, termination, viewcells); 
     5477} 
     5478 
     5479 
     5480void VspOspViewCellsManager::ExportViewCellGeometry(Exporter *exporter, 
     5481                                                    ViewCell *vc, 
     5482                                                                                                        const Plane3 *clipPlane) const 
     5483{ 
     5484        // matt: TODO 
     5485} 
     5486 
     5487 
     5488bool 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 
     5564ViewCell *VspOspViewCellsManager::GetViewCell(const Vector3 &point, const bool active) const 
     5565{ 
    47355566        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 
     5576void VspOspViewCellsManager::CreateMesh(ViewCell *vc) 
     5577{ 
     5578        // matt: TODO 
     5579        Mesh *mesh = MeshManager::GetSingleton()->CreateResource(); 
     5580        vc->SetMesh(mesh); 
     5581} 
     5582 
     5583 
     5584int VspOspViewCellsManager::CastBeam(Beam &beam) 
     5585{ 
     5586        // matt: TODO 
     5587        return 0; 
     5588} 
     5589 
     5590 
     5591void 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 
     5627void VspOspViewCellsManager::PrepareLoadedViewCells() 
     5628{ 
     5629        // TODO 
    48275630} 
    48285631 
  • GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h

    r1006 r1021  
    3232class MergeCandidate; 
    3333class BoundingBoxConverter; 
     34class VspTree; 
     35class OspTree; 
     36class VspNode; 
    3437 
    3538 
     
    6669 
    6770        /// view cell container types 
    68         enum {BSP, KD, VSP_KD, VSP_BSP}; 
     71        enum {BSP, KD, VSP_KD, VSP_BSP, VSP_OSP}; 
    6972   
    7073        /// render cost evaluation type 
     
    369372        void CollectViewCells(const int n); 
    370373 
    371         /** Returns true if this (logical) view cell is equal to a spatial node. 
    372         */ 
    373         virtual bool EqualToSpatialNode(ViewCell *viewCell) const; 
    374  
    375374        /** Sets current view cells set to active, i.e., the sampling is done in this view cell set. 
    376375        */ 
     
    472471 
    473472 
     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 
    474477protected: 
    475478        /** Exports bounding boxes as xml stream 
     
    528531        /** Sets exporter color. 
    529532        */ 
    530         virtual void ExportColor(Exporter *exporter, ViewCell *vc) const = 0; 
     533        virtual void ExportColor(Exporter *exporter, ViewCell *vc) const; 
    531534 
    532535        /** Returns volume of the view space. 
     
    619622        /// if rays should be used to collect merge candidates 
    620623        bool mUseRaysForMerge; 
     624 
    621625        /// if there should be an additional merge step after the subdivision 
    622626        bool mMergeViewCells; 
     
    718722protected: 
    719723 
    720  
    721724        void CollectViewCells(); 
    722725 
    723         void ExportColor(Exporter *exporter, ViewCell *vc) const; 
    724726         
    725727        /// the BSP tree. 
     
    799801        KdNode *GetNodeForPvs(KdLeaf *leaf); 
    800802 
    801         void ExportColor(Exporter *exporter, ViewCell *vc) const; 
    802  
    803803 
    804804        /// the BSP tree. 
     
    880880        BspNode *GetSpatialNode(ViewCell *viewCell) const; 
    881881 
    882         /** Merges the view cells. 
     882        /** Merges view cells according to some criteria 
    883883        */ 
    884884        void MergeViewCells(const VssRayContainer &rays,  
     
    895895         
    896896 
    897         void ExportColor(Exporter *exporter, ViewCell *vc) const; 
    898  
    899897        /** Prepare view cells for use after loading them from disc. 
    900898        */ 
     
    921919        void EvalFromPointQueries(); 
    922920 
     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 
    923931 
    924932        /// the view space partition BSP tree. 
     
    928936private: 
    929937 
    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*/ 
     947class VspOspViewCellsManager: public ViewCellsManager 
     948{ 
     949 
     950public: 
     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 
     996protected: 
     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); 
    9341012 
    9351013        /** Exports visualization of the BSP PVS. 
     
    9381016                                          const VssRayContainer &rays); 
    9391017 
    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; 
    9431022}; 
    9441023 
  • GTP/trunk/Lib/Vis/Preprocessing/src/VspOspTree.cpp

    r1020 r1021  
    5050 
    5151 
     52 
     53void 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 
    52117/******************************************************************/ 
    53118/*                  class VspNode implementation                  */ 
     
    218283} 
    219284 
     285 
    220286int VspLeaf::Type() const 
    221287{ 
    222288        return Leaf; 
    223289} 
    224  
    225290 
    226291 
     
    13831448 
    13841449 
     1450void VspTree::SetViewCellsManager(ViewCellsManager *vcm) 
     1451{ 
     1452        mViewCellsManager = vcm; 
     1453} 
     1454 
     1455 
    13851456void VspTree::ValidateTree() 
    13861457{ 
     
    21602231 
    21612232 
     2233 
     2234int 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 
    21622308/*****************************************************************/ 
    2163 /*                class OpsTree implementation                   */ 
     2309/*                class OspTree implementation                   */ 
    21642310/*****************************************************************/ 
    21652311 
     
    23332479 
    23342480 
    2335 /*****************************************************************/ 
    2336 /*              class HierarchyManager implementation            */ 
    2337 /*****************************************************************/ 
     2481bool 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 
     2493bool 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 
     2503void 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/*********************************************************************/ 
    23382564 
    23392565HierarchyManager::HierarchyManager() 
  • GTP/trunk/Lib/Vis/Preprocessing/src/VspOspTree.h

    r1020 r1021  
    309309        virtual bool IsLeaf() const = 0; 
    310310 
    311         virtual int Type() const; 
     311        virtual int Type() const = 0; 
    312312 
    313313        /** Determines whether this node is a root 
     
    435435        bool IsLeaf() const; 
    436436         
    437                 virtual int Type() const; 
     437        int Type() const; 
    438438 
    439439        /** Returns pointer of view cell. 
Note: See TracChangeset for help on using the changeset viewer.