source: trunk/VUT/GtpVisibility/src/CoherentHierarchicalCullingManager.cpp @ 187

Revision 187, 4.7 KB checked in by mattausch, 19 years ago (diff)

added animationbug fix (deleting while animation)fixed visibilityQueriesadditive shadow volumes fixed for octree
hack to fully empty queue after traversal
added demo for vienna model

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        bool isAvailable = false;
27        //Ogre::LogManager::getSingleton().logMessage("Coherent Hierarchical Culling");
28
29        //-- PART 1: process finished occlusion queries
30        while (!mHierarchyInterface->GetQueue()->empty() || !queryQueue.empty())
31        {
32                while (!queryQueue.empty() &&
33                           queryQueue.front().second->GetQueryResult(visiblePixels,
34                                                                        mHierarchyInterface->GetQueue()->empty()))
35                {
36                HierarchyNode *node = queryQueue.front().first;
37                       
38                        queryQueue.pop();
39
40                        if (visiblePixels > mVisibilityThreshold)
41                        {
42                                mHierarchyInterface->PullUpVisibility(node);
43                                mHierarchyInterface->TraverseNode(node);
44                        }
45                        else
46                        {       
47                                ++ mNumQueryCulledNodes;
48                               
49                                if(mVisualizeCulledNodes)
50                                {
51                                        mHierarchyInterface->VisualizeCulledNode(node, QUERY_CULLED);
52                                }
53                        }
54                }
55               
56                //-- PART 2: hierarchical traversal
57                if (!mHierarchyInterface->GetQueue()->empty())
58                {
59                        HierarchyNode *node = mHierarchyInterface->GetQueue()->top();
60                        mHierarchyInterface->GetQueue()->pop();
61                               
62                        bool intersects = false;
63
64                        if (!mHierarchyInterface->CheckFrustumVisible(node, intersects))
65                        {
66                                ++ mNumFrustumCulledNodes;
67                               
68                                if (mVisualizeCulledNodes)
69                                {
70                                        mHierarchyInterface->VisualizeCulledNode(node, FRUSTUM_CULLED);
71                                }
72                        }
73                        // -- if node intersects near plane, skip query because wrong results possible
74                        else if (intersects)
75                        {
76                                SkipQuery(node);
77                        }
78                        else
79                        {
80                                // identify previously visible nodes
81                                bool wasVisible = mHierarchyInterface->IsNodeVisible(node) &&
82                                        (mHierarchyInterface->LastVisited(node) == mHierarchyInterface->GetFrameId() - 1);
83                                       
84                                // if we assume node to be visible in this frame => skip query
85                                if (wasVisible && (mAssumedVisibility > 0) &&  DecideVisible(node) && mHierarchyInterface->HasGeometry(node))
86                                {
87                                        SkipQuery(node);
88
89                                        continue;
90                                }
91
92                // identify nodes that we cannot skip queries for
93                                // geometry not only in leaves => test for renderable geometry
94                                bool issueQuery = !wasVisible || mHierarchyInterface->HasGeometry(node);
95                                                               
96                                // reset node's visibility classification
97                                mHierarchyInterface->SetNodeVisible(node, false);
98
99                                // update node's visited flag
100                                mHierarchyInterface->SetLastVisited(node, mHierarchyInterface->GetFrameId());
101                       
102                                // skip testing previously visible nodes without geometry
103                                if (issueQuery)
104                                {
105                                        ++ mNumQueriesIssued;
106                                       
107                                        queryQueue.push(QueryPair(node, mHierarchyInterface->
108                                                IssueNodeOcclusionQuery(node, wasVisible)));
109                                }
110                               
111                                // always traverse a node if it was visible
112                                if (wasVisible)
113                                {
114                                        mHierarchyInterface->TraverseNode(node);
115                                }
116                        }
117                }
118        }
119}
120//-----------------------------------------------------------------------
121void CoherentHierarchicalCullingManager::SetAssumedVisibility(unsigned int assumedVisibility)
122{
123        mAssumedVisibility = assumedVisibility;
124       
125        mThreshold = 0;
126
127        if (mAssumedVisibility > 0)
128        {
129                mThreshold =  RAND_MAX - RAND_MAX / mAssumedVisibility;
130        }
131        //std::stringstream d; d << "*** setting assumed vis: " << mAssumedVisibility; Ogre::LogManager::getSingleton().logMessage(d.str());
132}
133//-----------------------------------------------------------------------
134bool CoherentHierarchicalCullingManager::DecideVisible(HierarchyNode *node) const
135{
136        /*bool result = rand() < mThreshold; std::stringstream d; d << "Assumed vis: " << mAssumedVisibility << ", result: " << result;
137        Ogre::LogManager::getSingleton().logMessage(d.str()); return result;*/
138       
139        return rand() < mThreshold;
140}
141//-----------------------------------------------------------------------
142void CoherentHierarchicalCullingManager::SkipQuery(HierarchyNode *node)
143{
144        // -- set node to be visible in this frame, then traverse it
145        mHierarchyInterface->SetLastVisited(node, mHierarchyInterface->GetFrameId());
146
147        mHierarchyInterface->PullUpVisibility(node);                   
148        mHierarchyInterface->TraverseNode(node);
149}
150
151} // namespace GtpVisibility
Note: See TracBrowser for help on using the repository browser.