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

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