AABB(Axis Aligned Bounding Box)即轴向包围盒,每个物体都有一个包围盒,该包围盒完全罩住了物体,可利用该包围盒近似模拟物体形状,实现碰撞检测,如下图所示,可使用类似
1 |
m_pSceneMgr->getEntity("Cube01")->getParentSceneNode()->showBoundingBox(true); |
的方法取得场景中某个物体,让物体绑定的场景节点的包围盒显示出来
当该物体的包围盒与其他要检测的物体的包围盒发生接触时,即表示发生了碰撞,由于包围盒不能完全模拟物体形状,所以该方法精度有限,只能适用于形状规则的简单物体,Ogre::AxisAlignedBoxSceneQuery 类封装了许多包围盒碰撞检测的方法,可利用该场景查询实现简单的碰撞检测,对于不需要应用该碰撞检测方法的物体,我们可以使用setQueryFlags()方法设置查询标识,场景查询使用setQueryMask()方法实现要与哪些标识的物体做碰撞检测。查询标识是一个很好用的东西,对于一些不需要做碰撞检测的物体,就可以通过设置查询标识过滤掉.下面是一个实现AABB场景查询的类,可以应用到自己程序中,实现一个简单的AABB碰撞检测。
CollisionAabb.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
#ifndef COLLISIONAABB_H #define COLLISIONAABB_H #include <OgreSceneQuery.h> #include <Ogre.h> class CollisionAabb { public: Ogre::AxisAlignedBoxSceneQuery *mAabbSceneQuery; Ogre::SceneManager *mSceneMgr; CollisionAabb(Ogre::SceneManager *sceneMgr); ~CollisionAabb(); bool isCollision(Ogre::MovableObject* m,const Ogre::uint32 mqueryMask); }; #endif |
CollisionAabb.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
#include "CollisionAabb.h" CollisionAabb::CollisionAabb(Ogre::SceneManager *sceneMgr) { mSceneMgr = sceneMgr; } CollisionAabb::~CollisionAabb() { if (mAabbSceneQuery != NULL) delete mAabbSceneQuery; } bool CollisionAabb::isCollision(Ogre::MovableObject* m,const Ogre::uint32 mqueryMask) { bool collide=false; mAabbSceneQuery = mSceneMgr->createAABBQuery(m->getWorldBoundingBox(),mqueryMask); //创建场景查询 Ogre::SceneQueryResult &mResult = mAabbSceneQuery->execute(); //执行AABB场景查询,返回结果 Ogre::SceneQueryResultMovableList::iterator iter; //创建遍历查询结果列表的迭代器 if(mResult.movables.empty()) //如果结果为空,表示没有发生碰撞,返回false return false; else{ for (iter = mResult.movables.begin(); iter != mResult.movables.end(); iter++) { Ogre::MovableObject* mObject = static_cast<Ogre::MovableObject*>(*iter); if(mObject) { if(mObject->getMovableType() == "Entity") //如果该可移动物件类型为Entity,而不是light之类的 { Ogre::Entity* ent = static_cast<Ogre::Entity*>(mObject); //ent->setVisible(false); if(m->getName() == ent->getName()) continue; //判断该物体名称是否与本身名称一样(过滤掉自己,不让自己与自己做碰检) else{ collide=true; break; } } } } return collide; } } |
文章评论