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

Revision 2292, 10.1 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
6
7namespace Ogre {
8
9//-----------------------------------------------------------------------
10OctreeHierarchyInterface::OctreeHierarchyInterface(OctreeSceneManager *sm,
11                                                                                                   RenderSystem *rsys):
12SceneNodeHierarchyInterface(sm, rsys)
13{}
14//-----------------------------------------------------------------------
15void OctreeHierarchyInterface::TraverseNode(GtpVisibility::HierarchyNode *node)
16{
17        ++ mNumTraversedNodes;
18
19        Octree *octree = static_cast<Octree *>(node);
20
21        // if we come across some renderable geometry => render it
22        if (!octree->mNodes.empty())
23        {
24                RenderNode(node);
25        }
26       
27       
28        // if not all subtrees are empty
29        if (!IsLeaf(node))
30        {
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);
49        }
50}
51//-----------------------------------------------------------------------
52GtpVisibility::HierarchyNode *OctreeHierarchyInterface::GetRandomLeaf(GtpVisibility::HierarchyNode *root)
53{
54        if (IsLeaf(root))
55                return root;
56
57        Octree *octree = static_cast<Octree *>(root);
58
59        // random decision
60        Octree *child = NULL;
61       
62        std::vector<Octree *> nodes;
63        nodes.reserve(8);
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
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//-----------------------------------------------------------------------
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//-----------------------------------------------------------------------
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        {
172                octant->setOctreeFullyVisible(octant->isOctreeVisible());       
173                return;
174        }
175
176        octant->setOctreeFullyVisible(true);
177       
178        Octree *nextChild;
179       
180        for (int i = 0; i < 8; ++ i)
181        {
182                int x = (i & 4) / 4;
183                int y = (i & 2) / 2;
184                int z = i & 1;
185               
186                if ((nextChild = octant->mChildren[x][y][z]) != NULL)
187                {
188                        DetermineFullVisibility(nextChild);
189                        // this leaf is not fully visible => break
190                        if (!nextChild->isOctreeFullyVisible())
191                                octant->setOctreeFullyVisible(false);
192                }
193        }
194}
195//-----------------------------------------------------------------------
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);
204                OctreeSceneManager *ocm =
205                        static_cast<OctreeSceneManager *>(mSceneManager);
206
207                ocm->_renderOctant(mCamera,
208                                                   octant,
209                                                   mOnlyShadowCasters,
210                                                   mLeavePassesInQueue);
211
212                mVisibleNodes.push_back(node);
213        }
214#endif 
215}
216//-----------------------------------------------------------------------
217void OctreeHierarchyInterface::RenderNodeRecursive(GtpVisibility::HierarchyNode *node)
218{
219#ifdef GTP_VISIBILITY_MODIFIED_OGRE
220        Octree *octant = static_cast<Octree *>(node);
221
222        if (octant->lastRendered() != mFrameId)
223        {
224                octant->setLastRendered(mFrameId);
225
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//-----------------------------------------------------------------------
239bool OctreeHierarchyInterface::IsNodeVisible(GtpVisibility::HierarchyNode *node) const
240{
241#ifdef GTP_VISIBILITY_MODIFIED_OGRE
242        return static_cast<Octree *>(node)->isOctreeVisible();
243#else
244        return true;
245#endif
246}
247//-----------------------------------------------------------------------
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//-----------------------------------------------------------------------
257unsigned int OctreeHierarchyInterface::LastVisited(GtpVisibility::HierarchyNode *node) const
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{
268        // reuse box if node is the same
269        // only create renderable bounding box for new node
270        if (node != mSavedNode)
271        {
272                mSavedNode = node;
273            //static_cast<Octree *>(node)->_getCullBounds(&mBox);
274                mBox = static_cast<Octree *>(node)->_getWorldAABB();
275        }
276
277        return &mBox;
278}
279//-----------------------------------------------------------------------
280void OctreeHierarchyInterface::VisualizeCulledNode(GtpVisibility::HierarchyNode *node,
281                                                                                                   GtpVisibility::CullingType type) const
282{
283        WireBoundingBox *box = static_cast<Octree *>(node)->getWireBoundingBox();
284
285        if (type == GtpVisibility::FRUSTUM_CULLED)
286        {
287                box->setMaterial("FrustumCulledNodesMaterial");
288        }
289        else // type == GtpVisibility::QUERY_CULLED
290        {
291                box->setMaterial("QueryCulledNodesMaterial");
292        }
293
294        static_cast<OctreeSceneManager *>(mSceneManager)->getBoxes()->push_back(box);
295}
296//-----------------------------------------------------------------------
297void OctreeHierarchyInterface::GetNodeGeometryList(GtpVisibility::HierarchyNode *node,
298                                                                                                   GeometryVector *geometryList,
299                                                                                                   bool includeChildren)
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        {
306                SceneNodeHierarchyInterface::GetNodeGeometryList(*nodeIt, geometryList, includeChildren);
307        }
308}
309//-----------------------------------------------------------------------
310void OctreeHierarchyInterface::CollectLeaves(GtpVisibility::HierarchyNode *root,
311                                                                                         GtpVisibility::HierarchyNodeContainer &nodes)
312{
313        std::stack<GtpVisibility::HierarchyNode *> tStack;
314        tStack.push(root);
315
316        Octree *child;
317
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
347} // namespace Ogre
Note: See TracBrowser for help on using the repository browser.