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

Revision 2542, 7.4 KB checked in by mattausch, 17 years ago (diff)
RevLine 
[2258]1#include "RandomUpdateCullingManager.h"
[2280]2#include <time.h>
3#include "CullingLogManager.h"
[2292]4#include <vector>
5//#include <iostream>
6#include <sstream>
[2258]7
[2280]8
[2292]9using namespace std;
10
11
[2258]12namespace GtpVisibility {
13
[2287]14const static int R_CANDIDATES = 1;
[2455]15
[2258]16//-----------------------------------------------------------------------
[2455]17RandomUpdateCullingManager::RandomUpdateCullingManager(): mRandomCandidates(R_CANDIDATES)
[2258]18{
19}
20//-----------------------------------------------------------------------
[2455]21RandomUpdateCullingManager::RandomUpdateCullingManager(const unsigned int randomCandidates)
22{       
23        mRandomCandidates = std::max(randomCandidates, (unsigned int)1);
24}
25//-----------------------------------------------------------------------
26void RandomUpdateCullingManager::SetRandomCandidates(const unsigned int randomCandidates)
[2258]27{
[2455]28        mRandomCandidates = std::max(randomCandidates, (unsigned int)1);
[2258]29}
30//-----------------------------------------------------------------------
31void RandomUpdateCullingManager::RenderScene()
32{
[2292]33        if (0) CullingLogManager::GetSingleton()->LogMessage("ruc");
[2287]34
[2258]35        QueryQueue queryQueue;
36        unsigned int visiblePixels = 0;
37       
38        /////////////
39        //-- PART 1: process finished occlusion queries
[2287]40
[2258]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
[2259]58                                if (!mHierarchyInterface->IsNodeVisible(node) &&
59                                        !mHierarchyInterface->IsNodeFullyVisible(node))
[2258]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                        {
[2287]89                                ++ mNumFrustumCulledNodes;
90
[2258]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                        {
[2502]103                                // fully visible subtree => render all in one batch
[2258]104                                if (mHierarchyInterface->IsNodeFullyVisible(node))
[2281]105                                {
[2532]106                                        int nodesTested = 0;
107
[2542]108                                        if(1)
109                                        {
110                                                // test a certain ratio of random candidates
111                                                HierarchyNodeContainer mynodes;
112                                                mHierarchyInterface->CollectLeaves(node, mynodes);
[2258]113
[2542]114                                                const int p = mRandomCandidates * RAND_MAX / (int)mynodes.size();
[2455]115
[2542]116                                                HierarchyNodeContainer::const_iterator nit, nit_end = mynodes.end();
[2283]117
[2542]118                                                for (nit = mynodes.begin(); nit != nit_end; ++ nit)
119                                                {
120                                                        HierarchyNode *leaf = *nit;
121
122                                                        if (rand() > p)
123                                                                continue;
124
125                                                        bool intersects = false;
126                                                        const bool frustumCulled = !mHierarchyInterface->CheckFrustumVisible(leaf, intersects);
127
128                                                        // don't test in these cases ...
129                                                        if (frustumCulled || intersects)
130                                                                continue;
131
132                                                        ++ nodesTested;
133
134                                                        mHierarchyInterface->SetNodeVisible(leaf, false);
135
136                                                        // update node's visited flag: this is important as we are not testing
137                                                        // all nodes in the hierarchy in this mode
138                                                        mHierarchyInterface->PullUpLastVisited(leaf, mHierarchyInterface->GetFrameId());
139                                                        // issue the query
140                                                        mHierarchyInterface->IssueNodeOcclusionQuery(node, mTestGeometryForVisibleLeaves);
141                                                }
142
143                                                //std::stringstream d; d << "rc: " << mRandomCandidates << " tested: " << nodesTested << " of " << (int)mynodes.size();
144                                                //CullingLogManager::GetSingleton()->LogMessage(d.str());
145                                        }
146                                        else
[2292]147                                        {
[2542]148                                                // always test one random candidate
149                                                HierarchyNode *leaf = mHierarchyInterface->GetRandomLeaf(node);
[2455]150
[2532]151                                                bool intersects = false;
152                                                const bool frustumCulled = !mHierarchyInterface->CheckFrustumVisible(leaf, intersects);
153
[2542]154                                                if (frustumCulled || intersects) // don't test in these cases ...
[2532]155                                                        continue;
[2542]156
[2455]157                                                ++ nodesTested;
[2542]158
[2292]159                                                mHierarchyInterface->SetNodeVisible(leaf, false);
160
[2502]161                                                // update node's visited flag: this is important as we are not testing
162                                                // all nodes in the hierarchy in this mode
[2306]163                                                mHierarchyInterface->PullUpLastVisited(leaf, mHierarchyInterface->GetFrameId());
[2502]164                                                // issue the query
[2542]165                                                mHierarchyInterface->IssueNodeOcclusionQuery(leaf, mTestGeometryForVisibleLeaves);
[2292]166                                        }
[2532]167
[2542]168                                        // render the whole subtree
[2455]169                                        mHierarchyInterface->RenderNodeRecursive(node);
[2532]170
171                                        // bail out here, recursion has finished
[2258]172                                        continue;
173                                }
174
[2332]175                                // identify previously visible nodes
176                                const bool wasVisible = mHierarchyInterface->IsNodeVisible(node) &&
177                                        (mHierarchyInterface->LastVisited(node) == mHierarchyInterface->GetFrameId() - 1);
178                                       
179                                // if we assume node to be visible in this frame => skip query
[2497]180                                const bool skipQuery = false;
181                                //wasVisible && mHierarchyInterface->HasGeometry(node);
[2332]182
183                                if (skipQuery)
184                                {
185                                        SkipQuery(node);
186                                        continue;
187                                }
188                                                       
[2258]189                // identify nodes that we cannot skip queries for
190                                // geometry not only in leaves => test for renderable geometry
191                                const bool issueQuery = !wasVisible || mHierarchyInterface->HasGeometry(node);
192                                                       
193                                // reset node's visibility classification
[2306]194                                // set visible if geometry in node => we only traverse the node once
[2258]195                                mHierarchyInterface->SetNodeVisible(node, wasVisible && issueQuery);
196
197                                // update node's visited flag
198                                mHierarchyInterface->SetLastVisited(node, mHierarchyInterface->GetFrameId());
199                               
200
201                                // skip testing previously visible nodes without geometry
202                                if (issueQuery)
203                                {
204                                        ++ mNumQueriesIssued;
205                                       
[2455]206                                        const bool testGeometry = wasVisible && mHierarchyInterface->IsLeaf(node) && mTestGeometryForVisibleLeaves;
207
[2258]208                                        queryQueue.push(QueryPair(node, mHierarchyInterface->
[2455]209                                                IssueNodeOcclusionQuery(node, testGeometry)));
[2258]210                                }
211                               
212                                // always traverse a node if it was visible
213                                if (wasVisible)
214                                {
215                                        mHierarchyInterface->TraverseNode(node);
216                                }
217                        }
218                }
219        }
[2292]220
221        // update the fully visible classifications
222        mHierarchyInterface->DetermineFullVisibility(mHierarchyInterface->GetHierarchyRoot());
[2258]223}
224//-----------------------------------------------------------------------
225inline void RandomUpdateCullingManager::SkipQuery(HierarchyNode *node) const
226{
227        // -- set node to be visible in this frame, then traverse it
228        mHierarchyInterface->SetLastVisited(node, mHierarchyInterface->GetFrameId());
229       
230        mHierarchyInterface->PullUpVisibility(node);                   
231        mHierarchyInterface->TraverseNode(node);
232}
[2455]233//-----------------------------------------------------------------------
234void RandomUpdateCullingManager::SetTestGeometryForVisibleLeaves(const bool testGeometry)
235{
236        mTestGeometryForVisibleLeaves = testGeometry;
237}
238//-----------------------------------------------------------------------
239bool RandomUpdateCullingManager::GetTestGeometryForVisibleLeaves()
240{
241        return mTestGeometryForVisibleLeaves;
242}
[2258]243
244} // namespace GtpVisibility
Note: See TracBrowser for help on using the repository browser.