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

Revision 2455, 6.9 KB checked in by mattausch, 17 years ago (diff)
Line 
1#include "CoherentHierarchicalCullingManager.h"
2#include "CullingLogManager.h"
3
4#include <time.h>
5#include <sstream>
6
7
8namespace GtpVisibility {
9
10
11static int batchSize = 5;
12
13//-----------------------------------------------------------------------
14CoherentHierarchicalCullingManager::CoherentHierarchicalCullingManager():
15mAssumedVisibility(0)
16{
17}
18//-----------------------------------------------------------------------
19CoherentHierarchicalCullingManager::CoherentHierarchicalCullingManager(
20                                                                                                                const unsigned int assumedVisibility):
21mAssumedVisibility(assumedVisibility)
22{
23}
24//-----------------------------------------------------------------------
25void CoherentHierarchicalCullingManager::AssignAssumedVisibility(GtpVisibility::HierarchyNode *node)
26{
27        if (!mHierarchyInterface->IsNodeVisible(node))
28                // previously invisible nodes: give random offset just for the first test after
29                // becoming visible to avoid that all nodes are tested in the same frame
30                mHierarchyInterface->SetNodeAssumedVisible(node, rand() * mAssumedVisibility / RAND_MAX);
31        else
32                mHierarchyInterface->SetNodeAssumedVisible(node, mAssumedVisibility);
33}
34//-----------------------------------------------------------------------
35void CoherentHierarchicalCullingManager::RenderScene()
36{
37        if (0) CullingLogManager::GetSingleton()->LogMessage("chc");
38        QueryQueue queryQueue;
39        unsigned int visiblePixels = 0;
40       
41        /////////////
42        //-- PART 1: process finished occlusion queries
43
44        while (!mHierarchyInterface->GetQueue()->empty() || !queryQueue.empty())
45        {
46                //////////
47                //-- only wait for result if there are no nodes to process
48
49                while (!queryQueue.empty() &&
50                           (NodeInvalid(queryQueue.front().first) ||
51                            queryQueue.front().second->GetQueryResult(
52                                             visiblePixels, mHierarchyInterface->GetQueue()->empty())))
53                {
54                        HierarchyNode *node = queryQueue.front().first;
55                        queryQueue.pop();
56
57                        // "invalid nodes" happen for hierarchies that have geometry
58                        // not neccessarily in the leaves:
59                        // parent was tested invisible => remove children from queue
60
61                        if (1 && NodeInvalid(node))
62                                continue;
63
64                        // tested visible
65                        if (visiblePixels > mVisibilityThreshold)
66                        {
67                                // assing the #frames the node is assumed to stay visible
68                                AssignAssumedVisibility(node);
69
70                                // for previously visible interior node which contains geometry:
71                                // ensure that we did not already traverse this node
72                                // (which means that the visibility flag is set)
73                                if (!mHierarchyInterface->IsNodeVisible(node))
74                                        mHierarchyInterface->TraverseNode(node);
75
76                                mHierarchyInterface->PullUpVisibility(node);
77                        }
78                        else
79                        {       
80                                mHierarchyInterface->SetNodeVisible(node, false);
81
82                ++ mNumQueryCulledNodes;
83
84                                if (mVisualizeCulledNodes)
85                                        mHierarchyInterface->VisualizeCulledNode(node, QUERY_CULLED);
86                        }
87                       
88                        // update node's visited flag
89                        mHierarchyInterface->SetLastVisited(node, mHierarchyInterface->GetFrameId());   
90                }
91               
92                ////////////////
93                //-- PART 2: hierarchical traversal
94
95                if (!mHierarchyInterface->GetQueue()->empty())
96                {
97                        HierarchyNode *node = mHierarchyInterface->GetQueue()->top();
98                        mHierarchyInterface->GetQueue()->pop();
99                               
100                        // parent was tested invisible => remove children from queue
101                        if (1 && NodeInvalid(node))
102                                continue;
103
104                        bool intersects = false;
105
106                        if (!mHierarchyInterface->CheckFrustumVisible(node, intersects))
107                        {
108                                ++ mNumFrustumCulledNodes;
109
110                                if (mVisualizeCulledNodes)
111                                        mHierarchyInterface->VisualizeCulledNode(node, FRUSTUM_CULLED);
112                        }
113                        //-- if node intersects near plane, skip query because wrong results possible
114                        else if (intersects)
115                        {
116                                SkipQuery(node);
117                        }
118                        else
119                        {
120                                // identify previously visible nodes
121                                bool wasVisible = mHierarchyInterface->IsNodeVisible(node) &&
122                                        (mHierarchyInterface->LastVisited(node) == mHierarchyInterface->GetFrameId() - 1);
123                               
124                                // if we assume node to be visible in this frame => skip query
125                                const bool skipQuery = wasVisible &&
126                                                                           DecideVisible(node) &&
127                                                                           mHierarchyInterface->HasGeometry(node);
128
129                                if (skipQuery)
130                                {
131                                        SkipQuery(node);
132                                        continue;
133                                }
134
135                // identify nodes that we cannot skip queries for
136                                // geometry not only in leaves => test for renderable geometry
137                                bool issueQuery = !wasVisible || mHierarchyInterface->HasGeometry(node);
138                                                       
139                                // set node's visibility classification
140                                // we identify previously visible / invisible nodes in the query queue
141                                mHierarchyInterface->SetNodeVisible(node, wasVisible && issueQuery);
142
143                                if (issueQuery)
144                                {
145                                        ++ mNumQueriesIssued;
146                                       
147                                        const bool testGeometry = wasVisible && mHierarchyInterface->IsLeaf(node) && mTestGeometryForVisibleLeaves;
148
149                                        queryQueue.push(QueryPair(node, mHierarchyInterface->
150                                                IssueNodeOcclusionQuery(node, testGeometry)));
151                                }
152                                else
153                                {
154                                        // skip testing previously visible nodes without geometry
155                    // just update node's visited flag
156                                        mHierarchyInterface->SetLastVisited(node, mHierarchyInterface->GetFrameId());
157                                }
158
159                                // always traverse a node if it was visible
160                                if (wasVisible)
161                                {
162                                        mHierarchyInterface->TraverseNode(node);
163                                }
164                        }
165                }
166        }
167}
168//-----------------------------------------------------------------------
169void CoherentHierarchicalCullingManager::SetAssumedVisibility(const unsigned int assumedVisibility)
170{
171        mAssumedVisibility = assumedVisibility;
172}
173//-----------------------------------------------------------------------
174inline bool CoherentHierarchicalCullingManager::DecideVisible(HierarchyNode *node) const
175{
176        mHierarchyInterface->DecNodeAssumedVisible(node);
177        //std::stringstream d; d << "node visible: " << mHierarchyInterface->GetNodeAssumedVisible(node);
178        //CullingLogManager::GetSingleton()->LogMessage(d.str());
179        return mHierarchyInterface->GetNodeAssumedVisible(node) > 0;
180}
181//-----------------------------------------------------------------------
182inline void CoherentHierarchicalCullingManager::SkipQuery(HierarchyNode *node) const
183{
184        //-- set node to be visible in this frame, then traverse it
185        mHierarchyInterface->SetLastVisited(node, mHierarchyInterface->GetFrameId());
186       
187        mHierarchyInterface->PullUpVisibility(node);                   
188        mHierarchyInterface->TraverseNode(node);
189}
190//-----------------------------------------------------------------------
191bool CoherentHierarchicalCullingManager::NodeInvalid(HierarchyNode *node) const
192{
193        // parent was tested invisible in this frame
194        HierarchyNode *parent = mHierarchyInterface->GetParent(node);
195    return
196                parent &&
197                (mHierarchyInterface->LastVisited(node) == mHierarchyInterface->GetFrameId()) &&
198                !mHierarchyInterface->IsNodeVisible(parent);
199}
200//-----------------------------------------------------------------------
201void CoherentHierarchicalCullingManager::SetTestGeometryForVisibleLeaves(const bool testGeometry)
202{
203        mTestGeometryForVisibleLeaves = testGeometry;
204}
205//-----------------------------------------------------------------------
206bool CoherentHierarchicalCullingManager::GetTestGeometryForVisibleLeaves()
207{
208        return mTestGeometryForVisibleLeaves;
209}
210
211}
Note: See TracBrowser for help on using the repository browser.