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