OGRE里如何实现碰撞检测
浏览:1600次 出处信息
在3D游戏中,碰撞检测算得上是最复杂也是最影响游戏效果的环节了,这里简单介绍一下如何在OGRE引擎里实现简单的碰撞检测。
话不多说,先贴代码:
bool EdenCollisionManager::Collide()
{
bool collide=false;
m_KeyObject=*(m_ResearchObject.begin()); // m_Keyobjects是待检测的物体(游戏角色)
Ogre::AxisAlignedBox AABB = m_KeyObject->getWorldBoundingBox(true); // 获取包围盒
m_AABBSceneQuery->setBox(AABB); // 以包围盒建立场景查询
m_AABBSceneQuery->setQueryMask(ENTITY_QUERY_MASK); // 设置查询标识
Ogre::SceneQueryResult& results = m_AABBSceneQuery->execute(); // 获取查询结果
Ogre::SceneQueryResultMovableList::iterator iter = results.movables.begin();
if(results.movables.empty())
return false;
else
{
for(;iter!=results.movables.end();iter++)
{
if((*iter)->getMovableType()=="Entity")
{
if(m_KeyObject->getName()==(*iter)->getName())
continue;
else
{
collide=true;
break;
}
}
}
return collide;
}
}
{
bool collide=false;
m_KeyObject=*(m_ResearchObject.begin()); // m_Keyobjects是待检测的物体(游戏角色)
Ogre::AxisAlignedBox AABB = m_KeyObject->getWorldBoundingBox(true); // 获取包围盒
m_AABBSceneQuery->setBox(AABB); // 以包围盒建立场景查询
m_AABBSceneQuery->setQueryMask(ENTITY_QUERY_MASK); // 设置查询标识
Ogre::SceneQueryResult& results = m_AABBSceneQuery->execute(); // 获取查询结果
Ogre::SceneQueryResultMovableList::iterator iter = results.movables.begin();
if(results.movables.empty())
return false;
else
{
for(;iter!=results.movables.end();iter++)
{
if((*iter)->getMovableType()=="Entity")
{
if(m_KeyObject->getName()==(*iter)->getName())
continue;
else
{
collide=true;
break;
}
}
}
return collide;
}
}
OK,对OGRE熟悉一点的人一眼就可以看出来,这里采用的是基于包围盒的碰撞检测方法,什么是基于包围盒的碰撞检测呢?简单点说,就是用一个立方体的盒子把物体装起来,然后用这个盒子里代替原先的物体,在场景中进行检测,按照一定的策略(比如距离)判断两两物体间是否碰撞。
包围盒法虽然简单快速,但是准确性却不太高,而且有很大的局限性。因为是采用立方体的包围盒,盒子的范围比原先的物体大,所以会造成一定的误差(特别是在物体形状不规则的情况下),这个误差随着“盒子”的体积紧包物体表面而无限接近真实结果,所以为了减少这个误差,配合着场景物体的形状,我们可以用球体、圆柱体等来代替包围盒,所有这些替代,都是为了减少误差,是碰撞检测更加精确。可以说,包围盒法检测结果的准确性依赖于包围盒的选择,包围盒的体积愈接近3D物体,结果越精确,但是在游戏中,一个场景中往往有各种大小、各种形状的物体,所以我们的包围盒往往只能折中选择。
上面的代码只是在OGRE引擎里实现碰撞检测的演示代码,下面具体讲讲包围盒法碰撞检测的算法:
包围盒法碰撞一般是使用球体或圆柱体的范围包围每个Object或测试一定范围内的碰撞。假设我们有两个Object A和B,两个Object分别被一个半径为ra,rb的球体包围,半径ra,rb来检测。我们可以简单的检测AB间的距离是否小于ra+rb,小于,则碰撞;反之则没有。
碰撞检测还有很多其他的方法,比如射线法等,甚至还有三角面级别的精确碰撞检测,这里不再详述,以后再做介绍。
优化问题
最后简单提一下碰撞检测的优化问题。
举一个简单的例子,假设一个场景中有1000个对象(object,子弹等等)。现在假设我们要对这1000个obejcts进行碰撞检测,考虑到每两个物体之间我们都要计算一次,那么总共会有1000x1000 = 1000000的计算量,这个计算量是很恐怖的,因此我们不得不对碰撞问题进行一些优化,这里介绍一下空间分割方法。
还是这个场景,但是我们现在把利用BSP树(二叉树)对场景里的object进行管理,并且将所有的object划分成一组一组,每一组50个object,共有1000 / 50 = 20组。很显然,现在我们只需要在每一组的objects里进行检测就可以了,所以现在的计算量是50 * 50 * 20 = 50000。计算量只有原来的5%!可见使用BSP树进行场景管理对我们游戏性能的提高有多大帮助了!
建议继续学习:
QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习
扫一扫订阅我的微信号:IT技术博客大学习
<< 前一篇:搜索引擎停用词
文章信息
- 作者:ian 来源: Vimer
- 标签: OGRE 碰撞
- 发布时间:2010-04-15 09:52:09
建议继续学习
近3天十大热文
- [55] IOS安全–浅谈关于IOS加固的几种方法
- [53] android 开发入门
- [52] 如何拿下简短的域名
- [52] 图书馆的世界纪录
- [50] Oracle MTS模式下 进程地址与会话信
- [50] Go Reflect 性能
- [48] 【社会化设计】自我(self)部分――欢迎区
- [47] 读书笔记-壹百度:百度十年千倍的29条法则
- [36] 程序员技术练级攻略
- [27] 视觉调整-设计师 vs. 逻辑