source: trunk/VUT/work/ogre_changes/Plugins/OctreeSceneManager/src/OgreOctree.cpp @ 139

Revision 139, 7.3 KB checked in by mattausch, 19 years ago (diff)

fixed bug with tight octree boxes
added more flexible renderqueue (can delete per flag)
reordered functions in visibility terrain scene manager

Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4(Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2005 The OGRE Team
8Also see acknowledgements in Readme.html
9
10This program is free software; you can redistribute it and/or modify it under
11the terms of the GNU Lesser General Public License as published by the Free Software
12Foundation; either version 2 of the License, or (at your option) any later
13version.
14
15This program is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License along with
20this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22http://www.gnu.org/copyleft/lesser.txt.
23-----------------------------------------------------------------------------
24*/
25/***************************************************************************
26octree.cpp  -  description
27-------------------
28begin                : Mon Sep 30 2002
29copyright            : (C) 2002 by Jon Anderson
30email                : janders@users.sf.net
31
32Enhancements 2003 - 2004 (C) The OGRE Team
33
34***************************************************************************/
35
36#include <OgreOctree.h>
37#include <OgreOctreeNode.h>
38#include <OgreLogManager.h>
39
40namespace Ogre
41{
42
43/** Returns true is the box will fit in a child.
44*/
45bool Octree::_isTwiceSize( AxisAlignedBox &box )
46{
47    const Vector3 * pts1 = mBox.getAllCorners();
48    const Vector3 * pts2 = box.getAllCorners();
49
50    return ( ( pts2[ 4 ].x -pts2[ 0 ].x ) <= ( pts1[ 4 ].x - pts1[ 0 ].x ) / 2 ) &&
51           ( ( pts2[ 4 ].y - pts2[ 0 ].y ) <= ( pts1[ 4 ].y - pts1[ 0 ].y ) / 2 ) &&
52           ( ( pts2[ 4 ].z - pts2[ 0 ].z ) <= ( pts1[ 4 ].z - pts1[ 0 ].z ) / 2 ) ;
53
54}
55
56/** It's assumed the the given box has already been proven to fit into
57* a child.  Since it's a loose octree, only the centers need to be
58* compared to find the appropriate node.
59*/
60void Octree::_getChildIndexes( AxisAlignedBox &box, int *x, int *y, int *z )
61{
62    Vector3 max = mBox.getMaximum();
63    Vector3 min = box.getMinimum();
64
65    Vector3 center = mBox.getMaximum().midPoint( mBox.getMinimum() );
66
67    Vector3 ncenter = box.getMaximum().midPoint( box.getMinimum() );
68
69    if ( ncenter.x > center.x )
70        * x = 1;
71    else
72        *x = 0;
73
74    if ( ncenter.y > center.y )
75        * y = 1;
76    else
77        *y = 0;
78
79    if ( ncenter.z > center.z )
80        * z = 1;
81    else
82        *z = 0;
83
84}
85
86Octree::Octree( Octree * parent )
87    : mWireBoundingBox(0),
88      mHalfSize( 0, 0, 0 )
89#ifdef GTP_VISIBILITY_MODIFIED_OGRE
90        , mLastVisited(0), mVisible(false), mLastRendered(-1)
91#endif //GTP_VISIBILITY_MODIFIED_OGRE
92{
93    //initialize all children to null.
94    for ( int i = 0; i < 2; i++ )
95    {
96        for ( int j = 0; j < 2; j++ )
97        {
98            for ( int k = 0; k < 2; k++ )
99            {
100                mChildren[ i ][ j ][ k ] = 0;
101            }
102        }
103    }
104
105    mParent = parent;
106#ifdef GTP_VISIBILITY_MODIFIED_OGRE
107        if (mParent)
108                mDepth = parent->getDepth() + 1;
109        else
110                mDepth = 0;
111
112        _updateBounds();
113#endif //GTP_VISIBILITY_MODIFIED_OGRE
114    mNumNodes = 0;
115}
116
117Octree::~Octree()
118{
119    //initialize all children to null.
120    for ( int i = 0; i < 2; i++ )
121    {
122        for ( int j = 0; j < 2; j++ )
123        {
124            for ( int k = 0; k < 2; k++ )
125            {
126                if ( mChildren[ i ][ j ][ k ] != 0 )
127                    delete mChildren[ i ][ j ][ k ];
128            }
129        }
130    }
131
132    if(mWireBoundingBox)
133        delete mWireBoundingBox;
134
135    mParent = 0;
136}
137
138void Octree::_addNode( OctreeNode * n )
139{
140    mNodes.push_back( n );
141    n -> setOctant( this );
142
143    //update total counts.
144    _ref();
145
146#ifdef GTP_VISIBILITY_MODIFIED_OGRE
147        _updateBounds();
148#endif
149
150}
151
152void Octree::_removeNode( OctreeNode * n )
153{
154    mNodes.erase( std::find( mNodes.begin(), mNodes.end(), n ) );
155    n -> setOctant( 0 );
156
157    //update total counts.
158    _unref();
159
160#ifdef GTP_VISIBILITY_MODIFIED_OGRE
161        _updateBounds();
162#endif
163}
164
165void Octree::_getCullBounds( AxisAlignedBox *b )
166{
167    const Vector3 * corners = mBox.getAllCorners();
168    b -> setExtents( corners[ 0 ] - mHalfSize, corners[ 4 ] + mHalfSize );
169}
170
171WireBoundingBox* Octree::getWireBoundingBox()
172{
173        // Create a WireBoundingBox if needed
174    if(mWireBoundingBox == 0)
175        mWireBoundingBox = new WireBoundingBox();
176
177        //mWireBoundingBox->setupBoundingBox(mBox);
178        mWireBoundingBox->setupBoundingBox(mWorldAABB);
179
180    return mWireBoundingBox;
181}
182
183#ifdef GTP_VISIBILITY_MODIFIED_OGRE
184//-----------------------------------------------------------------------       
185int Octree::lastVisited()
186{
187        return mLastVisited;
188}
189//-----------------------------------------------------------------------
190void Octree::setLastVisited(int frameid)
191{
192        mLastVisited = frameid;
193}
194//-----------------------------------------------------------------------       
195int Octree::lastRendered()
196{
197        return mLastRendered;
198}
199//-----------------------------------------------------------------------
200void Octree::setLastRendered(int frameid)
201{
202        mLastRendered = frameid;
203}
204//-----------------------------------------------------------------------       
205void Octree::setOctreeVisible(bool visible)
206{
207        mVisible = visible;
208}
209//-----------------------------------------------------------------------       
210bool Octree::isOctreeVisible()
211{
212        return mVisible;
213}
214//-----------------------------------------------------------------------       
215Octree *Octree::getParent()
216{
217        return mParent;
218}
219//-----------------------------------------------------------------------       
220int Octree::getDepth()
221{
222        return mDepth;
223}
224//-----------------------------------------------------------------------       
225AxisAlignedBox Octree::_getWorldAABB(void) const
226{
227        return mWorldAABB;
228}
229//-----------------------------------------------------------------------
230void Octree::_updateBounds()
231{
232        // Reset bounds first
233    mWorldAABB.setNull();
234 
235    // Update bounds from own attached objects
236        NodeList::iterator it, it_end;
237        it_end = mNodes.end();
238
239    for (it = mNodes.begin(); it != it_end; ++it)
240    {
241        // Merge world bounds of each object
242                mWorldAABB.merge((*it)->_getWorldAABB());
243    }
244
245    // Merge with children
246        for (int i = 0; i < 2; ++i)
247    {
248        for (int j = 0; j < 2; ++j)
249        {
250            for (int k = 0; k < 2; ++k)
251            {
252                if (mChildren[i][j][k])
253                                {
254                                        mWorldAABB.merge(mChildren[i][j][k]->_getWorldAABB());
255                                }
256            }
257        }
258        }
259        // HACK: clamp to bounds
260        AxisAlignedBox box;
261        _getCullBounds(&box);
262        mWorldAABB = mWorldAABB.intersection(box);
263       
264        //std::stringstream d; d << "updating box: " << mWorldAABB << ", depth: " << mDepth << "null: " << mBox.isNull();
265        //LogManager::getSingleton().logMessage(d.str());
266
267        // recursively update parent bounds
268        if (mParent)
269        {
270                mParent->_updateBounds();
271        }
272 }
273#endif //GTP_VISIBILITY_MODIFIED_OGRE
274}
Note: See TracBrowser for help on using the repository browser.