source: GTP/trunk/Lib/Vis/OnlineCullingCHC/src/CoherentHierarchicalCullingManager2.cpp @ 2360

Revision 2360, 9.0 KB checked in by mattausch, 17 years ago (diff)
Line 
1#include "CoherentHierarchicalCullingManager2.h"
2#include "CullingLogManager.h"
3
4#include <time.h>
5#include <sstream>
6
7namespace GtpVisibility {
8
9//-----------------------------------------------------------------------
10CoherentHierarchicalCullingManager2::CoherentHierarchicalCullingManager2()
11{
12        SetAssumedVisibility(0);
13        // initialise random generator in case we use assumed visibility
14        //srand(time(NULL));
15}
16//-----------------------------------------------------------------------
17CoherentHierarchicalCullingManager2::CoherentHierarchicalCullingManager2(
18                                                                                                                const unsigned int assumedVisibility)
19{
20        SetAssumedVisibility(assumedVisibility);
21        // initialise random generator in case we use assumed visibility
22        //srand(time(NULL));
23}
24//-----------------------------------------------------------------------
25#if 1
26
27void CoherentHierarchicalCullingManager2::RenderScene()
28{
29        //CullingLogManager::GetSingleton()->LogMessage("chc");
30        QueryQueue queryQueue;
31        unsigned int visiblePixels = 0;
32       
33        /////////////
34        //-- PART 1: process finished occlusion queries
35
36        while (!mHierarchyInterface->GetQueue()->empty() || !queryQueue.empty())
37        {
38                bool resultAvailable = false;
39
40                const bool nodeQueueEmpty = mHierarchyInterface->GetQueue()->empty();
41                const int queryQueueSize = (int)queryQueue.size();
42                bool queryAvailable = true;
43
44                //-- only wait for result if there are no nodes to process
45                while (!queryQueue.empty() &&
46                                (queryAvailable = queryQueue.front().second->GetQueryResult(visiblePixels, false)))
47                {
48                        HierarchyNode *node = queryQueue.front().first;
49                        queryQueue.pop();
50
51                        // render nodes if queue is still idle ...
52
53                        if (1&&nodeQueueEmpty)
54                        {
55                                std::stringstream d; d << "qu: " << queryQueueSize;
56                                CullingLogManager::GetSingleton()->LogMessage(d.str());
57                        }
58
59                       
60                        if (visiblePixels > mVisibilityThreshold)
61                        {
62                                // check visibility to ensure that we traverse node only once
63                                // (important for interior nodes with geometry
64                                if (!mHierarchyInterface->IsNodeVisible(node))
65                                {
66                                        mHierarchyInterface->TraverseNode(node);
67                                }
68
69                                mHierarchyInterface->PullUpVisibility(node);
70                        }
71                        else
72                        {       
73                                mHierarchyInterface->SetNodeVisible(node, false);
74
75                                ++ mNumQueryCulledNodes;
76                               
77                                if (mVisualizeCulledNodes)
78                                {
79                                        mHierarchyInterface->VisualizeCulledNode(node, QUERY_CULLED);
80                                }
81                        }
82                }
83               
84
85                if (!queryAvailable)
86                {
87                         // query not yet available => render some geometry
88                        HierarchyNode *node = queryQueue.front().first;
89                       
90                        // check visibility to ensure that we traverse node only once
91                        // (important for interior nodes with geometry
92                        if (!mHierarchyInterface->IsNodeVisible(node))
93                        {
94                                mHierarchyInterface->SetNodeVisible(node, true);
95                                mHierarchyInterface->TraverseNode(node);
96                        }
97                }
98
99
100                //-- PART 2: hierarchical traversal
101                if (!mHierarchyInterface->GetQueue()->empty())
102                {
103                        HierarchyNode *node = mHierarchyInterface->GetQueue()->top();
104               
105                        mHierarchyInterface->GetQueue()->pop();
106                               
107                        bool intersects = false;
108
109                        if (!mHierarchyInterface->CheckFrustumVisible(node, intersects))
110                        {
111                                ++ mNumFrustumCulledNodes;
112
113                                if (mVisualizeCulledNodes)
114                                {
115                                        mHierarchyInterface->VisualizeCulledNode(node, FRUSTUM_CULLED);
116                                }
117                        }
118                        //-- if node intersects near plane, skip query because wrong results possible
119                        else if (intersects)
120                        {
121                                SkipQuery(node);
122                        }
123                        else
124                        {
125                                // identify previously visible nodes
126                                bool wasVisible = mHierarchyInterface->IsNodeVisible(node) &&
127                                        (mHierarchyInterface->LastVisited(node) == mHierarchyInterface->GetFrameId() - 1);
128                               
129                                // if we assume node to be visible in this frame => skip query
130                                bool skipQuery = wasVisible && (mAssumedVisibility > 0) &&
131                                        DecideVisible(node) && mHierarchyInterface->HasGeometry(node);
132
133                                if (skipQuery)
134                                {
135                                        SkipQuery(node);
136                                        continue;
137                                }
138
139                // identify nodes that we cannot skip queries for
140                                // geometry not only in leaves => test for renderable geometry
141                                bool issueQuery = !wasVisible || mHierarchyInterface->HasGeometry(node);
142                                                       
143                                // reset node's visibility classification
144                                // set visibe if geometry in node so we only traverse once
145                                mHierarchyInterface->SetNodeVisible(node, wasVisible && issueQuery);
146
147                                // update node's visited flag
148                                mHierarchyInterface->SetLastVisited(node, mHierarchyInterface->GetFrameId());
149                               
150                                // skip testing previously visible nodes without geometry
151                                if (issueQuery)
152                                {
153                                        ++ mNumQueriesIssued;
154                                       
155                                        queryQueue.push(QueryPair(node, mHierarchyInterface->
156                                                IssueNodeOcclusionQuery(node, wasVisible)));
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
169#else
170
171void CoherentHierarchicalCullingManager2::RenderScene()
172{
173        //CullingLogManager::GetSingleton()->LogMessage("chc");
174        QueryQueue queryQueue;
175        unsigned int visiblePixels = 0;
176       
177        /////////////
178        //-- PART 1: process finished occlusion queries
179
180        while (!mHierarchyInterface->GetQueue()->empty() || !queryQueue.empty())
181        {
182                bool resultAvailable = false;
183
184                const bool nodeQueueEmpty = mHierarchyInterface->GetQueue()->empty();
185                const int queryQueueSize = (int)queryQueue.size();
186
187                //-- only wait for result if there are no nodes to process
188                while (!queryQueue.empty() &&
189                                queryQueue.front().second->GetQueryResult(visiblePixels,
190                                nodeQueueEmpty))
191                {
192                        HierarchyNode *node = queryQueue.front().first;
193                        queryQueue.pop();
194
195                        // render nodes if queue is still idle ...
196
197                        if (1&&nodeQueueEmpty)
198                        {
199                                std::stringstream d; d << "qu: " << queryQueueSize;
200                                CullingLogManager::GetSingleton()->LogMessage(d.str());
201                        }
202
203                       
204                        if (visiblePixels > mVisibilityThreshold)
205                        {
206                                // in case geometry is in omterior node: ensure that we only traverse once
207                                if (!mHierarchyInterface->IsNodeVisible(node))
208                                {
209                                        mHierarchyInterface->TraverseNode(node);
210                                }
211
212                                mHierarchyInterface->PullUpVisibility(node);
213                        }
214                        else
215                        {       
216                                mHierarchyInterface->SetNodeVisible(node, false);
217
218                                ++ mNumQueryCulledNodes;
219                               
220                                if (mVisualizeCulledNodes)
221                                {
222                                        mHierarchyInterface->VisualizeCulledNode(node, QUERY_CULLED);
223                                }
224                        }
225                }
226               
227                //-- PART 2: hierarchical traversal
228                if (!mHierarchyInterface->GetQueue()->empty())
229                {
230                        HierarchyNode *node = mHierarchyInterface->GetQueue()->top();
231                        mHierarchyInterface->GetQueue()->pop();
232                               
233                        bool intersects = false;
234
235                        if (!mHierarchyInterface->CheckFrustumVisible(node, intersects))
236                        {
237                                ++ mNumFrustumCulledNodes;
238
239                                if (mVisualizeCulledNodes)
240                                {
241                                        mHierarchyInterface->VisualizeCulledNode(node, FRUSTUM_CULLED);
242                                }
243                        }
244                        //-- if node intersects near plane, skip query because wrong results possible
245                        else if (intersects)
246                        {
247                                SkipQuery(node);
248                        }
249                        else
250                        {
251                                // identify previously visible nodes
252                                bool wasVisible = mHierarchyInterface->IsNodeVisible(node) &&
253                                        (mHierarchyInterface->LastVisited(node) == mHierarchyInterface->GetFrameId() - 1);
254                               
255                                // if we assume node to be visible in this frame => skip query
256                                bool skipQuery = wasVisible && (mAssumedVisibility > 0) &&
257                                        DecideVisible(node) && mHierarchyInterface->HasGeometry(node);
258
259                                if (skipQuery)
260                                {
261                                        SkipQuery(node);
262                                        continue;
263                                }
264
265                // identify nodes that we cannot skip queries for
266                                // geometry not only in leaves => test for renderable geometry
267                                bool issueQuery = !wasVisible || mHierarchyInterface->HasGeometry(node);
268                                                       
269                                // reset node's visibility classification
270                                // set visibe if geometry in node so we only traverse once
271                                mHierarchyInterface->SetNodeVisible(node, wasVisible && issueQuery);
272
273                                // update node's visited flag
274                                mHierarchyInterface->SetLastVisited(node, mHierarchyInterface->GetFrameId());
275                               
276                                // skip testing previously visible nodes without geometry
277                                if (issueQuery)
278                                {
279                                        ++ mNumQueriesIssued;
280                                       
281                                        queryQueue.push(QueryPair(node, mHierarchyInterface->
282                                                IssueNodeOcclusionQuery(node, wasVisible)));
283                                }
284                               
285                                // always traverse a node if it was visible
286                                if (wasVisible)
287                                {
288                                        mHierarchyInterface->TraverseNode(node);
289                                }
290                        }
291                }
292        }
293}
294
295#endif
296//-----------------------------------------------------------------------
297void CoherentHierarchicalCullingManager2::SetAssumedVisibility(const unsigned int assumedVisibility)
298{
299        mAssumedVisibility = assumedVisibility;
300       
301        mThreshold = 0;
302
303        if (mAssumedVisibility > 0)
304        {
305                mThreshold = RAND_MAX - RAND_MAX / mAssumedVisibility;
306                 // fix visibility
307                if (mAssumedVisibility > 100)
308                        mThreshold = RAND_MAX;
309        }
310       
311}
312//-----------------------------------------------------------------------
313inline bool CoherentHierarchicalCullingManager2::DecideVisible(HierarchyNode *node) const
314{
315        return rand() < mThreshold;
316}
317//-----------------------------------------------------------------------
318inline void CoherentHierarchicalCullingManager2::SkipQuery(HierarchyNode *node) const
319{
320        // -- set node to be visible in this frame, then traverse it
321        mHierarchyInterface->SetLastVisited(node, mHierarchyInterface->GetFrameId());
322       
323        mHierarchyInterface->PullUpVisibility(node);                   
324        mHierarchyInterface->TraverseNode(node);
325}
326
327} // namespace GtpVisibility
Note: See TracBrowser for help on using the repository browser.