Ogre中的碰撞检测(2)

 

     Ogre 中,每个节点有AABB(轴对齐包围盒),通过包围盒,可以实现碰撞检测判断。具体实现过程如下:

     通过Ogre::SceneNode::_getWorldAABB()可以取得这个叶子节点的AABB(Ogre::AxisAlignedBox),Ogre::AxisAlignedBox封装了对AABB的支持,该类的成员函数Ogre::AxisAlignedBox::intersects()可以判断一个AABB和"球体、点、面以及其他面"的相交情况(碰撞情况)。

ContractedBlock.gif ExpandedBlockStart.gif Code
     m_SphereNode;  //树的叶子,挂了一个"球"
     m_CubeNode;  //树的叶子,挂了一个"正方体"

     AxisAlignedBox spbox
=m_SphereNode->_getWorldAABB();
     AxisAlignedBox cbbox
=m_CubeNode->_getWorldAABB();
     
if(spbox.intersects(cbbox))
    {
      
//相交
     }

 

下面是测试2个节点通过AABB判断碰撞的程序代码:

 

ContractedBlock.gif ExpandedBlockStart.gif Code
#ifndef __gkd4_h_
#define __gkd4_h_


#include 
"ExampleApplication.h"
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
#include 
"../res/resource.h"
#endif
#include 
<CEGUI.h>
#include 
<CEGUISystem.h>
#include 
<CEGUISchemeManager.h>
#include 
<OgreCEGUIRenderer.h>

//两个场景节点
SceneNode*node1;
SceneNode
* node2;

CEGUI::MouseButton convertOISMouseButtonToCegui(
int buttonID)
{
    
switch (buttonID)
    {
    
case 0return CEGUI::LeftButton;
    
case 1return CEGUI::RightButton;
    
case 2:    return CEGUI::MiddleButton;
    
case 3return CEGUI::X1Button;
    
defaultreturn 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, 
falsetrue),
      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, 
false3000, 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.50.50.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
<gkd4FrameListener*>(mFrameListener)->requestShutdown();
      
return true;
   }
};

#endif // #ifndef __gkd4_h_

 

 

posted on 2009-11-19 13:44 迈克老狼 阅读( ...) 评论( ...)   编辑 收藏

转载于:https://www.cnblogs.com/mikewolf2009/articles/1606027.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值