source: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/CHCTraverser.cpp @ 2792

Revision 2792, 3.2 KB checked in by mattausch, 16 years ago (diff)
Line 
1#include "CHCTraverser.h"
2#include "SceneEntity.h"
3
4
5namespace CHCDemoEngine
6{
7
8CHCTraverser::CHCTraverser()
9{}
10
11
12OcclusionQuery *CHCTraverser::IssueOcclusionQueryWithGeometry(BvhNode *node)
13{
14        OcclusionQuery *query = mQueryHandler.RequestQuery();
15        query->AddNode(node);
16
17        ++ mStats.mNumIssuedQueries;
18
19        query->BeginQuery();
20
21        RenderNode(node);
22
23        if (mUseRenderQueue)
24        {
25                mRenderQueue.Render();
26                mRenderQueue.Clear();
27        }
28
29        query->EndQuery();
30
31        return query;
32}
33
34
35void CHCTraverser::Traverse()
36{
37        //-- PART 1: process finished occlusion queries
38        while (!mDistanceQueue.empty() || !mQueryQueue.empty())
39        {
40                while (!mQueryQueue.empty() &&
41                           (mQueryQueue.front()->ResultAvailable() || mDistanceQueue.empty()))
42                {
43                        OcclusionQuery *query = mQueryQueue.front();
44                        mQueryQueue.pop();
45                       
46                        // wait until result available
47                        int visiblePixels = query->GetQueryResult();
48
49                        if (visiblePixels > mVisibilityThreshold)
50                        {
51                                BvhNode *node = query->GetFrontNode();
52                                node->SetAssumedVisibleFrameId(mFrameId + mAssumedVisibleFrames);
53
54                                node->SetVisible(true);
55                                mBvh->MakeParentsVisible(node);
56                                TraverseNode(node);
57                        }
58                        else
59                        {
60                               
61                                ++ mStats.mNumQueryCulledNodes;
62                        }
63                }       
64
65                //-- PART 2: hierarchical traversal
66                if (!mDistanceQueue.empty())
67                {
68                        BvhNode *node = mDistanceQueue.top();
69                        mDistanceQueue.pop();
70       
71                        if (mBvh->IsWithinViewFrustum(node))
72                        {
73                                // for near plane intersecting bounding box possible
74                                // wrong results => skip occlusion query
75                                if (IntersectsNearPlane(node))
76                                {
77                                        // update node's visited flag
78                                        node->SetLastVisitedFrame(mFrameId);
79                                        node->SetVisible(true);
80                                        mBvh->MakeParentsVisible(node);
81
82                                        TraverseNode(node);
83                                }
84                                else
85                                {               
86                                        // identify previously visible nodes
87                                        const bool wasVisible = node->IsVisible() && (node->GetLastVisitedFrame() == mFrameId - 1);
88                                       
89                                        // identify nodes that we cannot skip queries for
90                                        const bool queryFeasible = (!wasVisible ||
91                                                (node->IsVirtualLeaf() && (node->GetAssumedVisibleFrameId() <= mFrameId)));
92
93                                        // update node's visited flag
94                                        node->SetLastVisitedFrame(mFrameId);
95                                       
96                                        // skip testing previously visible interior nodes
97                                        if (queryFeasible)
98                                        {
99                                                OcclusionQuery *query;
100
101                                                // if this node is a previous visible leaf:
102                                                // leaves will be rendered anyway => we can directly query the real geometry
103                                                if (wasVisible && mUseOptimization)
104                                                        query = IssueOcclusionQueryWithGeometry(node);
105                                                else
106                                                        query = IssueOcclusionQuery(node);
107
108                                                mQueryQueue.push(query);
109                                        }
110                                        else
111                                        {
112                                                if (node->IsVirtualLeaf())
113                                                {
114                                                        node->SetVisible(true);
115                                                        mBvh->MakeParentsVisible(node);
116                                                }
117                                                else // reset visibility classification
118                                                {
119                                                        node->SetVisible(false);
120                                                }
121                                        }
122
123                                       
124                                        // always traverse a node if it was visible
125                                        if (wasVisible)
126                                                TraverseNode(node);
127                                }
128                        }
129                        else
130                        {
131                                // for stats
132                                ++ mStats.mNumFrustumCulledNodes;
133                        }
134                }
135        }
136
137        /// Empty render queue.
138        if (mUseRenderQueue)
139        {
140                mRenderQueue.Render();
141                mRenderQueue.Clear();
142        }
143}
144
145}
Note: See TracBrowser for help on using the repository browser.