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

Revision 2455, 10.8 KB checked in by mattausch, 17 years ago (diff)
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                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        }
47        }
48}
49//-----------------------------------------------------------------------
50GtpVisibility::HierarchyNode *OctreeHierarchyInterface::GetRandomLeaf(GtpVisibility::HierarchyNode *root)
51{
52        if (IsLeaf(root))
53                return root;
54
55        Octree *octree = static_cast<Octree *>(root);
56
57        // random decision
58        Octree *child = NULL;
59       
60        std::vector<Octree *> nodes;
61        nodes.reserve(8);
62
63        for (int z = 0; z < 2; ++ z)
64        {       
65                for (int y = 0; y < 2; ++ y)
66                {
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                        }
74                }
75        }
76
77        if (nodes.empty())
78                return NULL;
79
80        int r = (int)(((float)rand() / RAND_MAX) * ((float)nodes.size() - 0.5f));
81
82        return GetRandomLeaf(nodes[r]);
83}
84//-----------------------------------------------------------------------
85bool OctreeHierarchyInterface::IsLeaf(GtpVisibility::HierarchyNode *node) const
86{
87        Octree *octree = static_cast<Octree *>(node);
88
89        // HACK: if there are subtrees, they are empty => we are not interested in them
90        return octree->numNodes() == (int)octree->mNodes.size();
91}
92//-----------------------------------------------------------------------
93bool OctreeHierarchyInterface::HasGeometry(GtpVisibility::HierarchyNode *node) const
94{
95        return !(static_cast<Octree *>(node))->mNodes.empty();
96}
97//-----------------------------------------------------------------------
98float OctreeHierarchyInterface::GetSquaredDistance(GtpVisibility::HierarchyNode *node) const
99{
100        const Vector3 bmin = static_cast<Octree *>(node)->mBox.getMinimum();
101        const Vector3 bmax = static_cast<Octree *>(node)->mBox.getMaximum();
102
103        const Vector3 pos = (bmax - bmin) * 0.5f + bmin;
104       
105        return (mCameraPosition - pos).squaredLength();
106}
107//-----------------------------------------------------------------------
108void OctreeHierarchyInterface::SetNodeVisible(GtpVisibility::HierarchyNode *node,
109                                                                                          const bool visible) const
110{
111#ifdef GTP_VISIBILITY_MODIFIED_OGRE
112        static_cast<Octree *>(node)->setOctreeVisible(visible);
113#endif
114}
115//-----------------------------------------------------------------------
116void OctreeHierarchyInterface::SetLastVisited(GtpVisibility::HierarchyNode *node,
117                                                                                          const unsigned int frameId) const
118{
119#ifdef GTP_VISIBILITY_MODIFIED_OGRE
120        static_cast<Octree *>(node)->setLastVisited(frameId);
121#endif
122}
123//-----------------------------------------------------------------------
124void OctreeHierarchyInterface::PullUpVisibility(GtpVisibility::HierarchyNode *node) const
125{               
126#ifdef GTP_VISIBILITY_MODIFIED_OGRE
127        Octree *octant = static_cast<Octree *>(node);
128
129        while (octant && !octant->isOctreeVisible())
130        {
131                octant->setOctreeVisible(true);
132                octant = octant->getParent();
133        }
134#endif
135}
136//-----------------------------------------------------------------------
137void OctreeHierarchyInterface::PullUpLastVisited(GtpVisibility::HierarchyNode *node, const int frameId) const
138{               
139#ifdef GTP_VISIBILITY_MODIFIED_OGRE
140        Octree *octant = static_cast<Octree *>(node);
141
142        while (octant && (octant->lastVisited() != frameId))
143        {
144                octant->setLastVisited(frameId);
145                octant = octant->getParent();
146        }
147#endif
148}
149//-----------------------------------------------------------------------
150void OctreeHierarchyInterface::DetermineFullVisibility(GtpVisibility::HierarchyNode *node) const
151{               
152        Octree *octant = static_cast<Octree *>(node);
153
154        // node not visited in this frame => no change
155        if (octant->lastVisited() != mFrameId)
156                return;
157
158        // leaf node: terminate recursion
159        if (IsLeaf(node))
160        {
161                octant->setOctreeFullyVisible(octant->isOctreeVisible());       
162                return;
163        }
164
165        octant->setOctreeFullyVisible(true);
166        Octree *nextChild;
167       
168        for (int i = 0; i < 8; ++ i)
169        {
170                int x = (i & 4) / 4;
171                int y = (i & 2) / 2;
172                int z = i & 1;
173
174                nextChild = octant->mChildren[x][y][z];
175
176                if (!nextChild)
177                        continue;
178               
179                // recursive traversal
180                DetermineFullVisibility(nextChild);
181               
182                // this leaf is not fully visible
183                if (!nextChild->isOctreeFullyVisible())
184                {
185                        octant->setOctreeFullyVisible(false);
186                }
187        }
188}
189//-----------------------------------------------------------------------
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);
198                OctreeSceneManager *ocm =
199                        static_cast<OctreeSceneManager *>(mSceneManager);
200
201                ocm->_renderOctant(mCamera,
202                                                   octant,
203                                                   mOnlyShadowCasters,
204                                                   mLeavePassesInQueue);
205
206                mVisibleNodes.push_back(node);
207        }
208#endif 
209}
210//-----------------------------------------------------------------------
211void OctreeHierarchyInterface::RenderNodeRecursive(GtpVisibility::HierarchyNode *node)
212{
213#ifdef GTP_VISIBILITY_MODIFIED_OGRE
214        Octree *octant = static_cast<Octree *>(node);
215
216        if (octant->lastRendered() != mFrameId)
217        {
218                octant->setLastRendered(mFrameId);
219
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//-----------------------------------------------------------------------
233bool OctreeHierarchyInterface::IsNodeVisible(GtpVisibility::HierarchyNode *node) const
234{
235#ifdef GTP_VISIBILITY_MODIFIED_OGRE
236        return static_cast<Octree *>(node)->isOctreeVisible();
237#else
238        return true;
239#endif
240}
241//-----------------------------------------------------------------------
242bool OctreeHierarchyInterface::IsNodeFullyVisible(GtpVisibility::HierarchyNode *node) const
243{
244        return static_cast<Octree *>(node)->isOctreeFullyVisible();
245}
246//-----------------------------------------------------------------------
247unsigned int OctreeHierarchyInterface::LastVisited(GtpVisibility::HierarchyNode *node) const
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{
258        // reuse box if node is the same
259        // only create renderable bounding box for new node
260        if (node != mOldNode)
261        {
262                mOldNode = node;
263            //static_cast<Octree *>(node)->_getCullBounds(&mBox);
264                mBox = static_cast<Octree *>(node)->_getWorldAABB();
265        }
266
267        return &mBox;
268}
269//-----------------------------------------------------------------------
270void OctreeHierarchyInterface::VisualizeCulledNode(GtpVisibility::HierarchyNode *node,
271                                                                                                   GtpVisibility::CullingType type) const
272{
273        WireBoundingBox *box = static_cast<Octree *>(node)->getWireBoundingBox();
274
275        if (type == GtpVisibility::FRUSTUM_CULLED)
276        {
277                box->setMaterial("FrustumCulledNodesMaterial");
278        }
279        else // type == GtpVisibility::QUERY_CULLED
280        {
281                box->setMaterial("QueryCulledNodesMaterial");
282        }
283
284        static_cast<OctreeSceneManager *>(mSceneManager)->getBoxes()->push_back(box);
285}
286//-----------------------------------------------------------------------
287void OctreeHierarchyInterface::GetNodeGeometryList(GtpVisibility::HierarchyNode *node,
288                                                                                                   GeometryVector *geometryList,
289                                                                                                   bool includeChildren)
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        {
296                SceneNodeHierarchyInterface::GetNodeGeometryList(*nodeIt, geometryList, includeChildren);
297        }
298}
299//-----------------------------------------------------------------------
300void OctreeHierarchyInterface::CollectLeaves(GtpVisibility::HierarchyNode *root,
301                                                                                         GtpVisibility::HierarchyNodeContainer &nodes)
302{
303        std::stack<GtpVisibility::HierarchyNode *> tStack;
304        tStack.push(root);
305
306        Octree *child;
307
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                       
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);
326                }
327        }
328}
329
330//-----------------------------------------------------------------------
331GtpVisibility::HierarchyNode *OctreeHierarchyInterface::GetParent(GtpVisibility::HierarchyNode *node)
332{
333        Octree *octree = static_cast<Octree *>(node);
334        return octree->getParent();
335}
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);
358
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
368} // namespace Ogre
Note: See TracBrowser for help on using the repository browser.