Ogre中的碰撞檢測

2021-05-21 23:26:25 字數 4920 閱讀 5248

基於射線查詢的方式,實現攝像機和地形的碰撞檢測,防止攝像機穿透地面,這也是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 事件中,進行射線查詢,...