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

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