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

Revision 2278, 6.2 KB checked in by mattausch, 17 years ago (diff)

worked on randomupdatemanager

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                                if (mHierarchyInterface->IsLeaf(node))
109                                {
110                                        if (mHierarchyInterface->IsNodeVisible(node))
111                                                Ogre::LogManager::getSingleton().logMessage("u");
112                                        else
113                                                Ogre::LogManager::getSingleton().logMessage("g");
114                                }
115
116                                if (mHierarchyInterface->IsNodeFullyVisible(node))
117                                {Ogre::LogManager::getSingleton().logMessage("here8");
118                                        // node fully visible => test only random leaves
119                                        for (int i = 0; i < mRandomCandidates; ++ i)
120                                        {
121                                                Ogre::LogManager::getSingleton().logMessage("z");
122                                                HierarchyNode *randomLeaf = mHierarchyInterface->GetRandomLeaf(node);
123
124                                                mHierarchyInterface->SetNodeVisible(randomLeaf, false);
125
126                                                // update node's visited flag
127                                                mHierarchyInterface->SetLastVisited(randomLeaf,
128                                                                                                                        mHierarchyInterface->GetFrameId());
129
130                                                queryQueue.push(QueryPair(node,
131                                                        mHierarchyInterface->IssueNodeOcclusionQuery(node)));
132                                               
133                                                mHierarchyInterface->TraverseNode2(node);
134                                        }
135
136                                        continue;
137                                }
138
139                // identify nodes that we cannot skip queries for
140                                // geometry not only in leaves => test for renderable geometry
141                                const bool issueQuery = !wasVisible || mHierarchyInterface->HasGeometry(node);
142                                                       
143                                // reset node's visibility classification
144                                // set visibe if geometry in node => we only traverse the node once
145                                mHierarchyInterface->SetNodeVisible(node, wasVisible && issueQuery);
146
147                                // update node's visited flag
148                                mHierarchyInterface->SetLastVisited(node, mHierarchyInterface->GetFrameId());
149                               
150
151                                // skip testing previously visible nodes without geometry
152                                if (issueQuery)
153                                {
154                                        ++ mNumQueriesIssued;
155                                       
156                                        queryQueue.push(QueryPair(node, mHierarchyInterface->
157                                                IssueNodeOcclusionQuery(node, wasVisible)));
158                                }
159                               
160                                // always traverse a node if it was visible
161                                if (wasVisible)
162                                {
163                                        mHierarchyInterface->TraverseNode(node);
164                                }
165                        }
166                }
167        }
168
169        // update the fully visible classifications
170        mHierarchyInterface->DetermineFullVisibility(mHierarchyInterface->GetHierarchyRoot());
171}
172//-----------------------------------------------------------------------
173void RandomUpdateCullingManager::SetAssumedVisibility(const unsigned int assumedVisibility)
174{
175        mAssumedVisibility = assumedVisibility;
176       
177        mThreshold = 0;
178
179        if (mAssumedVisibility > 0)
180        {
181                mThreshold = RAND_MAX - RAND_MAX / mAssumedVisibility;
182                if (mAssumedVisibility > 100) // fix visibility
183                        mThreshold = RAND_MAX;
184        }
185        //std::stringstream d; d << "*** setting assumed vis: " << mAssumedVisibility; Ogre::LogManager::getSingleton().logMessage(d.str());
186}
187//-----------------------------------------------------------------------
188inline bool RandomUpdateCullingManager::DecideVisible(HierarchyNode *node) const
189{
190        //bool result = rand() < mThreshold; std::stringstream d; d << "Assumed vis: " << mAssumedVisibility << ", result: " << result;
191        //Ogre::LogManager::getSingleton().logMessage(d.str()); return result;
192       
193        return rand() < mThreshold;
194}
195//-----------------------------------------------------------------------
196inline void RandomUpdateCullingManager::SkipQuery(HierarchyNode *node) const
197{
198        // -- set node to be visible in this frame, then traverse it
199        mHierarchyInterface->SetLastVisited(node, mHierarchyInterface->GetFrameId());
200       
201        mHierarchyInterface->PullUpVisibility(node);                   
202        mHierarchyInterface->TraverseNode(node);
203}
204
205} // namespace GtpVisibility
Note: See TracBrowser for help on using the repository browser.