Ogre中的碰撞检测(4)

本文介绍如何使用Ogre3D引擎实现精确的碰撞检测,包括通过设置掩码过滤特定对象,利用光线和球形查询进行高效碰撞检测的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

通过设置不同的掩码,可以实现有选择的碰撞检测,下面的代码中,ogre头能被查询器检测到,而机器人由于掩码不同,不能被检测到。

 

 


#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),0x01);
        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");
        ogreHead
->setQueryFlags(0x01);//
和球形场景查询器的掩码相同,所以该实体能被球形实体检测到

        
//创建ogre head实体,测试通过射线查询movable来实现摄像机碰撞检测

        SceneNode* headNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("ogreHead");
        headNode
->
attachObject(ogreHead);
        headNode
->setPosition(500.0100.0500.0
);
        headNode
->scale(Vector3(2,2,2
));

        Entity
* entRobot = mSceneMgr->createEntity("Robot""robot.mesh"
);
        entRobot
->setQueryFlags(0x02);//掩码为2,不会和球形场景查询器检测到


        SceneNode
* RobotNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("nodeRobot");
        RobotNode
->
attachObject(entRobot);
        RobotNode
->setPosition(400.050.0400.0
);
        RobotNode
->scale(Vector3(2,2,2
));
        

    }
    
// Create new frame listener

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

};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值