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

Revision 2259, 5.9 KB checked in by mattausch, 18 years ago (diff)
Line 
1#include "RandomUpdateCullingManager.h"
2#include <OgreLogManager.h>
3
4namespace GtpVisibility {
5
6//-----------------------------------------------------------------------
7RandomUpdateCullingManager::RandomUpdateCullingManager()
8{
9        SetAssumedVisibility(0);
10        // initialise random generator in case we use assumed visibility
11        srand(time(NULL));
12
13        mRandomCandidates = 1;
14}
15//-----------------------------------------------------------------------
16RandomUpdateCullingManager::RandomUpdateCullingManager(
17                        const unsigned int assumedVisibility)
18{
19        SetAssumedVisibility(assumedVisibility);
20        // initialise random generator in case we use assumed visibility
21        srand(time(NULL));
22
23        mRandomCandidates = 1;
24}
25//-----------------------------------------------------------------------
26void RandomUpdateCullingManager::RenderScene()
27{
28        QueryQueue queryQueue;
29        unsigned int visiblePixels = 0;
30       
31        /////////////
32        //-- PART 1: process finished occlusion queries
33
34        while (!mHierarchyInterface->GetQueue()->empty() || !queryQueue.empty())
35        {
36                bool resultAvailable = false;
37
38                //-- only wait for result if there are no nodes to process
39                while (!queryQueue.empty() &&
40                                queryQueue.front().second->GetQueryResult(visiblePixels,
41                                mHierarchyInterface->GetQueue()->empty()))
42                {
43                HierarchyNode *node = queryQueue.front().first;
44                       
45                        queryQueue.pop();
46                       
47                        if (visiblePixels > mVisibilityThreshold)
48                        {
49                                // in case geometry is in interior node:
50                                // ensure that we only traverse once
51                                if (!mHierarchyInterface->IsNodeVisible(node) &&
52                                        !mHierarchyInterface->IsNodeFullyVisible(node))
53                                {
54                                        mHierarchyInterface->TraverseNode(node);
55                                }
56
57                                mHierarchyInterface->PullUpVisibility(node);
58                        }
59                        else
60                        {       
61                                mHierarchyInterface->SetNodeVisible(node, false);
62
63                                ++ mNumQueryCulledNodes;
64                               
65                                if (mVisualizeCulledNodes)
66                                {
67                                        mHierarchyInterface->VisualizeCulledNode(node, QUERY_CULLED);
68                                }
69                        }
70                }
71               
72                //-- PART 2: hierarchical traversal
73                if (!mHierarchyInterface->GetQueue()->empty())
74                {
75                        HierarchyNode *node = mHierarchyInterface->GetQueue()->top();
76                        mHierarchyInterface->GetQueue()->pop();
77                               
78                        bool intersects = false;
79
80                        if (!mHierarchyInterface->CheckFrustumVisible(node, intersects))
81                        {
82                                ++ mNumFrustumCulledNodes;     
83                                if (mVisualizeCulledNodes)
84                                {
85                                        mHierarchyInterface->VisualizeCulledNode(node, FRUSTUM_CULLED);
86                                }
87                        }
88                        //-- if node intersects near plane, skip query because wrong results possible
89                        else if (intersects)
90                        {
91                                SkipQuery(node);
92                        }
93                        else
94                        {
95                                // identify previously visible nodes
96                                const bool wasVisible = mHierarchyInterface->IsNodeVisible(node) &&
97                                        (mHierarchyInterface->LastVisited(node) == mHierarchyInterface->GetFrameId() - 1);
98                               
99                                // if we assume node to be visible in this frame => skip query
100                                const bool skipQuery = wasVisible && (mAssumedVisibility > 0) &&
101                                        DecideVisible(node) && mHierarchyInterface->HasGeometry(node);
102
103                                if (skipQuery)
104                                {
105                                        SkipQuery(node);
106                                        continue;
107                                }
108                               
109                                if (mHierarchyInterface->IsNodeFullyVisible(node))
110                                {
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                                                mHierarchyInterface->SetNodeVisible(randomLeaf, false);
117
118                                                // update node's visited flag
119                                                mHierarchyInterface->SetLastVisited(randomLeaf,
120                                                                                                                        mHierarchyInterface->GetFrameId());
121
122                                                queryQueue.push(QueryPair(node,
123                                                        mHierarchyInterface->IssueNodeOcclusionQuery(node)));
124                                               
125                                                mHierarchyInterface->TraverseNode2(node);
126                                        }
127
128                                        continue;
129                                }
130
131                // identify nodes that we cannot skip queries for
132                                // geometry not only in leaves => test for renderable geometry
133                                const bool issueQuery = !wasVisible || mHierarchyInterface->HasGeometry(node);
134                                                       
135                                // reset node's visibility classification
136                                // set visibe if geometry in node => we only traverse the node once
137                                mHierarchyInterface->SetNodeVisible(node, wasVisible && issueQuery);
138
139                                // update node's visited flag
140                                mHierarchyInterface->SetLastVisited(node, mHierarchyInterface->GetFrameId());
141                               
142
143                                // skip testing previously visible nodes without geometry
144                                if (issueQuery)
145                                {
146                                        ++ mNumQueriesIssued;
147                                       
148                                        queryQueue.push(QueryPair(node, mHierarchyInterface->
149                                                IssueNodeOcclusionQuery(node, wasVisible)));
150                                }
151                               
152                                // always traverse a node if it was visible
153                                if (wasVisible)
154                                {
155                                        mHierarchyInterface->TraverseNode(node);
156                                }
157                        }
158                }
159        }
160
161        // update the fully visible classifications
162        mHierarchyInterface->DetermineFullVisibility(mHierarchyInterface->GetHierarchyRoot());
163}
164//-----------------------------------------------------------------------
165void RandomUpdateCullingManager::SetAssumedVisibility(const unsigned int assumedVisibility)
166{
167        mAssumedVisibility = assumedVisibility;
168       
169        mThreshold = 0;
170
171        if (mAssumedVisibility > 0)
172        {
173                mThreshold = RAND_MAX - RAND_MAX / mAssumedVisibility;
174                if (mAssumedVisibility > 100) // fix visibility
175                        mThreshold = RAND_MAX;
176        }
177        //std::stringstream d; d << "*** setting assumed vis: " << mAssumedVisibility; Ogre::LogManager::getSingleton().logMessage(d.str());
178}
179//-----------------------------------------------------------------------
180inline bool RandomUpdateCullingManager::DecideVisible(HierarchyNode *node) const
181{
182        //bool result = rand() < mThreshold; std::stringstream d; d << "Assumed vis: " << mAssumedVisibility << ", result: " << result;
183        //Ogre::LogManager::getSingleton().logMessage(d.str()); return result;
184       
185        return rand() < mThreshold;
186}
187//-----------------------------------------------------------------------
188inline void RandomUpdateCullingManager::SkipQuery(HierarchyNode *node) const
189{
190        // -- set node to be visible in this frame, then traverse it
191        mHierarchyInterface->SetLastVisited(node, mHierarchyInterface->GetFrameId());
192       
193        mHierarchyInterface->PullUpVisibility(node);                   
194        mHierarchyInterface->TraverseNode(node);
195}
196
197} // namespace GtpVisibility
Note: See TracBrowser for help on using the repository browser.