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

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