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

Revision 2455, 10.8 KB checked in by mattausch, 17 years ago (diff)
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
[2306]34                for (int z = 0; z < 2; ++ z)
35                {       
36                        for (int y = 0; y < 2; ++ y)
37                        {
38                                for (int x = 0; x < 2; ++ x)
39                                {
40                                        nextChild = octree->mChildren[x][y][z];
41       
42                                        if (nextChild)
43                        GetQueue()->push(nextChild);
44                                }
45            }
46        }
[59]47        }
48}
49//-----------------------------------------------------------------------
[2259]50GtpVisibility::HierarchyNode *OctreeHierarchyInterface::GetRandomLeaf(GtpVisibility::HierarchyNode *root)
[2258]51{
[2259]52        if (IsLeaf(root))
53                return root;
54
55        Octree *octree = static_cast<Octree *>(root);
56
57        // random decision
[2278]58        Octree *child = NULL;
59       
[2281]60        std::vector<Octree *> nodes;
[2283]61        nodes.reserve(8);
[2281]62
[2306]63        for (int z = 0; z < 2; ++ z)
64        {       
65                for (int y = 0; y < 2; ++ y)
[2281]66                {
[2306]67                        for (int x = 0; x < 2; ++ x)
68                        {
69                                if ((child = octree->mChildren[x][y][z]) != NULL)
70                                {
71                                        nodes.push_back(child);
72                                }
73                        }
[2281]74                }
75        }
76
77        if (nodes.empty())
78                return NULL;
79
[2283]80        int r = (int)(((float)rand() / RAND_MAX) * ((float)nodes.size() - 0.5f));
[2281]81
82        return GetRandomLeaf(nodes[r]);
[2258]83}
84//-----------------------------------------------------------------------
[74]85bool OctreeHierarchyInterface::IsLeaf(GtpVisibility::HierarchyNode *node) const
[59]86{
[94]87        Octree *octree = static_cast<Octree *>(node);
[944]88
[94]89        // HACK: if there are subtrees, they are empty => we are not interested in them
90        return octree->numNodes() == (int)octree->mNodes.size();
[59]91}
92//-----------------------------------------------------------------------
[74]93bool OctreeHierarchyInterface::HasGeometry(GtpVisibility::HierarchyNode *node) const
[59]94{
[722]95        return !(static_cast<Octree *>(node))->mNodes.empty();
[59]96}
97//-----------------------------------------------------------------------
[87]98float OctreeHierarchyInterface::GetSquaredDistance(GtpVisibility::HierarchyNode *node) const
[59]99{
[726]100        const Vector3 bmin = static_cast<Octree *>(node)->mBox.getMinimum();
101        const Vector3 bmax = static_cast<Octree *>(node)->mBox.getMaximum();
[722]102
[2292]103        const Vector3 pos = (bmax - bmin) * 0.5f + bmin;
[345]104       
[726]105        return (mCameraPosition - pos).squaredLength();
[59]106}
107//-----------------------------------------------------------------------
[74]108void OctreeHierarchyInterface::SetNodeVisible(GtpVisibility::HierarchyNode *node,
[345]109                                                                                          const bool visible) const
[59]110{
111#ifdef GTP_VISIBILITY_MODIFIED_OGRE
112        static_cast<Octree *>(node)->setOctreeVisible(visible);
113#endif
114}
115//-----------------------------------------------------------------------
[74]116void OctreeHierarchyInterface::SetLastVisited(GtpVisibility::HierarchyNode *node,
[345]117                                                                                          const unsigned int frameId) const
[59]118{
119#ifdef GTP_VISIBILITY_MODIFIED_OGRE
120        static_cast<Octree *>(node)->setLastVisited(frameId);
121#endif
122}
123//-----------------------------------------------------------------------
[345]124void OctreeHierarchyInterface::PullUpVisibility(GtpVisibility::HierarchyNode *node) const
[59]125{               
126#ifdef GTP_VISIBILITY_MODIFIED_OGRE
127        Octree *octant = static_cast<Octree *>(node);
128
[155]129        while (octant && !octant->isOctreeVisible())
[59]130        {
131                octant->setOctreeVisible(true);
132                octant = octant->getParent();
133        }
134#endif
135}
136//-----------------------------------------------------------------------
[2306]137void OctreeHierarchyInterface::PullUpLastVisited(GtpVisibility::HierarchyNode *node, const int frameId) const
[2292]138{               
139#ifdef GTP_VISIBILITY_MODIFIED_OGRE
140        Octree *octant = static_cast<Octree *>(node);
141
[2306]142        while (octant && (octant->lastVisited() != frameId))
[2292]143        {
[2306]144                octant->setLastVisited(frameId);
[2292]145                octant = octant->getParent();
146        }
147#endif
[2306]148}
[2292]149//-----------------------------------------------------------------------
[2258]150void OctreeHierarchyInterface::DetermineFullVisibility(GtpVisibility::HierarchyNode *node) const
151{               
152        Octree *octant = static_cast<Octree *>(node);
153
[2306]154        // node not visited in this frame => no change
155        if (octant->lastVisited() != mFrameId)
156                return;
157
[2258]158        // leaf node: terminate recursion
159        if (IsLeaf(node))
160        {
[2292]161                octant->setOctreeFullyVisible(octant->isOctreeVisible());       
[2258]162                return;
163        }
164
[2278]165        octant->setOctreeFullyVisible(true);
[2258]166        Octree *nextChild;
[2283]167       
[2258]168        for (int i = 0; i < 8; ++ i)
169        {
[2278]170                int x = (i & 4) / 4;
171                int y = (i & 2) / 2;
[2258]172                int z = i & 1;
[2306]173
174                nextChild = octant->mChildren[x][y][z];
175
176                if (!nextChild)
177                        continue;
[2283]178               
[2306]179                // recursive traversal
180                DetermineFullVisibility(nextChild);
181               
182                // this leaf is not fully visible
183                if (!nextChild->isOctreeFullyVisible())
[2258]184                {
[2306]185                        octant->setOctreeFullyVisible(false);
[2258]186                }
187        }
188}
189//-----------------------------------------------------------------------
[59]190void OctreeHierarchyInterface::RenderNode(GtpVisibility::HierarchyNode *node)
191{
192#ifdef GTP_VISIBILITY_MODIFIED_OGRE
193        Octree *octant = static_cast<Octree *>(node);
194
195        if (octant->lastRendered() != mFrameId)
196        {
197                octant->setLastRendered(mFrameId);
[726]198                OctreeSceneManager *ocm =
[2066]199                        static_cast<OctreeSceneManager *>(mSceneManager);
[938]200
[2258]201                ocm->_renderOctant(mCamera,
202                                                   octant,
203                                                   mOnlyShadowCasters,
204                                                   mLeavePassesInQueue);
[59]205
[174]206                mVisibleNodes.push_back(node);
[59]207        }
[2258]208#endif 
[59]209}
210//-----------------------------------------------------------------------
[2259]211void OctreeHierarchyInterface::RenderNodeRecursive(GtpVisibility::HierarchyNode *node)
212{
213#ifdef GTP_VISIBILITY_MODIFIED_OGRE
214        Octree *octant = static_cast<Octree *>(node);
215
[2292]216        if (octant->lastRendered() != mFrameId)
[2259]217        {
218                octant->setLastRendered(mFrameId);
[2287]219
[2259]220                OctreeSceneManager *ocm =
221                        static_cast<OctreeSceneManager *>(mSceneManager);
222
223                ocm->_renderOctantRecursive(mCamera,
224                                                                        octant,
225                                                                        mOnlyShadowCasters,
226                                                                        mLeavePassesInQueue);
227
228                mVisibleNodes.push_back(node);
229        }
230#endif 
231}
232//-----------------------------------------------------------------------
[74]233bool OctreeHierarchyInterface::IsNodeVisible(GtpVisibility::HierarchyNode *node) const
[59]234{
235#ifdef GTP_VISIBILITY_MODIFIED_OGRE
236        return static_cast<Octree *>(node)->isOctreeVisible();
237#else
238        return true;
239#endif
240}
241//-----------------------------------------------------------------------
[2259]242bool OctreeHierarchyInterface::IsNodeFullyVisible(GtpVisibility::HierarchyNode *node) const
243{
244        return static_cast<Octree *>(node)->isOctreeFullyVisible();
245}
246//-----------------------------------------------------------------------
[74]247unsigned int OctreeHierarchyInterface::LastVisited(GtpVisibility::HierarchyNode *node) const
[59]248{
249#ifdef GTP_VISIBILITY_MODIFIED_OGRE
250        return static_cast<Octree *>(node)->lastVisited();
251#else
252        return 0;
253#endif
254}
255//-----------------------------------------------------------------------
256AxisAlignedBox *OctreeHierarchyInterface::GetBoundingBox(GtpVisibility::HierarchyNode *node)
257{
[925]258        // reuse box if node is the same
259        // only create renderable bounding box for new node
[2455]260        if (node != mOldNode)
[85]261        {
[2455]262                mOldNode = node;
[880]263            //static_cast<Octree *>(node)->_getCullBounds(&mBox);
[135]264                mBox = static_cast<Octree *>(node)->_getWorldAABB();
[85]265        }
[59]266
267        return &mBox;
268}
[112]269//-----------------------------------------------------------------------
270void OctreeHierarchyInterface::VisualizeCulledNode(GtpVisibility::HierarchyNode *node,
[345]271                                                                                                   GtpVisibility::CullingType type) const
[112]272{
273        WireBoundingBox *box = static_cast<Octree *>(node)->getWireBoundingBox();
[59]274
[112]275        if (type == GtpVisibility::FRUSTUM_CULLED)
276        {
277                box->setMaterial("FrustumCulledNodesMaterial");
278        }
279        else // type == GtpVisibility::QUERY_CULLED
280        {
281                box->setMaterial("QueryCulledNodesMaterial");
282        }
[113]283
[2066]284        static_cast<OctreeSceneManager *>(mSceneManager)->getBoxes()->push_back(box);
[112]285}
[130]286//-----------------------------------------------------------------------
[726]287void OctreeHierarchyInterface::GetNodeGeometryList(GtpVisibility::HierarchyNode *node,
[2280]288                                                                                                   GeometryVector *geometryList,
[726]289                                                                                                   bool includeChildren)
[130]290{
291        NodeList::const_iterator nodeIt, nodeIt_end;
292        nodeIt_end = static_cast<Octree *>(node)->mNodes.end();
293
294        for (nodeIt = static_cast<Octree *>(node)->mNodes.begin(); nodeIt != nodeIt_end; ++nodeIt)
295        {
[155]296                SceneNodeHierarchyInterface::GetNodeGeometryList(*nodeIt, geometryList, includeChildren);
[130]297        }
298}
[2292]299//-----------------------------------------------------------------------
300void OctreeHierarchyInterface::CollectLeaves(GtpVisibility::HierarchyNode *root,
301                                                                                         GtpVisibility::HierarchyNodeContainer &nodes)
302{
303        std::stack<GtpVisibility::HierarchyNode *> tStack;
304        tStack.push(root);
[174]305
[2292]306        Octree *child;
[2258]307
[2292]308        while (!tStack.empty())
309        {
310                GtpVisibility::HierarchyNode *node = tStack.top();
311                tStack.pop();
312
313                if (IsLeaf(node))
314                {
315                        nodes.push_back(node);
316                }
317                else
318                {
319                        Octree *octree = static_cast<Octree *>(node);
320                       
[2306]321                        for (int z = 0; z < 2; ++ z)
322                                for (int y = 0; y < 2; ++ y)
323                                        for (int x = 0; x < 2; ++ x)
324                                                if ((child = octree->mChildren[x][y][z]) != NULL)
325                                                        tStack.push(child);
[2292]326                }
327        }
328}
329
[2332]330//-----------------------------------------------------------------------
331GtpVisibility::HierarchyNode *OctreeHierarchyInterface::GetParent(GtpVisibility::HierarchyNode *node)
332{
333        Octree *octree = static_cast<Octree *>(node);
334        return octree->getParent();
335}
[2455]336//-----------------------------------------------------------------------
337int OctreeHierarchyInterface::GetNodeAssumedVisible(GtpVisibility::HierarchyNode *node)
338{
339        Octree *octree = static_cast<Octree *>(node);
340        return octree->getAssumedVisible();
341}
342//-----------------------------------------------------------------------
343void OctreeHierarchyInterface::SetNodeAssumedVisible(GtpVisibility::HierarchyNode *node, int assumedVisible)
344{
345        Octree *octree = static_cast<Octree *>(node);
346        octree->setAssumedVisible(assumedVisible);
347}
348//-----------------------------------------------------------------------
349void OctreeHierarchyInterface::DecNodeAssumedVisible(GtpVisibility::HierarchyNode *node)
350{
351        Octree *octree = static_cast<Octree *>(node);
352        octree->decAssumedVisible();
353}
354//-----------------------------------------------------------------------
355void OctreeHierarchyInterface::RenderGeometryBounds(GtpVisibility::HierarchyNode *node)
356{
357        Octree *octree = static_cast<Octree *>(node);
[2332]358
[2455]359        NodeList::iterator it, it_end = octree->mNodes.end();
360
361    for (it = octree->mNodes.begin(); it != it_end; ++ it)
362    {
363                RenderBoundingBox(&(*it)->_getWorldAABB());
364    }   
365}
366
367
[59]368} // namespace Ogre
Note: See TracBrowser for help on using the repository browser.