Ignore:
Timestamp:
10/05/07 15:36:52 (17 years ago)
Author:
mattausch
Message:

added partial implementation of chc++. problem: bounding box rendering in Ogre is VERY slow

File:
1 edited

Legend:

Unmodified
Added
Removed
  • GTP/trunk/Lib/Vis/OnlineCullingCHC/src/CoherentHierarchicalCullingPlusPlusManager.cpp

    r2553 r2555  
    1 #include "BatchedQueriesCullingManager.h" 
     1#include "CoherentHierarchicalCullingPlusPlusManager.h" 
     2#include "CullingLogManager.h" 
     3 
     4#include <time.h> 
     5#include <sstream> 
     6 
    27 
    38 
    49namespace GtpVisibility { 
    510 
    6 //----------------------------------------------------------------------- 
    7 BatchedQueriesCullingManager::BatchedQueriesCullingManager(): 
    8 mMaxPending(5) 
    9 { 
    10 } 
    11 //----------------------------------------------------------------------- 
    12 BatchedQueriesCullingManager::BatchedQueriesCullingManager(const unsigned int  
    13                                                                                                                    assumedVisibility): 
    14 CoherentHierarchicalCullingManager(assumedVisibility), mMaxPending(5) 
    15 { 
    16 } 
    17  
    18 //----------------------------------------------------------------------- 
    19 void BatchedQueriesCullingManager::RenderScene() 
    20 { 
    21         QueryQueue queryQueue; 
     11 
     12static const bool CULL_INVALID_NODES = false; 
     13 
     14//----------------------------------------------------------------------- 
     15CoherentHierarchicalCullingPlusPlusManager::CoherentHierarchicalCullingPlusPlusManager(): 
     16mAssumedVisibility(0), mMaxInvisibleNodesSize(50) 
     17{ 
     18} 
     19//----------------------------------------------------------------------- 
     20CoherentHierarchicalCullingPlusPlusManager::CoherentHierarchicalCullingPlusPlusManager( 
     21                                                                                                                const unsigned int assumedVisibility): 
     22mAssumedVisibility(assumedVisibility), mMaxInvisibleNodesSize(50) 
     23{ 
     24} 
     25//----------------------------------------------------------------------- 
     26void CoherentHierarchicalCullingPlusPlusManager::AssignAssumedVisibility(GtpVisibility::HierarchyNode *node) 
     27{ 
     28        if (!mHierarchyInterface->IsNodeVisible(node)) 
     29                // previously invisible nodes: give random offset just for the first test after 
     30                // becoming visible to avoid that all nodes are tested in the same frame 
     31                mHierarchyInterface->SetNodeAssumedVisible(node, rand() * mAssumedVisibility / RAND_MAX); 
     32        else 
     33                mHierarchyInterface->SetNodeAssumedVisible(node, mAssumedVisibility); 
     34} 
     35//----------------------------------------------------------------------- 
     36void CoherentHierarchicalCullingPlusPlusManager::RenderScene() 
     37{ 
     38        if (0) CullingLogManager::GetSingleton()->LogMessage("chc++"); 
     39         
    2240        unsigned int visiblePixels = 0; 
    2341 
    24         PendingQueue pendingQueue; 
    25  
     42        ///////////// 
    2643        //-- PART 1: process finished occlusion queries 
    27         while (!mHierarchyInterface->GetQueue()->empty() || !queryQueue.empty() ||!pendingQueue.empty()) 
     44 
     45        while (!mHierarchyInterface->GetQueue()->empty() || !mQueryQueue.empty() || 
     46                   !mInvisibleNodes.empty() || !mVisibleNodes.empty()) 
    2847        { 
    29                 while (!queryQueue.empty() &&  
    30                            queryQueue.front().second->GetQueryResult(visiblePixels,  
    31                                                                         mHierarchyInterface->GetQueue()->empty())) 
     48                ////////// 
     49                //-- only wait for result if there are no nodes to process 
     50 
     51                bool resultAvailable = false; 
     52                while ( 
     53                           !mQueryQueue.empty() &&  
     54                           (NodeInvalid(mQueryQueue.front().first) || 
     55                           mHierarchyInterface->GetQueue()->empty() || 
     56                           (resultAvailable = mQueryQueue.front().second->GetQueryResult(visiblePixels, false))) 
     57                           ) 
    3258                { 
    33                 HierarchyNode *node = queryQueue.front().first; 
    34                          
    35                         queryQueue.pop(); 
    36  
     59                        HierarchyNode *node = mQueryQueue.front().first; 
     60 
     61                        // "invalid nodes" happen for hierarchies that store geometry in the interiors 
     62                        // parent was tested invisible => remove children from queue 
     63                        if (NodeInvalid(node)) {mQueryQueue.pop(); continue;} 
     64 
     65                        // during the wait time issue nodes from visible queue 
     66                        while (!mVisibleNodes.empty() && !resultAvailable) 
     67                        { 
     68                                HierarchyNode *vn = mVisibleNodes.front(); 
     69                                mVisibleNodes.pop(); 
     70                                IssueQuery(vn, false); 
     71 
     72                                // check if result is already availalbe 
     73                                resultAvailable = mQueryQueue.front().second->GetQueryResult(visiblePixels, false); 
     74                        } 
     75 
     76                        if (!resultAvailable) 
     77                                mQueryQueue.front().second->GetQueryResult(visiblePixels, true); 
     78 
     79                        resultAvailable = false; 
     80                mQueryQueue.pop(); 
     81 
     82                        // tested visible 
    3783                        if (visiblePixels > mVisibilityThreshold) 
    3884                        { 
    39                                 // ensure that we only traverse once if geometry in node 
     85                                // assing the #frames the node is assumed to stay visible 
     86                                AssignAssumedVisibility(node); 
     87 
     88                                // for previously visible interior node which contains geometry:  
     89                                // ensure that we did not already traverse this node  
     90                                // (which means that the visibility flag is set) 
    4091                                if (!mHierarchyInterface->IsNodeVisible(node)) 
    41                                         mHierarchyInterface->TraverseNode(node); 
     92                                        mHierarchyInterface->TraverseNode2(node); 
    4293 
    4394                                mHierarchyInterface->PullUpVisibility(node); 
     
    50101                                 
    51102                                if (mVisualizeCulledNodes) 
    52                                 { 
    53103                                        mHierarchyInterface->VisualizeCulledNode(node, QUERY_CULLED); 
    54104                                } 
    55                         } 
     105                         
     106                        // update node's visited flag 
     107                        mHierarchyInterface->SetLastVisited(node, mHierarchyInterface->GetFrameId());    
    56108                } 
    57109                 
     110                //////////////// 
    58111                //-- PART 2: hierarchical traversal 
     112 
    59113                if (!mHierarchyInterface->GetQueue()->empty()) 
    60114                { 
     
    62116                        mHierarchyInterface->GetQueue()->pop(); 
    63117                                 
     118                        // parent was tested invisible => remove children from queue 
     119                        if (NodeInvalid(node)) continue; 
     120 
    64121                        bool intersects = false; 
    65122 
     
    69126                                 
    70127                                if (mVisualizeCulledNodes) 
    71                                 { 
    72128                                        mHierarchyInterface->VisualizeCulledNode(node, FRUSTUM_CULLED); 
    73                                 } 
    74                         } 
    75                         // -- if node intersects near plane, skip query because wrong results possible 
     129                        } 
    76130                        else if (intersects) 
    77131                        { 
     132                                //-- if node intersects near plane, skip query because wrong results possible 
    78133                                SkipQuery(node); 
    79134                        } 
     
    85140                                 
    86141                                // if we assume node to be visible in this frame => skip query  
    87                                 bool skipQuery = wasVisible && (mAssumedVisibility > 0) &&  
    88                                         DecideVisible(node) && mHierarchyInterface->HasGeometry(node); 
     142                                const bool skipQuery = wasVisible && 
     143                                                                           DecideVisible(node) &&  
     144                                                                           mHierarchyInterface->HasGeometry(node); 
    89145 
    90146                                if (skipQuery) 
     
    96152                // identify nodes that we cannot skip queries for 
    97153                                // geometry not only in leaves => test for renderable geometry 
    98                                 bool issueQuery = !wasVisible || mHierarchyInterface->HasGeometry(node); 
     154                                const bool issueQuery = !wasVisible || mHierarchyInterface->HasGeometry(node); 
    99155                                                         
    100                                 // reset node's visibility classification 
    101                                 // set visible if geometry in node so we only traverse once 
     156                                // set node's visibility classification 
     157                                // we identify previously visible / invisible nodes in the query queue 
    102158                                mHierarchyInterface->SetNodeVisible(node, wasVisible && issueQuery); 
    103159 
    104                                 // update node's visited flag 
    105                                 mHierarchyInterface->SetLastVisited(node, mHierarchyInterface->GetFrameId()); 
    106  
    107                                 // skip testing previously visible nodes without geometry 
    108160                                if (issueQuery) 
    109161                                { 
    110162                                        ++ mNumQueriesIssued; 
    111                                         // add to the pending queue instead of immediate query 
    112                                         if ((int)pendingQueue.size() < mMaxPending) 
    113                                                 pendingQueue.push(PendingQuery(node, wasVisible)); 
     163 
     164                                        if (!wasVisible) 
     165                                        { 
     166                                                mInvisibleNodes.push_back(node); 
     167 
     168                                                if ((int)mInvisibleNodes.size() >= mMaxInvisibleNodesSize) 
     169                                                { 
     170                                                        mHierarchyInterface->RenderQueue(); 
     171                                                        // issue the batched queries 
     172                                                        IssueBatchedQuery(mInvisibleNodes); 
     173                                                } 
     174                                        } 
    114175                                        else 
    115176                                        { 
    116                                                 IssueMultipleQueries(pendingQueue, queryQueue);  
     177                                                mVisibleNodes.push(node); 
     178                                                //IssueQuery(node, false); 
    117179                                        } 
     180                                } 
     181                                else 
     182                                { 
     183                                        // skip testing previously visible nodes without geometry 
     184                    // just update node's visited flag 
     185                                        mHierarchyInterface->SetLastVisited(node, mHierarchyInterface->GetFrameId()); 
    118186                                } 
    119187                                 
     
    121189                                if (wasVisible) 
    122190                                { 
    123                                         mHierarchyInterface->TraverseNode(node); 
     191                                        mHierarchyInterface->TraverseNode2(node); 
    124192                                } 
    125193                        } 
    126194                } 
    127195 
    128                 // issue rest of queries 
    129                 IssueMultipleQueries(pendingQueue, queryQueue); 
     196                 
     197                if (mHierarchyInterface->GetQueue()->empty() && !mInvisibleNodes.empty()) 
     198                { 
     199                        if (0) 
     200                        { 
     201                                std::stringstream d; 
     202                                d << "inv nodes: " << (int)mInvisibleNodes.size(); 
     203                                CullingLogManager::GetSingleton()->LogMessage(d.str()); 
     204                        } 
     205                         
     206                        mHierarchyInterface->RenderQueue(); 
     207                        IssueBatchedQuery(mInvisibleNodes); 
     208                } 
     209 
     210        // issue rest of nodes from nodes from visible queue 
     211                if (mHierarchyInterface->GetQueue()->empty() && mQueryQueue.empty() && !mVisibleNodes.empty()) 
     212                { 
     213                        if (0) 
     214                        { 
     215                                std::stringstream d; 
     216                                d << "vis nodes: " << (int)mVisibleNodes.size(); 
     217                                CullingLogManager::GetSingleton()->LogMessage(d.str()); 
     218                        } 
     219 
     220                        while (!mVisibleNodes.empty()) 
     221                        { 
     222                                IssueQuery(mVisibleNodes.front(), false); 
     223                                mVisibleNodes.pop(); 
     224                        } 
     225                } 
    130226        } 
    131 } 
    132  
    133 void BatchedQueriesCullingManager::IssueMultipleQueries(PendingQueue &pendingQueue,  
    134                                                                                                                 QueryQueue &queryQueue) 
    135 { 
    136         while (!pendingQueue.empty()) 
     227 
     228 
     229        if (0) 
    137230        { 
    138                 HierarchyNode *node = pendingQueue.front().first; 
    139                 const bool wasVisible = pendingQueue.front().second; 
    140  
    141                 pendingQueue.pop(); 
    142  
    143                 queryQueue.push(QueryPair(node, mHierarchyInterface-> 
    144                                         IssueNodeOcclusionQuery(node, wasVisible))); 
     231                std::stringstream d; 
     232                d << "queries: " << (int)mQueryQueue.size() << " vis: " << (int)mVisibleNodes.size() << " inv: " << (int)mInvisibleNodes.size(); 
     233                CullingLogManager::GetSingleton()->LogMessage(d.str()); 
    145234        } 
    146 } 
    147  
    148 void BatchedQueriesCullingManager::SetMaxPending(int maxPending) 
    149 { 
    150         mMaxPending = maxPending; 
    151 } 
    152  
    153 } // namespace GtpVisibility 
     235         
     236        // render rest 
     237        mHierarchyInterface->RenderQueue(); 
     238} 
     239//----------------------------------------------------------------------- 
     240void CoherentHierarchicalCullingPlusPlusManager::SetAssumedVisibility(const unsigned int assumedVisibility) 
     241{ 
     242        mAssumedVisibility = assumedVisibility; 
     243} 
     244//----------------------------------------------------------------------- 
     245inline bool CoherentHierarchicalCullingPlusPlusManager::DecideVisible(HierarchyNode *node) const 
     246{ 
     247        mHierarchyInterface->DecNodeAssumedVisible(node); 
     248        //std::stringstream d; d << "node visible: " << mHierarchyInterface->GetNodeAssumedVisible(node); 
     249        //CullingLogManager::GetSingleton()->LogMessage(d.str()); 
     250        return mHierarchyInterface->GetNodeAssumedVisible(node) > 0; 
     251} 
     252//----------------------------------------------------------------------- 
     253inline void CoherentHierarchicalCullingPlusPlusManager::SkipQuery(HierarchyNode *node) const 
     254{ 
     255        //-- set node to be visible in this frame, then traverse it 
     256        mHierarchyInterface->SetLastVisited(node, mHierarchyInterface->GetFrameId()); 
     257 
     258        mHierarchyInterface->PullUpVisibility(node);                     
     259        mHierarchyInterface->TraverseNode2(node); 
     260} 
     261//----------------------------------------------------------------------- 
     262inline bool CoherentHierarchicalCullingPlusPlusManager::NodeInvalid(HierarchyNode *node) const 
     263{ 
     264        if (!CULL_INVALID_NODES) return false; 
     265 
     266        // parent was tested invisible in this frame 
     267    return (  
     268                    mHierarchyInterface->GetParent(node) &&  
     269                    (mHierarchyInterface->LastVisited(node) == mHierarchyInterface->GetFrameId()) &&  
     270                    !mHierarchyInterface->IsNodeVisible(mHierarchyInterface->GetParent(node)) 
     271           ); 
     272} 
     273//----------------------------------------------------------------------- 
     274void CoherentHierarchicalCullingPlusPlusManager::SetTestGeometryForVisibleLeaves(const bool testGeometry) 
     275{ 
     276        mTestGeometryForVisibleLeaves = testGeometry; 
     277} 
     278//----------------------------------------------------------------------- 
     279bool CoherentHierarchicalCullingPlusPlusManager::GetTestGeometryForVisibleLeaves() 
     280{ 
     281        return mTestGeometryForVisibleLeaves; 
     282} 
     283//----------------------------------------------------------------------- 
     284inline void CoherentHierarchicalCullingPlusPlusManager::IssueQuery(HierarchyNode *node,  
     285                                                                                                                                   const bool queryGeometry) 
     286{ 
     287        mQueryQueue.push(QueryPair(node, mHierarchyInterface-> 
     288                IssueNodeOcclusionQuery(node, queryGeometry))); 
     289} 
     290//----------------------------------------------------------------------- 
     291void CoherentHierarchicalCullingPlusPlusManager::IssueBatchedQuery(HierarchyNodeContainer &nodes) 
     292{ 
     293        HierarchyNodeContainer::const_iterator nit, nit_end = nodes.end(); 
     294 
     295        for (nit = nodes.begin(); nit != nit_end; ++ nit) 
     296                IssueQuery(*nit, false); 
     297 
     298        nodes.clear(); 
     299} 
     300                 
     301} 
Note: See TracChangeset for help on using the changeset viewer.