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

Revision 2306, 6.5 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->PullUpLastVisited(randomLeaf, mHierarchyInterface->GetFrameId());
136
137                                                queryQueue.push(QueryPair(randomLeaf,
138                                                        mHierarchyInterface->IssueNodeOcclusionQuery(node)));
139                                        }
140#else
141                                        // test all leaves for visibility changes
142                                        HierarchyNodeContainer mynodes;
143                                        mHierarchyInterface->CollectLeaves(node, mynodes);
144
145                                        HierarchyNodeContainer::const_iterator nit, nit_end = mynodes.end();
146
147                                        for (nit = mynodes.begin(); nit != nit_end; ++ nit)
148                                        {
149                                                HierarchyNode *leaf = *nit;
150                                                mHierarchyInterface->SetNodeVisible(leaf, false);
151
152                                                // update node's visited flag
153                                                mHierarchyInterface->PullUpLastVisited(leaf, mHierarchyInterface->GetFrameId());
154
155                                                queryQueue.push(QueryPair(leaf,
156                                                        mHierarchyInterface->IssueNodeOcclusionQuery(node)));
157                                        }
158#endif
159                                        mHierarchyInterface->RenderNodeRecursive(node);
160
161                                        continue;
162                                }
163
164                // identify nodes that we cannot skip queries for
165                                // geometry not only in leaves => test for renderable geometry
166                                const bool issueQuery = !wasVisible || mHierarchyInterface->HasGeometry(node);
167                                                       
168                                // reset node's visibility classification
169                                // set visible if geometry in node => we only traverse the node once
170                                mHierarchyInterface->SetNodeVisible(node, wasVisible && issueQuery);
171
172                                // update node's visited flag
173                                mHierarchyInterface->SetLastVisited(node, mHierarchyInterface->GetFrameId());
174                               
175
176                                // skip testing previously visible nodes without geometry
177                                if (issueQuery)
178                                {
179                                        ++ mNumQueriesIssued;
180                                       
181                                        queryQueue.push(QueryPair(node, mHierarchyInterface->
182                                                IssueNodeOcclusionQuery(node, wasVisible)));
183                                }
184                               
185                                // always traverse a node if it was visible
186                                if (wasVisible)
187                                {
188                                        mHierarchyInterface->TraverseNode(node);
189                                }
190                        }
191                }
192        }
193
194        // update the fully visible classifications
195        mHierarchyInterface->DetermineFullVisibility(mHierarchyInterface->GetHierarchyRoot());
196        //mHierarchyInterface->DetermineVisibilityRatio(mHierarchyInterface->GetHierarchyRoot());
197}
198//-----------------------------------------------------------------------
199void RandomUpdateCullingManager::SetAssumedVisibility(const unsigned int assumedVisibility)
200{
201        mAssumedVisibility = assumedVisibility;
202       
203        mThreshold = 0;
204
205        if (mAssumedVisibility > 0)
206        {
207                mThreshold = RAND_MAX - RAND_MAX / mAssumedVisibility;
208                if (mAssumedVisibility > 100) // no random decicion
209                        mThreshold = RAND_MAX;
210        }
211
212}
213//-----------------------------------------------------------------------
214inline bool RandomUpdateCullingManager::DecideVisible(HierarchyNode *node) const
215{
216        return rand() < mThreshold;
217}
218//-----------------------------------------------------------------------
219inline void RandomUpdateCullingManager::SkipQuery(HierarchyNode *node) const
220{
221        // -- set node to be visible in this frame, then traverse it
222        mHierarchyInterface->SetLastVisited(node, mHierarchyInterface->GetFrameId());
223       
224        mHierarchyInterface->PullUpVisibility(node);                   
225        mHierarchyInterface->TraverseNode(node);
226}
227
228} // namespace GtpVisibility
Note: See TracBrowser for help on using the repository browser.