Ignore:
Timestamp:
06/18/06 03:47:06 (18 years ago)
Author:
mattausch
Message:

worked on view-object space partition
fixed some loading bugs
fixeds some exporting bugs using line segments
enabling other methods for view space sampling in ViewCellsManager? OBJECT_DIRECTION_BASED_DISTRIBUTION)
added class interface for a sampling strategy

File:
1 edited

Legend:

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

    r1016 r1020  
    1616#include "ViewCellsManager.h" 
    1717#include "Beam.h" 
     18#include "KdTree.h" 
     19 
    1820 
    1921namespace GtpVisibilityPreprocessor { 
     
    381383 
    382384 
    383 void VspTree::Construct(const VssRayContainer &sampleRays, 
    384                                                    AxisAlignedBox3 *forcedBoundingBox) 
     385void VspTree::PrepareConstruction(const VssRayContainer &sampleRays, 
     386                                                                  AxisAlignedBox3 *forcedBoundingBox)  
    385387{ 
    386388        mVspStats.nodes = 1; 
    387         mBox.Initialize();      // initialise BSP tree bounding box 
     389        mBoundingBox.Initialize();      // initialise vsp tree bounding box 
    388390 
    389391        if (forcedBoundingBox) 
    390                 mBox = *forcedBoundingBox; 
    391          
    392         PolygonContainer polys; 
    393         RayInfoContainer *rays = new RayInfoContainer(); 
    394  
     392                mBoundingBox = *forcedBoundingBox; 
     393         
    395394        VssRayContainer::const_iterator rit, rit_end = sampleRays.end(); 
    396395 
    397         long startTime = GetTime(); 
    398  
    399         cout << "Extracting polygons from rays ... "; 
    400  
    401396        Intersectable::NewMail(); 
    402397 
    403         int numObj = 0; 
    404  
    405         //-- store rays 
     398        //-- compute bounding box 
    406399        for (rit = sampleRays.begin(); rit != rit_end; ++ rit) 
    407400        { 
    408401                VssRay *ray = *rit; 
    409402 
    410                 float minT, maxT; 
    411  
    412                 static Ray hray; 
    413                 hray.Init(*ray); 
    414  
    415                 // TODO: not very efficient to implictly cast between rays types 
    416                 if (mBox.GetRaySegment(hray, minT, maxT)) 
    417                 { 
    418                         float len = ray->Length(); 
    419  
    420                         if (!len) 
    421                                 len = Limits::Small; 
    422  
    423                         rays->push_back(RayInfo(ray, minT / len, maxT / len)); 
    424                 } 
    425         } 
    426  
    427         mTermMinProbability *= mBox.GetVolume(); 
    428  
     403                // compute bounding box of view space 
     404                if (!forcedBoundingBox) 
     405                { 
     406                        mBoundingBox.Include(ray->GetTermination()); 
     407                        mBoundingBox.Include(ray->GetOrigin()); 
     408                } 
     409        } 
     410 
     411        mTermMinProbability *= mBoundingBox.GetVolume(); 
    429412        mGlobalCostMisses = 0; 
    430  
    431         cout << "finished" << endl; 
    432  
    433         // use split cost priority queue 
    434         Construct(rays); 
     413} 
     414 
     415 
     416void VspTree::AddSubdivisionStats(const int viewCells, 
     417                                                                  const float renderCostDecr, 
     418                                                                  const float splitCandidateCost, 
     419                                                                  const float totalRenderCost, 
     420                                                                         const float avgRenderCost) 
     421{ 
     422        mSubdivisionStats  
     423                        << "#ViewCells\n" << viewCells << endl 
     424                        << "#RenderCostDecrease\n" << renderCostDecr << endl  
     425                        << "#SplitCandidateCost\n" << splitCandidateCost << endl 
     426                        << "#TotalRenderCost\n" << totalRenderCost << endl 
     427                        << "#AvgRenderCost\n" << avgRenderCost << endl; 
    435428} 
    436429 
     
    449442 
    450443 
    451 void VspTree::Construct(RayInfoContainer *rays) 
    452 { 
    453 #if TODO 
    454         VspSplitQueue tQueue; 
    455         /// create new vsp tree 
    456         mRoot = new VspLeaf(); 
    457         /// we use the overall probability as normalizer 
    458         const float prop = mBox.GetVolume(); 
    459  
    460         VspTraversalData tData(mRoot, 
    461                                                   0, 
    462                                                   rays, 
    463                           ComputePvsSize(*rays), 
    464                                                   prop, 
    465                                                   mBox); 
    466  
    467  
    468         // compute first split candidate 
    469         VspSplitCandidate splitCandidate; 
    470         EvalSplitCandidate(tData, splitCandidate); 
    471  
    472         tQueue.push(splitCandidate); 
    473  
    474         mTotalCost = tData.mPvs * tData.mProbability / mBox.GetVolume(); 
    475         mTotalPvsSize = tData.mPvs; 
    476          
    477         mSubdivisionStats  
    478                         << "#ViewCells\n1\n" <<  endl 
    479                         << "#RenderCostDecrease\n0\n" << endl  
    480                         << "#SplitCandidateCost\n0\n" << endl 
    481                         << "#TotalRenderCost\n" << mTotalCost << endl 
    482                         << "#AvgRenderCost\n" << mTotalPvsSize << endl; 
    483  
    484         Debug << "total cost: " << mTotalCost << endl; 
    485          
    486          
    487         mVspStats.Start(); 
    488         cout << "Constructing vsp bsp tree ... \n"; 
    489  
    490         long startTime = GetTime();      
    491         int nLeaves = 500; 
    492         int nViewCells = 500; 
    493  
    494         // used for intermediate time measurements and progress 
    495         long interTime = GetTime();      
    496  
    497         mOutOfMemory = false; 
    498  
    499         mCreatedViewCells = 0; 
    500          
    501         while (!tQueue.empty()) 
    502         { 
    503                 splitCandidate = tQueue.top(); 
    504             tQueue.pop();                
    505  
    506                 // cost ratio of cost decrease / totalCost 
    507                 float costRatio = splitCandidate.GetCost() / mTotalCost; 
    508  
    509                 //Debug << "cost ratio: " << costRatio << endl; 
    510  
    511                 if (costRatio < mTermMinGlobalCostRatio) 
    512                         ++ mGlobalCostMisses; 
    513                  
    514                 if (0 && !mOutOfMemory) 
    515                 { 
    516                         float mem = GetMemUsage(); 
    517  
    518                         if (mem > mMaxMemory) 
    519                         { 
    520                                 mOutOfMemory = true; 
    521                                 Debug << "memory limit reached: " << mem << endl; 
    522                         } 
    523                 } 
    524  
    525                 // subdivide leaf node 
    526                 VspNode *r = Subdivide(tQueue, splitCandidate); 
    527  
    528                 if (r == mRoot) 
    529                         Debug << "VSP BSP tree construction time spent at root: " 
    530                                   << TimeDiff(startTime, GetTime())*1e-3 << "s" << endl; 
    531  
    532                 if (mVspStats.Leaves() >= nLeaves) 
    533                 { 
    534                         nLeaves += 500; 
    535  
    536                         cout << "leaves=" << mVspStats.Leaves() << endl; 
    537                         Debug << "needed " 
    538                                   << TimeDiff(interTime, GetTime())*1e-3  
    539                                   << " secs to create 500 view cells" << endl; 
    540                         interTime = GetTime(); 
    541                 } 
    542  
    543                 if (mCreatedViewCells == nViewCells) 
    544                 { 
    545                         nViewCells += 500; 
    546  
    547                         cout << "generated " << mCreatedViewCells << " viewcells" << endl; 
    548                 } 
    549         } 
    550  
    551         Debug << "Used Memory: " << GetMemUsage() << " MB" << endl << endl; 
    552         cout << "finished\n"; 
    553  
    554         mVspStats.Stop(); 
    555 #endif 
    556 } 
    557  
    558  
    559444bool VspTree::LocalTerminationCriteriaMet(const VspTraversalData &data) const 
    560445{ 
     
    577462 
    578463 
    579 // subdivide using a split plane queue 
    580464VspNode *VspTree::Subdivide(SplitQueue &tQueue, 
    581                                                         VspSplitCandidate &splitCandidate) 
     465                                                        VspSplitCandidate &splitCandidate, 
     466                                                        const bool globalCriteriaMet) 
    582467{ 
    583468        VspTraversalData &tData = splitCandidate.mParentData; 
     
    585470        VspNode *newNode = tData.mNode; 
    586471 
    587         if (!LocalTerminationCriteriaMet(tData) && !GlobalTerminationCriteriaMet(tData)) 
     472        if (!LocalTerminationCriteriaMet(tData) && !globalCriteriaMet) 
    588473        {        
    589474                VspTraversalData tFrontData; 
     
    594479                // create new interior node and two leaf node 
    595480                const AxisAlignedPlane splitPlane = splitCandidate.mSplitPlane; 
    596  
    597481                newNode = SubdivideNode(splitPlane, tData, tFrontData, tBackData); 
    598482         
     
    604488                tBackData.mMaxCostMisses = maxCostMisses; 
    605489                         
    606                  
     490                //-- statistics 
    607491                if (1) 
    608492                { 
    609                         float cFront = (float)tFrontData.mPvs * tFrontData.mProbability; 
    610                         float cBack = (float)tBackData.mPvs * tBackData.mProbability; 
    611                         float cData = (float)tData.mPvs * tData.mProbability; 
    612  
    613                          
    614                         float costDecr =  
    615                                 (cFront + cBack - cData) / mBox.GetVolume(); 
     493                        const float cFront = (float)tFrontData.mPvs * tFrontData.mProbability; 
     494                        const float cBack = (float)tBackData.mPvs * tBackData.mProbability; 
     495                        const float cData = (float)tData.mPvs * tData.mProbability; 
     496         
     497                        const float costDecr =  
     498                                (cFront + cBack - cData) / mBoundingBox.GetVolume(); 
    616499 
    617500                        mTotalCost += costDecr; 
    618501                        mTotalPvsSize += tFrontData.mPvs + tBackData.mPvs - tData.mPvs; 
    619502 
    620                         mSubdivisionStats  
    621                                         << "#ViewCells\n" << mVspStats.Leaves() << endl 
    622                                         << "#RenderCostDecrease\n" << -costDecr << endl 
    623                                         << "#SplitCandidateCost\n" << splitCandidate.GetPriority() << endl 
    624                                         << "#TotalRenderCost\n" << mTotalCost << endl 
    625                                         << "#AvgRenderCost\n" << (float)mTotalPvsSize / (float)mVspStats.Leaves() << endl; 
    626                 } 
    627  
    628          
    629                 //-- push the new split candidates on the stack 
    630                 VspSplitCandidate frontCandidate; 
    631                 VspSplitCandidate backCandidate; 
    632  
    633                 EvalSplitCandidate(tFrontData, frontCandidate); 
    634                 EvalSplitCandidate(tBackData, backCandidate); 
    635 #if TODO 
     503                        AddSubdivisionStats(mVspStats.Leaves(), 
     504                                                                -costDecr, 
     505                                                                splitCandidate.GetPriority(), 
     506                                                                mTotalCost, 
     507                                                                (float)mTotalPvsSize / (float)mVspStats.Leaves()); 
     508                } 
     509 
     510         
     511                //-- push the new split candidates on the queue 
     512                VspSplitCandidate *frontCandidate = new VspSplitCandidate(); 
     513                VspSplitCandidate *backCandidate = new VspSplitCandidate(); 
     514 
     515                EvalSplitCandidate(tFrontData, *frontCandidate); 
     516                EvalSplitCandidate(tBackData, *backCandidate); 
     517 
    636518                tQueue.push(frontCandidate); 
    637519                tQueue.push(backCandidate); 
    638 #endif 
     520 
    639521                // delete old leaf node 
    640522                DEL_PTR(tData.mNode); 
     
    646528        { 
    647529                VspLeaf *leaf = dynamic_cast<VspLeaf *>(newNode); 
     530         
    648531                VspViewCell *viewCell = new VspViewCell(); 
    649  
    650532        leaf->SetViewCell(viewCell); 
    651533                 
     
    671553                        } 
    672554                } 
    673  
    674                 // should I check here? 
     555                 
    675556                viewCell->mLeaf = leaf; 
    676557 
     
    678559        leaf->mProbability = tData.mProbability; 
    679560 
    680                 EvaluateLeafStats(tData);                
     561                // finally evaluate stats until this leaf 
     562                EvaluateLeafStats(tData); 
    681563        } 
    682564 
    683565        //-- cleanup 
    684566        tData.Clear(); 
    685  
     567         
    686568        return newNode; 
    687569} 
     
    691573                                                                 VspSplitCandidate &splitData) 
    692574{ 
    693         VspTraversalData frontData; 
    694         VspTraversalData backData; 
    695  
     575        float frontProb; 
     576        float backtProb; 
     577         
    696578        VspLeaf *leaf = dynamic_cast<VspLeaf *>(tData.mNode); 
    697  
     579         
    698580        // compute locally best split plane 
    699581        const bool success =  
    700582                SelectPlane(tData, splitData.mSplitPlane, 
    701                                         frontData.mProbability, backData.mProbability); 
     583                                        frontProb, backtProb); 
    702584 
    703585        //TODO 
     
    789671        return interior; 
    790672} 
    791  
    792 /* 
    793 KdNode *VspOpsTree::SubdivideSpatialNode(KdLeaf *leaf, 
    794                                                                                  const AxisAlignedPlane &splitPlane, 
    795                                                                                  const AxisAlignedBox3 &box, 
    796                                                                                  AxisAlignedBox3 &backBBox, 
    797                                                                                  AxisAlignedBox3 &frontBBox) 
    798 { 
    799         float position; 
    800  
    801 #if TODO 
    802     mSpatialStat.nodes += 2; 
    803         mSpatialStat.splits[axis]; 
    804 #endif 
    805  
    806         // add the new nodes to the tree 
    807         KdInterior *node = new KdInterior(leaf->mParent); 
    808  
    809         node->mAxis = splitPlane.mAxis; 
    810         node->mPosition = splitPlane.mPosition; 
    811         node->mBox = box; 
    812  
    813     backBBox = box; 
    814         frontBBox = box; 
    815    
    816         // first count ray sides 
    817         int objectsBack = 0; 
    818         int objectsFront = 0; 
    819    
    820         backBBox.SetMax(axis, position); 
    821         frontBBox.SetMin(axis, position); 
    822  
    823         SplitObjects(leaf->m 
    824         ObjectContainer::const_iterator mi, mi_end = leaf->mObjects.end(); 
    825  
    826         for ( mi = leaf->mObjects.begin(); mi != mi_end; ++ mi)  
    827         { 
    828                 // determine the side of this ray with respect to the plane 
    829                 AxisAlignedBox3 box = (*mi)->GetBox(); 
    830                  
    831                 if (box.Max(axis) > position )  
    832                         ++ objectsFront; 
    833      
    834                 if (box.Min(axis) < position ) 
    835       objectsBack++; 
    836   } 
    837  
    838    
    839   KdLeaf *back = new KdLeaf(node, objectsBack); 
    840   KdLeaf *front = new KdLeaf(node, objectsFront); 
    841  
    842   // replace a link from node's parent 
    843   if (  leaf->mParent ) 
    844     leaf->mParent->ReplaceChildLink(leaf, node); 
    845  
    846   // and setup child links 
    847   node->SetupChildLinks(back, front); 
    848    
    849   for (mi = leaf->mObjects.begin(); 
    850        mi != leaf->mObjects.end(); 
    851        mi++) { 
    852     // determine the side of this ray with respect to the plane 
    853     AxisAlignedBox3 box = (*mi)->GetBox(); 
    854  
    855     if (box.Max(axis) >= position ) 
    856       front->mObjects.push_back(*mi); 
    857      
    858     if (box.Min(axis) < position ) 
    859       back->mObjects.push_back(*mi); 
    860      
    861     mStat.objectRefs -= (int)leaf->mObjects.size(); 
    862     mStat.objectRefs += objectsBack + objectsFront; 
    863   } 
    864    
    865   delete leaf; 
    866   return node; 
    867 } 
    868 */ 
    869  
    870673 
    871674 
     
    12671070                 
    12681071 
    1269         // -- pvs rendering heuristics 
     1072        //-- pvs rendering heuristics 
    12701073        const int lowerPvsLimit = mViewCellsManager->GetMinPvsSize(); 
    12711074        const int upperPvsLimit = mViewCellsManager->GetMaxPvsSize(); 
    12721075 
    1273         // only render cost heuristics or combined with standard deviation 
    1274         const float penaltyOld = EvalPvsPenalty(totalPvs, lowerPvsLimit, upperPvsLimit); 
    1275     const float penaltyFront = EvalPvsPenalty(pvsFront, lowerPvsLimit, upperPvsLimit); 
    1276         const float penaltyBack = EvalPvsPenalty(pvsBack, lowerPvsLimit, upperPvsLimit); 
     1076        //-- only render cost heuristics or combined with standard deviation 
     1077        const float penaltyOld = EvalPvsPenalty((int)totalPvs, lowerPvsLimit, upperPvsLimit); 
     1078    const float penaltyFront = EvalPvsPenalty((int)pvsFront, lowerPvsLimit, upperPvsLimit); 
     1079        const float penaltyBack = EvalPvsPenalty((int)pvsBack, lowerPvsLimit, upperPvsLimit); 
    12771080                         
    12781081        const float oldRenderCost = pOverall * penaltyOld; 
     
    12801083 
    12811084        //Debug << "decrease: " << oldRenderCost - newRenderCost << endl; 
    1282         const float renderCostDecrease = (oldRenderCost - newRenderCost) / mBox.GetVolume(); 
     1085        const float renderCostDecrease = (oldRenderCost - newRenderCost) / mBoundingBox.GetVolume(); 
    12831086         
    12841087 
    12851088#if 1 
    1286         // take render cost of node into account to avoid being stuck in a local minimum 
    1287         const float normalizedOldRenderCost = oldRenderCost / mBox.GetVolume(); 
     1089        // take render cost of node into account  
     1090        // otherwise danger of being stuck in a local minimum!! 
     1091        const float normalizedOldRenderCost = oldRenderCost / mBoundingBox.GetVolume(); 
    12881092        return 0.99f * renderCostDecrease + 0.01f * normalizedOldRenderCost; 
    12891093#else 
     
    14341238AxisAlignedBox3 VspTree::GetBoundingBox() const 
    14351239{ 
    1436         return mBox; 
     1240        return mBoundingBox; 
    14371241} 
    14381242 
     
    15811385void VspTree::ValidateTree() 
    15821386{ 
     1387        mVspStats.invalidLeaves = 0; 
     1388 
    15831389        stack<VspNode *> nodeStack; 
    15841390 
     
    15871393 
    15881394        nodeStack.push(mRoot); 
    1589          
    1590         mVspStats.invalidLeaves = 0; 
     1395 
    15911396        while (!nodeStack.empty())  
    15921397        { 
     
    16621467                } 
    16631468        } 
    1664  
    16651469} 
    16661470 
    16671471 
    16681472int VspTree::FindNeighbors(VspLeaf *n, 
    1669                                                           vector<VspLeaf *> &neighbors, 
    1670                                                           const bool onlyUnmailed) const 
     1473                                                   vector<VspLeaf *> &neighbors, 
     1474                                                   const bool onlyUnmailed) const 
    16711475{ 
    16721476        stack<VspNode *> nodeStack; 
    1673  
    16741477        nodeStack.push(mRoot); 
    16751478 
     
    19461749        float maxt, mint; 
    19471750 
    1948         if (!mBox.GetRaySegment(ray, mint, maxt)) 
     1751        if (!mBoundingBox.GetRaySegment(ray, mint, maxt)) 
    19491752                return 0; 
    19501753 
     
    19781781                                        // cases N1,N2,N3,P5,Z2,Z3 
    19791782                                        continue; 
    1980                                 } else 
     1783                                }  
     1784                                else 
    19811785                                { 
    19821786                                        // case N4 
     
    20201824                                ++ hits; 
    20211825                        } 
    2022  
    20231826#if 0 
    2024                                 leaf->mRays.push_back(RayInfo(new VssRay(origin, termination, NULL, NULL, 0))); 
     1827                        leaf->mRays.push_back(RayInfo(new VssRay(origin, termination, NULL, NULL, 0))); 
    20251828#endif 
    20261829                        // get the next node from the stack 
     
    20881891{ 
    20891892        int collapsed = 0; 
    2090         //TODO 
    2091 #if HAS_TO_BE_REDONE 
     1893 
    20921894        (void)CollapseTree(mRoot, collapsed); 
    2093  
    20941895        // revalidate leaves 
    20951896        RepairViewCellsLeafLists(); 
    2096 #endif 
     1897 
    20971898        return collapsed; 
    20981899} 
     
    22862087 
    22872088int VspTree::SplitRays(const AxisAlignedPlane &plane, 
    2288                                                   RayInfoContainer &rays, 
    2289                                                   RayInfoContainer &frontRays, 
    2290                                                   RayInfoContainer &backRays) const 
     2089                                           RayInfoContainer &rays, 
     2090                                           RayInfoContainer &frontRays, 
     2091                                           RayInfoContainer &backRays) const 
    22912092{ 
    22922093        int splits = 0; 
     
    23382139{ 
    23392140        if (!node->GetParent()) 
    2340                 return mBox; 
     2141                return mBoundingBox; 
    23412142 
    23422143        if (!node->IsLeaf()) 
     
    23582159 
    23592160 
     2161 
     2162/*****************************************************************/ 
     2163/*                class OpsTree implementation                   */ 
     2164/*****************************************************************/ 
     2165 
     2166 
     2167void OspTree::SplitObjects(const AxisAlignedPlane & splitPlane, 
     2168                                                   const ObjectContainer &objects, 
     2169                                                   ObjectContainer &back, 
     2170                                                   ObjectContainer &front) 
     2171{ 
     2172        ObjectContainer::const_iterator oit, oit_end = objects.end(); 
     2173 
     2174    for (oit = objects.begin(); oit != oit_end; ++ oit)  
     2175        { 
     2176                // determine the side of this ray with respect to the plane 
     2177                const AxisAlignedBox3 box = (*oit)->GetBox(); 
     2178 
     2179                if (box.Max(splitPlane.mAxis) >= splitPlane.mPosition) 
     2180            front.push_back(*oit); 
     2181     
     2182                if (box.Min(splitPlane.mAxis) < splitPlane.mPosition) 
     2183                        back.push_back(*oit); 
     2184#if TODO     
     2185                mStat.objectRefs -= (int)objects.size(); 
     2186                mStat.objectRefs += objectsBack + objectsFront; 
     2187#endif 
     2188        } 
     2189} 
     2190 
     2191 
     2192KdInterior *OspTree::SubdivideNode(KdLeaf *leaf, 
     2193                                                                   const AxisAlignedPlane &splitPlane, 
     2194                                                                   const AxisAlignedBox3 &box, 
     2195                                                                   AxisAlignedBox3 &backBBox, 
     2196                                                                   AxisAlignedBox3 &frontBBox) 
     2197{ 
     2198#if TODO 
     2199    mSpatialStat.nodes += 2; 
     2200        mSpatialStat.splits[axis]; 
     2201#endif 
     2202 
     2203        // add the new nodes to the tree 
     2204        KdInterior *node = new KdInterior(leaf->mParent); 
     2205 
     2206        const int axis = splitPlane.mAxis; 
     2207        const float position = splitPlane.mPosition; 
     2208 
     2209        node->mAxis = axis; 
     2210        node->mPosition = position; 
     2211        node->mBox = box; 
     2212 
     2213    backBBox = box; 
     2214        frontBBox = box; 
     2215   
     2216        // first count ray sides 
     2217        int objectsBack = 0; 
     2218        int objectsFront = 0; 
     2219   
     2220        backBBox.SetMax(axis, position); 
     2221        frontBBox.SetMin(axis, position); 
     2222 
     2223        ObjectContainer::const_iterator mi, mi_end = leaf->mObjects.end(); 
     2224 
     2225        for ( mi = leaf->mObjects.begin(); mi != mi_end; ++ mi)  
     2226        { 
     2227                // determine the side of this ray with respect to the plane 
     2228                const AxisAlignedBox3 box = (*mi)->GetBox(); 
     2229                 
     2230                if (box.Max(axis) > position)  
     2231                        ++ objectsFront; 
     2232     
     2233                if (box.Min(axis) < position) 
     2234                        ++ objectsBack; 
     2235        } 
     2236 
     2237        KdLeaf *back = new KdLeaf(node, objectsBack); 
     2238        KdLeaf *front = new KdLeaf(node, objectsFront); 
     2239 
     2240        // replace a link from node's parent 
     2241        if (leaf->mParent) 
     2242                leaf->mParent->ReplaceChildLink(leaf, node); 
     2243 
     2244        // and setup child links 
     2245        node->SetupChildLinks(back, front); 
     2246 
     2247        SplitObjects(splitPlane, leaf->mObjects, back->mObjects, front->mObjects); 
     2248   
     2249        //delete leaf; 
     2250        return node; 
     2251} 
     2252 
     2253 
     2254KdNode *OspTree::Subdivide(SplitQueue &tQueue, 
     2255                                                   OspSplitCandidate &splitCandidate, 
     2256                                                   const bool globalCriteriaMet) 
     2257{ 
     2258        OspTraversalData &tData = splitCandidate.mParentData; 
     2259 
     2260        KdNode *newNode = tData.mNode; 
     2261 
     2262        if (!LocalTerminationCriteriaMet(tData) && !globalCriteriaMet) 
     2263        {        
     2264                OspTraversalData tFrontData; 
     2265                OspTraversalData tBackData; 
     2266 
     2267                //-- continue subdivision 
     2268                 
     2269                // create new interior node and two leaf node 
     2270                const AxisAlignedPlane splitPlane = splitCandidate.mSplitPlane; 
     2271                newNode = SubdivideNode(dynamic_cast<KdLeaf *>(newNode),  
     2272                                                                splitPlane,  
     2273                                                                tData.mBoundingBox,  
     2274                                                                tFrontData.mBoundingBox,  
     2275                                                                tBackData.mBoundingBox); 
     2276         
     2277                const int maxCostMisses = splitCandidate.mMaxCostMisses; 
     2278 
     2279                // how often was max cost ratio missed in this branch? 
     2280                tFrontData.mMaxCostMisses = maxCostMisses; 
     2281                tBackData.mMaxCostMisses = maxCostMisses; 
     2282                         
     2283                //-- push the new split candidates on the queue 
     2284                OspSplitCandidate *frontCandidate = new OspSplitCandidate(); 
     2285                OspSplitCandidate *backCandidate = new OspSplitCandidate(); 
     2286 
     2287                EvalSplitCandidate(tFrontData, *frontCandidate); 
     2288                EvalSplitCandidate(tBackData, *backCandidate); 
     2289 
     2290                tQueue.push(frontCandidate); 
     2291                tQueue.push(backCandidate); 
     2292 
     2293                // delete old leaf node 
     2294                DEL_PTR(tData.mNode); 
     2295        } 
     2296 
     2297 
     2298        //-- terminate traversal 
     2299        if (newNode->IsLeaf()) 
     2300        { 
     2301                //KdLeaf *leaf = dynamic_cast<KdLeaf *>(newNode); 
     2302                EvaluateLeafStats(tData);                
     2303        } 
     2304 
     2305        //-- cleanup 
     2306        tData.Clear(); 
     2307         
     2308        return newNode; 
     2309} 
     2310 
     2311 
     2312void OspTree::EvalSplitCandidate(OspTraversalData &tData, 
     2313                                                                 OspSplitCandidate &splitData) 
     2314{ 
     2315        float frontProb; 
     2316        float backtProb; 
     2317         
     2318        KdLeaf *leaf = dynamic_cast<KdLeaf *>(tData.mNode); 
     2319 
     2320        // compute locally best split plane 
     2321        const bool success = false; 
     2322#if TODO 
     2323        SelectPlane(tData, splitData.mSplitPlane, 
     2324                                frontData.mProbability, backData.mProbability); 
     2325 
     2326        //TODO 
     2327        // compute global decrease in render cost 
     2328        splitData.mPriority = EvalRenderCostDecrease(splitData.mSplitPlane, tData); 
     2329        splitData.mParentData = tData; 
     2330        splitData.mMaxCostMisses = success ? tData.mMaxCostMisses : tData.mMaxCostMisses + 1; 
     2331#endif 
     2332} 
     2333 
     2334 
    23602335/*****************************************************************/ 
    23612336/*              class HierarchyManager implementation            */ 
     
    23762351 
    23772352 
    2378 void HierarchyManager::PrepareTraversal() 
    2379 { 
    2380  
    2381 #if TODO 
    2382         /// create new vsp tree 
    2383         mRoot = new VspLeaf(); 
    2384         /// we use the overall probability as normalizer 
    2385         const float prop = mBoundingBox.GetVolume(); 
    2386  
    2387         VspTraversalData tData(mRoot, 
    2388                                                    0, 
    2389                                                    rays, 
    2390                            ComputePvsSize(*rays), 
    2391                                                    prop, 
    2392                                                    mBoundingBox); 
    2393  
    2394  
    2395         // compute first split candidates 
    2396         VspTree::VspSplitCandidate vspSplitCandidate = new VspTree::VspSplitCandidate(); 
    2397         EvalSplitCandidate(tData, *vspSplitCandidate); 
    2398         mTQueue.push(splitCandidate); 
    2399  
    2400     OspSplitCandidate ospSplitCandidate = new OspSplitCandidate(); 
    2401         EvalSplitCandidate(tData, *ospSplitCandidate); 
    2402         mTQueue.push(ospSplitCandidate); 
    2403  
    2404         mTotalCost = tData.mPvs * tData.mProbability / mBox.GetVolume(); 
    2405         mTotalPvsSize = tData.mPvs; 
    2406          
    2407         mSubdivisionStats  
    2408                         << "#ViewCells\n1\n" <<  endl 
    2409                         << "#RenderCostDecrease\n0\n" << endl  
    2410                         << "#SplitCandidateCost\n0\n" << endl 
    2411                         << "#TotalRenderCost\n" << mTotalCost << endl 
    2412                         << "#AvgRenderCost\n" << mTotalPvsSize << endl; 
    2413  
    2414         Debug << "total cost: " << mTotalCost << endl; 
    2415  
    2416 #endif 
     2353void HierarchyManager::PrepareConstruction(const VssRayContainer &sampleRays, 
     2354                                                                                   AxisAlignedBox3 *forcedViewSpace, 
     2355                                                                                   RayInfoContainer &rays) 
     2356{ 
     2357        VssRayContainer::const_iterator rit, rit_end = sampleRays.end(); 
     2358 
     2359        long startTime = GetTime(); 
     2360 
     2361        cout << "storing rays ... "; 
     2362 
     2363        Intersectable::NewMail(); 
     2364 
     2365        mVspTree->PrepareConstruction(sampleRays, forcedViewSpace); 
     2366 
     2367        //-- store rays 
     2368        for (rit = sampleRays.begin(); rit != rit_end; ++ rit) 
     2369        { 
     2370                VssRay *ray = *rit; 
     2371 
     2372                float minT, maxT; 
     2373 
     2374                static Ray hray; 
     2375                hray.Init(*ray); 
     2376 
     2377                // TODO: not very efficient to implictly cast between rays types 
     2378                if (mBoundingBox.GetRaySegment(hray, minT, maxT)) 
     2379                { 
     2380                        float len = ray->Length(); 
     2381 
     2382                        if (!len) 
     2383                                len = Limits::Small; 
     2384 
     2385                        rays.push_back(RayInfo(ray, minT / len, maxT / len)); 
     2386                } 
     2387        } 
     2388 
     2389        cout << "finished" << endl; 
     2390 
     2391        //mOspTree->PrepareConstruction(sampleRays, forcedViewSpace, rays); 
     2392} 
     2393 
     2394 
     2395bool HierarchyManager::GlobalTerminationCriteriaMet(SplitCandidate *candidate) const 
     2396{ 
     2397        if (candidate->Type() == SplitCandidate::VIEW_SPACE) 
     2398        { 
     2399                VspTree::VspSplitCandidate *sc =  
     2400                        dynamic_cast<VspTree::VspSplitCandidate *>(candidate); 
     2401                 
     2402                return mVspTree->GlobalTerminationCriteriaMet(sc->mParentData); 
     2403        } 
     2404 
     2405        return true; 
    24172406} 
    24182407 
     
    24202409void HierarchyManager::Construct(const VssRayContainer &sampleRays, 
    24212410                                                                 const ObjectContainer &objects, 
    2422                                                                  AxisAlignedBox3 *forcedBoundingBox) 
    2423 { 
    2424 #if TODO 
    2425         //-- store rays 
    2426         for (rit = sampleRays.begin(); rit != rit_end; ++ rit) 
    2427         { 
    2428                 VssRay *ray = *rit; 
    2429  
    2430                 float minT, maxT; 
    2431  
    2432                 static Ray hray; 
    2433                 hray.Init(*ray); 
    2434  
    2435                 // TODO: not very efficient to implictly cast between rays types 
    2436                 if (mBoundingBox.GetRaySegment(hray, minT, maxT)) 
    2437                 { 
    2438                         float len = ray->Length(); 
    2439  
    2440                         if (!len) 
    2441                                 len = Limits::Small; 
    2442  
    2443                         rays->push_back(RayInfo(ray, minT / len, maxT / len)); 
    2444                 } 
    2445         } 
    2446 #endif 
    2447 } 
    2448  
    2449  
    2450 bool HierarchyManager::FinishedConstruction() 
    2451 { 
    2452         return mTQueue.empty(); 
    2453 } 
    2454  
    2455  
    2456 void HierarchyManager::Construct(RayInfoContainer *rays) 
    2457 { 
    2458         PrepareTraversal(); 
     2411                                                                 AxisAlignedBox3 *forcedViewSpace) 
     2412{ 
     2413        RayInfoContainer *rays = new RayInfoContainer(); 
     2414         
     2415        // prepare vsp and osp trees for traversal 
     2416        PrepareConstruction(sampleRays, forcedViewSpace, *rays); 
    24592417 
    24602418        mVspTree->mVspStats.Start(); 
    2461         cout << "Constructing vsp bsp tree ... \n"; 
    2462  
     2419 
     2420        cout << "Constructing view space / object space tree ... \n"; 
    24632421        const long startTime = GetTime();        
    24642422 
     
    24672425                SplitCandidate *splitCandidate = NextSplitCandidate(); 
    24682426             
     2427                const bool globalTerminationCriteriaMet =  
     2428                        GlobalTerminationCriteriaMet(splitCandidate); 
     2429 
    24692430                // cost ratio of cost decrease / totalCost 
    24702431                const float costRatio = splitCandidate->GetPriority() / mTotalCost; 
    2471                  
    24722432                //Debug << "cost ratio: " << costRatio << endl; 
    24732433 
     
    24752435                        ++ mGlobalCostMisses; 
    24762436         
    2477                 // subdivide leaf node 
    2478                 // either object space or view space 
     2437                //-- subdivide leaf node 
     2438                //-- either a object space or view space split 
    24792439                if (splitCandidate->Type() == SplitCandidate::VIEW_SPACE) 
    24802440                { 
     
    24822442                                dynamic_cast<VspTree::VspSplitCandidate *>(splitCandidate); 
    24832443 
    2484                         VspNode *r = mVspTree->Subdivide(mTQueue, *sc); 
    2485                 } 
    2486                 else // object space 
     2444                        VspNode *r = mVspTree->Subdivide(mTQueue, *sc, globalTerminationCriteriaMet); 
     2445                } 
     2446                else // object space split 
    24872447                { 
    24882448#if TODO 
     
    24902450#endif 
    24912451                } 
    2492         } 
    2493  
    2494         cout << "finished\n"; 
     2452 
     2453                DEL_PTR(splitCandidate); 
     2454        } 
     2455 
     2456        cout << "finished in " << TimeDiff(startTime, GetTime())*1e-3 << "secs" << endl; 
    24952457 
    24962458        mVspTree->mVspStats.Stop(); 
    24972459} 
    24982460 
    2499 } 
     2461 
     2462bool HierarchyManager::FinishedConstruction() 
     2463{ 
     2464        return mTQueue.empty(); 
     2465} 
     2466 
     2467 
     2468} 
Note: See TracChangeset for help on using the changeset viewer.