Ogre中的碰撞检测(3)

 

       在Ogre中,可以创建一个查询器,比如球体查询器,AABB查询器,面查询器等。下面我们以最常用的球形查询器为例来说明:

如下面的代码,我们首先创建一个球形查询器,它需要定义一个球体,我们把它的位置,设置为摄像机的位置,半径为10,掩码为第二个参数,默认为-1,

通过掩码,可以把碰撞的物体分成不同的组,比如我们设置球形场景查询器的掩码为0x1,则它只检测和它掩码相同物体的碰撞。该摄像机检测到entity对象后,就把摄像机位置沿摄像机方向,向后移动一个单位,这样会实现碰撞检测,但是摄像机因为向后有个移动,所以会有抖动。

ContractedBlock.gif ExpandedBlockStart.gif Code
        //创建球形查询器,第二个参数表示掩码,默认情况下为-1
        SphereSceneQuery * pQuery=mSceneMgr->createSphereQuery(Sphere(mCamera->getPosition(),10));
        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()=="Head")
                    
//{
                    
//    //m_node->setScale(10,10,10);
                    
//    pObject->getParentNode()->scale(0.5,0.5,0.5);
                    
//    break;
                    
//}
                    Ogre::Vector3 v = mCamera->getPosition();
                    Ogre::Vector3 d 
= mCamera->getDirection();
                    v 
= v + d*(-1);
                    mCamera
->setPosition(v);

                }
            }
        }

 

              全部的代码:

 

ContractedBlock.gif ExpandedBlockStart.gif Code
#include "ExampleApplication.h"

RaySceneQuery
* raySceneQuery = 0;

// Event handler to add ability to alter curvature
class TerrainFrameListener : public ExampleFrameListener
{
public:
    SceneManager
* mSceneMgr;
    TerrainFrameListener(SceneManager 
*sceneMgr,RenderWindow* win, Camera* cam)
        : ExampleFrameListener(win, cam)
    {
        
// Reduce move speed
        mMoveSpeed = 50;
        mSceneMgr 
= sceneMgr;
    }

    
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)//把摄像机定在地形10个单位高的地方。
        {
            mCamera
->setPosition(mCamera->getPosition().x, 
                i
->worldFragment->singleIntersection.y + 10
                mCamera
->getPosition().z);
        }
        
//创建球形查询器,第二个参数表示掩码,默认情况下为-1
        SphereSceneQuery * pQuery=mSceneMgr->createSphereQuery(Sphere(mCamera->getPosition(),10));
        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()=="Head")
                    
//{
                    
//    //m_node->setScale(10,10,10);
                    
//    pObject->getParentNode()->scale(0.5,0.5,0.5);
                    
//    break;
                    
//}
                    Ogre::Vector3 v = mCamera->getPosition();
                    Ogre::Vector3 d 
= mCamera->getDirection();
                    v 
= v + d*(-1);
                    mCamera
->setPosition(v);

                }
            }
        }

        
return true;

    }

};



class TerrainApplication : public ExampleApplication
{
public:
    TerrainApplication() {}

    
~TerrainApplication()
    {
        delete raySceneQuery;
    }

protected:


    
virtual void chooseSceneManager(void)
    {
        
// Get the SceneManager, in this case a generic one
        mSceneMgr = mRoot->createSceneManager("TerrainSceneManager");
    }

    
virtual void createCamera(void)
    {
        
// Create the camera
        mCamera = mSceneMgr->createCamera("PlayerCam");

        
// Position it at 500 in Z direction
        mCamera->setPosition(Vector3(128,25,128));
        
// Look back along -Z
        mCamera->lookAt(Vector3(0,0,-300));
        mCamera
->setNearClipDistance( 1 );
        mCamera
->setFarClipDistance( 1000 );

    }
   
    
// Just override the mandatory create scene method
    void createScene(void)
    {

        
// Set ambient light
        mSceneMgr->setAmbientLight(ColourValue(0.50.50.5));

        
// Create a light
        Light* l = mSceneMgr->createLight("MainLight");
        
// Accept default settings: point light, white diffuse, just set position
        
// NB I could attach the light to a SceneNode if I wanted it to move automatically with
        
//  other objects, but I don't
        l->setPosition(20,80,50);

        
// Fog
        
// NB it's VERY important to set this before calling setWorldGeometry 
        
// because the vertex program picked will be different
        ColourValue fadeColour(0.930.860.76);
        mSceneMgr
->setFog( FOG_LINEAR, fadeColour, .0015001000);
        mWindow
->getViewport(0)->setBackgroundColour(fadeColour);

        std::
string terrain_cfg("terrain.cfg");
        mSceneMgr 
-> setWorldGeometry( terrain_cfg );
        
// Infinite far plane?
        if (mRoot->getRenderSystem()->getCapabilities()->hasCapability(RSC_INFINITE_FAR_PLANE))
        {
            mCamera
->setFarClipDistance(0);
        }

        
// Set a nice viewpoint
        mCamera->setPosition(707,2500,528);
        mCamera
->setOrientation(Quaternion(-0.34860.01220.93650.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.0100.0500.0);
        headNode
->scale(Vector3(2,2,2));

    }
    
// Create new frame listener
    void createFrameListener(void)
    {
        mFrameListener
= new TerrainFrameListener(mSceneMgr,mWindow, mCamera);
        mRoot
->addFrameListener(mFrameListener);
    }

};

 

 

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

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

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值