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

Revision 2332, 5.9 KB checked in by mattausch, 17 years ago (diff)

implemented part of rendering estimation of wimmer et al. for view space / object space subdivision.
warning: not working with undersampling estimation + local visibility based subdivision.

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