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

Revision 2292, 10.1 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>
[59]5
[115]6
[59]7namespace Ogre {
[94]8
[59]9//-----------------------------------------------------------------------
[2258]10OctreeHierarchyInterface::OctreeHierarchyInterface(OctreeSceneManager *sm,
11                                                                                                   RenderSystem *rsys):
[158]12SceneNodeHierarchyInterface(sm, rsys)
[2258]13{}
[59]14//-----------------------------------------------------------------------
[158]15void OctreeHierarchyInterface::TraverseNode(GtpVisibility::HierarchyNode *node)
[59]16{
[139]17        ++ mNumTraversedNodes;
[59]18
[87]19        Octree *octree = static_cast<Octree *>(node);
20
[59]21        // if we come across some renderable geometry => render it
[726]22        if (!octree->mNodes.empty())
[87]23        {
24                RenderNode(node);
25        }
[59]26       
[925]27       
[726]28        // if not all subtrees are empty
[94]29        if (!IsLeaf(node))
[59]30        {
[726]31                Octree *nextChild;
32
33                if ((nextChild = octree->mChildren[0][0][0]) != NULL)
34                        mDistanceQueue->push(nextChild);
35                if ((nextChild = octree->mChildren[0][0][1]) != NULL)
36                        mDistanceQueue->push(nextChild);
37                if ((nextChild = octree->mChildren[0][1][0]) != NULL)
38                        mDistanceQueue->push(nextChild);
39                if ((nextChild = octree->mChildren[0][1][1]) != NULL)
40                mDistanceQueue->push(nextChild);
41                if ((nextChild = octree->mChildren[1][0][0]) != NULL)
42                        mDistanceQueue->push(nextChild);
43                if ((nextChild = octree->mChildren[1][0][1]) != NULL)
44                        mDistanceQueue->push(nextChild);
45                if ((nextChild = octree->mChildren[1][1][0]) != NULL)
46                        mDistanceQueue->push(nextChild);
47                if ((nextChild = octree->mChildren[1][1][1]) != NULL)
48                        mDistanceQueue->push(nextChild);
[59]49        }
50}
51//-----------------------------------------------------------------------
[2259]52GtpVisibility::HierarchyNode *OctreeHierarchyInterface::GetRandomLeaf(GtpVisibility::HierarchyNode *root)
[2258]53{
[2259]54        if (IsLeaf(root))
55                return root;
56
57        Octree *octree = static_cast<Octree *>(root);
58
59        // random decision
[2278]60        Octree *child = NULL;
61       
[2281]62        std::vector<Octree *> nodes;
[2283]63        nodes.reserve(8);
[2281]64
65        for (int i = 0; i < 8; ++ i)
66        {
67                int x = (i & 4) / 4;
68                int y = (i & 2) / 2;
69                int z = i & 1;
70       
71                if ((child = octree->mChildren[x][y][z]) != NULL)
72                {
73                        nodes.push_back(child);
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//-----------------------------------------------------------------------
[2292]137/*void OctreeHierarchyInterface::PullUpFullVisibility(GtpVisibility::HierarchyNode *node) const
138{               
139#ifdef GTP_VISIBILITY_MODIFIED_OGRE
140        Octree *octant = static_cast<Octree *>(node);
141
142        for (int i = 0; i < 8; ++ i)
143        {
144                int x = (i & 4) / 4;
145                int y = (i & 2) / 2;
146                int z = i & 1;
147               
148                if ((nextChild = octant->mChildren[x][y][z]) != NULL)
149                {
150                        DetermineFullVisibility(nextChild);
151                        // this leaf is not fully visible => break
152                        if (!nextChild->isOctreeFullyVisible())
153                                octant->setOctreeFullyVisible(false);
154                }
155        }
156
157        while (octant && !octant->isOctreeVisible())
158        {
159                octant->setOctreeVisible(true);
160                octant = octant->getParent();
161        }
162#endif
163}*/
164//-----------------------------------------------------------------------
[2258]165void OctreeHierarchyInterface::DetermineFullVisibility(GtpVisibility::HierarchyNode *node) const
166{               
167        Octree *octant = static_cast<Octree *>(node);
168
169        // leaf node: terminate recursion
170        if (IsLeaf(node))
171        {
[2292]172                octant->setOctreeFullyVisible(octant->isOctreeVisible());       
[2258]173                return;
174        }
175
[2278]176        octant->setOctreeFullyVisible(true);
177       
[2258]178        Octree *nextChild;
[2283]179       
[2258]180        for (int i = 0; i < 8; ++ i)
181        {
[2278]182                int x = (i & 4) / 4;
183                int y = (i & 2) / 2;
[2258]184                int z = i & 1;
[2283]185               
[2292]186                if ((nextChild = octant->mChildren[x][y][z]) != NULL)
[2258]187                {
188                        DetermineFullVisibility(nextChild);
[2278]189                        // this leaf is not fully visible => break
[2258]190                        if (!nextChild->isOctreeFullyVisible())
[2278]191                                octant->setOctreeFullyVisible(false);
[2258]192                }
193        }
194}
195//-----------------------------------------------------------------------
[59]196void OctreeHierarchyInterface::RenderNode(GtpVisibility::HierarchyNode *node)
197{
198#ifdef GTP_VISIBILITY_MODIFIED_OGRE
199        Octree *octant = static_cast<Octree *>(node);
200
201        if (octant->lastRendered() != mFrameId)
202        {
203                octant->setLastRendered(mFrameId);
[726]204                OctreeSceneManager *ocm =
[2066]205                        static_cast<OctreeSceneManager *>(mSceneManager);
[938]206
[2258]207                ocm->_renderOctant(mCamera,
208                                                   octant,
209                                                   mOnlyShadowCasters,
210                                                   mLeavePassesInQueue);
[59]211
[174]212                mVisibleNodes.push_back(node);
[59]213        }
[2258]214#endif 
[59]215}
216//-----------------------------------------------------------------------
[2259]217void OctreeHierarchyInterface::RenderNodeRecursive(GtpVisibility::HierarchyNode *node)
218{
219#ifdef GTP_VISIBILITY_MODIFIED_OGRE
220        Octree *octant = static_cast<Octree *>(node);
221
[2292]222        if (octant->lastRendered() != mFrameId)
[2259]223        {
224                octant->setLastRendered(mFrameId);
[2287]225
[2259]226                OctreeSceneManager *ocm =
227                        static_cast<OctreeSceneManager *>(mSceneManager);
228
229                ocm->_renderOctantRecursive(mCamera,
230                                                                        octant,
231                                                                        mOnlyShadowCasters,
232                                                                        mLeavePassesInQueue);
233
234                mVisibleNodes.push_back(node);
235        }
236#endif 
237}
238//-----------------------------------------------------------------------
[74]239bool OctreeHierarchyInterface::IsNodeVisible(GtpVisibility::HierarchyNode *node) const
[59]240{
241#ifdef GTP_VISIBILITY_MODIFIED_OGRE
242        return static_cast<Octree *>(node)->isOctreeVisible();
243#else
244        return true;
245#endif
246}
247//-----------------------------------------------------------------------
[2259]248bool OctreeHierarchyInterface::IsNodeFullyVisible(GtpVisibility::HierarchyNode *node) const
249{
250#ifdef GTP_VISIBILITY_MODIFIED_OGRE
251        return static_cast<Octree *>(node)->isOctreeFullyVisible();
252#else
253        return true;
254#endif
255}
256//-----------------------------------------------------------------------
[74]257unsigned int OctreeHierarchyInterface::LastVisited(GtpVisibility::HierarchyNode *node) const
[59]258{
259#ifdef GTP_VISIBILITY_MODIFIED_OGRE
260        return static_cast<Octree *>(node)->lastVisited();
261#else
262        return 0;
263#endif
264}
265//-----------------------------------------------------------------------
266AxisAlignedBox *OctreeHierarchyInterface::GetBoundingBox(GtpVisibility::HierarchyNode *node)
267{
[925]268        // reuse box if node is the same
269        // only create renderable bounding box for new node
[938]270        if (node != mSavedNode)
[85]271        {
[155]272                mSavedNode = node;
[880]273            //static_cast<Octree *>(node)->_getCullBounds(&mBox);
[135]274                mBox = static_cast<Octree *>(node)->_getWorldAABB();
[85]275        }
[59]276
277        return &mBox;
278}
[112]279//-----------------------------------------------------------------------
280void OctreeHierarchyInterface::VisualizeCulledNode(GtpVisibility::HierarchyNode *node,
[345]281                                                                                                   GtpVisibility::CullingType type) const
[112]282{
283        WireBoundingBox *box = static_cast<Octree *>(node)->getWireBoundingBox();
[59]284
[112]285        if (type == GtpVisibility::FRUSTUM_CULLED)
286        {
287                box->setMaterial("FrustumCulledNodesMaterial");
288        }
289        else // type == GtpVisibility::QUERY_CULLED
290        {
291                box->setMaterial("QueryCulledNodesMaterial");
292        }
[113]293
[2066]294        static_cast<OctreeSceneManager *>(mSceneManager)->getBoxes()->push_back(box);
[112]295}
[130]296//-----------------------------------------------------------------------
[726]297void OctreeHierarchyInterface::GetNodeGeometryList(GtpVisibility::HierarchyNode *node,
[2280]298                                                                                                   GeometryVector *geometryList,
[726]299                                                                                                   bool includeChildren)
[130]300{
301        NodeList::const_iterator nodeIt, nodeIt_end;
302        nodeIt_end = static_cast<Octree *>(node)->mNodes.end();
303
304        for (nodeIt = static_cast<Octree *>(node)->mNodes.begin(); nodeIt != nodeIt_end; ++nodeIt)
305        {
[155]306                SceneNodeHierarchyInterface::GetNodeGeometryList(*nodeIt, geometryList, includeChildren);
[130]307        }
308}
[2292]309//-----------------------------------------------------------------------
310void OctreeHierarchyInterface::CollectLeaves(GtpVisibility::HierarchyNode *root,
311                                                                                         GtpVisibility::HierarchyNodeContainer &nodes)
312{
313        std::stack<GtpVisibility::HierarchyNode *> tStack;
314        tStack.push(root);
[174]315
[2292]316        Octree *child;
[2258]317
[2292]318        while (!tStack.empty())
319        {
320                GtpVisibility::HierarchyNode *node = tStack.top();
321                tStack.pop();
322
323                if (IsLeaf(node))
324                {
325                        nodes.push_back(node);
326                }
327                else
328                {
329                        Octree *octree = static_cast<Octree *>(node);
330                       
331                        for (int i = 0; i < 8; ++ i)
332                        {
333                                int x = (i & 4) / 4;
334                                int y = (i & 2) / 2;
335                                int z = i & 1;
336       
337                                if ((child = octree->mChildren[x][y][z]) != NULL)
338                                {
339                                        tStack.push(child);
340                                }
341                        }
342                }
343        }
344}
345
346
[59]347} // namespace Ogre
Note: See TracBrowser for help on using the repository browser.