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

Revision 2184, 5.4 KB checked in by mattausch, 18 years ago (diff)

debug version: please don't check out

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