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

Revision 2278, 10.1 KB checked in by mattausch, 18 years ago (diff)

worked on randomupdatemanager

Line 
1#include "OgreOctreeHierarchyInterface.h"
2//#include "OgreVisibilityOctreeSceneManager.h"
3#include <OgreOctree.h>
4#include <OgreLogManager.h>
5#include <OgreStringConverter.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                if ((nextChild = octree->mChildren[0][0][0]) != NULL)
35                        mDistanceQueue->push(nextChild);
36                if ((nextChild = octree->mChildren[0][0][1]) != NULL)
37                        mDistanceQueue->push(nextChild);
38                if ((nextChild = octree->mChildren[0][1][0]) != NULL)
39                        mDistanceQueue->push(nextChild);
40                if ((nextChild = octree->mChildren[0][1][1]) != NULL)
41                mDistanceQueue->push(nextChild);
42                if ((nextChild = octree->mChildren[1][0][0]) != NULL)
43                        mDistanceQueue->push(nextChild);
44                if ((nextChild = octree->mChildren[1][0][1]) != NULL)
45                        mDistanceQueue->push(nextChild);
46                if ((nextChild = octree->mChildren[1][1][0]) != NULL)
47                        mDistanceQueue->push(nextChild);
48                if ((nextChild = octree->mChildren[1][1][1]) != NULL)
49                        mDistanceQueue->push(nextChild);
50        }
51}
52//-----------------------------------------------------------------------
53GtpVisibility::HierarchyNode *OctreeHierarchyInterface::GetRandomLeaf(GtpVisibility::HierarchyNode *root)
54{
55        if (IsLeaf(root))
56                return root;
57
58        Octree *octree = static_cast<Octree *>(root);
59
60        int mask = (int) (rand() * 8.0f);
61       
62        // random decision
63        Octree *child = NULL;
64       
65        while (!child)
66                child = octree->mChildren[(mask & 4) / 4][(mask & 2) / 2][mask & 1];
67
68        return GetRandomLeaf(child);
69}
70//-----------------------------------------------------------------------
71void OctreeHierarchyInterface::TraverseNode2(GtpVisibility::HierarchyNode *node)
72{
73        ++ mNumTraversedNodes;
74
75        Octree *octree = static_cast<Octree *>(node);
76
77        // if we come across some renderable geometry => render it
78        if (!octree->mNodes.empty())
79        {
80                // render everything from here
81                if (octree->isOctreeFullyVisible())
82                {               
83                        RenderNodeRecursive(node);
84                        return;
85                }
86
87                RenderNode(node);
88        }
89               
90        // if not all subtrees are empty
91        if (!IsLeaf(node))
92        {
93                Octree *nextChild;
94
95                if ((nextChild = octree->mChildren[0][0][0]) != NULL)
96                        mDistanceQueue->push(nextChild);
97                if ((nextChild = octree->mChildren[0][0][1]) != NULL)
98                        mDistanceQueue->push(nextChild);
99                if ((nextChild = octree->mChildren[0][1][0]) != NULL)
100                        mDistanceQueue->push(nextChild);
101                if ((nextChild = octree->mChildren[0][1][1]) != NULL)
102                mDistanceQueue->push(nextChild);
103                if ((nextChild = octree->mChildren[1][0][0]) != NULL)
104                        mDistanceQueue->push(nextChild);
105                if ((nextChild = octree->mChildren[1][0][1]) != NULL)
106                        mDistanceQueue->push(nextChild);
107                if ((nextChild = octree->mChildren[1][1][0]) != NULL)
108                        mDistanceQueue->push(nextChild);
109                if ((nextChild = octree->mChildren[1][1][1]) != NULL)
110                        mDistanceQueue->push(nextChild);
111        }
112}
113//-----------------------------------------------------------------------
114bool OctreeHierarchyInterface::IsLeaf(GtpVisibility::HierarchyNode *node) const
115{
116        Octree *octree = static_cast<Octree *>(node);
117
118        // HACK: if there are subtrees, they are empty => we are not interested in them
119        return octree->numNodes() == (int)octree->mNodes.size();
120}
121//-----------------------------------------------------------------------
122bool OctreeHierarchyInterface::HasGeometry(GtpVisibility::HierarchyNode *node) const
123{
124        return !(static_cast<Octree *>(node))->mNodes.empty();
125}
126//-----------------------------------------------------------------------
127float OctreeHierarchyInterface::GetSquaredDistance(GtpVisibility::HierarchyNode *node) const
128{
129        const Vector3 bmin = static_cast<Octree *>(node)->mBox.getMinimum();
130        const Vector3 bmax = static_cast<Octree *>(node)->mBox.getMaximum();
131
132        const Vector3 pos = (bmax - bmin) * 0.5 + bmin;
133       
134/*      std::stringstream d;
135        d << "a: " << (mCameraPosition - pos).squaredLength()
136          << " b: " << (mCullCamera->getDerivedPosition() - pos).squaredLength();
137        LogManager::getSingleton().logMessage(d.str());*/
138        return (mCameraPosition - pos).squaredLength();
139}
140//-----------------------------------------------------------------------
141void OctreeHierarchyInterface::SetNodeVisible(GtpVisibility::HierarchyNode *node,
142                                                                                          const bool visible) const
143{
144#ifdef GTP_VISIBILITY_MODIFIED_OGRE
145        static_cast<Octree *>(node)->setOctreeVisible(visible);
146#endif
147}
148//-----------------------------------------------------------------------
149void OctreeHierarchyInterface::SetLastVisited(GtpVisibility::HierarchyNode *node,
150                                                                                          const unsigned int frameId) const
151{
152#ifdef GTP_VISIBILITY_MODIFIED_OGRE
153        static_cast<Octree *>(node)->setLastVisited(frameId);
154#endif
155}
156//-----------------------------------------------------------------------
157void OctreeHierarchyInterface::PullUpVisibility(GtpVisibility::HierarchyNode *node) const
158{               
159#ifdef GTP_VISIBILITY_MODIFIED_OGRE
160        Octree *octant = static_cast<Octree *>(node);
161
162        while (octant && !octant->isOctreeVisible())
163        {
164                octant->setOctreeVisible(true);
165                octant = octant->getParent();
166        }
167#endif
168}
169//-----------------------------------------------------------------------
170void OctreeHierarchyInterface::DetermineFullVisibility(GtpVisibility::HierarchyNode *node) const
171{               
172        Octree *octant = static_cast<Octree *>(node);
173
174        // leaf node: terminate recursion
175        if (IsLeaf(node))
176        {
177                octant->setOctreeFullyVisible(octant->isOctreeVisible());
178                       
179                return;
180        }
181
182        octant->setOctreeFullyVisible(true);
183       
184        Octree *nextChild;
185        //LogManager::getSingleton().logMessage("***");
186        for (int i = 0; i < 8; ++ i)
187        {
188                int x = (i & 4) / 4;
189                int y = (i & 2) / 2;
190                int z = i & 1;
191
192                //std::stringstream d; d << "x " << x << " y " << y << " z " << z;
193                //LogManager::getSingleton().logMessage(d.str());
194
195                if ((nextChild = octant->mChildren[x][y][z]) != NULL)
196                {
197                        DetermineFullVisibility(nextChild);
198                        // this leaf is not fully visible => break
199                        if (!nextChild->isOctreeFullyVisible())
200                                octant->setOctreeFullyVisible(false);
201                }
202        }
203}
204//-----------------------------------------------------------------------
205void OctreeHierarchyInterface::RenderNode(GtpVisibility::HierarchyNode *node)
206{
207#ifdef GTP_VISIBILITY_MODIFIED_OGRE
208        Octree *octant = static_cast<Octree *>(node);
209
210        if (octant->lastRendered() != mFrameId)
211        {
212                octant->setLastRendered(mFrameId);
213                OctreeSceneManager *ocm =
214                        static_cast<OctreeSceneManager *>(mSceneManager);
215
216                ocm->_renderOctant(mCamera,
217                                                   octant,
218                                                   mOnlyShadowCasters,
219                                                   mLeavePassesInQueue);
220
221                mVisibleNodes.push_back(node);
222        }
223#endif 
224}
225//-----------------------------------------------------------------------
226void OctreeHierarchyInterface::RenderNodeRecursive(GtpVisibility::HierarchyNode *node)
227{
228#ifdef GTP_VISIBILITY_MODIFIED_OGRE
229        Octree *octant = static_cast<Octree *>(node);
230
231        if (octant->lastRendered() != mFrameId)
232        {
233                octant->setLastRendered(mFrameId);
234                OctreeSceneManager *ocm =
235                        static_cast<OctreeSceneManager *>(mSceneManager);
236
237                ocm->_renderOctantRecursive(mCamera,
238                                                                        octant,
239                                                                        mOnlyShadowCasters,
240                                                                        mLeavePassesInQueue);
241
242                mVisibleNodes.push_back(node);
243        }
244#endif 
245}
246//-----------------------------------------------------------------------
247bool OctreeHierarchyInterface::IsNodeVisible(GtpVisibility::HierarchyNode *node) const
248{
249#ifdef GTP_VISIBILITY_MODIFIED_OGRE
250        return static_cast<Octree *>(node)->isOctreeVisible();
251#else
252        return true;
253#endif
254}
255//-----------------------------------------------------------------------
256bool OctreeHierarchyInterface::IsNodeFullyVisible(GtpVisibility::HierarchyNode *node) const
257{
258#ifdef GTP_VISIBILITY_MODIFIED_OGRE
259        return static_cast<Octree *>(node)->isOctreeFullyVisible();
260#else
261        return true;
262#endif
263}
264//-----------------------------------------------------------------------
265unsigned int OctreeHierarchyInterface::LastVisited(GtpVisibility::HierarchyNode *node) const
266{
267#ifdef GTP_VISIBILITY_MODIFIED_OGRE
268        return static_cast<Octree *>(node)->lastVisited();
269#else
270        return 0;
271#endif
272}
273//-----------------------------------------------------------------------
274AxisAlignedBox *OctreeHierarchyInterface::GetBoundingBox(GtpVisibility::HierarchyNode *node)
275{
276        // reuse box if node is the same
277        // only create renderable bounding box for new node
278        if (node != mSavedNode)
279        {
280                mSavedNode = node;
281            //static_cast<Octree *>(node)->_getCullBounds(&mBox);
282                mBox = static_cast<Octree *>(node)->_getWorldAABB();
283        }
284
285        return &mBox;
286}
287//-----------------------------------------------------------------------
288void OctreeHierarchyInterface::VisualizeCulledNode(GtpVisibility::HierarchyNode *node,
289                                                                                                   GtpVisibility::CullingType type) const
290{
291        WireBoundingBox *box = static_cast<Octree *>(node)->getWireBoundingBox();
292
293        if (type == GtpVisibility::FRUSTUM_CULLED)
294        {
295                box->setMaterial("FrustumCulledNodesMaterial");
296        }
297        else // type == GtpVisibility::QUERY_CULLED
298        {
299                box->setMaterial("QueryCulledNodesMaterial");
300        }
301
302        static_cast<OctreeSceneManager *>(mSceneManager)->getBoxes()->push_back(box);
303}
304//-----------------------------------------------------------------------
305void OctreeHierarchyInterface::GetNodeGeometryList(GtpVisibility::HierarchyNode *node,
306                                                                                                   GtpVisibility::GeometryVector *geometryList,
307                                                                                                   bool includeChildren)
308{
309        NodeList::const_iterator nodeIt, nodeIt_end;
310        nodeIt_end = static_cast<Octree *>(node)->mNodes.end();
311
312        for (nodeIt = static_cast<Octree *>(node)->mNodes.begin(); nodeIt != nodeIt_end; ++nodeIt)
313        {
314                SceneNodeHierarchyInterface::GetNodeGeometryList(*nodeIt, geometryList, includeChildren);
315        }
316}
317
318
319} // namespace Ogre
Note: See TracBrowser for help on using the repository browser.