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

Revision 2455, 6.9 KB checked in by mattausch, 17 years ago (diff)
RevLine 
[59]1#include "CoherentHierarchicalCullingManager.h"
[2287]2#include "CullingLogManager.h"
3
[2280]4#include <time.h>
[2455]5#include <sstream>
[59]6
[2455]7
[59]8namespace GtpVisibility {
9
[2455]10
11static int batchSize = 5;
12
[59]13//-----------------------------------------------------------------------
[2455]14CoherentHierarchicalCullingManager::CoherentHierarchicalCullingManager():
15mAssumedVisibility(0)
[142]16{
17}
18//-----------------------------------------------------------------------
[2258]19CoherentHierarchicalCullingManager::CoherentHierarchicalCullingManager(
[2455]20                                                                                                                const unsigned int assumedVisibility):
21mAssumedVisibility(assumedVisibility)
[155]22{
23}
24//-----------------------------------------------------------------------
[2455]25void CoherentHierarchicalCullingManager::AssignAssumedVisibility(GtpVisibility::HierarchyNode *node)
26{
27        if (!mHierarchyInterface->IsNodeVisible(node))
28                // previously invisible nodes: give random offset just for the first test after
29                // becoming visible to avoid that all nodes are tested in the same frame
30                mHierarchyInterface->SetNodeAssumedVisible(node, rand() * mAssumedVisibility / RAND_MAX);
31        else
32                mHierarchyInterface->SetNodeAssumedVisible(node, mAssumedVisibility);
33}
34//-----------------------------------------------------------------------
[59]35void CoherentHierarchicalCullingManager::RenderScene()
36{
[2292]37        if (0) CullingLogManager::GetSingleton()->LogMessage("chc");
[85]38        QueryQueue queryQueue;
[86]39        unsigned int visiblePixels = 0;
[925]40       
[2171]41        /////////////
[59]42        //-- PART 1: process finished occlusion queries
[2171]43
[59]44        while (!mHierarchyInterface->GetQueue()->empty() || !queryQueue.empty())
45        {
[2332]46                //////////
[955]47                //-- only wait for result if there are no nodes to process
[2455]48
[59]49                while (!queryQueue.empty() &&
[2332]50                           (NodeInvalid(queryQueue.front().first) ||
51                            queryQueue.front().second->GetQueryResult(
52                                             visiblePixels, mHierarchyInterface->GetQueue()->empty())))
[59]53                {
[2287]54                        HierarchyNode *node = queryQueue.front().first;
[59]55                        queryQueue.pop();
[2332]56
[2455]57                        // "invalid nodes" happen for hierarchies that have geometry
58                        // not neccessarily in the leaves:
[2332]59                        // parent was tested invisible => remove children from queue
[2455]60
61                        if (1 && NodeInvalid(node))
[2332]62                                continue;
[2455]63
[2332]64                        // tested visible
[96]65                        if (visiblePixels > mVisibilityThreshold)
[59]66                        {
[2455]67                                // assing the #frames the node is assumed to stay visible
68                                AssignAssumedVisibility(node);
69
70                                // for previously visible interior node which contains geometry:
71                                // ensure that we did not already traverse this node
72                                // (which means that the visibility flag is set)
[348]73                                if (!mHierarchyInterface->IsNodeVisible(node))
74                                        mHierarchyInterface->TraverseNode(node);
[726]75
[59]76                                mHierarchyInterface->PullUpVisibility(node);
77                        }
78                        else
[142]79                        {       
[348]80                                mHierarchyInterface->SetNodeVisible(node, false);
81
[2332]82                ++ mNumQueryCulledNodes;
[2455]83
[348]84                                if (mVisualizeCulledNodes)
[112]85                                        mHierarchyInterface->VisualizeCulledNode(node, QUERY_CULLED);
[59]86                        }
[2332]87                       
88                        // update node's visited flag
89                        mHierarchyInterface->SetLastVisited(node, mHierarchyInterface->GetFrameId());   
[85]90                }
[87]91               
[2455]92                ////////////////
[59]93                //-- PART 2: hierarchical traversal
[2455]94
[59]95                if (!mHierarchyInterface->GetQueue()->empty())
96                {
97                        HierarchyNode *node = mHierarchyInterface->GetQueue()->top();
98                        mHierarchyInterface->GetQueue()->pop();
99                               
[2332]100                        // parent was tested invisible => remove children from queue
[2455]101                        if (1 && NodeInvalid(node))
[2332]102                                continue;
103
[59]104                        bool intersects = false;
105
[74]106                        if (!mHierarchyInterface->CheckFrustumVisible(node, intersects))
[130]107                        {
[2287]108                                ++ mNumFrustumCulledNodes;
109
[147]110                                if (mVisualizeCulledNodes)
[113]111                                        mHierarchyInterface->VisualizeCulledNode(node, FRUSTUM_CULLED);
[59]112                        }
[1486]113                        //-- if node intersects near plane, skip query because wrong results possible
[155]114                        else if (intersects)
115                        {
116                                SkipQuery(node);
117                        }
[74]118                        else
[59]119                        {
[148]120                                // identify previously visible nodes
121                                bool wasVisible = mHierarchyInterface->IsNodeVisible(node) &&
122                                        (mHierarchyInterface->LastVisited(node) == mHierarchyInterface->GetFrameId() - 1);
[346]123                               
[155]124                                // if we assume node to be visible in this frame => skip query
[2455]125                                const bool skipQuery = wasVisible &&
[2332]126                                                                           DecideVisible(node) &&
127                                                                           mHierarchyInterface->HasGeometry(node);
[348]128
129                                if (skipQuery)
[74]130                                {
[155]131                                        SkipQuery(node);
[74]132                                        continue;
133                                }
[59]134
[148]135                // identify nodes that we cannot skip queries for
[87]136                                // geometry not only in leaves => test for renderable geometry
[348]137                                bool issueQuery = !wasVisible || mHierarchyInterface->HasGeometry(node);
[345]138                                                       
[2455]139                                // set node's visibility classification
140                                // we identify previously visible / invisible nodes in the query queue
[348]141                                mHierarchyInterface->SetNodeVisible(node, wasVisible && issueQuery);
[59]142
[87]143                                if (issueQuery)
[74]144                                {
[147]145                                        ++ mNumQueriesIssued;
[142]146                                       
[2455]147                                        const bool testGeometry = wasVisible && mHierarchyInterface->IsLeaf(node) && mTestGeometryForVisibleLeaves;
148
[87]149                                        queryQueue.push(QueryPair(node, mHierarchyInterface->
[2455]150                                                IssueNodeOcclusionQuery(node, testGeometry)));
[74]151                                }
[2332]152                                else
153                                {
[2455]154                                        // skip testing previously visible nodes without geometry
155                    // just update node's visited flag
[2332]156                                        mHierarchyInterface->SetLastVisited(node, mHierarchyInterface->GetFrameId());
157                                }
158
[74]159                                // always traverse a node if it was visible
160                                if (wasVisible)
161                                {
[158]162                                        mHierarchyInterface->TraverseNode(node);
[74]163                                }
[59]164                        }
165                }
166        }
167}
[142]168//-----------------------------------------------------------------------
[345]169void CoherentHierarchicalCullingManager::SetAssumedVisibility(const unsigned int assumedVisibility)
[142]170{
171        mAssumedVisibility = assumedVisibility;
172}
173//-----------------------------------------------------------------------
[345]174inline bool CoherentHierarchicalCullingManager::DecideVisible(HierarchyNode *node) const
[142]175{
[2455]176        mHierarchyInterface->DecNodeAssumedVisible(node);
177        //std::stringstream d; d << "node visible: " << mHierarchyInterface->GetNodeAssumedVisible(node);
178        //CullingLogManager::GetSingleton()->LogMessage(d.str());
179        return mHierarchyInterface->GetNodeAssumedVisible(node) > 0;
[142]180}
[155]181//-----------------------------------------------------------------------
[345]182inline void CoherentHierarchicalCullingManager::SkipQuery(HierarchyNode *node) const
[155]183{
[2292]184        //-- set node to be visible in this frame, then traverse it
[155]185        mHierarchyInterface->SetLastVisited(node, mHierarchyInterface->GetFrameId());
[345]186       
[155]187        mHierarchyInterface->PullUpVisibility(node);                   
[158]188        mHierarchyInterface->TraverseNode(node);
[155]189}
[2332]190//-----------------------------------------------------------------------
191bool CoherentHierarchicalCullingManager::NodeInvalid(HierarchyNode *node) const
192{
193        // parent was tested invisible in this frame
194        HierarchyNode *parent = mHierarchyInterface->GetParent(node);
195    return
196                parent &&
197                (mHierarchyInterface->LastVisited(node) == mHierarchyInterface->GetFrameId()) &&
198                !mHierarchyInterface->IsNodeVisible(parent);
199}
[2455]200//-----------------------------------------------------------------------
201void CoherentHierarchicalCullingManager::SetTestGeometryForVisibleLeaves(const bool testGeometry)
202{
203        mTestGeometryForVisibleLeaves = testGeometry;
204}
205//-----------------------------------------------------------------------
206bool CoherentHierarchicalCullingManager::GetTestGeometryForVisibleLeaves()
207{
208        return mTestGeometryForVisibleLeaves;
209}
210
211}
Note: See TracBrowser for help on using the repository browser.