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

RevLine 
[59]1#include "OgreOctreeHierarchyInterface.h"
2#include <OgreOctree.h>
[94]3#include <OgreLogManager.h>
[113]4#include <OgreStringConverter.h>
[2455]5#include <OgreOctreeNode.h>
[59]6
[115]7
[59]8namespace Ogre {
[94]9
[59]10//-----------------------------------------------------------------------
[2258]11OctreeHierarchyInterface::OctreeHierarchyInterface(OctreeSceneManager *sm,
12                                                                                                   RenderSystem *rsys):
[158]13SceneNodeHierarchyInterface(sm, rsys)
[2258]14{}
[59]15//-----------------------------------------------------------------------
[158]16void OctreeHierarchyInterface::TraverseNode(GtpVisibility::HierarchyNode *node)
[59]17{
[139]18        ++ mNumTraversedNodes;
[59]19
[87]20        Octree *octree = static_cast<Octree *>(node);
21
[59]22        // if we come across some renderable geometry => render it
[726]23        if (!octree->mNodes.empty())
[87]24        {
25                RenderNode(node);
26        }
[59]27       
[925]28       
[726]29        // if not all subtrees are empty
[94]30        if (!IsLeaf(node))
[59]31        {
[726]32                Octree *nextChild;
33
[2555]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        }
[2306]56       
[2555]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);
[59]70        }
71}
72//-----------------------------------------------------------------------
[2259]73GtpVisibility::HierarchyNode *OctreeHierarchyInterface::GetRandomLeaf(GtpVisibility::HierarchyNode *root)
[2258]74{
[2259]75        if (IsLeaf(root))
76                return root;
77
78        Octree *octree = static_cast<Octree *>(root);
79
80        // random decision
[2278]81        Octree *child = NULL;
82       
[2281]83        std::vector<Octree *> nodes;
[2283]84        nodes.reserve(8);
[2281]85
[2306]86        for (int z = 0; z < 2; ++ z)
87        {       
88                for (int y = 0; y < 2; ++ y)
[2281]89                {
[2306]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                        }
[2281]97                }
98        }
99
100        if (nodes.empty())
101                return NULL;
102
[2283]103        int r = (int)(((float)rand() / RAND_MAX) * ((float)nodes.size() - 0.5f));
[2281]104
105        return GetRandomLeaf(nodes[r]);
[2258]106}
107//-----------------------------------------------------------------------
[74]108bool OctreeHierarchyInterface::IsLeaf(GtpVisibility::HierarchyNode *node) const
[59]109{
[94]110        Octree *octree = static_cast<Octree *>(node);
[944]111
[94]112        // HACK: if there are subtrees, they are empty => we are not interested in them
113        return octree->numNodes() == (int)octree->mNodes.size();
[59]114}
115//-----------------------------------------------------------------------
[74]116bool OctreeHierarchyInterface::HasGeometry(GtpVisibility::HierarchyNode *node) const
[59]117{
[722]118        return !(static_cast<Octree *>(node))->mNodes.empty();
[59]119}
120//-----------------------------------------------------------------------
[87]121float OctreeHierarchyInterface::GetSquaredDistance(GtpVisibility::HierarchyNode *node) const
[59]122{
[726]123        const Vector3 bmin = static_cast<Octree *>(node)->mBox.getMinimum();
124        const Vector3 bmax = static_cast<Octree *>(node)->mBox.getMaximum();
[722]125
[2292]126        const Vector3 pos = (bmax - bmin) * 0.5f + bmin;
[345]127       
[726]128        return (mCameraPosition - pos).squaredLength();
[59]129}
130//-----------------------------------------------------------------------
[74]131void OctreeHierarchyInterface::SetNodeVisible(GtpVisibility::HierarchyNode *node,
[345]132                                                                                          const bool visible) const
[59]133{
134#ifdef GTP_VISIBILITY_MODIFIED_OGRE
135        static_cast<Octree *>(node)->setOctreeVisible(visible);
136#endif
137}
138//-----------------------------------------------------------------------
[74]139void OctreeHierarchyInterface::SetLastVisited(GtpVisibility::HierarchyNode *node,
[345]140                                                                                          const unsigned int frameId) const
[59]141{
142#ifdef GTP_VISIBILITY_MODIFIED_OGRE
143        static_cast<Octree *>(node)->setLastVisited(frameId);
144#endif
145}
146//-----------------------------------------------------------------------
[345]147void OctreeHierarchyInterface::PullUpVisibility(GtpVisibility::HierarchyNode *node) const
[59]148{               
149#ifdef GTP_VISIBILITY_MODIFIED_OGRE
150        Octree *octant = static_cast<Octree *>(node);
151
[155]152        while (octant && !octant->isOctreeVisible())
[59]153        {
154                octant->setOctreeVisible(true);
155                octant = octant->getParent();
156        }
157#endif
158}
159//-----------------------------------------------------------------------
[2306]160void OctreeHierarchyInterface::PullUpLastVisited(GtpVisibility::HierarchyNode *node, const int frameId) const
[2292]161{               
162#ifdef GTP_VISIBILITY_MODIFIED_OGRE
163        Octree *octant = static_cast<Octree *>(node);
164
[2306]165        while (octant && (octant->lastVisited() != frameId))
[2292]166        {
[2306]167                octant->setLastVisited(frameId);
[2292]168                octant = octant->getParent();
169        }
170#endif
[2306]171}
[2292]172//-----------------------------------------------------------------------
[2258]173void OctreeHierarchyInterface::DetermineFullVisibility(GtpVisibility::HierarchyNode *node) const
174{               
175        Octree *octant = static_cast<Octree *>(node);
176
[2306]177        // node not visited in this frame => no change
178        if (octant->lastVisited() != mFrameId)
179                return;
180
[2258]181        // leaf node: terminate recursion
182        if (IsLeaf(node))
183        {
[2292]184                octant->setOctreeFullyVisible(octant->isOctreeVisible());       
[2258]185                return;
186        }
187
[2278]188        octant->setOctreeFullyVisible(true);
[2258]189        Octree *nextChild;
[2283]190       
[2258]191        for (int i = 0; i < 8; ++ i)
192        {
[2278]193                int x = (i & 4) / 4;
194                int y = (i & 2) / 2;
[2258]195                int z = i & 1;
[2306]196
197                nextChild = octant->mChildren[x][y][z];
198
199                if (!nextChild)
200                        continue;
[2283]201               
[2306]202                // recursive traversal
203                DetermineFullVisibility(nextChild);
204               
205                // this leaf is not fully visible
206                if (!nextChild->isOctreeFullyVisible())
[2258]207                {
[2306]208                        octant->setOctreeFullyVisible(false);
[2258]209                }
210        }
211}
212//-----------------------------------------------------------------------
[59]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        {
[2555]220                mTestMode = false;
221
[59]222                octant->setLastRendered(mFrameId);
[726]223                OctreeSceneManager *ocm =
[2066]224                        static_cast<OctreeSceneManager *>(mSceneManager);
[938]225
[2555]226                ocm->_addOctantToQueue(mCamera,
[2258]227                                                   octant,
228                                                   mOnlyShadowCasters,
229                                                   mLeavePassesInQueue);
[59]230
[2555]231                ocm->_renderOctant(mLeavePassesInQueue);
232
[174]233                mVisibleNodes.push_back(node);
[59]234        }
[2258]235#endif 
[59]236}
237//-----------------------------------------------------------------------
[2555]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//-----------------------------------------------------------------------
[2259]271void OctreeHierarchyInterface::RenderNodeRecursive(GtpVisibility::HierarchyNode *node)
272{
273#ifdef GTP_VISIBILITY_MODIFIED_OGRE
274        Octree *octant = static_cast<Octree *>(node);
275
[2292]276        if (octant->lastRendered() != mFrameId)
[2259]277        {
278                octant->setLastRendered(mFrameId);
[2287]279
[2259]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//-----------------------------------------------------------------------
[74]293bool OctreeHierarchyInterface::IsNodeVisible(GtpVisibility::HierarchyNode *node) const
[59]294{
295#ifdef GTP_VISIBILITY_MODIFIED_OGRE
296        return static_cast<Octree *>(node)->isOctreeVisible();
297#else
298        return true;
299#endif
300}
301//-----------------------------------------------------------------------
[2259]302bool OctreeHierarchyInterface::IsNodeFullyVisible(GtpVisibility::HierarchyNode *node) const
303{
304        return static_cast<Octree *>(node)->isOctreeFullyVisible();
305}
306//-----------------------------------------------------------------------
[74]307unsigned int OctreeHierarchyInterface::LastVisited(GtpVisibility::HierarchyNode *node) const
[59]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{
[925]318        // reuse box if node is the same
319        // only create renderable bounding box for new node
[2455]320        if (node != mOldNode)
[85]321        {
[2455]322                mOldNode = node;
[880]323            //static_cast<Octree *>(node)->_getCullBounds(&mBox);
[135]324                mBox = static_cast<Octree *>(node)->_getWorldAABB();
[85]325        }
[59]326
327        return &mBox;
328}
[112]329//-----------------------------------------------------------------------
330void OctreeHierarchyInterface::VisualizeCulledNode(GtpVisibility::HierarchyNode *node,
[345]331                                                                                                   GtpVisibility::CullingType type) const
[112]332{
333        WireBoundingBox *box = static_cast<Octree *>(node)->getWireBoundingBox();
[59]334
[112]335        if (type == GtpVisibility::FRUSTUM_CULLED)
336        {
337                box->setMaterial("FrustumCulledNodesMaterial");
338        }
339        else // type == GtpVisibility::QUERY_CULLED
340        {
341                box->setMaterial("QueryCulledNodesMaterial");
342        }
[113]343
[2066]344        static_cast<OctreeSceneManager *>(mSceneManager)->getBoxes()->push_back(box);
[112]345}
[130]346//-----------------------------------------------------------------------
[726]347void OctreeHierarchyInterface::GetNodeGeometryList(GtpVisibility::HierarchyNode *node,
[2280]348                                                                                                   GeometryVector *geometryList,
[726]349                                                                                                   bool includeChildren)
[130]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        {
[155]356                SceneNodeHierarchyInterface::GetNodeGeometryList(*nodeIt, geometryList, includeChildren);
[130]357        }
358}
[2292]359//-----------------------------------------------------------------------
360void OctreeHierarchyInterface::CollectLeaves(GtpVisibility::HierarchyNode *root,
361                                                                                         GtpVisibility::HierarchyNodeContainer &nodes)
362{
363        std::stack<GtpVisibility::HierarchyNode *> tStack;
364        tStack.push(root);
[174]365
[2292]366        Octree *child;
[2258]367
[2292]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                       
[2306]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);
[2292]386                }
387        }
388}
389
[2332]390//-----------------------------------------------------------------------
391GtpVisibility::HierarchyNode *OctreeHierarchyInterface::GetParent(GtpVisibility::HierarchyNode *node)
392{
393        Octree *octree = static_cast<Octree *>(node);
394        return octree->getParent();
395}
[2455]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);
[2332]418
[2455]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
[59]428} // namespace Ogre
Note: See TracBrowser for help on using the repository browser.