source: OGRE/trunk/ogre_changes/Ogre1.2/PlugIns/OctreeSceneManager/src/OgreOctree.cpp @ 2308

Revision 2308, 8.3 KB checked in by mattausch, 17 years ago (diff)
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        , mNumLeaves(1), mNumVisibleLeaves(0)
91        , mFullyVisible(false)
92#endif //GTP_VISIBILITY_MODIFIED_OGRE
93{
94    //initialize all children to null.
95    for ( int i = 0; i < 2; i++ )
96    {
97        for ( int j = 0; j < 2; j++ )
98        {
99            for ( int k = 0; k < 2; k++ )
100            {
101                mChildren[ i ][ j ][ k ] = 0;
102            }
103        }
104    }
105
106    mParent = parent;
107
108    mNumNodes = 0;
109
110#ifdef GTP_VISIBILITY_MODIFIED_OGRE
111        // recursively update number of children
112        if (0) _incNumChildren();
113#endif;
114}
115
116Octree::~Octree()
117{
118    //initialize all children to null.
119    for ( int i = 0; i < 2; i++ )
120    {
121        for ( int j = 0; j < 2; j++ )
122        {
123            for ( int k = 0; k < 2; k++ )
124            {
125                if ( mChildren[ i ][ j ][ k ] != 0 )
126                    delete mChildren[ i ][ j ][ k ];
127            }
128        }
129    }
130
131    if(mWireBoundingBox)
132        delete mWireBoundingBox;
133
134    mParent = 0;
135}
136
137void Octree::_addNode( OctreeNode * n )
138{
139    mNodes.push_back( n );
140    n -> setOctant( this );
141
142    //update total counts.
143    _ref();
144
145#ifdef GTP_VISIBILITY_MODIFIED_OGRE
146        _updateBounds();
147#endif
148}
149
150void Octree::_removeNode( OctreeNode * n )
151{
152    mNodes.erase( std::find( mNodes.begin(), mNodes.end(), n ) );
153    n -> setOctant( 0 );
154
155    //update total counts.
156    _unref();
157
158#ifdef GTP_VISIBILITY_MODIFIED_OGRE
159        _updateBounds();
160#endif
161}
162
163void Octree::_getCullBounds( AxisAlignedBox *b )
164{
165    const Vector3 * corners = mBox.getAllCorners();
166    b -> setExtents( corners[ 0 ] - mHalfSize, corners[ 4 ] + mHalfSize );
167}
168
169WireBoundingBox* Octree::getWireBoundingBox()
170{
171    // Create a WireBoundingBox if needed
172    if(mWireBoundingBox == 0)
173        mWireBoundingBox = new WireBoundingBox();
174
175#ifdef GTP_VISIBILITY_MODIFIED_OGRE
176        mWireBoundingBox->setupBoundingBox(mWorldAABB);
177#else
178        mWireBoundingBox->setupBoundingBox(mBox);
179#endif 
180
181    return mWireBoundingBox;
182}
183
184#ifdef GTP_VISIBILITY_MODIFIED_OGRE
185//-----------------------------------------------------------------------       
186int Octree::lastVisited()
187{
188        return mLastVisited;
189}
190//-----------------------------------------------------------------------
191void Octree::setLastVisited(int frameid)
192{
193        mLastVisited = frameid;
194}
195//-----------------------------------------------------------------------       
196int Octree::lastRendered()
197{
198        return mLastRendered;
199}
200//-----------------------------------------------------------------------
201void Octree::setLastRendered(int frameid)
202{
203        mLastRendered = frameid;
204}
205//-----------------------------------------------------------------------       
206void Octree::setOctreeVisible(bool visible)
207{
208        mVisible = visible;
209}
210//-----------------------------------------------------------------------       
211bool Octree::isOctreeVisible()
212{
213        return mVisible;
214}
215//-----------------------------------------------------------------------       
216void Octree::setOctreeFullyVisible(bool visible)
217{
218        mFullyVisible = visible;
219}
220//-----------------------------------------------------------------------       
221bool Octree::isOctreeFullyVisible()
222{
223        // all childrens are visible
224#if 0
225        return mNumChildren == mNumVisibleChildren;
226#else
227        return mFullyVisible;
228#endif
229}
230//-----------------------------------------------------------------------       
231float Octree::getVisibilityRatio()
232{
233        // all childrens are visible
234        return (float)mNumVisibleLeaves / (float)mNumLeaves;
235}
236//-----------------------------------------------------------------------
237void Octree::setNumVisibleLeaves(int leaves)
238{
239        int mNumVisibleLeaves = leaves;
240}
241//-----------------------------------------------------------------------
242int Octree::getNumVisibleLeaves()
243{
244        return mNumVisibleLeaves;
245}
246//-----------------------------------------------------------------------
247void Octree::setNumLeaves(int leaves)
248{
249        mNumLeaves = leaves;
250}
251//-----------------------------------------------------------------------
252int Octree::getNumLeaves()
253{
254        return mNumLeaves;
255}
256//-----------------------------------------------------------------------
257Octree *Octree::getParent()
258{
259        return mParent;
260}
261//-----------------------------------------------------------------------       
262AxisAlignedBox Octree::_getWorldAABB(void) const
263{
264        return mWorldAABB;
265}
266//-----------------------------------------------------------------------
267void Octree::_updateBounds()
268{
269        // Reset bounds first
270    mWorldAABB.setNull();
271 
272    // Update bounds from own attached objects
273        NodeList::iterator it, it_end;
274        it_end = mNodes.end();
275
276    for (it = mNodes.begin(); it != it_end; ++it)
277    {
278        // Merge world bounds of each object
279                mWorldAABB.merge((*it)->_getWorldAABB());
280    }
281
282    // Merge with children
283        for (int i = 0; i < 2; ++i)
284    {
285        for (int j = 0; j < 2; ++j)
286        {
287            for (int k = 0; k < 2; ++k)
288            {
289                if (mChildren[i][j][k])
290                                {
291                                        mWorldAABB.merge(mChildren[i][j][k]->_getWorldAABB());
292                                }
293            }
294        }
295        }
296
297        // HACK: clamp to bounds
298        AxisAlignedBox box;
299        _getCullBounds(&box);
300        mWorldAABB = mWorldAABB.intersection(box);
301       
302        // recursively update parent bounds
303        if (mParent)
304        {
305                mParent->_updateBounds();
306        }
307}
308
309
310void Octree::_incNumChildren()
311{
312/*      ++ mNumChildren;
313
314        if (mParent)   
315        {
316                mParent->_incNumChildren();
317        }*/
318}
319
320#endif //GTP_VISIBILITY_MODIFIED_OGRE
321}
Note: See TracBrowser for help on using the repository browser.