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

Revision 2332, 5.9 KB checked in by mattausch, 18 years ago (diff)

implemented part of rendering estimation of wimmer et al. for view space / object space subdivision.
warning: not working with undersampling estimation + local visibility based subdivision.

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        if (0) 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                //////////
36                //-- only wait for result if there are no nodes to process
37                while (!queryQueue.empty() &&
38                           (NodeInvalid(queryQueue.front().first) ||
39                            queryQueue.front().second->GetQueryResult(
40                                             visiblePixels, mHierarchyInterface->GetQueue()->empty())))
41                {
42                        HierarchyNode *node = queryQueue.front().first;
43                        queryQueue.pop();
44
45                        // parent was tested invisible => remove children from queue
46                        if (NodeInvalid(node))
47                        {
48                                //CullingLogManager::GetSingleton()->LogMessage("skipping this node");
49                                continue;
50                        }
51                        // tested visible
52                        if (visiblePixels > mVisibilityThreshold)
53                        {
54                                // in case geometry is in interior node: ensure that we only traverse once
55                                if (!mHierarchyInterface->IsNodeVisible(node))
56                                {
57                                        mHierarchyInterface->TraverseNode(node);
58                                }
59
60                                mHierarchyInterface->PullUpVisibility(node);
61                        }
62                        else
63                        {       
64                                mHierarchyInterface->SetNodeVisible(node, false);
65
66                ++ mNumQueryCulledNodes;
67                               
68                                if (mVisualizeCulledNodes)
69                                {
70                                        mHierarchyInterface->VisualizeCulledNode(node, QUERY_CULLED);
71                                }
72                        }
73                       
74                        // update node's visited flag
75                        mHierarchyInterface->SetLastVisited(node, mHierarchyInterface->GetFrameId());   
76                }
77               
78                //-- PART 2: hierarchical traversal
79                if (!mHierarchyInterface->GetQueue()->empty())
80                {
81                        HierarchyNode *node = mHierarchyInterface->GetQueue()->top();
82                        mHierarchyInterface->GetQueue()->pop();
83                               
84                        // parent was tested invisible => remove children from queue
85                        if (NodeInvalid(node))
86                        {
87                                //CullingLogManager::GetSingleton()->LogMessage("skipping this node");
88                                continue;
89                        }
90
91                        bool intersects = false;
92
93                        if (!mHierarchyInterface->CheckFrustumVisible(node, intersects))
94                        {
95                                ++ mNumFrustumCulledNodes;
96
97                                if (mVisualizeCulledNodes)
98                                {
99                                        mHierarchyInterface->VisualizeCulledNode(node, FRUSTUM_CULLED);
100                                }
101                        }
102                        //-- if node intersects near plane, skip query because wrong results possible
103                        else if (intersects)
104                        {
105                                SkipQuery(node);
106                        }
107                        else
108                        {
109                                // identify previously visible nodes
110                                bool wasVisible = mHierarchyInterface->IsNodeVisible(node) &&
111                                        (mHierarchyInterface->LastVisited(node) == mHierarchyInterface->GetFrameId() - 1);
112                               
113                                // if we assume node to be visible in this frame => skip query
114                                const bool skipQuery = wasVisible &&
115                                                           (mAssumedVisibility > 0) &&
116                                                                           DecideVisible(node) &&
117                                                                           mHierarchyInterface->HasGeometry(node);
118
119                                if (skipQuery)
120                                {
121                                        SkipQuery(node);
122                                        continue;
123                                }
124
125                // identify nodes that we cannot skip queries for
126                                // geometry not only in leaves => test for renderable geometry
127                                bool issueQuery = !wasVisible || mHierarchyInterface->HasGeometry(node);
128                                                       
129                                // reset node's visibility classification
130                                // set visible if geometry in node so we only traverse once
131                                mHierarchyInterface->SetNodeVisible(node, wasVisible && issueQuery);
132
133                                // skip testing previously visible nodes without geometry
134                                if (issueQuery)
135                                {
136                                        ++ mNumQueriesIssued;
137                                       
138                                        queryQueue.push(QueryPair(node, mHierarchyInterface->
139                                                IssueNodeOcclusionQuery(node, wasVisible)));
140                                }
141                                else
142                                {
143                                        // update node's visited flag
144                                        mHierarchyInterface->SetLastVisited(node, mHierarchyInterface->GetFrameId());
145                                }
146
147                                // always traverse a node if it was visible
148                                if (wasVisible)
149                                {
150                                        mHierarchyInterface->TraverseNode(node);
151                                }
152                        }
153                }
154        }
155}
156//-----------------------------------------------------------------------
157void CoherentHierarchicalCullingManager::SetAssumedVisibility(const unsigned int assumedVisibility)
158{
159        mAssumedVisibility = assumedVisibility;
160       
161        mThreshold = 0;
162
163        if (mAssumedVisibility > 0)
164        {
165                mThreshold = RAND_MAX - RAND_MAX / mAssumedVisibility;
166                 // fix visibility
167                if (mAssumedVisibility > 100)
168                        mThreshold = RAND_MAX;
169        }
170       
171}
172//-----------------------------------------------------------------------
173inline bool CoherentHierarchicalCullingManager::DecideVisible(HierarchyNode *node) const
174{
175        return rand() < mThreshold;
176}
177//-----------------------------------------------------------------------
178inline void CoherentHierarchicalCullingManager::SkipQuery(HierarchyNode *node) const
179{
180        //-- set node to be visible in this frame, then traverse it
181        mHierarchyInterface->SetLastVisited(node, mHierarchyInterface->GetFrameId());
182       
183        mHierarchyInterface->PullUpVisibility(node);                   
184        mHierarchyInterface->TraverseNode(node);
185}
186//-----------------------------------------------------------------------
187bool CoherentHierarchicalCullingManager::NodeInvalid(HierarchyNode *node) const
188{
189        // parent was tested invisible in this frame
190        HierarchyNode *parent = mHierarchyInterface->GetParent(node);
191    return
192                parent &&
193                (mHierarchyInterface->LastVisited(node) == mHierarchyInterface->GetFrameId()) &&
194                !mHierarchyInterface->IsNodeVisible(parent);
195}
196} // namespace GtpVisibility
Note: See TracBrowser for help on using the repository browser.