source: GTP/trunk/Lib/Vis/OnlineCullingCHC/src/CoherentHierarchicalCullingManager.cpp @ 726

Revision 726, 5.2 KB checked in by mattausch, 18 years ago (diff)

improved performance of TerrainSceneManager?
revisit octreescenemanager

RevLine 
[59]1#include "CoherentHierarchicalCullingManager.h"
[147]2#include <OgreLogManager.h>
[59]3
4namespace GtpVisibility {
5
6//-----------------------------------------------------------------------
[155]7CoherentHierarchicalCullingManager::CoherentHierarchicalCullingManager()
[142]8{
[155]9        SetAssumedVisibility(0);
10        // initialise random generator in case we use assumed visibility
[142]11        srand(time(NULL));
12}
13//-----------------------------------------------------------------------
[155]14CoherentHierarchicalCullingManager::CoherentHierarchicalCullingManager(const unsigned int
[295]15                                                                                                                                           assumedVisibility)
[155]16{
17        SetAssumedVisibility(assumedVisibility);
18        // initialise random generator in case we use assumed visibility
19        srand(time(NULL));
20}
21//-----------------------------------------------------------------------
[59]22void CoherentHierarchicalCullingManager::RenderScene()
23{
[85]24        QueryQueue queryQueue;
[86]25        unsigned int visiblePixels = 0;
26        bool isAvailable = false;
[346]27        //Ogre::LogManager::getSingleton().logMessage("Coherent Hierarchical Culling");
[175]28
[59]29        //-- PART 1: process finished occlusion queries
30        while (!mHierarchyInterface->GetQueue()->empty() || !queryQueue.empty())
31        {
[726]32                // only wait for result if queue is empty
[59]33                while (!queryQueue.empty() &&
[86]34                           queryQueue.front().second->GetQueryResult(visiblePixels,
35                                                                        mHierarchyInterface->GetQueue()->empty()))
[59]36                {
[94]37                HierarchyNode *node = queryQueue.front().first;
[115]38                       
[59]39                        queryQueue.pop();
40
[96]41                        if (visiblePixels > mVisibilityThreshold)
[59]42                        {
[726]43                                // in case geometry is in omterior node: ensure that we only traverse once
[348]44                                if (!mHierarchyInterface->IsNodeVisible(node))
[726]45                                {
[348]46                                        mHierarchyInterface->TraverseNode(node);
[726]47                                }
48
[59]49                                mHierarchyInterface->PullUpVisibility(node);
50                        }
51                        else
[142]52                        {       
[348]53                                mHierarchyInterface->SetNodeVisible(node, false);
54
[155]55                                ++ mNumQueryCulledNodes;
[112]56                               
[348]57                                if (mVisualizeCulledNodes)
[112]58                                {
59                                        mHierarchyInterface->VisualizeCulledNode(node, QUERY_CULLED);
60                                }
[59]61                        }
[85]62                }
[87]63               
[59]64                //-- PART 2: hierarchical traversal
65                if (!mHierarchyInterface->GetQueue()->empty())
66                {
67                        HierarchyNode *node = mHierarchyInterface->GetQueue()->top();
68                        mHierarchyInterface->GetQueue()->pop();
69                               
70                        bool intersects = false;
71
[74]72                        if (!mHierarchyInterface->CheckFrustumVisible(node, intersects))
[130]73                        {
[147]74                                ++ mNumFrustumCulledNodes;
[112]75                               
[147]76                                if (mVisualizeCulledNodes)
[112]77                                {
[113]78                                        mHierarchyInterface->VisualizeCulledNode(node, FRUSTUM_CULLED);
[112]79                                }
[59]80                        }
[155]81                        // -- if node intersects near plane, skip query because wrong results possible
82                        else if (intersects)
83                        {
84                                SkipQuery(node);
85                        }
[74]86                        else
[59]87                        {
[148]88                                // identify previously visible nodes
89                                bool wasVisible = mHierarchyInterface->IsNodeVisible(node) &&
90                                        (mHierarchyInterface->LastVisited(node) == mHierarchyInterface->GetFrameId() - 1);
[346]91                               
[155]92                                // if we assume node to be visible in this frame => skip query
[348]93                                bool skipQuery = wasVisible && (mAssumedVisibility > 0) &&
94                                        DecideVisible(node) && mHierarchyInterface->HasGeometry(node);
95
[350]96                                //if (mHierarchyInterface->LastVisited(node) >= mHierarchyInterface->GetFrameId())
[348]97                                //      Ogre::LogManager::getSingleton().logMessage("error");
98                               
99                                if (skipQuery)
[74]100                                {
[155]101                                        SkipQuery(node);
[74]102                                        continue;
103                                }
[59]104
[148]105                // identify nodes that we cannot skip queries for
[87]106                                // geometry not only in leaves => test for renderable geometry
[348]107                                bool issueQuery = !wasVisible || mHierarchyInterface->HasGeometry(node);
[345]108                                                       
[147]109                                // reset node's visibility classification
[348]110                                // set visibe if geometry in node so we only traverse once
111                                mHierarchyInterface->SetNodeVisible(node, wasVisible && issueQuery);
[59]112
[74]113                                // update node's visited flag
114                                mHierarchyInterface->SetLastVisited(node, mHierarchyInterface->GetFrameId());
[345]115
[87]116                                // skip testing previously visible nodes without geometry
117                                if (issueQuery)
[74]118                                {
[147]119                                        ++ mNumQueriesIssued;
[142]120                                       
[87]121                                        queryQueue.push(QueryPair(node, mHierarchyInterface->
[175]122                                                IssueNodeOcclusionQuery(node, wasVisible)));
[74]123                                }
[147]124                               
[74]125                                // always traverse a node if it was visible
126                                if (wasVisible)
127                                {
[158]128                                        mHierarchyInterface->TraverseNode(node);
[74]129                                }
[59]130                        }
131                }
132        }
133}
[142]134//-----------------------------------------------------------------------
[345]135void CoherentHierarchicalCullingManager::SetAssumedVisibility(const unsigned int assumedVisibility)
[142]136{
137        mAssumedVisibility = assumedVisibility;
[146]138       
139        mThreshold = 0;
140
[147]141        if (mAssumedVisibility > 0)
[146]142        {
[147]143                mThreshold =  RAND_MAX - RAND_MAX / mAssumedVisibility;
[146]144        }
[147]145        //std::stringstream d; d << "*** setting assumed vis: " << mAssumedVisibility; Ogre::LogManager::getSingleton().logMessage(d.str());
[142]146}
147//-----------------------------------------------------------------------
[345]148inline bool CoherentHierarchicalCullingManager::DecideVisible(HierarchyNode *node) const
[142]149{
[345]150        //bool result = rand() < mThreshold; std::stringstream d; d << "Assumed vis: " << mAssumedVisibility << ", result: " << result;
151        //Ogre::LogManager::getSingleton().logMessage(d.str()); return result;
[147]152       
[146]153        return rand() < mThreshold;
[142]154}
[155]155//-----------------------------------------------------------------------
[345]156inline void CoherentHierarchicalCullingManager::SkipQuery(HierarchyNode *node) const
[155]157{
158        // -- set node to be visible in this frame, then traverse it
159        mHierarchyInterface->SetLastVisited(node, mHierarchyInterface->GetFrameId());
[345]160       
[155]161        mHierarchyInterface->PullUpVisibility(node);                   
[158]162        mHierarchyInterface->TraverseNode(node);
[155]163}
164
[59]165} // namespace GtpVisibility
Note: See TracBrowser for help on using the repository browser.