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.

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                               
108                                if (mHierarchyInterface->IsNodeFullyVisible(node))
109                                {
110#if 1
111                                        // node fully visible => test only random leaves
112                                        for (int i = 0; i < mRandomCandidates; ++ i)
113                                        {
114                                                HierarchyNode *randomLeaf = mHierarchyInterface->GetRandomLeaf(node);
115                                               
116                                                if (!randomLeaf)
117                                                        continue;
118
119                                                mHierarchyInterface->SetNodeVisible(randomLeaf, false);
120
121                                                // update node's visited flag
122                                                mHierarchyInterface->PullUpLastVisited(randomLeaf, mHierarchyInterface->GetFrameId());
123
124                                                queryQueue.push(QueryPair(randomLeaf,
125                                                        mHierarchyInterface->IssueNodeOcclusionQuery(node)));
126                                        }
127#else
128                                        // test all leaves for visibility changes
129                                        HierarchyNodeContainer mynodes;
130                                        mHierarchyInterface->CollectLeaves(node, mynodes);
131
132                                        HierarchyNodeContainer::const_iterator nit, nit_end = mynodes.end();
133
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
140                                                mHierarchyInterface->PullUpLastVisited(leaf, mHierarchyInterface->GetFrameId());
141
142                                                queryQueue.push(QueryPair(leaf,
143                                                        mHierarchyInterface->IssueNodeOcclusionQuery(node)));
144                                        }
145#endif
146                                        mHierarchyInterface->RenderNodeRecursive(node);
147
148                                        continue;
149                                }
150
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                                                       
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
171                                // set visible if geometry in node => we only traverse the node once
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        }
195
196        // update the fully visible classifications
197        mHierarchyInterface->DetermineFullVisibility(mHierarchyInterface->GetHierarchyRoot());
198        //mHierarchyInterface->DetermineVisibilityRatio(mHierarchyInterface->GetHierarchyRoot());
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;
210                if (mAssumedVisibility > 100) // no random decicion
211                        mThreshold = RAND_MAX;
212        }
213
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.