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

Revision 1486, 5.8 KB checked in by mattausch, 18 years ago (diff)

worked on guided visibility sampling

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