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

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