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( -10000, -10000, -10000, 10000, 10000, 10000 );
00155     int depth = 8; 
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     mBox = box;
00183 
00184     mOctree -> mBox = box;
00185 
00186     Vector3 min = box.getMinimum();
00187 
00188     Vector3 max = box.getMaximum();
00189 
00190     mOctree -> mHalfSize = ( max - min ) / 2;
00191 
00192 
00193     mShowBoxes = false;
00194 
00195     mCullCamera = false;
00196 
00197     mNumObjects = 0;
00198 
00199     Vector3 v( 1.5, 1.5, 1.5 );
00200 
00201     mScaleFactor.setScale( v );
00202 
00203 
00204 
00205     // setDisplaySceneNodes( true );
00206     // setShowBoxes( true );
00207 
00208     //
00209     //setUseCullCamera( true );
00210     //mSceneRoot isn't put into the octree since it has no volume.
00211 
00212 }
00213 
00214 OctreeSceneManager::~OctreeSceneManager()
00215 {
00216     // -- Changed by Steve
00217     // Don't do this here, SceneManager will do it
00218     /*
00219     if( mSceneRoot )
00220     delete mSceneRoot;
00221     */ 
00222     // --End Changes by Steve
00223 
00224     if ( mOctree )
00225         delete mOctree;
00226 }
00227 
00228 Camera * OctreeSceneManager::createCamera( const String &name )
00229 {
00230     Camera * c = new OctreeCamera( name, this );
00231     mCameras.insert( CameraList::value_type( name, c ) );
00232     return c;
00233 }
00234 
00235 void OctreeSceneManager::destroySceneNode( const String &name )
00236 {
00237     OctreeNode * on = static_cast < OctreeNode* > ( getSceneNode( name ) );
00238 
00239     if ( on != 0 )
00240         _removeOctreeNode( on );
00241 
00242     SceneManager::destroySceneNode( name );
00243 }
00244 
00245 bool OctreeSceneManager::getOptionValues( const String & key, std::list < SDDataChunk > &refValueList )
00246 {
00247     return SceneManager::getOptionValues( key, refValueList );
00248 }
00249 
00250 bool OctreeSceneManager::getOptionKeys( std::list < String > & refKeys )
00251 {
00252     SceneManager::getOptionKeys( refKeys );
00253     refKeys.push_back( "CullCamera" );
00254     refKeys.push_back( "Size" );
00255     refKeys.push_back( "ShowOctree" );
00256     refKeys.push_back( "Depth" );
00257 
00258     return true;
00259 }
00260 
00261 
00262 void OctreeSceneManager::_updateOctreeNode( OctreeNode * onode )
00263 {
00264     AxisAlignedBox box = onode -> _getWorldAABB();
00265 
00266     if ( box.isNull() )
00267         return ;
00268 
00269 
00270     if ( onode -> getOctant() == 0 )
00271     {
00272       //if outside the octree, force into the root node.
00273       if ( ! onode -> _isIn( mOctree -> mBox ) ) 
00274     mOctree->_addNode( onode );
00275       else
00276     _addOctreeNode( onode, mOctree );
00277       return ;
00278     }
00279 
00280     if ( ! onode -> _isIn( onode -> getOctant() -> mBox ) )
00281     {
00282         _removeOctreeNode( onode );
00283 
00284     //if outside the octree, force into the root node.
00285     if ( ! onode -> _isIn( mOctree -> mBox ) ) 
00286       mOctree->_addNode( onode );
00287     else
00288       _addOctreeNode( onode, mOctree );
00289     }
00290 }
00291 
00294 void OctreeSceneManager::_removeOctreeNode( OctreeNode * n )
00295 {
00296     Octree * oct = n -> getOctant();
00297 
00298     if ( oct )
00299     {
00300         oct -> _removeNode( n );
00301     }
00302 }
00303 
00304 
00305 void OctreeSceneManager::_addOctreeNode( OctreeNode * n, Octree *octant, int depth )
00306 {
00307 
00308     AxisAlignedBox bx = n -> _getWorldAABB();
00309 
00310 
00311     //if the octree is twice as big as the scene node,
00312     //we will add it to a child.
00313     if ( ( depth < mMaxDepth ) && octant -> _isTwiceSize( bx ) )
00314     {
00315         int x, y, z;
00316         octant -> _getChildIndexes( bx, &x, &y, &z );
00317 
00318         if ( octant -> mChildren[ x ][ y ][ z ] == 0 )
00319         {
00320             octant -> mChildren[ x ][ y ][ z ] = new Octree( octant );
00321 
00322             const Vector3 *corners = octant -> mBox.getAllCorners();
00323             Vector3 min, max;
00324 
00325             if ( x == 0 )
00326             {
00327                 min.x = corners[ 0 ].x;
00328                 max.x = ( corners[ 0 ].x + corners[ 4 ].x ) / 2;
00329             }
00330 
00331             else
00332             {
00333                 min.x = ( corners[ 0 ].x + corners[ 4 ].x ) / 2;
00334                 max.x = corners[ 4 ].x;
00335             }
00336 
00337             if ( y == 0 )
00338             {
00339                 min.y = corners[ 0 ].y;
00340                 max.y = ( corners[ 0 ].y + corners[ 4 ].y ) / 2;
00341             }
00342 
00343             else
00344             {
00345                 min.y = ( corners[ 0 ].y + corners[ 4 ].y ) / 2;
00346                 max.y = corners[ 4 ].y;
00347             }
00348 
00349             if ( z == 0 )
00350             {
00351                 min.z = corners[ 0 ].z;
00352                 max.z = ( corners[ 0 ].z + corners[ 4 ].z ) / 2;
00353             }
00354 
00355             else
00356             {
00357                 min.z = ( corners[ 0 ].z + corners[ 4 ].z ) / 2;
00358                 max.z = corners[ 4 ].z;
00359             }
00360 
00361             octant -> mChildren[ x ][ y ][ z ] -> mBox.setExtents( min, max );
00362             octant -> mChildren[ x ][ y ][ z ] -> mHalfSize = ( max - min ) / 2;
00363         }
00364 
00365         _addOctreeNode( n, octant -> mChildren[ x ][ y ][ z ], ++depth );
00366 
00367     }
00368 
00369     else
00370     {
00371         octant -> _addNode( n );
00372     }
00373 }
00374 
00375 
00376 SceneNode * OctreeSceneManager::createSceneNode( void )
00377 {
00378     OctreeNode * on = new OctreeNode( this );
00379     mSceneNodes[ on->getName() ] = on;
00380     return on;
00381 }
00382 
00383 SceneNode * OctreeSceneManager::createSceneNode( const String &name )
00384 {
00385     OctreeNode * on = new OctreeNode( this, name );
00386     mSceneNodes[ on->getName() ] = on;
00387     return on;
00388 }
00389 
00390 void OctreeSceneManager::_updateSceneGraph( Camera * cam )
00391 {
00392     SceneManager::_updateSceneGraph( cam );
00393 }
00394 
00395 void OctreeSceneManager::_alertVisibleObjects( void )
00396 {
00397     NodeList::iterator it = mVisible.begin();
00398 
00399     while ( it != mVisible.end() )
00400     {
00401         OctreeNode * node = *it;
00402 
00403         ++it;
00404     }
00405 }
00406 
00407 void OctreeSceneManager::_findVisibleObjects( Camera * cam, bool onlyShadowCasters )
00408 {
00409 
00410     getRenderQueue()->clear();
00411     mBoxes.clear();
00412     mVisible.clear();
00413 
00414     if ( mCullCamera )
00415     {
00416         Camera * c = getCamera( "CullCamera" );
00417 
00418         if ( c != 0 )
00419             cam = getCamera( "CullCamera" );
00420     }
00421 
00422     mNumObjects = 0;
00423 
00424     //walk the octree, adding all visible Octreenodes nodes to the render queue.
00425     walkOctree( static_cast < OctreeCamera * > ( cam ), getRenderQueue(), mOctree, false, onlyShadowCasters );
00426 
00427 
00428     // Show the octree boxes & cull camera if required
00429     if ( mShowBoxes || mCullCamera )
00430     {
00431 
00432         
00433 
00434         if ( mShowBoxes )
00435         {
00436             for ( BoxList::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it )
00437             {
00438                 getRenderQueue()->addRenderable(*it);
00439             }
00440         }
00441 
00442         if ( mCullCamera )
00443         {
00444             OctreeCamera * c = static_cast<OctreeCamera*>(getCamera( "CullCamera" ));
00445 
00446             if ( c != 0 )
00447             {
00448                 getRenderQueue()->addRenderable(c);
00449             }
00450         }
00451 
00452     }
00453 
00454 
00455 
00456 }
00457 
00458 void OctreeSceneManager::walkOctree( OctreeCamera *camera, RenderQueue *queue, 
00459     Octree *octant, bool foundvisible, bool onlyShadowCasters )
00460 {
00461 
00462     //return immediately if nothing is in the node.
00463     if ( octant -> numNodes() == 0 )
00464         return ;
00465 
00466     OctreeCamera::Visibility v = OctreeCamera::NONE;
00467 
00468     if ( foundvisible )
00469     {
00470         v = OctreeCamera::FULL;
00471     }
00472 
00473     else if ( octant == mOctree )
00474     {
00475         v = OctreeCamera::PARTIAL;
00476     }
00477 
00478     else
00479     {
00480         AxisAlignedBox box;
00481         octant -> _getCullBounds( &box );
00482         v = camera -> getVisibility( box );
00483     }
00484 
00485 
00486     // if the octant is visible, or if it's the root node...
00487     if ( v != OctreeCamera::NONE )
00488     {
00489 
00490         //Add stuff to be rendered;
00491         NodeList::iterator it = octant -> mNodes.begin();
00492 
00493         if ( mShowBoxes )
00494         {
00495             mBoxes.push_back( octant->getWireBoundingBox() );
00496         }
00497 
00498         bool vis = true;
00499 
00500         while ( it != octant -> mNodes.end() )
00501         {
00502             OctreeNode * sn = *it;
00503 
00504             // if this octree is partially visible, manually cull all
00505             // scene nodes attached directly to this level.
00506 
00507             if ( v == OctreeCamera::PARTIAL )
00508                 vis = camera -> isVisible( sn -> _getWorldAABB() );
00509 
00510             if ( vis )
00511             {
00512 
00513                 mNumObjects++;
00514                 sn -> _addToRenderQueue(camera, queue, onlyShadowCasters );
00515 
00516                 mVisible.push_back( sn );
00517 
00518                 if ( mDisplayNodes )
00519                     queue -> addRenderable( sn );
00520 
00521         // check if the scene manager or this node wants the bounding box shown.
00522         if (sn->getShowBoundingBox() || mShowBoundingBoxes) 
00523             sn->_addBoundingBoxToQueue(queue);
00524             }
00525 
00526             ++it;
00527         }
00528 
00529         if ( octant -> mChildren[ 0 ][ 0 ][ 0 ] != 0 ) walkOctree( camera, queue, octant -> mChildren[ 0 ][ 0 ][ 0 ], ( v == OctreeCamera::FULL ), onlyShadowCasters );
00530 
00531         if ( octant -> mChildren[ 1 ][ 0 ][ 0 ] != 0 ) walkOctree( camera, queue, octant -> mChildren[ 1 ][ 0 ][ 0 ], ( v == OctreeCamera::FULL ), onlyShadowCasters );
00532 
00533         if ( octant -> mChildren[ 0 ][ 1 ][ 0 ] != 0 ) walkOctree( camera, queue, octant -> mChildren[ 0 ][ 1 ][ 0 ], ( v == OctreeCamera::FULL ), onlyShadowCasters );
00534 
00535         if ( octant -> mChildren[ 1 ][ 1 ][ 0 ] != 0 ) walkOctree( camera, queue, octant -> mChildren[ 1 ][ 1 ][ 0 ], ( v == OctreeCamera::FULL ), onlyShadowCasters );
00536 
00537         if ( octant -> mChildren[ 0 ][ 0 ][ 1 ] != 0 ) walkOctree( camera, queue, octant -> mChildren[ 0 ][ 0 ][ 1 ], ( v == OctreeCamera::FULL ), onlyShadowCasters );
00538 
00539         if ( octant -> mChildren[ 1 ][ 0 ][ 1 ] != 0 ) walkOctree( camera, queue, octant -> mChildren[ 1 ][ 0 ][ 1 ], ( v == OctreeCamera::FULL ), onlyShadowCasters );
00540 
00541         if ( octant -> mChildren[ 0 ][ 1 ][ 1 ] != 0 ) walkOctree( camera, queue, octant -> mChildren[ 0 ][ 1 ][ 1 ], ( v == OctreeCamera::FULL ), onlyShadowCasters );
00542 
00543         if ( octant -> mChildren[ 1 ][ 1 ][ 1 ] != 0 ) walkOctree( camera, queue, octant -> mChildren[ 1 ][ 1 ][ 1 ], ( v == OctreeCamera::FULL ), onlyShadowCasters );
00544 
00545     }
00546 
00547 }
00548 
00549 void OctreeSceneManager::findNodesIn( const AxisAlignedBox &box, std::list < SceneNode * > &list, SceneNode *exclude )
00550 {
00551     _findNodes( box, list, exclude );
00552 }
00553 
00554 void OctreeSceneManager::findNodesIn( const Sphere &sphere, std::list < SceneNode * > &list, SceneNode *exclude )
00555 {
00556     _findNodes( sphere, list, exclude );
00557 }
00558 
00559 void OctreeSceneManager::_findNodes( const AxisAlignedBox &box, std::list < SceneNode * > &list, SceneNode *exclude, bool full, Octree *octant )
00560 {
00561     if ( octant == 0 )
00562     {
00563         octant = mOctree;
00564     }
00565 
00566     if ( !full )
00567     {
00568         AxisAlignedBox obox;
00569         octant -> _getCullBounds( &obox );
00570 
00571         Intersection isect = intersect( box, obox );
00572 
00573         if ( isect == OUTSIDE )
00574             return ;
00575 
00576         full = ( isect == INSIDE );
00577     }
00578 
00579 
00580     NodeList::iterator it = octant -> mNodes.begin();
00581 
00582     while ( it != octant -> mNodes.end() )
00583     {
00584         OctreeNode * on = ( *it );
00585 
00586         if ( on != exclude )
00587         {
00588             if ( full )
00589             {
00590                 list.push_back( on );
00591             }
00592 
00593             else
00594             {
00595                 Intersection nsect = intersect( box, on -> _getWorldAABB() );
00596 
00597                 if ( nsect != OUTSIDE )
00598                 {
00599                     list.push_back( on );
00600                 }
00601             }
00602 
00603         }
00604 
00605         ++it;
00606     }
00607 
00608 
00609 
00610     if ( octant -> mChildren[ 0 ][ 0 ][ 0 ] != 0 ) _findNodes( box, list, exclude, full, octant -> mChildren[ 0 ][ 0 ][ 0 ] );
00611 
00612     if ( octant -> mChildren[ 1 ][ 0 ][ 0 ] != 0 ) _findNodes( box, list, exclude, full, octant -> mChildren[ 1 ][ 0 ][ 0 ] );
00613 
00614     if ( octant -> mChildren[ 0 ][ 1 ][ 0 ] != 0 ) _findNodes( box, list, exclude, full, octant -> mChildren[ 0 ][ 1 ][ 0 ] );
00615 
00616     if ( octant -> mChildren[ 1 ][ 1 ][ 0 ] != 0 ) _findNodes( box, list, exclude, full, octant -> mChildren[ 1 ][ 1 ][ 0 ] );
00617 
00618     if ( octant -> mChildren[ 0 ][ 0 ][ 1 ] != 0 ) _findNodes( box, list, exclude, full, octant -> mChildren[ 0 ][ 0 ][ 1 ] );
00619 
00620     if ( octant -> mChildren[ 1 ][ 0 ][ 1 ] != 0 ) _findNodes( box, list, exclude, full, octant -> mChildren[ 1 ][ 0 ][ 1 ] );
00621 
00622     if ( octant -> mChildren[ 0 ][ 1 ][ 1 ] != 0 ) _findNodes( box, list, exclude, full, octant -> mChildren[ 0 ][ 1 ][ 1 ] );
00623 
00624     if ( octant -> mChildren[ 1 ][ 1 ][ 1 ] != 0 ) _findNodes( box, list, exclude, full, octant -> mChildren[ 1 ][ 1 ][ 1 ] );
00625 
00626 }
00627 
00628 void OctreeSceneManager::_findNodes( const Sphere &sphere, std::list < SceneNode * > &list, SceneNode *exclude, bool full, Octree *octant )
00629 {
00630     if ( octant == 0 )
00631     {
00632         octant = mOctree;
00633     }
00634 
00635     if ( !full )
00636     {
00637         AxisAlignedBox obox;
00638         octant -> _getCullBounds( &obox );
00639 
00640         Intersection isect = intersect( sphere, obox );
00641 
00642         if ( isect == OUTSIDE )
00643             return ;
00644 
00645         full = ( isect == INSIDE );
00646     }
00647 
00648     NodeList::iterator it = octant -> mNodes.begin();
00649 
00650     while ( it != octant -> mNodes.end() )
00651     {
00652         OctreeNode * on = ( *it );
00653 
00654         if ( on != exclude )
00655         {
00656             if ( full )
00657             {
00658                 list.push_back( on );
00659             }
00660 
00661             else
00662             {
00663                 Intersection nsect = intersect( sphere, on -> _getWorldAABB() );
00664 
00665                 if ( nsect != OUTSIDE )
00666                 {
00667                     list.push_back( on );
00668                 }
00669             }
00670         }
00671 
00672         ++it;
00673     }
00674 
00675 
00676 
00677     if ( octant -> mChildren[ 0 ][ 0 ][ 0 ] != 0 ) _findNodes( sphere, list, exclude, full, octant -> mChildren[ 0 ][ 0 ][ 0 ] );
00678 
00679     if ( octant -> mChildren[ 1 ][ 0 ][ 0 ] != 0 ) _findNodes( sphere, list, exclude, full, octant -> mChildren[ 1 ][ 0 ][ 0 ] );
00680 
00681     if ( octant -> mChildren[ 0 ][ 1 ][ 0 ] != 0 ) _findNodes( sphere, list, exclude, full, octant -> mChildren[ 0 ][ 1 ][ 0 ] );
00682 
00683     if ( octant -> mChildren[ 1 ][ 1 ][ 0 ] != 0 ) _findNodes( sphere, list, exclude, full, octant -> mChildren[ 1 ][ 1 ][ 0 ] );
00684 
00685     if ( octant -> mChildren[ 0 ][ 0 ][ 1 ] != 0 ) _findNodes( sphere, list, exclude, full, octant -> mChildren[ 0 ][ 0 ][ 1 ] );
00686 
00687     if ( octant -> mChildren[ 1 ][ 0 ][ 1 ] != 0 ) _findNodes( sphere, list, exclude, full, octant -> mChildren[ 1 ][ 0 ][ 1 ] );
00688 
00689     if ( octant -> mChildren[ 0 ][ 1 ][ 1 ] != 0 ) _findNodes( sphere, list, exclude, full, octant -> mChildren[ 0 ][ 1 ][ 1 ] );
00690 
00691     if ( octant -> mChildren[ 1 ][ 1 ][ 1 ] != 0 ) _findNodes( sphere, list, exclude, full, octant -> mChildren[ 1 ][ 1 ][ 1 ] );
00692 
00693 }
00694 
00695 void OctreeSceneManager::resize( const AxisAlignedBox &box )
00696 {
00697     std::list < SceneNode * > nodes;
00698     std::list < SceneNode * > ::iterator it;
00699 
00700     _findNodes( mOctree->mBox, nodes, 0, true, mOctree );
00701 
00702     delete mOctree;
00703 
00704     mOctree = new Octree( 0 );
00705     mOctree->mBox = box;
00706 
00707     it = nodes.begin();
00708 
00709     while ( it != nodes.end() )
00710     {
00711         OctreeNode * on = static_cast < OctreeNode * > ( *it );
00712         on -> setOctant( 0 );
00713         _updateOctreeNode( on );
00714         ++it;
00715     }
00716 
00717 }
00718 
00719 bool OctreeSceneManager::setOption( const String & key, const void * val )
00720 {
00721     if ( key == "Size" )
00722     {
00723         resize( * static_cast < const AxisAlignedBox * > ( val ) );
00724         return true;
00725     }
00726 
00727     else if ( key == "Depth" )
00728     {
00729         mMaxDepth = * static_cast < const int * > ( val );
00730         resize( mOctree->mBox );
00731         return true;
00732     }
00733 
00734     else if ( key == "ShowOctree" )
00735     {
00736         mShowBoxes = * static_cast < const bool * > ( val );
00737         return true;
00738     }
00739 
00740     else if ( key == "CullCamera" )
00741     {
00742         mCullCamera = * static_cast < const bool * > ( val );
00743         return true;
00744     }
00745 
00746     return SceneManager::setOption( key, val );
00747 
00748 
00749 }
00750 
00751 bool OctreeSceneManager::getOption( const String & key, void *val )
00752 {
00753     if ( key == "Size" )
00754     {
00755         AxisAlignedBox * b = static_cast < AxisAlignedBox * > ( val );
00756         b -> setExtents( mOctree->mBox.getMinimum(), mOctree->mBox.getMaximum() );
00757         return true;
00758     }
00759 
00760     else if ( key == "Depth" )
00761     {
00762         * static_cast < int * > ( val ) = mMaxDepth;
00763         return true;
00764     }
00765 
00766     else if ( key == "ShowOctree" )
00767     {
00768 
00769         * static_cast < bool * > ( val ) = mShowBoxes;
00770         return true;
00771     }
00772 
00773     else if ( key == "CullCamera" )
00774     {
00775         * static_cast < bool * > ( val ) = mCullCamera;
00776         return true;
00777     }
00778 
00779     return SceneManager::getOption( key, val );
00780 
00781 }
00782 
00783 void OctreeSceneManager::clearScene(void)
00784 {
00785     SceneManager::clearScene();
00786     init(mBox, mMaxDepth);
00787 
00788 }
00789 
00790 }

Copyright © 2002-2003 by The OGRE Team
Last modified Fri May 14 23:22:29 2004