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

Revision 2556, 7.1 KB checked in by mattausch, 17 years ago (diff)

implemented part of chc++

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