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