基於射線查詢的方式,實現攝像機和地形的碰撞檢測,防止攝像機穿透地面,這也是ogre demo中terrian例子中的方法。
首先定義 rayscenequery* rayscenequery = 0;
在createscene時候,建立場景查詢
framerenderingqueued事件中,進行射線查詢,設定攝像機位置
rayscenequery = mscenemgr->createrayquery(
ray(mcamera->getposition(), vector3::negative_unit_y));//光線的位置和方向,垂直向下
然後在bool framerenderingqueued(const frameevent& evt)
if( exampleframelistener::framerenderingqueued(evt) == false )
return false;
// clamp to terrain
static ray updateray;
updateray.setorigin(mcamera->getposition());
updateray.setdirection(vector3::negative_unit_y);
rayscenequery->setray(updateray);
rayscenequeryresult& qryresult = rayscenequery->execute();
rayscenequeryresult::iterator i = qryresult.begin();
if (i != qryresult.end() && i->worldfragment)//把攝像機定在地形個單位高的地方。
mcamera->setposition(mcamera->getposition().x,
i->worldfragment->singleintersection.y + 10,
mcamera->getposition().z);
return true;
這樣就把攝像機設在離地形高10個單位的地方。
ogre 中,每個節點有aabb(軸對齊包圍盒),通過包圍盒,可以實現碰撞檢測判斷。具體實現過程如下: 通過ogre::scenenode::_getworldaabb()可以取得這個葉子節點的aabb(ogre::axisalignedbox),ogre::axisalignedbox封裝了對aabb的支援,該類的成員函式ogre::axisalignedbox::intersects()可以判斷乙個aabb和"球體、點、面以及其他面"的相交情況(碰撞情況)。 code m_spherenode; //樹的葉子,掛了乙個"球" m_cubenode; //樹的葉子,掛了乙個"正方體"
axisalignedbox spbox=m_spherenode->_getworldaabb(); axisalignedbox cbbox=m_cubenode->_getworldaabb();
if(spbox.intersects(cbbox)) 下面是測試2個節點通過aabb判斷碰撞的程式**:
code
#ifndef __gkd4_h_
#define __gkd4_h_
#if ogre_platform == ogre_platform_win32
#include "../res/resource.h"
#endif
#include
#include
#include
#include
//兩個場景節點
scenenode*node1;
scenenode* node2;
cegui::mousebutton convertoismousebuttontocegui(int buttonid)
switch (buttonid)
else
axisalignedbox spbox=node1->_getworldaabb(); axisalignedbox cbbox=node2->_getworldaabb();
if(spbox.intersects(cbbox))
return ret;
bool processunbufferedkeyinput(const frameevent& evt)
bool ret =exampleframelistener::processunbufferedkeyinput(evt);
// see if switching is on, and you want to toggle if (minputtypeswitchingon && mkeyboard->iskeydown(ois::kc_m) && mtimeuntilnexttoggle <= 0)
ogre::vector3 v = mcamera->getposition();
ogre::vector3 d = mcamera->getdirection();
v = v + d*(-1);
mcamera->setposition(v);}}
}全部的**:
rayscenequery* rayscenequery = 0;
// event handler to add ability to alter curvature
class terrainframelistener : public exampleframelistener
bool framerenderingqueued(const frameevent& evt)
//建立球形查詢器,第二個引數表示掩碼,預設情況下為-1
spherescenequery * pquery=mscenemgr->createspherequery(sphere(mcamera->getposition(),10));
scenequeryresult qresult=pquery->execute();
for (std::list::iterator iter = qresult.movables.begin(); iter != qresult.movables.end();++iter)
ogre::vector3 v = mcamera->getposition();
ogre::vector3 d = mcamera->getdirection();
v = v + d*(-1);
mcamera->setposition(v);}}
}return true;
protected:
virtual void choosescenemanager(void)
virtual void createcamera(void)
// just override the mandatory create scene method
void createscene(void)
// set a nice viewpoint
mcamera->setposition(707,2500,528);
mcamera->setorientation(quaternion(-0.3486, 0.0122, 0.9365, 0.0329));
//mroot -> showdebugoverlay( true );
rayscenequery = mscenemgr->createrayquery(
ray(mcamera->getposition(), vector3::negative_unit_y));//光線的位置和方向,垂直向下
entity* ogrehead = mscenemgr->createentity("head", "ogrehead.mesh");
//建立ogre head實體,測試通過射線查詢movable來實現攝像機碰撞檢測
scenenode* headnode = mscenemgr->getrootscenenode()->createchildscenenode("ogrehead");
headnode->attachobject(ogrehead);
headnode->setposition(500.0, 100.0, 500.0);
headnode->scale(vector3(2,2,2));
}// create new frame listener
void createframelistener(void)
在3中,我提到檢測到碰撞時候,後移乙個單位,攝像機會抖動,現在通過記錄攝像機上步移動偏移量,如果檢測到碰撞則反移回來,可以解決這個問題。
下面是修改後的**:
code
bool framerenderingqueued(const frameevent& evt)
//建立球形查詢器,第二個引數表示掩碼,預設情況下為-1
vector3 oldpos = mcamera->getposition();
spherescenequery * pquery=mscenemgr->createspherequery(sphere(mcamera->getposition(),10),0x01);
scenequeryresult qresult=pquery->execute();
for (std::list::iterator iter = qresult.movables.begin(); iter != qresult.movables.end();++iter)
//ogre::vector3 v = mcamera->getposition();
//ogre::vector3 d = mcamera->getdirection();
//v = v + d*(-1);
//mcamera->setposition(v);
mcamera->moverelative( - mtranslatevector);}}
}return true;
OGRE 地形碰撞檢測
我們現在要實現它,以便當我們向著地面移動時,能夠不穿過地面。因為baseframelistener已經處理了攝像機移動,所以我們就不用碰那些 了。替代地,在baseframelistener移動了攝像機後,我們要確保攝像機在地面以上10個單位處。如果它不在,我們要把它移到那兒。請跟緊這段 我們將在本...
OGRE碰撞檢測MOC
上找到它。我決定把其中最核心的一段 挑出來,詳細解讀。ray,求交射線 result,與模型麵片的交點 target,相交物體 closest distance,距離最近交點的距離 querymask,碰撞檢測掩碼 bool collisiontools raycast const ogre ray...
Ogre中的碰撞檢測 1
基於射線查詢的方式,實現攝像機和地形的碰撞檢測,防止攝像機穿透地面,這也是ogre demo中terrian例子中的方法。首先定義 rayscenequery rayscenequery 0 在createscene時候,建立場景查詢 framerenderingqueued 事件中,進行射線查詢,...