source: trunk/VUT/GtpVisibility/src/CoherentHierarchicalCullingManager.cpp @ 350

Revision 350, 5.2 KB checked in by mattausch, 19 years ago (diff)

ray merge started

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