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

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