这两天遇到了一个问题(毕竟接触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;
}

在使用Octree场景时,遇到一个问题,即通过OSMLoader导入的模型节点无法利用子节点更新包围盒。Ogre源代码中的_OctreeNode类在更新包围盒时不考虑子节点,导致无法通过_getWorldAABB获取rootNode的大小。为解决此问题,自定义了一个函数CalculateNodeBounds,递归遍历所有子节点,合并它们的世界坐标轴对齐包围盒,从而计算出rootNode的有效包围盒。
2566

被折叠的 条评论
为什么被折叠?



