Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

OgreOctreeSceneManager.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002 octreescenemanager.cpp  -  description
00003 -------------------
00004 begin                : Fri Sep 27 2002
00005 copyright            : (C) 2002 by Jon Anderson
00006 email                : janders@users.sf.net
00007 ***************************************************************************/
00008 
00009 /***************************************************************************
00010 *                                                                         *
00011 *   This program is free software; you can redistribute it and/or modify  *
00012 *   it under the terms of the GNU Lesser General Public License as        *
00013 *   published by the Free Software Foundation; either version 2 of the    * 
00014 *   License, or (at your option) any later version.                       *
00015 *                                                                         *
00016 ***************************************************************************/
00017 
00018 #include <OgreOctreeSceneManager.h>
00019 #include <OgreOctreeNode.h>
00020 #include <OgreOctreeCamera.h>
00021 #include <OgreRenderSystem.h>
00022 
00023 
00024 extern "C" 
00025 {
00026   void findNodesInBox( Ogre::SceneManager *sm, 
00027                const Ogre::AxisAlignedBox &box, 
00028                std::list < Ogre::SceneNode * > &list, 
00029                Ogre::SceneNode *exclude )
00030   {
00031     static_cast<Ogre::OctreeSceneManager*>( sm ) -> findNodesIn( box, list, exclude );
00032   }
00033   void findNodesInSphere( Ogre::SceneManager *sm, 
00034               const Ogre::Sphere &sphere, 
00035               std::list < Ogre::SceneNode * > &list, 
00036               Ogre::SceneNode *exclude )
00037   {
00038     static_cast<Ogre::OctreeSceneManager*>( sm ) -> findNodesIn( sphere, list, exclude );
00039   }
00040 }
00041 
00042 namespace Ogre
00043 {
00044 enum Intersection
00045 {
00046     OUTSIDE=0,
00047     INSIDE=1,
00048     INTERSECT=2
00049 };
00050 int OctreeSceneManager::intersect_call = 0;
00051 
00052 
00053 
00056 Intersection intersect( const AxisAlignedBox &one, const AxisAlignedBox &two )
00057 {
00058     OctreeSceneManager::intersect_call++;
00059     const Vector3 * outside = one.getAllCorners();
00060     const Vector3 *inside = two.getAllCorners();
00061 
00062     if ( inside[ 4 ].x < outside[ 0 ].x ||
00063             inside[ 4 ].y < outside[ 0 ].y ||
00064             inside[ 4 ].z < outside[ 0 ].z ||
00065             inside[ 0 ].x > outside[ 4 ].x ||
00066             inside[ 0 ].y > outside[ 4 ].y ||
00067             inside[ 0 ].z > outside[ 4 ].z )
00068     {
00069         return OUTSIDE;
00070     }
00071 
00072     bool full = ( inside[ 0 ].x > outside[ 0 ].x &&
00073                   inside[ 0 ].y > outside[ 0 ].y &&
00074                   inside[ 0 ].z > outside[ 0 ].z &&
00075                   inside[ 4 ].x < outside[ 4 ].x &&
00076                   inside[ 4 ].y < outside[ 4 ].y &&
00077                   inside[ 4 ].z < outside[ 4 ].z );
00078 
00079     if ( full )
00080         return INSIDE;
00081     else
00082         return INTERSECT;
00083 
00084 }
00085 
00088 Intersection intersect( const Sphere &one, const AxisAlignedBox &two )
00089 {
00090     OctreeSceneManager::intersect_call++;
00091     float sradius = one.getRadius();
00092 
00093     sradius *= sradius;
00094 
00095     Vector3 scenter = one.getCenter();
00096 
00097     const Vector3 *corners = two.getAllCorners();
00098 
00099     float s, d = 0;
00100 
00101     Vector3 mndistance = ( corners[ 0 ] - scenter );
00102     Vector3 mxdistance = ( corners[ 4 ] - scenter );
00103 
00104     if ( mndistance.squaredLength() < sradius &&
00105             mxdistance.squaredLength() < sradius )
00106     {
00107         return INSIDE;
00108     }
00109 
00110     //find the square of the distance
00111     //from the sphere to the box
00112     for ( int i = 0 ; i < 3 ; i++ )
00113     {
00114         if ( scenter[ i ] < corners[ 0 ][ i ] )
00115         {
00116             s = scenter[ i ] - corners[ 0 ][ i ];
00117             d += s * s;
00118         }
00119 
00120         else if ( scenter[ i ] > corners[ 4 ][ i ] )
00121         {
00122             s = scenter[ i ] - corners[ 4 ][ i ];
00123             d += s * s;
00124         }
00125 
00126     }
00127 
00128     bool partial = ( d <= sradius );
00129 
00130     if ( !partial )
00131     {
00132         return OUTSIDE;
00133     }
00134 
00135     else
00136     {
00137         return INTERSECT;
00138     }
00139 
00140 
00141 }
00142 
00143 unsigned long white = 0xFFFFFFFF;
00144 
00145 unsigned short OctreeSceneManager::mIndexes[ 24 ] = {0, 1, 1, 2, 2, 3, 3, 0,       //back
00146         0, 6, 6, 5, 5, 1,             //left
00147         3, 7, 7, 4, 4, 2,             //right
00148         6, 7, 5, 4 };          //front
00149 unsigned long OctreeSceneManager::mColors[ 8 ] = {white, white, white, white, white, white, white, white };
00150 
00151 
00152 OctreeSceneManager::OctreeSceneManager( ) : SceneManager()
00153 {
00154     AxisAlignedBox b( -500, -500, -500, 500, 500, 500 );
00155     int depth = 5; 
00156     mOctree = 0;
00157     init( b, depth );
00158 }
00159 
00160 OctreeSceneManager::OctreeSceneManager( AxisAlignedBox &box, int max_depth ) : SceneManager()
00161 {
00162     mOctree = 0;
00163     init( box, max_depth );
00164 }
00165 
00166 void OctreeSceneManager::init( AxisAlignedBox &box, int depth )
00167 {
00168     delete mSceneRoot; //get rid of old root.
00169 
00170     // -- Changes by Steve
00171     // Don't do it this way, it will add it to the mSceneNodes which we don't want
00172     //mSceneRoot = createSceneNode( "SceneRoot" );
00173     mSceneRoot = new OctreeNode( this, "SceneRoot" );
00174     // -- End changes by Steve
00175 
00176     if ( mOctree != 0 )
00177         delete mOctree;
00178 
00179     mOctree = new Octree( 0 );
00180 
00181     mMaxDepth = depth;
00182 
00183     mOctree -> mBox = box;
00184 
00185     Vector3 min = box.getMinimum();
00186 
00187     Vector3 max = box.getMaximum();
00188 
00189     mOctree -> mHalfSize = ( max - min ) / 2;
00190 
00191 
00192     mShowBoxes = false;
00193 
00194     mCullCamera = false;
00195 
00196     mNumObjects = 0;
00197 
00198     Vector3 v( 1.5, 1.5, 1.5 );
00199 
00200     mScaleFactor.setScale( v );
00201 
00202 
00203 
00204     // setDisplaySceneNodes( true );
00205     // setShowBoxes( true );
00206 
00207     //
00208     //setUseCullCamera( true );
00209     //mSceneRoot isn't put into the octree since it has no volume.
00210 
00211 }
00212 
00213 OctreeSceneManager::~OctreeSceneManager()
00214 {
00215     // -- Changed by Steve
00216     // Don't do this here, SceneManager will do it
00217     /*
00218     if( mSceneRoot )
00219     delete mSceneRoot;
00220     */ 
00221     // --End Changes by Steve
00222 
00223     if ( mOctree )
00224         delete mOctree;
00225 }
00226 
00227 Camera * OctreeSceneManager::createCamera( const String &name )
00228 {
00229     Camera * c = new OctreeCamera( name, this );
00230     mCameras.insert( CameraList::value_type( name, c ) );
00231     return c;
00232 }
00233 
00234 void OctreeSceneManager::destroySceneNode( const String &name )
00235 {
00236     OctreeNode * on = static_cast < OctreeNode* > ( getSceneNode( name ) );
00237 
00238     if ( on != 0 )
00239         _removeOctreeNode( on );
00240 
00241     SceneManager::destroySceneNode( name );
00242 }
00243 
00244 bool OctreeSceneManager::getOptionValues( const String & key, std::list < SDDataChunk > &refValueList )
00245 {
00246     return SceneManager::getOptionValues( key, refValueList );
00247 }
00248 
00249 bool OctreeSceneManager::getOptionKeys( std::list < String > & refKeys )
00250 {
00251     SceneManager::getOptionKeys( refKeys );
00252     refKeys.push_back( "CullCamera" );
00253     refKeys.push_back( "Size" );
00254     refKeys.push_back( "ShowOctree" );
00255     refKeys.push_back( "Depth" );
00256 
00257     return true;
00258 }
00259 
00260 
00261 void OctreeSceneManager::_updateOctreeNode( OctreeNode * onode )
00262 {
00263     AxisAlignedBox box = onode -> _getWorldAABB();
00264 
00265     if ( box.isNull() )
00266         return ;
00267 
00268 
00269     if ( onode -> getOctant() == 0 )
00270     {
00271       //if outside the octree, force into the root node.
00272       if ( ! onode -> _isIn( mOctree -> mBox ) ) 
00273     mOctree->_addNode( onode );
00274       else
00275     _addOctreeNode( onode, mOctree );
00276       return ;
00277     }
00278 
00279     if ( ! onode -> _isIn( onode -> getOctant() -> mBox ) )
00280     {
00281         _removeOctreeNode( onode );
00282 
00283     //if outside the octree, force into the root node.
00284     if ( ! onode -> _isIn( mOctree -> mBox ) ) 
00285       mOctree->_addNode( onode );
00286     else
00287       _addOctreeNode( onode, mOctree );
00288     }
00289 }
00290 
00293 void OctreeSceneManager::_removeOctreeNode( OctreeNode * n )
00294 {
00295     Octree * oct = n -> getOctant();
00296 
00297     if ( oct )
00298     {
00299         oct -> _removeNode( n );
00300     }
00301 }
00302 
00303 
00304 void OctreeSceneManager::_addOctreeNode( OctreeNode * n, Octree *octant, int depth )
00305 {
00306 
00307     AxisAlignedBox bx = n -> _getWorldAABB();
00308 
00309 
00310     //if the octree is twice as big as the scene node,
00311     //we will add it to a child.
00312     if ( ( depth < mMaxDepth ) && octant -> _isTwiceSize( bx ) )
00313     {
00314         int x, y, z;
00315         octant -> _getChildIndexes( bx, &x, &y, &z );
00316 
00317         if ( octant -> mChildren[ x ][ y ][ z ] == 0 )
00318         {
00319             octant -> mChildren[ x ][ y ][ z ] = new Octree( octant );
00320 
00321             const Vector3 *corners = octant -> mBox.getAllCorners();
00322             Vector3 min, max;
00323 
00324             if ( x == 0 )
00325             {
00326                 min.x = corners[ 0 ].x;
00327                 max.x = ( corners[ 0 ].x + corners[ 4 ].x ) / 2;
00328             }
00329 
00330             else
00331             {
00332                 min.x = ( corners[ 0 ].x + corners[ 4 ].x ) / 2;
00333                 max.x = corners[ 4 ].x;
00334             }
00335 
00336             if ( y == 0 )
00337             {
00338                 min.y = corners[ 0 ].y;
00339                 max.y = ( corners[ 0 ].y + corners[ 4 ].y ) / 2;
00340             }
00341 
00342             else
00343             {
00344                 min.y = ( corners[ 0 ].y + corners[ 4 ].y ) / 2;
00345                 max.y = corners[ 4 ].y;
00346             }
00347 
00348             if ( z == 0 )
00349             {
00350                 min.z = corners[ 0 ].z;
00351                 max.z = ( corners[ 0 ].z + corners[ 4 ].z ) / 2;
00352             }
00353 
00354             else
00355             {
00356                 min.z = ( corners[ 0 ].z + corners[ 4 ].z ) / 2;
00357                 max.z = corners[ 4 ].z;
00358             }
00359 
00360             octant -> mChildren[ x ][ y ][ z ] -> mBox.setExtents( min, max );
00361             octant -> mChildren[ x ][ y ][ z ] -> mHalfSize = ( max - min ) / 2;
00362         }
00363 
00364         _addOctreeNode( n, octant -> mChildren[ x ][ y ][ z ], ++depth );
00365 
00366     }
00367 
00368     else
00369     {
00370         octant -> _addNode( n );
00371     }
00372 }
00373 
00374 
00375 SceneNode * OctreeSceneManager::createSceneNode( void )
00376 {
00377     OctreeNode * on = new OctreeNode( this );
00378     mSceneNodes[ on->getName() ] = on;
00379     return on;
00380 }
00381 
00382 SceneNode * OctreeSceneManager::createSceneNode( const String &name )
00383 {
00384     OctreeNode * on = new OctreeNode( this, name );
00385     mSceneNodes[ on->getName() ] = on;
00386     return on;
00387 }
00388 
00389 void OctreeSceneManager::_updateSceneGraph( Camera * cam )
00390 {
00391     SceneManager::_updateSceneGraph( cam );
00392 }
00393 
00394 void OctreeSceneManager::_alertVisibleObjects( void )
00395 {
00396     NodeList::iterator it = mVisible.begin();
00397 
00398     while ( it != mVisible.end() )
00399     {
00400         OctreeNode * node = *it;
00401 
00402         ++it;
00403     }
00404 }
00405 
00406 void OctreeSceneManager::_findVisibleObjects( Camera * cam )
00407 {
00408 
00409     mRenderQueue.clear();
00410     mBoxes.clear();
00411     mVisible.clear();
00412 
00413     if ( mCullCamera )
00414     {
00415         Camera * c = getCamera( "CullCamera" );
00416 
00417         if ( c != 0 )
00418             cam = getCamera( "CullCamera" );
00419     }
00420 
00421     mNumObjects = 0;
00422 
00423     //walk the octree, adding all visible Octreenodes nodes to the render queue.
00424     walkOctree( static_cast < OctreeCamera * > ( cam ), &mRenderQueue, mOctree, false );
00425 
00426 
00427     // Show the octree boxes & cull camera if required
00428     if ( mShowBoxes || mCullCamera )
00429     {
00430 
00431         
00432 
00433         if ( mShowBoxes )
00434         {
00435             for ( BoxList::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it )
00436             {
00437                 mRenderQueue.addRenderable(*it);
00438             }
00439         }
00440 
00441         if ( mCullCamera )
00442         {
00443             OctreeCamera * c = static_cast<OctreeCamera*>(getCamera( "CullCamera" ));
00444 
00445             if ( c != 0 )
00446             {
00447                 mRenderQueue.addRenderable(c);
00448             }
00449         }
00450 
00451     }
00452 
00453 
00454 
00455 }
00456 
00457 void OctreeSceneManager::walkOctree( OctreeCamera *camera, RenderQueue *queue, Octree *octant, bool foundvisible )
00458 {
00459 
00460     //return immediately if nothing is in the node.
00461     if ( octant -> numNodes() == 0 )
00462         return ;
00463 
00464     OctreeCamera::Visibility v = OctreeCamera::NONE;
00465 
00466     if ( foundvisible )
00467     {
00468         v = OctreeCamera::FULL;
00469     }
00470 
00471     else if ( octant == mOctree )
00472     {
00473         v = OctreeCamera::PARTIAL;
00474     }
00475 
00476     else
00477     {
00478         AxisAlignedBox box;
00479         octant -> _getCullBounds( &box );
00480         v = camera -> getVisibility( box );
00481     }
00482 
00483 
00484     // if the octant is visible, or if it's the root node...
00485     if ( v != OctreeCamera::NONE )
00486     {
00487 
00488         //Add stuff to be rendered;
00489         NodeList::iterator it = octant -> mNodes.begin();
00490 
00491         if ( mShowBoxes )
00492         {
00493             mBoxes.push_back( octant->getWireBoundingBox() );
00494         }
00495 
00496         bool vis = true;
00497 
00498         while ( it != octant -> mNodes.end() )
00499         {
00500             OctreeNode * sn = *it;
00501 
00502             // if this octree is partially visible, manually cull all
00503             // scene nodes attached directly to this level.
00504 
00505             if ( v == OctreeCamera::PARTIAL )
00506                 vis = camera -> isVisible( sn -> _getWorldAABB() );
00507 
00508             if ( vis )
00509             {
00510 
00511                 mNumObjects++;
00512                 sn -> _addToRenderQueue(camera, queue );
00513 
00514                 mVisible.push_back( sn );
00515 
00516                 if ( mDisplayNodes )
00517                     queue -> addRenderable( sn );
00518 
00519         // check if the scene manager or this node wants the bounding box shown.
00520         if (sn->getShowBoundingBox() || mShowBoundingBoxes) 
00521             sn->_addBoundingBoxToQueue(queue);
00522             }
00523 
00524             ++it;
00525         }
00526 
00527         if ( octant -> mChildren[ 0 ][ 0 ][ 0 ] != 0 ) walkOctree( camera, queue, octant -> mChildren[ 0 ][ 0 ][ 0 ], ( v == OctreeCamera::FULL ) );
00528 
00529         if ( octant -> mChildren[ 1 ][ 0 ][ 0 ] != 0 ) walkOctree( camera, queue, octant -> mChildren[ 1 ][ 0 ][ 0 ], ( v == OctreeCamera::FULL ) );
00530 
00531         if ( octant -> mChildren[ 0 ][ 1 ][ 0 ] != 0 ) walkOctree( camera, queue, octant -> mChildren[ 0 ][ 1 ][ 0 ], ( v == OctreeCamera::FULL ) );
00532 
00533         if ( octant -> mChildren[ 1 ][ 1 ][ 0 ] != 0 ) walkOctree( camera, queue, octant -> mChildren[ 1 ][ 1 ][ 0 ], ( v == OctreeCamera::FULL ) );
00534 
00535         if ( octant -> mChildren[ 0 ][ 0 ][ 1 ] != 0 ) walkOctree( camera, queue, octant -> mChildren[ 0 ][ 0 ][ 1 ], ( v == OctreeCamera::FULL ) );
00536 
00537         if ( octant -> mChildren[ 1 ][ 0 ][ 1 ] != 0 ) walkOctree( camera, queue, octant -> mChildren[ 1 ][ 0 ][ 1 ], ( v == OctreeCamera::FULL ) );
00538 
00539         if ( octant -> mChildren[ 0 ][ 1 ][ 1 ] != 0 ) walkOctree( camera, queue, octant -> mChildren[ 0 ][ 1 ][ 1 ], ( v == OctreeCamera::FULL ) );
00540 
00541         if ( octant -> mChildren[ 1 ][ 1 ][ 1 ] != 0 ) walkOctree( camera, queue, octant -> mChildren[ 1 ][ 1 ][ 1 ], ( v == OctreeCamera::FULL ) );
00542 
00543     }
00544 
00545 }
00546 
00547 void OctreeSceneManager::findNodesIn( const AxisAlignedBox &box, std::list < SceneNode * > &list, SceneNode *exclude )
00548 {
00549     _findNodes( box, list, exclude );
00550 }
00551 
00552 void OctreeSceneManager::findNodesIn( const Sphere &sphere, std::list < SceneNode * > &list, SceneNode *exclude )
00553 {
00554     _findNodes( sphere, list, exclude );
00555 }
00556 
00557 void OctreeSceneManager::_findNodes( const AxisAlignedBox &box, std::list < SceneNode * > &list, SceneNode *exclude, bool full, Octree *octant )
00558 {
00559     if ( octant == 0 )
00560     {
00561         octant = mOctree;
00562     }
00563 
00564     if ( !full )
00565     {
00566         AxisAlignedBox obox;
00567         octant -> _getCullBounds( &obox );
00568 
00569         Intersection isect = intersect( box, obox );
00570 
00571         if ( isect == OUTSIDE )
00572             return ;
00573 
00574         full = ( isect == INSIDE );
00575     }
00576 
00577 
00578     NodeList::iterator it = octant -> mNodes.begin();
00579 
00580     while ( it != octant -> mNodes.end() )
00581     {
00582         OctreeNode * on = ( *it );
00583 
00584         if ( on != exclude )
00585         {
00586             if ( full )
00587             {
00588                 list.push_back( on );
00589             }
00590 
00591             else
00592             {
00593                 Intersection nsect = intersect( box, on -> _getWorldAABB() );
00594 
00595                 if ( nsect != OUTSIDE )
00596                 {
00597                     list.push_back( on );
00598                 }
00599             }
00600 
00601         }
00602 
00603         ++it;
00604     }
00605 
00606 
00607 
00608     if ( octant -> mChildren[ 0 ][ 0 ][ 0 ] != 0 ) _findNodes( box, list, exclude, full, octant -> mChildren[ 0 ][ 0 ][ 0 ] );
00609 
00610     if ( octant -> mChildren[ 1 ][ 0 ][ 0 ] != 0 ) _findNodes( box, list, exclude, full, octant -> mChildren[ 1 ][ 0 ][ 0 ] );
00611 
00612     if ( octant -> mChildren[ 0 ][ 1 ][ 0 ] != 0 ) _findNodes( box, list, exclude, full, octant -> mChildren[ 0 ][ 1 ][ 0 ] );
00613 
00614     if ( octant -> mChildren[ 1 ][ 1 ][ 0 ] != 0 ) _findNodes( box, list, exclude, full, octant -> mChildren[ 1 ][ 1 ][ 0 ] );
00615 
00616     if ( octant -> mChildren[ 0 ][ 0 ][ 1 ] != 0 ) _findNodes( box, list, exclude, full, octant -> mChildren[ 0 ][ 0 ][ 1 ] );
00617 
00618     if ( octant -> mChildren[ 1 ][ 0 ][ 1 ] != 0 ) _findNodes( box, list, exclude, full, octant -> mChildren[ 1 ][ 0 ][ 1 ] );
00619 
00620     if ( octant -> mChildren[ 0 ][ 1 ][ 1 ] != 0 ) _findNodes( box, list, exclude, full, octant -> mChildren[ 0 ][ 1 ][ 1 ] );
00621 
00622     if ( octant -> mChildren[ 1 ][ 1 ][ 1 ] != 0 ) _findNodes( box, list, exclude, full, octant -> mChildren[ 1 ][ 1 ][ 1 ] );
00623 
00624 }
00625 
00626 void OctreeSceneManager::_findNodes( const Sphere &sphere, std::list < SceneNode * > &list, SceneNode *exclude, bool full, Octree *octant )
00627 {
00628     if ( octant == 0 )
00629     {
00630         octant = mOctree;
00631     }
00632 
00633     if ( !full )
00634     {
00635         AxisAlignedBox obox;
00636         octant -> _getCullBounds( &obox );
00637 
00638         Intersection isect = intersect( sphere, obox );
00639 
00640         if ( isect == OUTSIDE )
00641             return ;
00642 
00643         full = ( isect == INSIDE );
00644     }
00645 
00646     NodeList::iterator it = octant -> mNodes.begin();
00647 
00648     while ( it != octant -> mNodes.end() )
00649     {
00650         OctreeNode * on = ( *it );
00651 
00652         if ( on != exclude )
00653         {
00654             if ( full )
00655             {
00656                 list.push_back( on );
00657             }
00658 
00659             else
00660             {
00661                 Intersection nsect = intersect( sphere, on -> _getWorldAABB() );
00662 
00663                 if ( nsect != OUTSIDE )
00664                 {
00665                     list.push_back( on );
00666                 }
00667             }
00668         }
00669 
00670         ++it;
00671     }
00672 
00673 
00674 
00675     if ( octant -> mChildren[ 0 ][ 0 ][ 0 ] != 0 ) _findNodes( sphere, list, exclude, full, octant -> mChildren[ 0 ][ 0 ][ 0 ] );
00676 
00677     if ( octant -> mChildren[ 1 ][ 0 ][ 0 ] != 0 ) _findNodes( sphere, list, exclude, full, octant -> mChildren[ 1 ][ 0 ][ 0 ] );
00678 
00679     if ( octant -> mChildren[ 0 ][ 1 ][ 0 ] != 0 ) _findNodes( sphere, list, exclude, full, octant -> mChildren[ 0 ][ 1 ][ 0 ] );
00680 
00681     if ( octant -> mChildren[ 1 ][ 1 ][ 0 ] != 0 ) _findNodes( sphere, list, exclude, full, octant -> mChildren[ 1 ][ 1 ][ 0 ] );
00682 
00683     if ( octant -> mChildren[ 0 ][ 0 ][ 1 ] != 0 ) _findNodes( sphere, list, exclude, full, octant -> mChildren[ 0 ][ 0 ][ 1 ] );
00684 
00685     if ( octant -> mChildren[ 1 ][ 0 ][ 1 ] != 0 ) _findNodes( sphere, list, exclude, full, octant -> mChildren[ 1 ][ 0 ][ 1 ] );
00686 
00687     if ( octant -> mChildren[ 0 ][ 1 ][ 1 ] != 0 ) _findNodes( sphere, list, exclude, full, octant -> mChildren[ 0 ][ 1 ][ 1 ] );
00688 
00689     if ( octant -> mChildren[ 1 ][ 1 ][ 1 ] != 0 ) _findNodes( sphere, list, exclude, full, octant -> mChildren[ 1 ][ 1 ][ 1 ] );
00690 
00691 }
00692 
00693 void OctreeSceneManager::resize( const AxisAlignedBox &box )
00694 {
00695     std::list < SceneNode * > nodes;
00696     std::list < SceneNode * > ::iterator it;
00697 
00698     _findNodes( mOctree->mBox, nodes, 0, true, mOctree );
00699 
00700     delete mOctree;
00701 
00702     mOctree = new Octree( 0 );
00703     mOctree->mBox = box;
00704 
00705     it = nodes.begin();
00706 
00707     while ( it != nodes.end() )
00708     {
00709         OctreeNode * on = static_cast < OctreeNode * > ( *it );
00710         on -> setOctant( 0 );
00711         _updateOctreeNode( on );
00712         ++it;
00713     }
00714 
00715 }
00716 
00717 bool OctreeSceneManager::setOption( const String & key, const void * val )
00718 {
00719     if ( key == "Size" )
00720     {
00721         resize( * static_cast < const AxisAlignedBox * > ( val ) );
00722         return true;
00723     }
00724 
00725     else if ( key == "Depth" )
00726     {
00727         mMaxDepth = * static_cast < const int * > ( val );
00728         resize( mOctree->mBox );
00729         return true;
00730     }
00731 
00732     else if ( key == "ShowOctree" )
00733     {
00734         mShowBoxes = * static_cast < const bool * > ( val );
00735         return true;
00736     }
00737 
00738     else if ( key == "CullCamera" )
00739     {
00740         mCullCamera = * static_cast < const bool * > ( val );
00741         return true;
00742     }
00743 
00744     return SceneManager::setOption( key, val );
00745 
00746 
00747 }
00748 
00749 bool OctreeSceneManager::getOption( const String & key, void *val )
00750 {
00751     if ( key == "Size" )
00752     {
00753         AxisAlignedBox * b = static_cast < AxisAlignedBox * > ( val );
00754         b -> setExtents( mOctree->mBox.getMinimum(), mOctree->mBox.getMaximum() );
00755         return true;
00756     }
00757 
00758     else if ( key == "Depth" )
00759     {
00760         * static_cast < int * > ( val ) = mMaxDepth;
00761         return true;
00762     }
00763 
00764     else if ( key == "ShowOctree" )
00765     {
00766 
00767         * static_cast < bool * > ( val ) = mShowBoxes;
00768         return true;
00769     }
00770 
00771     else if ( key == "CullCamera" )
00772     {
00773         * static_cast < bool * > ( val ) = mCullCamera;
00774         return true;
00775     }
00776 
00777     return SceneManager::getOption( key, val );
00778 
00779 }
00780 }

Copyright © 2002-2003 by The OGRE Team
Last modified Wed Jan 21 00:10:19 2004