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

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