source: GTP/trunk/Lib/Vis/OnlineCullingCHC/src/RandomUpdateCullingManager.cpp @ 2283

Revision 2283, 5.7 KB checked in by mattausch, 17 years ago (diff)
Line 
1#include "RandomUpdateCullingManager.h"
2#include <time.h>
3#include "CullingLogManager.h"
4
5
6namespace GtpVisibility {
7
8//-----------------------------------------------------------------------
9RandomUpdateCullingManager::RandomUpdateCullingManager()
10{
11        SetAssumedVisibility(0);
12        // initialise random generator in case we use assumed visibility
13        srand(time(NULL));
14
15        mRandomCandidates = 1;
16}
17//-----------------------------------------------------------------------
18RandomUpdateCullingManager::RandomUpdateCullingManager(
19                        const unsigned int assumedVisibility)
20{
21        SetAssumedVisibility(assumedVisibility);
22        // initialise random generator in case we use assumed visibility
23        srand(time(NULL));
24
25        mRandomCandidates = 1;
26}
27//-----------------------------------------------------------------------
28void RandomUpdateCullingManager::RenderScene()
29{
30        QueryQueue queryQueue;
31        unsigned int visiblePixels = 0;
32       
33        /////////////
34        //-- PART 1: process finished occlusion queries
35        //mHierarchyInterface->TraverseNode2(mHierarchyInterface->GetHierarchyRoot());
36        //return;
37
38        while (!mHierarchyInterface->GetQueue()->empty() || !queryQueue.empty())
39        {
40                bool resultAvailable = false;
41
42                //-- only wait for result if there are no nodes to process
43                while (!queryQueue.empty() &&
44                                queryQueue.front().second->GetQueryResult(visiblePixels,
45                                mHierarchyInterface->GetQueue()->empty()))
46                {
47                HierarchyNode *node = queryQueue.front().first;
48                       
49                        queryQueue.pop();
50                       
51                        if (visiblePixels > mVisibilityThreshold)
52                        {
53                                // in case geometry is in interior node:
54                                // ensure that we only traverse once
55                                if (!mHierarchyInterface->IsNodeVisible(node) &&
56                                        !mHierarchyInterface->IsNodeFullyVisible(node))
57                                {
58                                        mHierarchyInterface->TraverseNode(node);
59                                }
60
61                                mHierarchyInterface->PullUpVisibility(node);
62                        }
63                        else
64                        {       
65                                mHierarchyInterface->SetNodeVisible(node, false);
66
67                                ++ mNumQueryCulledNodes;
68                               
69                                if (mVisualizeCulledNodes)
70                                {
71                                        mHierarchyInterface->VisualizeCulledNode(node, QUERY_CULLED);
72                                }
73                        }
74                }
75               
76                //-- PART 2: hierarchical traversal
77                if (!mHierarchyInterface->GetQueue()->empty())
78                {
79                        HierarchyNode *node = mHierarchyInterface->GetQueue()->top();
80                        mHierarchyInterface->GetQueue()->pop();
81                               
82                        bool intersects = false;
83
84                        if (!mHierarchyInterface->CheckFrustumVisible(node, intersects))
85                        {
86                                ++ mNumFrustumCulledNodes;     
87                                if (mVisualizeCulledNodes)
88                                {
89                                        mHierarchyInterface->VisualizeCulledNode(node, FRUSTUM_CULLED);
90                                }
91                        }
92                        //-- if node intersects near plane, skip query because wrong results possible
93                        else if (intersects)
94                        {
95                                SkipQuery(node);
96                        }
97                        else
98                        {
99                                // identify previously visible nodes
100                                const bool wasVisible = mHierarchyInterface->IsNodeVisible(node) &&
101                                        (mHierarchyInterface->LastVisited(node) == mHierarchyInterface->GetFrameId() - 1);
102                               
103                                // if we assume node to be visible in this frame => skip query
104                                const bool skipQuery = wasVisible && (mAssumedVisibility > 0) &&
105                                        DecideVisible(node) && mHierarchyInterface->HasGeometry(node);
106
107                                if (skipQuery)
108                                {
109                                        SkipQuery(node);
110                                        continue;
111                                }
112                                                               
113                                if (mHierarchyInterface->IsNodeFullyVisible(node))
114                                {
115                                        // node fully visible => test only random leaves
116                                        for (int i = 0; i < mRandomCandidates; ++ i)
117                                        {
118                                                HierarchyNode *randomLeaf = mHierarchyInterface->GetRandomLeaf(node);
119                                               
120                                                if (!randomLeaf)
121                                                        continue;
122
123                                                mHierarchyInterface->SetNodeVisible(randomLeaf, false);
124
125                                                // update node's visited flag
126                                                mHierarchyInterface->SetLastVisited(randomLeaf,
127                                                                                                                        mHierarchyInterface->GetFrameId());
128
129                                                queryQueue.push(QueryPair(node,
130                                                        mHierarchyInterface->IssueNodeOcclusionQuery(node)));
131                                        }
132
133                                        mHierarchyInterface->TraverseNode2(node);
134
135                                        continue;
136                                }
137
138                // identify nodes that we cannot skip queries for
139                                // geometry not only in leaves => test for renderable geometry
140                                const bool issueQuery = !wasVisible || mHierarchyInterface->HasGeometry(node);
141                                                       
142                                // reset node's visibility classification
143                                // set visibe if geometry in node => we only traverse the node once
144                                mHierarchyInterface->SetNodeVisible(node, wasVisible && issueQuery);
145
146                                // update node's visited flag
147                                mHierarchyInterface->SetLastVisited(node, mHierarchyInterface->GetFrameId());
148                               
149
150                                // skip testing previously visible nodes without geometry
151                                if (issueQuery)
152                                {
153                                        ++ mNumQueriesIssued;
154                                       
155                                        queryQueue.push(QueryPair(node, mHierarchyInterface->
156                                                IssueNodeOcclusionQuery(node, wasVisible)));
157                                }
158                               
159                                // always traverse a node if it was visible
160                                if (wasVisible)
161                                {
162                                        mHierarchyInterface->TraverseNode(node);
163                                }
164                        }
165                }
166        }
167
168        // update the fully visible classifications
169        mHierarchyInterface->DetermineFullVisibility(mHierarchyInterface->GetHierarchyRoot());
170}
171//-----------------------------------------------------------------------
172void RandomUpdateCullingManager::SetAssumedVisibility(const unsigned int assumedVisibility)
173{
174        mAssumedVisibility = assumedVisibility;
175       
176        mThreshold = 0;
177
178        if (mAssumedVisibility > 0)
179        {
180                mThreshold = RAND_MAX - RAND_MAX / mAssumedVisibility;
181                if (mAssumedVisibility > 100) // fix visibility
182                        mThreshold = RAND_MAX;
183        }
184
185}
186//-----------------------------------------------------------------------
187inline bool RandomUpdateCullingManager::DecideVisible(HierarchyNode *node) const
188{
189        return rand() < mThreshold;
190}
191//-----------------------------------------------------------------------
192inline void RandomUpdateCullingManager::SkipQuery(HierarchyNode *node) const
193{
194        // -- set node to be visible in this frame, then traverse it
195        mHierarchyInterface->SetLastVisited(node, mHierarchyInterface->GetFrameId());
196       
197        mHierarchyInterface->PullUpVisibility(node);                   
198        mHierarchyInterface->TraverseNode(node);
199}
200
201} // namespace GtpVisibility
Note: See TracBrowser for help on using the repository browser.