source: GTP/trunk/Lib/Vis/OnlineCullingCHC/src/RandomUpdateCullingManager.cpp @ 2281

Revision 2281, 6.2 KB checked in by mattausch, 18 years ago (diff)
Line 
1#include "RandomUpdateCullingManager.h"
2#include <time.h>
3#include "CullingLogManager.h"
4
5
6namespace GtpVisibility {
7
8//-----------------------------------------------------------------------
9RandomUpdateCullingManager::RandomUpdateCullingManager()
10{
11        SetAssumedVisibility(0);
12        // initialise random generator in case we use assumed visibility
13        srand(time(NULL));
14
15        mRandomCandidates = 1;
16}
17//-----------------------------------------------------------------------
18RandomUpdateCullingManager::RandomUpdateCullingManager(
19                        const unsigned int assumedVisibility)
20{
21        SetAssumedVisibility(assumedVisibility);
22        // initialise random generator in case we use assumed visibility
23        srand(time(NULL));
24
25        mRandomCandidates = 1;
26}
27//-----------------------------------------------------------------------
28void RandomUpdateCullingManager::RenderScene()
29{
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                //-- only wait for result if there are no nodes to process
41                while (!queryQueue.empty() &&
42                                queryQueue.front().second->GetQueryResult(visiblePixels,
43                                mHierarchyInterface->GetQueue()->empty()))
44                {
45                HierarchyNode *node = queryQueue.front().first;
46                       
47                        queryQueue.pop();
48                       
49                        if (visiblePixels > mVisibilityThreshold)
50                        {
51                                // in case geometry is in interior node:
52                                // ensure that we only traverse once
53                                if (!mHierarchyInterface->IsNodeVisible(node) &&
54                                        !mHierarchyInterface->IsNodeFullyVisible(node))
55                                {
56                                        mHierarchyInterface->TraverseNode(node);
57                                }
58
59                                mHierarchyInterface->PullUpVisibility(node);
60                        }
61                        else
62                        {       
63                                mHierarchyInterface->SetNodeVisible(node, false);
64
65                                ++ mNumQueryCulledNodes;
66                               
67                                if (mVisualizeCulledNodes)
68                                {
69                                        mHierarchyInterface->VisualizeCulledNode(node, QUERY_CULLED);
70                                }
71                        }
72                }
73               
74                //-- PART 2: hierarchical traversal
75                if (!mHierarchyInterface->GetQueue()->empty())
76                {
77                        HierarchyNode *node = mHierarchyInterface->GetQueue()->top();
78                        mHierarchyInterface->GetQueue()->pop();
79                               
80                        bool intersects = false;
81
82                        if (!mHierarchyInterface->CheckFrustumVisible(node, intersects))
83                        {
84                                ++ mNumFrustumCulledNodes;     
85                                if (mVisualizeCulledNodes)
86                                {
87                                        mHierarchyInterface->VisualizeCulledNode(node, FRUSTUM_CULLED);
88                                }
89                        }
90                        //-- if node intersects near plane, skip query because wrong results possible
91                        else if (intersects)
92                        {
93                                SkipQuery(node);
94                        }
95                        else
96                        {
97                                // identify previously visible nodes
98                                const bool wasVisible = mHierarchyInterface->IsNodeVisible(node) &&
99                                        (mHierarchyInterface->LastVisited(node) == mHierarchyInterface->GetFrameId() - 1);
100                               
101                                // if we assume node to be visible in this frame => skip query
102                                const bool skipQuery = wasVisible && (mAssumedVisibility > 0) &&
103                                        DecideVisible(node) && mHierarchyInterface->HasGeometry(node);
104
105                                if (skipQuery)
106                                {
107                                        SkipQuery(node);
108                                        continue;
109                                }
110                                if (mHierarchyInterface->IsLeaf(node))
111                                {
112                                        if (mHierarchyInterface->IsNodeVisible(node))
113                                                CullingLogManager::GetSingleton()->LogMessage("u");
114                                        else
115                                                CullingLogManager::GetSingleton()->LogMessage("g");
116                                }
117                               
118                                if (mHierarchyInterface->IsNodeFullyVisible(node))
119                                {
120                                        CullingLogManager::GetSingleton()->LogMessage("here8");
121                                        // node fully visible => test only random leaves
122                                        for (int i = 0; i < mRandomCandidates; ++ i)
123                                        {
124                                                CullingLogManager::GetSingleton()->LogMessage("z");
125                                                HierarchyNode *randomLeaf = mHierarchyInterface->GetRandomLeaf(node);
126                                                CullingLogManager::GetSingleton()->LogMessage("c");
127                                                if (!randomLeaf)
128                                                        continue;
129
130                                                mHierarchyInterface->SetNodeVisible(randomLeaf, false);
131
132                                                // update node's visited flag
133                                                mHierarchyInterface->SetLastVisited(randomLeaf,
134                                                                                                                        mHierarchyInterface->GetFrameId());
135
136                                                queryQueue.push(QueryPair(node,
137                                                        mHierarchyInterface->IssueNodeOcclusionQuery(node)));
138                                               
139                                                        CullingLogManager::GetSingleton()->LogMessage("a");
140                                                mHierarchyInterface->TraverseNode2(node);
141                                                        CullingLogManager::GetSingleton()->LogMessage("b");
142                                        }
143
144                                        continue;
145                                }
146
147                // identify nodes that we cannot skip queries for
148                                // geometry not only in leaves => test for renderable geometry
149                                const bool issueQuery = !wasVisible || mHierarchyInterface->HasGeometry(node);
150                                                       
151                                // reset node's visibility classification
152                                // set visibe if geometry in node => we only traverse the node once
153                                mHierarchyInterface->SetNodeVisible(node, wasVisible && issueQuery);
154
155                                // update node's visited flag
156                                mHierarchyInterface->SetLastVisited(node, mHierarchyInterface->GetFrameId());
157                               
158
159                                // skip testing previously visible nodes without geometry
160                                if (issueQuery)
161                                {
162                                        ++ mNumQueriesIssued;
163                                       
164                                        queryQueue.push(QueryPair(node, mHierarchyInterface->
165                                                IssueNodeOcclusionQuery(node, wasVisible)));
166                                }
167                               
168                                // always traverse a node if it was visible
169                                if (wasVisible)
170                                {
171                                        mHierarchyInterface->TraverseNode(node);
172                                }
173                        }
174                }
175        }
176
177        // update the fully visible classifications
178        mHierarchyInterface->DetermineFullVisibility(mHierarchyInterface->GetHierarchyRoot());
179}
180//-----------------------------------------------------------------------
181void RandomUpdateCullingManager::SetAssumedVisibility(const unsigned int assumedVisibility)
182{
183        mAssumedVisibility = assumedVisibility;
184       
185        mThreshold = 0;
186
187        if (mAssumedVisibility > 0)
188        {
189                mThreshold = RAND_MAX - RAND_MAX / mAssumedVisibility;
190                if (mAssumedVisibility > 100) // fix visibility
191                        mThreshold = RAND_MAX;
192        }
193
194}
195//-----------------------------------------------------------------------
196inline bool RandomUpdateCullingManager::DecideVisible(HierarchyNode *node) const
197{
198        return rand() < mThreshold;
199}
200//-----------------------------------------------------------------------
201inline void RandomUpdateCullingManager::SkipQuery(HierarchyNode *node) const
202{
203        // -- set node to be visible in this frame, then traverse it
204        mHierarchyInterface->SetLastVisited(node, mHierarchyInterface->GetFrameId());
205       
206        mHierarchyInterface->PullUpVisibility(node);                   
207        mHierarchyInterface->TraverseNode(node);
208}
209
210} // namespace GtpVisibility
Note: See TracBrowser for help on using the repository browser.