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_
#include "ExampleApplication.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)
{ case 0: return CEGUI::LeftButton;
case 1: return CEGUI::RightButton;
case 2: return CEGUI::MiddleButton;
case 3: return CEGUI::X1Button;
default: return CEGUI::LeftButton;
}
}
class gkd4FrameListener : public ExampleFrameListener, public OIS::KeyListener, public OIS::MouseListener
{
private: SceneManager* mSceneMgr;
CEGUI::Renderer* mGUIRenderer;
bool mShutdownRequested;
bool mUseBufferedInputKeys, mUseBufferedInputMouse, mInputTypeSwitchingOn;
public: gkd4FrameListener(SceneManager *sceneMgr, RenderWindow* win, Camera* cam, CEGUI::Renderer* renderer) : ExampleFrameListener(win, cam, false, true), mGUIRenderer(renderer), mShutdownRequested(false), mUseBufferedInputKeys(false), mUseBufferedInputMouse(true), mSceneMgr(sceneMgr)
{
mMouse->setEventCallback(this);
mKeyboard->setEventCallback(this); mInputTypeSwitchingOn = mUseBufferedInputKeys || mUseBufferedInputMouse;
}
bool frameStarted(const FrameEvent& evt)
{ bool ret = ExampleFrameListener::frameStarted(evt);
if(mUseBufferedInputMouse) { CEGUI::MouseCursor::getSingleton().show( ); }
else
{ CEGUI::MouseCursor::getSingleton().hide( ); } AxisAlignedBox spbox=node1->_getWorldAABB(); AxisAlignedBox cbbox=node2->_getWorldAABB();
if(spbox.intersects(cbbox))
{ node2->setScale(10,10,10); }
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)
{ switchMouseMode();
mTimeUntilNextToggle = 1;
}
if (mInputTypeSwitchingOn && mKeyboard->isKeyDown(OIS::KC_K) && mTimeUntilNextToggle <= 0)
{
// must be going from immediate keyboard to buffered keyboard switchKeyMode();
mTimeUntilNextToggle = 1;
}
return ret;
}
void requestShutdown(void)
{
mShutdownRequested = true;
}
void switchMouseMode()
{ mUseBufferedInputMouse = !mUseBufferedInputMouse; mMouse->setBuffered(mUseBufferedInputMouse);
}
//----------------------------------------------------------------- void switchKeyMode()
{ mUseBufferedInputKeys = !mUseBufferedInputKeys; mKeyboard->setBuffered(mUseBufferedInputKeys);
}
bool frameEnded(const FrameEvent& evt)
{
if (mShutdownRequested)
return false;
else
return ExampleFrameListener::frameEnded(evt);
}
//----------------------------------------------------------------//
bool mouseMoved( const OIS::MouseEvent &arg )
{
CEGUI::System::getSingleton().injectMouseMove( arg.state.X.rel, arg.state.Y.rel ); return true;
}
//----------------------------------------------------------------//
bool mousePressed( const OIS::MouseEvent &arg, OIS::MouseButtonID id )
{
CEGUI::System::getSingleton().injectMouseButtonDown(convertOISMouseButtonToCegui(id));
return true;
}
//----------------------------------------------------------------//
bool mouseReleased( const OIS::MouseEvent &arg, OIS::MouseButtonID id )
{
CEGUI::System::getSingleton().injectMouseButtonUp(convertOISMouseButtonToCegui(id));
return true;
}
//----------------------------------------------------------------//
bool keyPressed( const OIS::KeyEvent &arg )
{
if( arg.key == OIS::KC_ESCAPE )
mShutdownRequested = true;
CEGUI::System::getSingleton().injectKeyDown( arg.key ); CEGUI::System::getSingleton().injectChar( arg.text );
return true;
}
//----------------------------------------------------------------//
bool keyReleased( const OIS::KeyEvent &arg )
{
if( arg.key == OIS::KC_M )
mMouse->setBuffered( !mMouse->buffered() );
else if( arg.key == OIS::KC_K )
mKeyboard->setBuffered( !mKeyboard->buffered() ); CEGUI::System::getSingleton().injectKeyUp( arg.key ); return true;
}
};
class gkd4App : public ExampleApplication
{ private: CEGUI::OgreCEGUIRenderer* mGUIRenderer; CEGUI::System* mGUISystem;
public: gkd4App() : mGUIRenderer(0), mGUISystem(0) {} ~gkd4App()
{
if(mGUISystem)
{
delete mGUISystem;
mGUISystem = 0;
}
if(mGUIRenderer)
{
delete mGUIRenderer;
mGUIRenderer = 0;
}
}
protected: virtual void createCamera(void)
{
// Create the camera
mCamera = mSceneMgr->createCamera("PlayerCam");
// Position it at 500 in Z direction
mCamera->setPosition(Vector3(0,0,80));
// Look back along -Z
mCamera->lookAt(Vector3(0,0,-300));
mCamera->setNearClipDistance(5);
}
virtual bool configure(void)
{
// Show the configuration dialog and initialise the system
// You can skip this and use root.restoreConfig() to load configuration
// settings if you were sure there are valid ones saved in ogre.cfg
if(mRoot->showConfigDialog())
{
// If returned true, user clicked OK so initialise
// Here we choose to let the system create a default rendering window by passing 'true'
mWindow = mRoot->initialise(true);
// Let's add a nice window icon
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 HWND hwnd;
mWindow->getCustomAttribute("WINDOW", (void*)&hwnd); LONG iconID = (LONG)LoadIcon( GetModuleHandle(0), MAKEINTRESOURCE(IDI_APPICON) );
SetClassLong( hwnd, GCL_HICON, iconID );
#endif return true;
}
else
{
return false;
}
}
// Just override the mandatory create scene method
virtual void createScene(void)
{
// setup GUI system
mGUIRenderer = new CEGUI::OgreCEGUIRenderer(mWindow, Ogre::RENDER_QUEUE_OVERLAY, false, 3000, mSceneMgr);
mGUISystem = new CEGUI::System(mGUIRenderer); CEGUI::Logger::getSingleton().setLoggingLevel(CEGUI::Informative);
// load scheme and set up defaults CEGUI::SchemeManager::getSingleton().loadScheme( (CEGUI::utf8*)"TaharezLookSkin.scheme");
mGUISystem->setDefaultMouseCursor( (CEGUI::utf8*)"TaharezLook", (CEGUI::utf8*)"MouseArrow");
mGUISystem->setDefaultFont((CEGUI::utf8*)"BlueHighway-12"); CEGUI::MouseCursor::getSingleton().setImage("TaharezLook", "MouseArrow"); CEGUI::MouseCursor::getSingleton().show( ); setupEventHandlers();
Entity* ent1=mSceneMgr->createEntity("robot","robot.mesh");
node1=mSceneMgr->getRootSceneNode()->createChildSceneNode("robotnode");
node1->attachObject(ent1);
Entity *ent2=mSceneMgr->createEntity("ogrehead","ogreHead.mesh");
node2=mSceneMgr->getRootSceneNode()->createChildSceneNode("ogreheadnode",Vector3(2,0,0)); node2->attachObject(ent2);
// Set ambient light mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5));
// Create a light
Light* l = mSceneMgr->createLight("MainLight"); l->setPosition(20,80,50);
}
// Create new frame listener void createFrameListener(void) { mFrameListener= new gkd4FrameListener(mSceneMgr, mWindow, mCamera, mGUIRenderer);
mRoot->addFrameListener(mFrameListener);
}
void setupEventHandlers(void)
{ }
bool handleQuit(const CEGUI::EventArgs& e)
{
static_cast(mFrameListener)->requestShutdown();
return true;
}
};
#endif
// #ifndef __gkd4_h_