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

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