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

Revision 1816, 5.3 KB checked in by mattausch, 18 years ago (diff)

changed scenemanager: options are directly given to it

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