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

Revision 2502, 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
16//-----------------------------------------------------------------------
17RandomUpdateCullingManager::RandomUpdateCullingManager(): mRandomCandidates(R_CANDIDATES)
18{
19}
20//-----------------------------------------------------------------------
21RandomUpdateCullingManager::RandomUpdateCullingManager(const unsigned int randomCandidates)
22{       
23        mRandomCandidates = std::max(randomCandidates, (unsigned int)1);
24}
25//-----------------------------------------------------------------------
26void RandomUpdateCullingManager::SetRandomCandidates(const unsigned int randomCandidates)
27{
28        mRandomCandidates = std::max(randomCandidates, (unsigned int)1);
29}
30//-----------------------------------------------------------------------
31void RandomUpdateCullingManager::RenderScene()
32{
33        if (0) CullingLogManager::GetSingleton()->LogMessage("ruc");
34
35        QueryQueue queryQueue;
36        unsigned int visiblePixels = 0;
37       
38        /////////////
39        //-- PART 1: process finished occlusion queries
40
41        while (!mHierarchyInterface->GetQueue()->empty() || !queryQueue.empty())
42        {
43                bool resultAvailable = false;
44
45                //-- only wait for result if there are no nodes to process
46                while (!queryQueue.empty() &&
47                                queryQueue.front().second->GetQueryResult(visiblePixels,
48                                mHierarchyInterface->GetQueue()->empty()))
49                {
50                HierarchyNode *node = queryQueue.front().first;
51                       
52                        queryQueue.pop();
53                       
54                        if (visiblePixels > mVisibilityThreshold)
55                        {
56                                // in case geometry is in interior node:
57                                // ensure that we only traverse once
58                                if (!mHierarchyInterface->IsNodeVisible(node) &&
59                                        !mHierarchyInterface->IsNodeFullyVisible(node))
60                                {
61                                        mHierarchyInterface->TraverseNode(node);
62                                }
63
64                                mHierarchyInterface->PullUpVisibility(node);
65                        }
66                        else
67                        {       
68                                mHierarchyInterface->SetNodeVisible(node, false);
69
70                                ++ mNumQueryCulledNodes;
71                               
72                                if (mVisualizeCulledNodes)
73                                {
74                                        mHierarchyInterface->VisualizeCulledNode(node, QUERY_CULLED);
75                                }
76                        }
77                }
78               
79                //-- PART 2: hierarchical traversal
80                if (!mHierarchyInterface->GetQueue()->empty())
81                {
82                        HierarchyNode *node = mHierarchyInterface->GetQueue()->top();
83                        mHierarchyInterface->GetQueue()->pop();
84                               
85                        bool intersects = false;
86
87                        if (!mHierarchyInterface->CheckFrustumVisible(node, intersects))
88                        {
89                                ++ mNumFrustumCulledNodes;
90
91                                if (mVisualizeCulledNodes)
92                                {
93                                        mHierarchyInterface->VisualizeCulledNode(node, FRUSTUM_CULLED);
94                                }
95                        }
96                        //-- if node intersects near plane, skip query because wrong results possible
97                        else if (intersects)
98                        {
99                                SkipQuery(node);
100                        }
101                        else
102                        {
103                                // fully visible subtree => render all in one batch
104                                if (mHierarchyInterface->IsNodeFullyVisible(node))
105                                {
106                                        // use different algorithm for finding random candidates
107                                        HierarchyNodeContainer mynodes;
108                                        mHierarchyInterface->CollectLeaves(node, mynodes);
109
110                                        const int p = mRandomCandidates * RAND_MAX / (int)mynodes.size();
111
112                                        HierarchyNodeContainer::const_iterator nit, nit_end = mynodes.end();
113
114                                        int nodesTested = 0;
115                                        for (nit = mynodes.begin(); nit != nit_end; ++ nit)
116                                        {
117                                                HierarchyNode *leaf = *nit;
118
119                                                if (rand() > p)
120                                                        continue;
121
122                                                ++ nodesTested;
123
124                                                mHierarchyInterface->SetNodeVisible(leaf, false);
125
126                                                // update node's visited flag: this is important as we are not testing
127                                                // all nodes in the hierarchy in this mode
128                                                mHierarchyInterface->PullUpLastVisited(leaf, mHierarchyInterface->GetFrameId());
129                                                // issue the query
130                                                mHierarchyInterface->IssueNodeOcclusionQuery(node, mTestGeometryForVisibleLeaves);
131                                        }
132               
133                                        //std::stringstream d; d << "rc: " << mRandomCandidates << " tested: " << nodesTested << " of " << (int)mynodes.size();
134                                        //CullingLogManager::GetSingleton()->LogMessage(d.str());
135
136                                        mHierarchyInterface->RenderNodeRecursive(node);
137                                        continue;
138                                }
139
140                                // identify previously visible nodes
141                                const bool wasVisible = mHierarchyInterface->IsNodeVisible(node) &&
142                                        (mHierarchyInterface->LastVisited(node) == mHierarchyInterface->GetFrameId() - 1);
143                                       
144                                // if we assume node to be visible in this frame => skip query
145                                const bool skipQuery = false;
146                                //wasVisible && mHierarchyInterface->HasGeometry(node);
147
148                                if (skipQuery)
149                                {
150                                        SkipQuery(node);
151                                        continue;
152                                }
153                                                       
154                // identify nodes that we cannot skip queries for
155                                // geometry not only in leaves => test for renderable geometry
156                                const bool issueQuery = !wasVisible || mHierarchyInterface->HasGeometry(node);
157                                                       
158                                // reset node's visibility classification
159                                // set visible if geometry in node => we only traverse the node once
160                                mHierarchyInterface->SetNodeVisible(node, wasVisible && issueQuery);
161
162                                // update node's visited flag
163                                mHierarchyInterface->SetLastVisited(node, mHierarchyInterface->GetFrameId());
164                               
165
166                                // skip testing previously visible nodes without geometry
167                                if (issueQuery)
168                                {
169                                        ++ mNumQueriesIssued;
170                                       
171                                        const bool testGeometry = wasVisible && mHierarchyInterface->IsLeaf(node) && mTestGeometryForVisibleLeaves;
172
173                                        // previously invisible node
174#if TODO       
175                                        if (!mHierarchyInterface->IsNodeVisible(node))
176                                        {
177                                                // batch queries so we can test invisible nodes
178                                        }
179#endif
180                                        queryQueue.push(QueryPair(node, mHierarchyInterface->
181                                                IssueNodeOcclusionQuery(node, testGeometry)));
182                                }
183                               
184                                // always traverse a node if it was visible
185                                if (wasVisible)
186                                {
187                                        mHierarchyInterface->TraverseNode(node);
188                                }
189                        }
190                }
191        }
192
193        // update the fully visible classifications
194        mHierarchyInterface->DetermineFullVisibility(mHierarchyInterface->GetHierarchyRoot());
195}
196//-----------------------------------------------------------------------
197inline void RandomUpdateCullingManager::SkipQuery(HierarchyNode *node) const
198{
199        // -- set node to be visible in this frame, then traverse it
200        mHierarchyInterface->SetLastVisited(node, mHierarchyInterface->GetFrameId());
201       
202        mHierarchyInterface->PullUpVisibility(node);                   
203        mHierarchyInterface->TraverseNode(node);
204}
205//-----------------------------------------------------------------------
206void RandomUpdateCullingManager::SetTestGeometryForVisibleLeaves(const bool testGeometry)
207{
208        mTestGeometryForVisibleLeaves = testGeometry;
209}
210//-----------------------------------------------------------------------
211bool RandomUpdateCullingManager::GetTestGeometryForVisibleLeaves()
212{
213        return mTestGeometryForVisibleLeaves;
214}
215
216} // namespace GtpVisibility
Note: See TracBrowser for help on using the repository browser.