原創 韓舉
http://www.hjpdiy.com
Ogre采用樹樁管理場景中的各種"元素"(攝像機、燈光、物體等),所有的東西都掛在"樹"上,不在"樹"上的東西不會被渲染。
Ogre::SceneManager就是"樹"的管理者,Ogre::SceneNode是從SceneManager中創建的(當然BSP和8*樹的管理也和這兩個類有關,這暫時不討論)。
AABB(軸對齊包圍盒)
這個東西是碰撞檢測的基礎(怎么總想起JJYY呢),和它類似的還有OBB(有向包圍盒),由于OBB創建復雜,所以Ogre采用了AABB。
最簡單的碰撞檢測:
通
過Ogre::SceneNode::_getWorldAABB()可以取得這個葉子節點的AABB(Ogre::AxisAlignedBox),
Ogre::AxisAlignedBox封裝了對AABB的支持,該類的成員函數Ogre::AxisAlignedBox::intersects
()可以判斷一個AABB和"球體、點、面以及其他面"的相交情況(碰撞情況)。
m_SphereNode樹的葉子,掛了一個"球"
m_CubeNode樹的葉子,掛了一個"正方體"
AxisAlignedBox spbox=m_SphereNode->_getWorldAABB();
AxisAlignedBox cbbox=m_CubeNode->_getWorldAABB();
if(spbox.intersects(cbbox))
{
//相交
}
區域查詢:
簡單的講就是,查詢某一區域中有什么東西,分為AABB、球體、面查詢。
//創建一個球體查詢,這里的100是m_SphereNode掛著的那個球體的半徑
SphereSceneQuery * pQuery=m_SceneMgr->createSphereQuery(Sphere(m_SphereNode->getPosition(),100));
//執行這個查詢
SceneQueryResult QResult=pQuery->execute();
//遍歷查詢列表找出范圍內的物體
for (std::list<MovableObject*>::iterator iter = QResult.movables.begin(); iter != QResult.movables.end();++iter)
{
MovableObject* pObject=static_cast<MovableObject*>(*iter);
if(pObject)
{
if(pObject->getMovableType()=="Entity")
{
Entity* ent = static_cast<Entity*>(pObject);
//這里簡化了操作,由于只有一個"球體"和一個"正方體",
//所以只判斷了球體和正方體的相交
if(ent->getName()=="cube")
{
//改變位置防止物體重疊
vtl=-vtl;
m_SphereNode->translate(vtl);
break;
}
}
}
}
相交查詢
遍歷所有的對象,找到一對一對的相交物體(廢話呀,相交當然至少兩個物體)。
//創建相交檢測
IntersectionSceneQuery* pISQuery=m_SceneMgr->createIntersectionQuery();
//執行查詢
IntersectionSceneQueryResult QResult=pISQuery->execute();
//遍歷查詢列表找出兩個相交的物體
for (SceneQueryMovableIntersectionList::iterator iter = QResult.movables2movables.begin();
iter != QResult.movables2movables.end();++iter)
{
SceneQueryMovableObjectPair pObject=static_cast<SceneQueryMovableObjectPair>(*iter);
//if(pObject)
{
String strFirst=pObject.first->getName();
String strSecond=pObject.second->getName();
//下面加入你自己的兩個物體相交判斷代碼,或者簡單的用AABB的判斷方法,
}
}