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

Revision 2332, 6.6 KB checked in by mattausch, 17 years ago (diff)

implemented part of rendering estimation of wimmer et al. for view space / object space subdivision.
warning: not working with undersampling estimation + local visibility based subdivision.

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;
[2258]15//-----------------------------------------------------------------------
16RandomUpdateCullingManager::RandomUpdateCullingManager()
17{
18        SetAssumedVisibility(0);
19        // initialise random generator in case we use assumed visibility
[2292]20        //srand(time(NULL));
[2259]21
[2287]22        mRandomCandidates = R_CANDIDATES;
[2258]23}
24//-----------------------------------------------------------------------
25RandomUpdateCullingManager::RandomUpdateCullingManager(
26                        const unsigned int assumedVisibility)
27{
28        SetAssumedVisibility(assumedVisibility);
29        // initialise random generator in case we use assumed visibility
[2292]30        //srand(time(NULL));
[2259]31
[2287]32        mRandomCandidates = R_CANDIDATES;
[2258]33}
34//-----------------------------------------------------------------------
35void RandomUpdateCullingManager::RenderScene()
36{
[2292]37        if (0) CullingLogManager::GetSingleton()->LogMessage("ruc");
[2287]38
[2258]39        QueryQueue queryQueue;
40        unsigned int visiblePixels = 0;
41       
42        /////////////
43        //-- PART 1: process finished occlusion queries
[2287]44
[2258]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
[2259]62                                if (!mHierarchyInterface->IsNodeVisible(node) &&
63                                        !mHierarchyInterface->IsNodeFullyVisible(node))
[2258]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                        {
[2287]93                                ++ mNumFrustumCulledNodes;
94
[2258]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                               
108                                if (mHierarchyInterface->IsNodeFullyVisible(node))
[2281]109                                {
[2292]110#if 1
[2258]111                                        // node fully visible => test only random leaves
[2259]112                                        for (int i = 0; i < mRandomCandidates; ++ i)
[2258]113                                        {
114                                                HierarchyNode *randomLeaf = mHierarchyInterface->GetRandomLeaf(node);
[2283]115                                               
[2281]116                                                if (!randomLeaf)
117                                                        continue;
[2258]118
119                                                mHierarchyInterface->SetNodeVisible(randomLeaf, false);
120
121                                                // update node's visited flag
[2306]122                                                mHierarchyInterface->PullUpLastVisited(randomLeaf, mHierarchyInterface->GetFrameId());
[2258]123
[2287]124                                                queryQueue.push(QueryPair(randomLeaf,
[2259]125                                                        mHierarchyInterface->IssueNodeOcclusionQuery(node)));
126                                        }
[2292]127#else
128                                        // test all leaves for visibility changes
129                                        HierarchyNodeContainer mynodes;
130                                        mHierarchyInterface->CollectLeaves(node, mynodes);
[2258]131
[2292]132                                        HierarchyNodeContainer::const_iterator nit, nit_end = mynodes.end();
[2283]133
[2292]134                                        for (nit = mynodes.begin(); nit != nit_end; ++ nit)
135                                        {
136                                                HierarchyNode *leaf = *nit;
137                                                mHierarchyInterface->SetNodeVisible(leaf, false);
138
139                                                // update node's visited flag
[2306]140                                                mHierarchyInterface->PullUpLastVisited(leaf, mHierarchyInterface->GetFrameId());
[2292]141
142                                                queryQueue.push(QueryPair(leaf,
143                                                        mHierarchyInterface->IssueNodeOcclusionQuery(node)));
144                                        }
145#endif
146                                        mHierarchyInterface->RenderNodeRecursive(node);
147
[2258]148                                        continue;
149                                }
150
[2332]151                                // identify previously visible nodes
152                                const bool wasVisible = mHierarchyInterface->IsNodeVisible(node) &&
153                                        (mHierarchyInterface->LastVisited(node) == mHierarchyInterface->GetFrameId() - 1);
154                                       
155
156                                // if we assume node to be visible in this frame => skip query
157                                const bool skipQuery = wasVisible && (mAssumedVisibility > 0) &&
158                                        DecideVisible(node) && mHierarchyInterface->HasGeometry(node);
159
160                                if (skipQuery)
161                                {
162                                        SkipQuery(node);
163                                        continue;
164                                }
165                                                       
[2258]166                // identify nodes that we cannot skip queries for
167                                // geometry not only in leaves => test for renderable geometry
168                                const bool issueQuery = !wasVisible || mHierarchyInterface->HasGeometry(node);
169                                                       
170                                // reset node's visibility classification
[2306]171                                // set visible if geometry in node => we only traverse the node once
[2258]172                                mHierarchyInterface->SetNodeVisible(node, wasVisible && issueQuery);
173
174                                // update node's visited flag
175                                mHierarchyInterface->SetLastVisited(node, mHierarchyInterface->GetFrameId());
176                               
177
178                                // skip testing previously visible nodes without geometry
179                                if (issueQuery)
180                                {
181                                        ++ mNumQueriesIssued;
182                                       
183                                        queryQueue.push(QueryPair(node, mHierarchyInterface->
184                                                IssueNodeOcclusionQuery(node, wasVisible)));
185                                }
186                               
187                                // always traverse a node if it was visible
188                                if (wasVisible)
189                                {
190                                        mHierarchyInterface->TraverseNode(node);
191                                }
192                        }
193                }
194        }
[2292]195
196        // update the fully visible classifications
197        mHierarchyInterface->DetermineFullVisibility(mHierarchyInterface->GetHierarchyRoot());
[2306]198        //mHierarchyInterface->DetermineVisibilityRatio(mHierarchyInterface->GetHierarchyRoot());
[2258]199}
200//-----------------------------------------------------------------------
201void RandomUpdateCullingManager::SetAssumedVisibility(const unsigned int assumedVisibility)
202{
203        mAssumedVisibility = assumedVisibility;
204       
205        mThreshold = 0;
206
207        if (mAssumedVisibility > 0)
208        {
209                mThreshold = RAND_MAX - RAND_MAX / mAssumedVisibility;
[2306]210                if (mAssumedVisibility > 100) // no random decicion
[2258]211                        mThreshold = RAND_MAX;
212        }
[2280]213
[2258]214}
215//-----------------------------------------------------------------------
216inline bool RandomUpdateCullingManager::DecideVisible(HierarchyNode *node) const
217{
218        return rand() < mThreshold;
219}
220//-----------------------------------------------------------------------
221inline void RandomUpdateCullingManager::SkipQuery(HierarchyNode *node) const
222{
223        // -- set node to be visible in this frame, then traverse it
224        mHierarchyInterface->SetLastVisited(node, mHierarchyInterface->GetFrameId());
225       
226        mHierarchyInterface->PullUpVisibility(node);                   
227        mHierarchyInterface->TraverseNode(node);
228}
229
230} // namespace GtpVisibility
Note: See TracBrowser for help on using the repository browser.