這兩天遇到了一個問題(畢竟接觸ogre不久,可能問題比較弱智哈),由於我把模型用OSMLoader的演示方法導入,它具體是通過一個場景(.osm文件)導入後,將其中的子模型分別用一個node保存,如果你提供了一個node(暫訂叫rootNode),那麼所有的子模型node都會添加rootNode下.
這樣本來也很沒有問題,畢竟如果我用.osm導入一個大場景,爲了處理碰撞,我肯定要把各個子模型分散到不同的node下,但是在Octree場景下,問題就來了,請看ogre源代碼:
//same as SceneNode, only it doesn't care about children...
void OctreeNode::_updateBounds( void )
{
mWorldAABB.setNull();
mLocalAABB.setNull();
// Update bounds from own attached objects
ObjectMap::iterator i = mObjectsByName.begin();
AxisAlignedBox bx;
while ( i != mObjectsByName.end() )
{
// Get local bounds of object
bx = i->second ->getBoundingBox();
mLocalAABB.merge( bx );
mWorldAABB.merge( i->second ->getWorldBoundingBox(true) );
++i;
}
//update the OctreeSceneManager that things might have moved.
// if it hasn't been added to the octree, add it, and if has moved
// enough to leave it's current node, we'll update it.
if ( ! mWorldAABB.isNull() )
{
static_cast < OctreeSceneManager * > ( mCreator ) -> _updateOctreeNode( this );
}
}
不需要看代碼內容,光那句註釋"same as SceneNode, only it doesn't care about children...",就差點讓我崩潰了,我提供的rootNode竟然無法利用子node來更新包圍盒!!雖然我知道ogre的設計者肯定有他們的用意,但是這樣就決定了我的rootNode無法通過_getWorldAABB來取得它的大小了(因爲不考慮update時只看有沒有movableObj而不看有沒有子node).
我的解決方案:
說來很簡單,ogre不幫我算我自己算,代碼如下:
AxisAlignedBox OSE_GameFrameListener::CalculateNodeBounds( String nodeName ){
SceneNode *node = mSceneMgr->getSceneNode( nodeName );
if( node->numChildren() == 0 )
return node->_getWorldAABB();
AxisAlignedBox tBox;
tBox.setNull();
for( int cIndex = 0; cIndex < node->numChildren(); ++cIndex ){
SceneNode *tmp = ( SceneNode* )( node->getChild( cIndex ) );
tBox.merge( tmp->_getWorldAABB() );
}
由於利用rootNode不可能有movableObj所以,我就不去理會,如果需要考慮,可以將在返回前,遍歷一次Object,並merge他們的保衛盒.
enjoy!!
return tBox;
}