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

Revision 955, 5.8 KB checked in by mattausch, 18 years ago (diff)
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                //if (mHierarchyInterface->GetQueue()->empty())
32                //      Ogre::LogManager::getSingleton().logMessage("distance queue empty!!");
33                bool resultAvailable = false;
34
35                //-- only wait for result if there are no nodes to process
36                while (!queryQueue.empty() &&
37                                queryQueue.front().second->GetQueryResult(visiblePixels,
38                                mHierarchyInterface->GetQueue()->empty()))
39                {
40               
41                /*while (!queryQueue.empty() &&
42                           ((resultAvailable = queryQueue.front().second->GetQueryResult(visiblePixels, false)) ||
43                mHierarchyInterface->GetQueue()->empty()))
44                {
45                        if (!resultAvailable) visiblePixels = 0;//1e20; // render if result not available
46                        */
47                HierarchyNode *node = queryQueue.front().first;
48                       
49                        queryQueue.pop();
50                       
51                        if (visiblePixels > mVisibilityThreshold)
52                        {
53                                // in case geometry is in omterior node: ensure that we only traverse once
54                                if (!mHierarchyInterface->IsNodeVisible(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                        //Ogre::LogManager::getSingleton().logMessage("traversal");
78                        HierarchyNode *node = mHierarchyInterface->GetQueue()->top();
79                        mHierarchyInterface->GetQueue()->pop();
80                               
81                        bool intersects = false;
82
83                        if (!mHierarchyInterface->CheckFrustumVisible(node, intersects))
84                        {
85                                ++ mNumFrustumCulledNodes;
86                               
87                                if (mVisualizeCulledNodes)
88                                {
89                                        mHierarchyInterface->VisualizeCulledNode(node, FRUSTUM_CULLED);
90                                }
91                        }
92                        // -- if node intersects near plane, skip query because wrong results possible
93                        else if (intersects)
94                        {
95                                SkipQuery(node);
96                        }
97                        else
98                        {
99                                // identify previously visible nodes
100                                bool wasVisible = mHierarchyInterface->IsNodeVisible(node) &&
101                                        (mHierarchyInterface->LastVisited(node) == mHierarchyInterface->GetFrameId() - 1);
102                               
103                                // if we assume node to be visible in this frame => skip query
104                                bool skipQuery = wasVisible && (mAssumedVisibility > 0) &&
105                                        DecideVisible(node) && mHierarchyInterface->HasGeometry(node);
106
107                                //if (mHierarchyInterface->LastVisited(node) >= mHierarchyInterface->GetFrameId())
108                                //      Ogre::LogManager::getSingleton().logMessage("error");
109                               
110                                if (skipQuery)
111                                {
112                                        SkipQuery(node);
113                                        continue;
114                                }
115
116                // identify nodes that we cannot skip queries for
117                                // geometry not only in leaves => test for renderable geometry
118                                bool issueQuery = !wasVisible || mHierarchyInterface->HasGeometry(node);
119                                                       
120                                // reset node's visibility classification
121                                // set visibe if geometry in node so we only traverse once
122                                mHierarchyInterface->SetNodeVisible(node, wasVisible && issueQuery);
123
124                                // update node's visited flag
125                                mHierarchyInterface->SetLastVisited(node, mHierarchyInterface->GetFrameId());
126
127                                // skip testing previously visible nodes without geometry
128                                if (issueQuery)
129                                {
130                                        ++ mNumQueriesIssued;
131                                       
132                                        queryQueue.push(QueryPair(node, mHierarchyInterface->
133                                                IssueNodeOcclusionQuery(node, wasVisible)));
134                                }
135                               
136                                // always traverse a node if it was visible
137                                if (wasVisible)
138                                {
139                                        mHierarchyInterface->TraverseNode(node);
140                                }
141                        }
142                }
143        }
144}
145//-----------------------------------------------------------------------
146void CoherentHierarchicalCullingManager::SetAssumedVisibility(const unsigned int assumedVisibility)
147{
148        mAssumedVisibility = assumedVisibility;
149       
150        mThreshold = 0;
151
152        if (mAssumedVisibility > 0)
153        {
154                mThreshold = RAND_MAX - RAND_MAX / mAssumedVisibility;
155                if (mAssumedVisibility > 100) // fix visibility
156                        mThreshold = RAND_MAX;
157        }
158        //std::stringstream d; d << "*** setting assumed vis: " << mAssumedVisibility; Ogre::LogManager::getSingleton().logMessage(d.str());
159}
160//-----------------------------------------------------------------------
161inline bool CoherentHierarchicalCullingManager::DecideVisible(HierarchyNode *node) const
162{
163        //bool result = rand() < mThreshold; std::stringstream d; d << "Assumed vis: " << mAssumedVisibility << ", result: " << result;
164        //Ogre::LogManager::getSingleton().logMessage(d.str()); return result;
165       
166        return rand() < mThreshold;
167}
168//-----------------------------------------------------------------------
169inline void CoherentHierarchicalCullingManager::SkipQuery(HierarchyNode *node) const
170{
171        // -- set node to be visible in this frame, then traverse it
172        mHierarchyInterface->SetLastVisited(node, mHierarchyInterface->GetFrameId());
173       
174        mHierarchyInterface->PullUpVisibility(node);                   
175        mHierarchyInterface->TraverseNode(node);
176}
177
178} // namespace GtpVisibility
Note: See TracBrowser for help on using the repository browser.