source: GTP/trunk/Lib/Vis/OnlineCullingCHC/src/CoherentHierarchicalCullingManager.cpp @ 1816

Revision 1816, 5.3 KB checked in by mattausch, 18 years ago (diff)

changed scenemanager: options are directly given to it

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