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

Revision 316, 7.2 KB checked in by mattausch, 19 years ago (diff)

queries are realized as templates

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
39namespace Ogre
40{
41
42/** Returns true is the box will fit in a child.
43*/
44bool Octree::_isTwiceSize( AxisAlignedBox &box )
45{
46    const Vector3 * pts1 = mBox.getAllCorners();
47    const Vector3 * pts2 = box.getAllCorners();
48
49    return ( ( pts2[ 4 ].x -pts2[ 0 ].x ) <= ( pts1[ 4 ].x - pts1[ 0 ].x ) / 2 ) &&
50           ( ( pts2[ 4 ].y - pts2[ 0 ].y ) <= ( pts1[ 4 ].y - pts1[ 0 ].y ) / 2 ) &&
51           ( ( pts2[ 4 ].z - pts2[ 0 ].z ) <= ( pts1[ 4 ].z - pts1[ 0 ].z ) / 2 ) ;
52
53}
54
55/** It's assumed the the given box has already been proven to fit into
56* a child.  Since it's a loose octree, only the centers need to be
57* compared to find the appropriate node.
58*/
59void Octree::_getChildIndexes( AxisAlignedBox &box, int *x, int *y, int *z )
60{
61    Vector3 max = mBox.getMaximum();
62    Vector3 min = box.getMinimum();
63
64    Vector3 center = mBox.getMaximum().midPoint( mBox.getMinimum() );
65
66    Vector3 ncenter = box.getMaximum().midPoint( box.getMinimum() );
67
68    if ( ncenter.x > center.x )
69        * x = 1;
70    else
71        *x = 0;
72
73    if ( ncenter.y > center.y )
74        * y = 1;
75    else
76        *y = 0;
77
78    if ( ncenter.z > center.z )
79        * z = 1;
80    else
81        *z = 0;
82
83}
84
85Octree::Octree( Octree * parent )
86    : mWireBoundingBox(0),
87      mHalfSize( 0, 0, 0 )
88#ifdef GTP_VISIBILITY_MODIFIED_OGRE
89        , mLastVisited(0), mVisible(false), mLastRendered(-1)
90#endif //GTP_VISIBILITY_MODIFIED_OGRE
91{
92    //initialize all children to null.
93    for ( int i = 0; i < 2; i++ )
94    {
95        for ( int j = 0; j < 2; j++ )
96        {
97            for ( int k = 0; k < 2; k++ )
98            {
99                mChildren[ i ][ j ][ k ] = 0;
100            }
101        }
102    }
103
104    mParent = parent;
105#ifdef GTP_VISIBILITY_MODIFIED_OGRE
106        if (mParent)
107                mDepth = parent->getDepth() + 1;
108        else
109                mDepth = 0;
110        // update bounds because we want tight octree
111        _updateBounds();
112       
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}
138
139void Octree::_addNode( OctreeNode * n )
140{
141    mNodes.push_back( n );
142    n -> setOctant( this );
143
144    //update total counts.
145    _ref();
146
147#ifdef GTP_VISIBILITY_MODIFIED_OGRE
148        _updateBounds();
149#endif
150
151}
152
153void Octree::_removeNode( OctreeNode * n )
154{
155    mNodes.erase( std::find( mNodes.begin(), mNodes.end(), n ) );
156    n -> setOctant( 0 );
157
158    //update total counts.
159    _unref();
160
161#ifdef GTP_VISIBILITY_MODIFIED_OGRE
162        _updateBounds();
163#endif
164}
165
166void Octree::_getCullBounds( AxisAlignedBox *b )
167{
168    const Vector3 * corners = mBox.getAllCorners();
169    b -> setExtents( corners[ 0 ] - mHalfSize, corners[ 4 ] + mHalfSize );
170}
171
172WireBoundingBox* Octree::getWireBoundingBox()
173{
174        // Create a WireBoundingBox if needed
175    if(mWireBoundingBox == 0)
176        mWireBoundingBox = new WireBoundingBox();
177#ifdef GTP_VISIBILITY_MODIFIED_OGRE
178        mWireBoundingBox->setupBoundingBox(mWorldAABB);
179#else
180        mWireBoundingBox->setupBoundingBox(mBox);
181#endif 
182
183    return mWireBoundingBox;
184}
185
186#ifdef GTP_VISIBILITY_MODIFIED_OGRE
187//-----------------------------------------------------------------------       
188int Octree::lastVisited()
189{
190        return mLastVisited;
191}
192//-----------------------------------------------------------------------
193void Octree::setLastVisited(int frameid)
194{
195        mLastVisited = frameid;
196}
197//-----------------------------------------------------------------------       
198int Octree::lastRendered()
199{
200        return mLastRendered;
201}
202//-----------------------------------------------------------------------
203void Octree::setLastRendered(int frameid)
204{
205        mLastRendered = frameid;
206}
207//-----------------------------------------------------------------------       
208void Octree::setOctreeVisible(bool visible)
209{
210        mVisible = visible;
211}
212//-----------------------------------------------------------------------       
213bool Octree::isOctreeVisible()
214{
215        return mVisible;
216}
217//-----------------------------------------------------------------------       
218Octree *Octree::getParent()
219{
220        return mParent;
221}
222//-----------------------------------------------------------------------       
223int Octree::getDepth()
224{
225        return mDepth;
226}
227//-----------------------------------------------------------------------       
228AxisAlignedBox Octree::_getWorldAABB(void) const
229{
230        return mWorldAABB;
231}
232//-----------------------------------------------------------------------
233void Octree::_updateBounds()
234{
235        // Reset bounds first
236    mWorldAABB.setNull();
237 
238    // Update bounds from own attached objects
239        NodeList::iterator it, it_end;
240        it_end = mNodes.end();
241
242    for (it = mNodes.begin(); it != it_end; ++it)
243    {
244        // Merge world bounds of each object
245                mWorldAABB.merge((*it)->_getWorldAABB());
246    }
247
248    // Merge with children
249        for (int i = 0; i < 2; ++i)
250    {
251        for (int j = 0; j < 2; ++j)
252        {
253            for (int k = 0; k < 2; ++k)
254            {
255                if (mChildren[i][j][k])
256                                {
257                                        mWorldAABB.merge(mChildren[i][j][k]->_getWorldAABB());
258                                }
259            }
260        }
261        }
262        // HACK: clamp to bounds
263        AxisAlignedBox box;
264        _getCullBounds(&box);
265        mWorldAABB = mWorldAABB.intersection(box);
266       
267        // recursively update parent bounds
268        if (mParent)
269        {
270                mParent->_updateBounds();
271        }
272 }
273
274#endif //GTP_VISIBILITY_MODIFIED_OGRE
275}
Note: See TracBrowser for help on using the repository browser.