source: GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreOctreeHierarchyInterface.cpp @ 2555

Revision 2555, 13.3 KB checked in by mattausch, 17 years ago (diff)

added partial implementation of chc++. problem: bounding box rendering in Ogre is VERY slow

Line 
1#include "OgreOctreeHierarchyInterface.h"
2#include <OgreOctree.h>
3#include <OgreLogManager.h>
4#include <OgreStringConverter.h>
5#include <OgreOctreeNode.h>
6
7
8namespace Ogre {
9
10//-----------------------------------------------------------------------
11OctreeHierarchyInterface::OctreeHierarchyInterface(OctreeSceneManager *sm,
12                                                                                                   RenderSystem *rsys):
13SceneNodeHierarchyInterface(sm, rsys)
14{}
15//-----------------------------------------------------------------------
16void OctreeHierarchyInterface::TraverseNode(GtpVisibility::HierarchyNode *node)
17{
18        ++ mNumTraversedNodes;
19
20        Octree *octree = static_cast<Octree *>(node);
21
22        // if we come across some renderable geometry => render it
23        if (!octree->mNodes.empty())
24        {
25                RenderNode(node);
26        }
27       
28       
29        // if not all subtrees are empty
30        if (!IsLeaf(node))
31        {
32                Octree *nextChild;
33
34                nextChild = octree->mChildren[0][0][0]; if (nextChild) GetQueue()->push(nextChild);
35                nextChild = octree->mChildren[1][0][0]; if (nextChild) GetQueue()->push(nextChild);
36                nextChild = octree->mChildren[0][1][0]; if (nextChild) GetQueue()->push(nextChild);
37                nextChild = octree->mChildren[1][1][0]; if (nextChild) GetQueue()->push(nextChild);
38                nextChild = octree->mChildren[0][0][1]; if (nextChild) GetQueue()->push(nextChild);
39                nextChild = octree->mChildren[1][0][1]; if (nextChild) GetQueue()->push(nextChild);
40                nextChild = octree->mChildren[0][1][1]; if (nextChild) GetQueue()->push(nextChild);
41                nextChild = octree->mChildren[1][1][1]; if (nextChild) GetQueue()->push(nextChild);
42        }
43}
44//-----------------------------------------------------------------------
45void OctreeHierarchyInterface::TraverseNode2(GtpVisibility::HierarchyNode *node)
46{
47        ++ mNumTraversedNodes;
48
49        Octree *octree = static_cast<Octree *>(node);
50
51        // if we come across some renderable geometry => render it
52        if (!octree->mNodes.empty())
53        {
54                AddToQueue(node);
55        }
56       
57        // if not all subtrees are empty
58        if (!IsLeaf(node))
59        {
60                Octree *nextChild;
61
62                nextChild = octree->mChildren[0][0][0]; if (nextChild) GetQueue()->push(nextChild);
63                nextChild = octree->mChildren[1][0][0]; if (nextChild) GetQueue()->push(nextChild);
64                nextChild = octree->mChildren[0][1][0]; if (nextChild) GetQueue()->push(nextChild);
65                nextChild = octree->mChildren[1][1][0]; if (nextChild) GetQueue()->push(nextChild);
66                nextChild = octree->mChildren[0][0][1]; if (nextChild) GetQueue()->push(nextChild);
67                nextChild = octree->mChildren[1][0][1]; if (nextChild) GetQueue()->push(nextChild);
68                nextChild = octree->mChildren[0][1][1]; if (nextChild) GetQueue()->push(nextChild);
69                nextChild = octree->mChildren[1][1][1]; if (nextChild) GetQueue()->push(nextChild);
70        }
71}
72//-----------------------------------------------------------------------
73GtpVisibility::HierarchyNode *OctreeHierarchyInterface::GetRandomLeaf(GtpVisibility::HierarchyNode *root)
74{
75        if (IsLeaf(root))
76                return root;
77
78        Octree *octree = static_cast<Octree *>(root);
79
80        // random decision
81        Octree *child = NULL;
82       
83        std::vector<Octree *> nodes;
84        nodes.reserve(8);
85
86        for (int z = 0; z < 2; ++ z)
87        {       
88                for (int y = 0; y < 2; ++ y)
89                {
90                        for (int x = 0; x < 2; ++ x)
91                        {
92                                if ((child = octree->mChildren[x][y][z]) != NULL)
93                                {
94                                        nodes.push_back(child);
95                                }
96                        }
97                }
98        }
99
100        if (nodes.empty())
101                return NULL;
102
103        int r = (int)(((float)rand() / RAND_MAX) * ((float)nodes.size() - 0.5f));
104
105        return GetRandomLeaf(nodes[r]);
106}
107//-----------------------------------------------------------------------
108bool OctreeHierarchyInterface::IsLeaf(GtpVisibility::HierarchyNode *node) const
109{
110        Octree *octree = static_cast<Octree *>(node);
111
112        // HACK: if there are subtrees, they are empty => we are not interested in them
113        return octree->numNodes() == (int)octree->mNodes.size();
114}
115//-----------------------------------------------------------------------
116bool OctreeHierarchyInterface::HasGeometry(GtpVisibility::HierarchyNode *node) const
117{
118        return !(static_cast<Octree *>(node))->mNodes.empty();
119}
120//-----------------------------------------------------------------------
121float OctreeHierarchyInterface::GetSquaredDistance(GtpVisibility::HierarchyNode *node) const
122{
123        const Vector3 bmin = static_cast<Octree *>(node)->mBox.getMinimum();
124        const Vector3 bmax = static_cast<Octree *>(node)->mBox.getMaximum();
125
126        const Vector3 pos = (bmax - bmin) * 0.5f + bmin;
127       
128        return (mCameraPosition - pos).squaredLength();
129}
130//-----------------------------------------------------------------------
131void OctreeHierarchyInterface::SetNodeVisible(GtpVisibility::HierarchyNode *node,
132                                                                                          const bool visible) const
133{
134#ifdef GTP_VISIBILITY_MODIFIED_OGRE
135        static_cast<Octree *>(node)->setOctreeVisible(visible);
136#endif
137}
138//-----------------------------------------------------------------------
139void OctreeHierarchyInterface::SetLastVisited(GtpVisibility::HierarchyNode *node,
140                                                                                          const unsigned int frameId) const
141{
142#ifdef GTP_VISIBILITY_MODIFIED_OGRE
143        static_cast<Octree *>(node)->setLastVisited(frameId);
144#endif
145}
146//-----------------------------------------------------------------------
147void OctreeHierarchyInterface::PullUpVisibility(GtpVisibility::HierarchyNode *node) const
148{               
149#ifdef GTP_VISIBILITY_MODIFIED_OGRE
150        Octree *octant = static_cast<Octree *>(node);
151
152        while (octant && !octant->isOctreeVisible())
153        {
154                octant->setOctreeVisible(true);
155                octant = octant->getParent();
156        }
157#endif
158}
159//-----------------------------------------------------------------------
160void OctreeHierarchyInterface::PullUpLastVisited(GtpVisibility::HierarchyNode *node, const int frameId) const
161{               
162#ifdef GTP_VISIBILITY_MODIFIED_OGRE
163        Octree *octant = static_cast<Octree *>(node);
164
165        while (octant && (octant->lastVisited() != frameId))
166        {
167                octant->setLastVisited(frameId);
168                octant = octant->getParent();
169        }
170#endif
171}
172//-----------------------------------------------------------------------
173void OctreeHierarchyInterface::DetermineFullVisibility(GtpVisibility::HierarchyNode *node) const
174{               
175        Octree *octant = static_cast<Octree *>(node);
176
177        // node not visited in this frame => no change
178        if (octant->lastVisited() != mFrameId)
179                return;
180
181        // leaf node: terminate recursion
182        if (IsLeaf(node))
183        {
184                octant->setOctreeFullyVisible(octant->isOctreeVisible());       
185                return;
186        }
187
188        octant->setOctreeFullyVisible(true);
189        Octree *nextChild;
190       
191        for (int i = 0; i < 8; ++ i)
192        {
193                int x = (i & 4) / 4;
194                int y = (i & 2) / 2;
195                int z = i & 1;
196
197                nextChild = octant->mChildren[x][y][z];
198
199                if (!nextChild)
200                        continue;
201               
202                // recursive traversal
203                DetermineFullVisibility(nextChild);
204               
205                // this leaf is not fully visible
206                if (!nextChild->isOctreeFullyVisible())
207                {
208                        octant->setOctreeFullyVisible(false);
209                }
210        }
211}
212//-----------------------------------------------------------------------
213void OctreeHierarchyInterface::RenderNode(GtpVisibility::HierarchyNode *node)
214{
215#ifdef GTP_VISIBILITY_MODIFIED_OGRE
216        Octree *octant = static_cast<Octree *>(node);
217
218        if (octant->lastRendered() != mFrameId)
219        {
220                mTestMode = false;
221
222                octant->setLastRendered(mFrameId);
223                OctreeSceneManager *ocm =
224                        static_cast<OctreeSceneManager *>(mSceneManager);
225
226                ocm->_addOctantToQueue(mCamera,
227                                                   octant,
228                                                   mOnlyShadowCasters,
229                                                   mLeavePassesInQueue);
230
231                ocm->_renderOctant(mLeavePassesInQueue);
232
233                mVisibleNodes.push_back(node);
234        }
235#endif 
236}
237//-----------------------------------------------------------------------
238void OctreeHierarchyInterface::AddToQueue(GtpVisibility::HierarchyNode *node)
239{
240#ifdef GTP_VISIBILITY_MODIFIED_OGRE
241        Octree *octant = static_cast<Octree *>(node);
242
243        if (octant->lastRendered() != mFrameId)
244        {
245                OctreeSceneManager *ocm =
246                        static_cast<OctreeSceneManager *>(mSceneManager);
247
248                octant->setLastRendered(mFrameId);
249
250                ocm->_addOctantToQueue(mCamera,
251                                                   octant,
252                                                   mOnlyShadowCasters,
253                                                   mLeavePassesInQueue);
254
255                mVisibleNodes.push_back(node);
256        }
257#endif 
258}
259//-----------------------------------------------------------------------
260void OctreeHierarchyInterface::RenderQueue()
261{
262#ifdef GTP_VISIBILITY_MODIFIED_OGRE
263        mTestMode = false;
264
265        OctreeSceneManager *ocm =
266                        static_cast<OctreeSceneManager *>(mSceneManager);
267        ocm->_renderOctant(mLeavePassesInQueue);
268#endif 
269}
270//-----------------------------------------------------------------------
271void OctreeHierarchyInterface::RenderNodeRecursive(GtpVisibility::HierarchyNode *node)
272{
273#ifdef GTP_VISIBILITY_MODIFIED_OGRE
274        Octree *octant = static_cast<Octree *>(node);
275
276        if (octant->lastRendered() != mFrameId)
277        {
278                octant->setLastRendered(mFrameId);
279
280                OctreeSceneManager *ocm =
281                        static_cast<OctreeSceneManager *>(mSceneManager);
282
283                ocm->_renderOctantRecursive(mCamera,
284                                                                        octant,
285                                                                        mOnlyShadowCasters,
286                                                                        mLeavePassesInQueue);
287
288                mVisibleNodes.push_back(node);
289        }
290#endif 
291}
292//-----------------------------------------------------------------------
293bool OctreeHierarchyInterface::IsNodeVisible(GtpVisibility::HierarchyNode *node) const
294{
295#ifdef GTP_VISIBILITY_MODIFIED_OGRE
296        return static_cast<Octree *>(node)->isOctreeVisible();
297#else
298        return true;
299#endif
300}
301//-----------------------------------------------------------------------
302bool OctreeHierarchyInterface::IsNodeFullyVisible(GtpVisibility::HierarchyNode *node) const
303{
304        return static_cast<Octree *>(node)->isOctreeFullyVisible();
305}
306//-----------------------------------------------------------------------
307unsigned int OctreeHierarchyInterface::LastVisited(GtpVisibility::HierarchyNode *node) const
308{
309#ifdef GTP_VISIBILITY_MODIFIED_OGRE
310        return static_cast<Octree *>(node)->lastVisited();
311#else
312        return 0;
313#endif
314}
315//-----------------------------------------------------------------------
316AxisAlignedBox *OctreeHierarchyInterface::GetBoundingBox(GtpVisibility::HierarchyNode *node)
317{
318        // reuse box if node is the same
319        // only create renderable bounding box for new node
320        if (node != mOldNode)
321        {
322                mOldNode = node;
323            //static_cast<Octree *>(node)->_getCullBounds(&mBox);
324                mBox = static_cast<Octree *>(node)->_getWorldAABB();
325        }
326
327        return &mBox;
328}
329//-----------------------------------------------------------------------
330void OctreeHierarchyInterface::VisualizeCulledNode(GtpVisibility::HierarchyNode *node,
331                                                                                                   GtpVisibility::CullingType type) const
332{
333        WireBoundingBox *box = static_cast<Octree *>(node)->getWireBoundingBox();
334
335        if (type == GtpVisibility::FRUSTUM_CULLED)
336        {
337                box->setMaterial("FrustumCulledNodesMaterial");
338        }
339        else // type == GtpVisibility::QUERY_CULLED
340        {
341                box->setMaterial("QueryCulledNodesMaterial");
342        }
343
344        static_cast<OctreeSceneManager *>(mSceneManager)->getBoxes()->push_back(box);
345}
346//-----------------------------------------------------------------------
347void OctreeHierarchyInterface::GetNodeGeometryList(GtpVisibility::HierarchyNode *node,
348                                                                                                   GeometryVector *geometryList,
349                                                                                                   bool includeChildren)
350{
351        NodeList::const_iterator nodeIt, nodeIt_end;
352        nodeIt_end = static_cast<Octree *>(node)->mNodes.end();
353
354        for (nodeIt = static_cast<Octree *>(node)->mNodes.begin(); nodeIt != nodeIt_end; ++nodeIt)
355        {
356                SceneNodeHierarchyInterface::GetNodeGeometryList(*nodeIt, geometryList, includeChildren);
357        }
358}
359//-----------------------------------------------------------------------
360void OctreeHierarchyInterface::CollectLeaves(GtpVisibility::HierarchyNode *root,
361                                                                                         GtpVisibility::HierarchyNodeContainer &nodes)
362{
363        std::stack<GtpVisibility::HierarchyNode *> tStack;
364        tStack.push(root);
365
366        Octree *child;
367
368        while (!tStack.empty())
369        {
370                GtpVisibility::HierarchyNode *node = tStack.top();
371                tStack.pop();
372
373                if (IsLeaf(node))
374                {
375                        nodes.push_back(node);
376                }
377                else
378                {
379                        Octree *octree = static_cast<Octree *>(node);
380                       
381                        for (int z = 0; z < 2; ++ z)
382                                for (int y = 0; y < 2; ++ y)
383                                        for (int x = 0; x < 2; ++ x)
384                                                if ((child = octree->mChildren[x][y][z]) != NULL)
385                                                        tStack.push(child);
386                }
387        }
388}
389
390//-----------------------------------------------------------------------
391GtpVisibility::HierarchyNode *OctreeHierarchyInterface::GetParent(GtpVisibility::HierarchyNode *node)
392{
393        Octree *octree = static_cast<Octree *>(node);
394        return octree->getParent();
395}
396//-----------------------------------------------------------------------
397int OctreeHierarchyInterface::GetNodeAssumedVisible(GtpVisibility::HierarchyNode *node)
398{
399        Octree *octree = static_cast<Octree *>(node);
400        return octree->getAssumedVisible();
401}
402//-----------------------------------------------------------------------
403void OctreeHierarchyInterface::SetNodeAssumedVisible(GtpVisibility::HierarchyNode *node, int assumedVisible)
404{
405        Octree *octree = static_cast<Octree *>(node);
406        octree->setAssumedVisible(assumedVisible);
407}
408//-----------------------------------------------------------------------
409void OctreeHierarchyInterface::DecNodeAssumedVisible(GtpVisibility::HierarchyNode *node)
410{
411        Octree *octree = static_cast<Octree *>(node);
412        octree->decAssumedVisible();
413}
414//-----------------------------------------------------------------------
415void OctreeHierarchyInterface::RenderGeometryBounds(GtpVisibility::HierarchyNode *node)
416{
417        Octree *octree = static_cast<Octree *>(node);
418
419        NodeList::iterator it, it_end = octree->mNodes.end();
420
421    for (it = octree->mNodes.begin(); it != it_end; ++ it)
422    {
423                RenderBoundingBox(&(*it)->_getWorldAABB());
424    }   
425}
426
427
428} // namespace Ogre
Note: See TracBrowser for help on using the repository browser.