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

Revision 2280, 6.0 KB checked in by mattausch, 18 years ago (diff)

removed dependency on ogre in gtpvisibility

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