Ogre 简易角色Demo
阅读原文时间:2023年07月15日阅读:1

参考Sample中的角色类,使用ExampleApplication.h改写,只编译了release,debug在配置文件名字上有不同

遗留一个问题

mBodyEnt->getSkeleton()获取骨骼获取到的为null值,不解。不设置动画方式为混合不影响程序运行。原因以后调试源码解决

3个类

NMain.cpp:入口类

#include "stdafx.h"
#include
#include "ExampleApplication.h"
using namespace std;

INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
{
ExampleApplication game;
try {
game.go();
} catch(Ogre::Exception& e) {

}  

}

ExampleApplication.h:初始化,(角色,摄像机)更新逻辑

#ifndef __ExampleApplication_H__
#define __ExampleApplication_H__
#include "Ogre.h"
#include "OgreConfigFile.h"
#include "ExampleFrameListener.h"
using namespace Ogre;

#define NUM_ANIMS 13 // number of animations the character has
#define CHAR_HEIGHT 5 // height of character's center of mass above ground
#define CAM_HEIGHT 2 // height of camera above character's center of mass
#define RUN_SPEED 17 // character running speed in units per second
#define TURN_SPEED 500.0f // character turning in degrees per second
#define ANIM_FADE_SPEED 7.5f // animation crossfade speed in % of full weight per second
#define JUMP_ACCEL 30.0f // character jump acceleration in upward units per squared second
#define GRAVITY 90.0f // gravity in downward units per squared second

class ExampleFrameListener;
class ExampleApplication
{
public:
ExampleApplication()
{
mFrameListener = 0;
mRoot = 0;
mResourcePath = "";
mConfigPath = mResourcePath;
}
virtual ~ExampleApplication()
{
if (mFrameListener)
delete mFrameListener;
if (mRoot)
OGRE_DELETE mRoot;

}  
virtual void go(void)  
{

    if (!setup())  
        return;  
    mRoot->startRendering();  
    destroyScene();  
}  
void update(Real deltaTime)  
{  
      updateBody(deltaTime);  
      updateAnimations(deltaTime);  
      updateCamera(deltaTime);  
}

ExampleFrameListener\* mFrameListener;

Root \*mRoot;  
Ogre::String mResourcePath;//资源路径  
Ogre::String mConfigPath;//配置文件路径

SceneManager\* mSceneMgr;//场景管理器  
RenderWindow\* mWindow;//渲染窗口  
Camera\* mCamera;//摄像机及相关节点  
SceneNode\* mCameraPivot;  
SceneNode\* mCameraGoal;  
SceneNode\* mCameraNode;  
Real mPivotPitch;

SceneNode\* mBodyNode;//角色节点  
Entity\* mBodyEnt;//角色实体

bool mSwordsDrawn;//角色武器  
RibbonTrail\* mSwordTrail;  
Entity\* mSword1;  
Entity\* mSword2;

//角色动画  
AnimationState\* mAnims\[NUM\_ANIMS\];    // master animation list  
bool mFadingIn\[NUM\_ANIMS\];            // which animations are fading in  
bool mFadingOut\[NUM\_ANIMS\];           // which animations are fading out  
enum AnimID  
{  
    ANIM\_IDLE\_BASE,  
    ANIM\_IDLE\_TOP,  
    ANIM\_RUN\_BASE,  
    ANIM\_RUN\_TOP,  
    ANIM\_HANDS\_CLOSED,  
    ANIM\_HANDS\_RELAXED,  
    ANIM\_DRAW\_SWORDS,  
    ANIM\_SLICE\_VERTICAL,  
    ANIM\_SLICE\_HORIZONTAL,  
    ANIM\_DANCE,  
    ANIM\_JUMP\_START,  
    ANIM\_JUMP\_LOOP,  
    ANIM\_JUMP\_END,  
    ANIM\_NONE  
};

Vector3 mKeyDirection;      // player's local intended direction based on WASD keys  
Vector3 mGoalDirection;     // actual intended direction in world-space  
Real mTimer;                // general timer to see how long animations have been playing  
AnimID mBaseAnimID;         // current base (full- or lower-body) animation  
AnimID mTopAnimID;          // current top (upper-body) animation  
Real mVerticalVelocity;     // for jumping

virtual bool setup(void)  
{  
    createRoot();//Step1----创建ROOT  
    bool carryOn = configure();//Step2----创建窗口(启动配置页面)  
    if (!carryOn)  
        return false;

    setupResources();//Step3----定位资源  
    loadResources();//Step4----导入资源,需要在窗口创建后?  
    TextureManager::getSingleton().setDefaultNumMipmaps(5);  
    createSceneManager();//Step5----创建(选择)场景管理器  
     setupCamera();//Step6----创建摄像机  
    createViewports();//Step7----创建视口  
    setupBody(mSceneMgr);//Step8----安装角色  
    setupAnimations();//Step9----安装角色动画  
    createFrameListener();//Step10----监听帧事件  
    return true;

}

void createRoot(void)  
{  
    String pluginsPath;  
    pluginsPath = mResourcePath + "plugins.cfg";  
    mRoot = OGRE\_NEW Root(pluginsPath,  
        mConfigPath + "ogre.cfg", mResourcePath + "Ogre.log");  
}  
virtual bool configure(void)  
{  
    if(mRoot->showConfigDialog())  
    {  
        mWindow = mRoot->initialise(true);  
        return true;  
    }  
    else  
    {  
        return false;  
    }  
}  
virtual void createSceneManager(void)  
{  
    mSceneMgr = mRoot->createSceneManager(ST\_GENERIC, "nafiosm");  
}  
virtual void createCamera(void)  
{  
    mCamera = mSceneMgr->createCamera("PlayerCam");  
    mCamera->setPosition(Vector3(0,200,500));  
    mCamera->lookAt(Vector3(0,0,-300));  
    mCamera->setNearClipDistance(5);

}  
virtual void createFrameListener(void)  
 {  
     mFrameListener= new ExampleFrameListener(this,mWindow);  
     mRoot->addFrameListener(mFrameListener);  
 }  
virtual void destroyScene(void)  
{

}  
virtual void createViewports(void)  
{  
    Viewport\* vp = mWindow->addViewport(mCamera);  
    vp->setBackgroundColour(ColourValue(0,0,0));  
    mCamera->setAspectRatio(  
        Real(vp->getActualWidth()) / Real(vp->getActualHeight()));

}  
virtual void setupResources(void)  
{  
    ConfigFile cf;  
cf.load(mResourcePath + "resources.cfg");  
    ConfigFile::SectionIterator seci = cf.getSectionIterator();

    String secName, typeName, archName;  
    while (seci.hasMoreElements())  
    {  
        secName = seci.peekNextKey();  
        ConfigFile::SettingsMultiMap \*settings = seci.getNext();  
        ConfigFile::SettingsMultiMap::iterator i;  
        for (i = settings->begin(); i != settings->end(); ++i)  
        {  
            typeName = i->first;  
            archName = i->second;

            ResourceGroupManager::getSingleton().addResourceLocation(  
                archName, typeName, secName);

        }  
    }  
}  
virtual void loadResources(void)  
{  
    ResourceGroupManager::getSingleton().initialiseAllResourceGroups();  
}  
void setupBody(SceneManager\* sceneMgr)  
{  
    // create main model  
    mBodyNode = sceneMgr->getRootSceneNode()->createChildSceneNode(Vector3::UNIT\_Y \* CHAR\_HEIGHT);  
    mBodyEnt = sceneMgr->createEntity("SinbadBody", "Sinbad.mesh");  
    mBodyNode->attachObject(mBodyEnt);

    Ogre::Light\* l = mSceneMgr->createLight("MainLight");  
    l->setPosition(20,80,50);  

    //创建地表  
    MeshManager::getSingleton().createPlane("floor", ResourceGroupManager::DEFAULT\_RESOURCE\_GROUP\_NAME,  
        Plane(Vector3::UNIT\_Y, 0), 100, 100, 10, 10, true, 1, 10, 10, Vector3::UNIT\_Z);  
    Entity\* floor = mSceneMgr->createEntity("Floor", "floor");  
    floor->setMaterialName("Examples/Rockwall");  
    floor->setCastShadows(false);  
    mSceneMgr->getRootSceneNode()->attachObject(floor);

    mKeyDirection = Vector3::ZERO;  
    mVerticalVelocity = 0;

}  
void setupCamera()  
{  
    mCamera = mSceneMgr->createCamera("PlayerCam");  
    mCameraPivot = mCamera->getSceneManager()->getRootSceneNode()->createChildSceneNode();

    mCameraGoal = mCameraPivot->createChildSceneNode(Vector3(0, 0, 15));  
    mCameraNode = mCamera->getSceneManager()->getRootSceneNode()->createChildSceneNode();  
    mCameraNode->setPosition(mCameraPivot->getPosition() + mCameraGoal->getPosition());

    mCameraPivot->setFixedYawAxis(true);  
    mCameraGoal->setFixedYawAxis(true);  
    mCameraNode->setFixedYawAxis(true);

    mCamera->setNearClipDistance(0.1);  
    mCamera->setFarClipDistance(100);  
    mCameraNode->attachObject(mCamera);

    mPivotPitch = 0;  
}  
void setupAnimations()  
{  
    //mBodyEnt->getSkeleton()->setBlendMode(ANIMBLEND\_CUMULATIVE);//nafio\_temp 为什么不能设置动画混合方式  
     String animNames\[\] =  
     {"IdleBase", "IdleTop", "RunBase", "RunTop", "HandsClosed", "HandsRelaxed", "DrawSwords",  
     "SliceVertical", "SliceHorizontal", "Dance", "JumpStart", "JumpLoop", "JumpEnd"};  
     // populate our animation list  
     for (int i = 0; i < NUM\_ANIMS; i++)  
     {  
         mAnims\[i\] = mBodyEnt->getAnimationState(animNames\[i\]);  
         mAnims\[i\]->setLoop(true);  
         mFadingIn\[i\] = false;  
         mFadingOut\[i\] = false;  
     }  
     setBaseAnimation(ANIM\_IDLE\_BASE);  
     setTopAnimation(ANIM\_IDLE\_TOP);

     mAnims\[ANIM\_HANDS\_RELAXED\]->setEnabled(true);

     mSwordsDrawn = false;  
}  
void setBaseAnimation(AnimID id, bool reset = false)  
{  
    if (mBaseAnimID >= 0 && mBaseAnimID < NUM\_ANIMS)  
    {  
        // if we have an old animation, fade it out  
        mFadingIn\[mBaseAnimID\] = false;  
        mFadingOut\[mBaseAnimID\] = true;  
    }

    mBaseAnimID = id;

    if (id != ANIM\_NONE)  
    {  
        // if we have a new animation, enable it and fade it in  
        mAnims\[id\]->setEnabled(true);  
        mAnims\[id\]->setWeight(0);  
        mFadingOut\[id\] = false;  
        mFadingIn\[id\] = true;  
        if (reset) mAnims\[id\]->setTimePosition(0);  
    }  
}  
void setTopAnimation(AnimID id, bool reset = false)  
{  
    if (mTopAnimID >= 0 && mTopAnimID < NUM\_ANIMS)  
    {  
        // if we have an old animation, fade it out  
        mFadingIn\[mTopAnimID\] = false;  
        mFadingOut\[mTopAnimID\] = true;  
    }

    mTopAnimID = id;

    if (id != ANIM\_NONE)  
    {  
        // if we have a new animation, enable it and fade it in  
        mAnims\[id\]->setEnabled(true);  
        mAnims\[id\]->setWeight(0);  
        mFadingOut\[id\] = false;  
        mFadingIn\[id\] = true;  
        if (reset) mAnims\[id\]->setTimePosition(0);  
    }  
}  
void updateCamera(Real deltaTime)  
{  
    // place the camera pivot roughly at the character's shoulder  
    mCameraPivot->setPosition(mBodyNode->getPosition() + Vector3::UNIT\_Y \* CAM\_HEIGHT);  
    // move the camera smoothly to the goal  
    Vector3 goalOffset = mCameraGoal->\_getDerivedPosition() - mCameraNode->getPosition();  
    mCameraNode->translate(goalOffset \* deltaTime \* 9.0f);  
    // always look at the pivot  
    mCameraNode->lookAt(mCameraPivot->\_getDerivedPosition(), Node::TS\_WORLD);  
}  
void updateBody(Real deltaTime)  
{  
    mGoalDirection = Vector3::ZERO;   // we will calculate this

    if (mKeyDirection != Vector3::ZERO && mBaseAnimID != ANIM\_DANCE)  
    {  
        // calculate actually goal direction in world based on player's key directions  
        mGoalDirection += mKeyDirection.z \* mCameraNode->getOrientation().zAxis();  
        mGoalDirection += mKeyDirection.x \* mCameraNode->getOrientation().xAxis();  
        mGoalDirection.y = 0;  
        mGoalDirection.normalise();

        Quaternion toGoal = mBodyNode->getOrientation().zAxis().getRotationTo(mGoalDirection);

        // calculate how much the character has to turn to face goal direction  
        Real yawToGoal = toGoal.getYaw().valueDegrees();  
        // this is how much the character CAN turn this frame  
        Real yawAtSpeed = yawToGoal / Math::Abs(yawToGoal) \* deltaTime \* TURN\_SPEED;  
        // reduce "turnability" if we're in midair  
        if (mBaseAnimID == ANIM\_JUMP\_LOOP) yawAtSpeed \*= 0.2f;

        // turn as much as we can, but not more than we need to  
        if (yawToGoal < 0) yawToGoal = std::min<Real>(0, std::max<Real>(yawToGoal, yawAtSpeed)); //yawToGoal = Math::Clamp<Real>(yawToGoal, yawAtSpeed, 0);  
        else if (yawToGoal > 0) yawToGoal = std::max<Real>(0, std::min<Real>(yawToGoal, yawAtSpeed)); //yawToGoal = Math::Clamp<Real>(yawToGoal, 0, yawAtSpeed);

        mBodyNode->yaw(Degree(yawToGoal));

        // move in current body direction (not the goal direction)  
         mBodyNode->translate(0, 0, deltaTime \* RUN\_SPEED \* mAnims\[mBaseAnimID\]->getWeight(),  
             Node::TS\_LOCAL);  
    }

    if (mBaseAnimID == ANIM\_JUMP\_LOOP)  
    {  
        // if we're jumping, add a vertical offset too, and apply gravity  
        mBodyNode->translate(0, mVerticalVelocity \* deltaTime, 0, Node::TS\_LOCAL);  
        mVerticalVelocity -= GRAVITY \* deltaTime;

        Vector3 pos = mBodyNode->getPosition();  
        if (pos.y <= CHAR\_HEIGHT)  
        {  
            // if we've hit the ground, change to landing state  
            pos.y = CHAR\_HEIGHT;  
            mBodyNode->setPosition(pos);  
            setBaseAnimation(ANIM\_JUMP\_END, true);  
            mTimer = 0;  
        }  
    }  
}  
void updateAnimations(Real deltaTime)  
{  
    Real baseAnimSpeed = 1;  
    Real topAnimSpeed = 1;

    mTimer += deltaTime;

    if (mTopAnimID == ANIM\_DRAW\_SWORDS)  
    {  
        // flip the draw swords animation if we need to put it back  
        topAnimSpeed = mSwordsDrawn ? -1 : 1;

        // half-way through the animation is when the hand grasps the handles...  
        if (mTimer >= mAnims\[mTopAnimID\]->getLength() / 2 &&  
            mTimer - deltaTime < mAnims\[mTopAnimID\]->getLength() / 2)  
        {  
            // so transfer the swords from the sheaths to the hands  
            mBodyEnt->detachAllObjectsFromBone();  
            mBodyEnt->attachObjectToBone(mSwordsDrawn ? "Sheath.L" : "Handle.L", mSword1);  
            mBodyEnt->attachObjectToBone(mSwordsDrawn ? "Sheath.R" : "Handle.R", mSword2);  
            // change the hand state to grab or let go  
            mAnims\[ANIM\_HANDS\_CLOSED\]->setEnabled(!mSwordsDrawn);  
            mAnims\[ANIM\_HANDS\_RELAXED\]->setEnabled(mSwordsDrawn);

            // toggle sword trails  
            if (mSwordsDrawn)  
            {  
                mSwordTrail->setVisible(false);  
                mSwordTrail->removeNode(mSword1->getParentNode());  
                mSwordTrail->removeNode(mSword2->getParentNode());  
            }  
            else  
            {  
                mSwordTrail->setVisible(true);  
                mSwordTrail->addNode(mSword1->getParentNode());  
                mSwordTrail->addNode(mSword2->getParentNode());  
            }  
        }

        if (mTimer >= mAnims\[mTopAnimID\]->getLength())  
        {  
            // animation is finished, so return to what we were doing before  
            if (mBaseAnimID == ANIM\_IDLE\_BASE) setTopAnimation(ANIM\_IDLE\_TOP);  
            else  
            {  
                setTopAnimation(ANIM\_RUN\_TOP);  
                mAnims\[ANIM\_RUN\_TOP\]->setTimePosition(mAnims\[ANIM\_RUN\_BASE\]->getTimePosition());  
            }  
            mSwordsDrawn = !mSwordsDrawn;  
        }  
    }  
    else if (mTopAnimID == ANIM\_SLICE\_VERTICAL || mTopAnimID == ANIM\_SLICE\_HORIZONTAL)  
    {  
        if (mTimer >= mAnims\[mTopAnimID\]->getLength())  
        {  
            // animation is finished, so return to what we were doing before  
            if (mBaseAnimID == ANIM\_IDLE\_BASE) setTopAnimation(ANIM\_IDLE\_TOP);  
            else  
            {  
                setTopAnimation(ANIM\_RUN\_TOP);  
                mAnims\[ANIM\_RUN\_TOP\]->setTimePosition(mAnims\[ANIM\_RUN\_BASE\]->getTimePosition());  
            }  
        }

        // don't sway hips from side to side when slicing. that's just embarrassing.  
        if (mBaseAnimID == ANIM\_IDLE\_BASE) baseAnimSpeed = 0;  
    }  
    else if (mBaseAnimID == ANIM\_JUMP\_START)  
    {  
        if (mTimer >= mAnims\[mBaseAnimID\]->getLength())  
        {  
            // takeoff animation finished, so time to leave the ground!  
            setBaseAnimation(ANIM\_JUMP\_LOOP, true);  
            // apply a jump acceleration to the character  
            mVerticalVelocity = JUMP\_ACCEL;  
        }  
    }  
    else if (mBaseAnimID == ANIM\_JUMP\_END)  
    {  
        if (mTimer >= mAnims\[mBaseAnimID\]->getLength())  
        {  
            // safely landed, so go back to running or idling  
            if (mKeyDirection == Vector3::ZERO)  
            {  
                setBaseAnimation(ANIM\_IDLE\_BASE);  
                setTopAnimation(ANIM\_IDLE\_TOP);  
            }  
            else  
            {  
                setBaseAnimation(ANIM\_RUN\_BASE, true);  
                setTopAnimation(ANIM\_RUN\_TOP, true);  
            }  
        }  
    }

    // increment the current base and top animation times  
    if (mBaseAnimID != ANIM\_NONE) mAnims\[mBaseAnimID\]->addTime(deltaTime \* baseAnimSpeed);  
    if (mTopAnimID != ANIM\_NONE) mAnims\[mTopAnimID\]->addTime(deltaTime \* topAnimSpeed);

    // apply smooth transitioning between our animations  
    fadeAnimations(deltaTime);  
}  
void fadeAnimations(Real deltaTime)  
{  
    for (int i = 0; i < NUM\_ANIMS; i++)  
    {  
        if (mFadingIn\[i\])  
        {  
            // slowly fade this animation in until it has full weight  
            Real newWeight = mAnims\[i\]->getWeight() + deltaTime \* ANIM\_FADE\_SPEED;  
            mAnims\[i\]->setWeight(Math::Clamp<Real>(newWeight, 0, 1));  
            if (newWeight >= 1) mFadingIn\[i\] = false;  
        }  
        else if (mFadingOut\[i\])  
        {  
            // slowly fade this animation out until it has no weight, and then disable it  
            Real newWeight = mAnims\[i\]->getWeight() - deltaTime \* ANIM\_FADE\_SPEED;  
            mAnims\[i\]->setWeight(Math::Clamp<Real>(newWeight, 0, 1));  
            if (newWeight <= 0)  
            {  
                mAnims\[i\]->setEnabled(false);  
                mFadingOut\[i\] = false;  
            }  
        }  
    }  
}

//----按键,鼠标事件处理
void injectKeyDown(const OIS::KeyEvent& evt)
{
if (evt.key == OIS::KC_Q && (mTopAnimID == ANIM_IDLE_TOP || mTopAnimID == ANIM_RUN_TOP))
{
// take swords out (or put them back, since it's the same animation but reversed)
setTopAnimation(ANIM_DRAW_SWORDS, true);
mTimer = 0;
}
else if (evt.key == OIS::KC_E && !mSwordsDrawn)
{
if (mTopAnimID == ANIM_IDLE_TOP || mTopAnimID == ANIM_RUN_TOP)
{
// start dancing
setBaseAnimation(ANIM_DANCE, true);
setTopAnimation(ANIM_NONE);
// disable hand animation because the dance controls hands
mAnims[ANIM_HANDS_RELAXED]->setEnabled(false);
}
else if (mBaseAnimID == ANIM_DANCE)
{
// stop dancing
setBaseAnimation(ANIM_IDLE_BASE);
setTopAnimation(ANIM_IDLE_TOP);
// re-enable hand animation
mAnims[ANIM_HANDS_RELAXED]->setEnabled(true);
}
}

    // keep track of the player's intended direction  
    else if (evt.key == OIS::KC\_W) mKeyDirection.z = -1;  
    else if (evt.key == OIS::KC\_A) mKeyDirection.x = -1;  
    else if (evt.key == OIS::KC\_S) mKeyDirection.z = 1;  
    else if (evt.key == OIS::KC\_D) mKeyDirection.x = 1;

    else if (evt.key == OIS::KC\_SPACE && (mTopAnimID == ANIM\_IDLE\_TOP || mTopAnimID == ANIM\_RUN\_TOP))  
    {  
        // jump if on ground  
        setBaseAnimation(ANIM\_JUMP\_START, true);  
        setTopAnimation(ANIM\_NONE);  
        mTimer = 0;  
    }

    if (!mKeyDirection.isZeroLength() && mBaseAnimID == ANIM\_IDLE\_BASE)  
    {  
        // start running if not already moving and the player wants to move  
        setBaseAnimation(ANIM\_RUN\_BASE, true);  
        if (mTopAnimID == ANIM\_IDLE\_TOP) setTopAnimation(ANIM\_RUN\_TOP, true);  
    }  
}  
void injectKeyUp(const OIS::KeyEvent& evt)  
{  
    // keep track of the player's intended direction  
    if (evt.key == OIS::KC\_W && mKeyDirection.z == -1) mKeyDirection.z = 0;  
    else if (evt.key == OIS::KC\_A && mKeyDirection.x == -1) mKeyDirection.x = 0;  
    else if (evt.key == OIS::KC\_S && mKeyDirection.z == 1) mKeyDirection.z = 0;  
    else if (evt.key == OIS::KC\_D && mKeyDirection.x == 1) mKeyDirection.x = 0;

    if (mKeyDirection.isZeroLength() && mBaseAnimID == ANIM\_RUN\_BASE)  
    {  
        // stop running if already moving and the player doesn't want to move  
        setBaseAnimation(ANIM\_IDLE\_BASE);  
        if (mTopAnimID == ANIM\_RUN\_TOP) setTopAnimation(ANIM\_IDLE\_TOP);  
    }  
}  
void injectMouseMove(const OIS::MouseEvent& evt)  
{  
    // update camera goal based on mouse movement  
    updateCameraGoal(-0.05f \* evt.state.X.rel, -0.05f \* evt.state.Y.rel, -0.0005f \* evt.state.Z.rel);  
}  
void injectMouseDown(const OIS::MouseEvent& evt, OIS::MouseButtonID id)  
{  
    if (mSwordsDrawn && (mTopAnimID == ANIM\_IDLE\_TOP || mTopAnimID == ANIM\_RUN\_TOP))  
    {  
        // if swords are out, and character's not doing something weird, then SLICE!  
        if (id == OIS::MB\_Left) setTopAnimation(ANIM\_SLICE\_VERTICAL, true);  
        else if (id == OIS::MB\_Right) setTopAnimation(ANIM\_SLICE\_HORIZONTAL, true);  
        mTimer = 0;  
    }  
}

private:
void updateCameraGoal(Real deltaYaw, Real deltaPitch, Real deltaZoom)
{
mCameraPivot->yaw(Degree(deltaYaw), Node::TS_WORLD);

    // bound the pitch  
    if (!(mPivotPitch + deltaPitch > 25 && deltaPitch > 0) &&  
        !(mPivotPitch + deltaPitch < -60 && deltaPitch < 0))  
    {  
        mCameraPivot->pitch(Degree(deltaPitch), Node::TS\_LOCAL);  
        mPivotPitch += deltaPitch;  
    }

    Real dist = mCameraGoal->\_getDerivedPosition().distance(mCameraPivot->\_getDerivedPosition());  
    Real distChange = deltaZoom \* dist;

    // bound the zoom  
    if (!(dist + distChange < 8 && distChange < 0) &&  
        !(dist + distChange > 25 && distChange > 0))  
    {  
        mCameraGoal->translate(0, 0, distChange, Node::TS\_LOCAL);  
    }  
}  

};

#endif

ExampleFrameListener.h:帧事件,输入事件监听

#ifndef __ExampleFrameListener_H__
#define __ExampleFrameListener_H__

#include "Ogre.h"
#include "OgreStringConverter.h"
#include "OgreException.h"

#define OIS_DYNAMIC_LIB
#include
using namespace Ogre;

class ExampleApplication;

class ExampleFrameListener: public FrameListener, public WindowEventListener,public OIS::KeyListener,
public OIS::MouseListener
{
protected:

public:

ExampleApplication \*eapp;

//渲染窗体,输入设备需要  
RenderWindow\* mWindow;

//输入设备  
OIS::InputManager\* mInputManager;  
OIS::Mouse\*    mMouse;  
OIS::Keyboard\* mKeyboard;

ExampleFrameListener(ExampleApplication \*ea,RenderWindow\* win, bool bufferedKeys = false, bool bufferedMouse = false,  
             bool bufferedJoy = false ) :  
    mWindow(win),

    mInputManager(0), mMouse(0), mKeyboard(0)  
{  
    eapp = ea;  
    LogManager::getSingletonPtr()->logMessage("\*\*\* Initializing OIS \*\*\*");  
    setupInput();  
    WindowEventUtilities::addWindowEventListener(mWindow, this);  
}  
virtual ~ExampleFrameListener()  
{  
    WindowEventUtilities::removeWindowEventListener(mWindow, this);  
    windowClosed(mWindow);  
}

//帧事件  
bool frameRenderingQueued(const FrameEvent& evt);  
bool frameStarted(const FrameEvent& evt)  
{  
    mKeyboard->capture();  
    mMouse->capture();  
    return true;  
}  
bool frameEnded(const FrameEvent& evt)  
{  
    return true;  
}

//窗口事件  
virtual void windowResized(Ogre::RenderWindow\* rw)  
{  
    const OIS::MouseState& ms = mMouse->getMouseState();  
    ms.width = rw->getWidth();  
    ms.height = rw->getHeight();  
}  
virtual void windowClosed(RenderWindow\* rw)  
{  
    if( rw == mWindow )  
    {  
        if( mInputManager )  
        {  
            mInputManager->destroyInputObject( mMouse );  
            mInputManager->destroyInputObject( mKeyboard );  
            OIS::InputManager::destroyInputSystem(mInputManager);  
            mInputManager = 0;  
        }  
    }  
}

//安装输入  
virtual void setupInput(bool nograb = false)  
{  
    OIS::ParamList pl;  
    size\_t winHandle = 0;  
    std::ostringstream winHandleStr;

    mWindow->getCustomAttribute("WINDOW", &winHandle);  
    winHandleStr << winHandle;  
    pl.insert(std::make\_pair("WINDOW", winHandleStr.str()));

    if (nograb)  
    {  
        pl.insert(std::make\_pair("x11\_keyboard\_grab", "false"));  
        pl.insert(std::make\_pair("x11\_mouse\_grab", "false"));  
        pl.insert(std::make\_pair("w32\_mouse", "DISCL\_FOREGROUND"));  
        pl.insert(std::make\_pair("w32\_mouse", "DISCL\_NONEXCLUSIVE"));  
        pl.insert(std::make\_pair("w32\_keyboard", "DISCL\_FOREGROUND"));  
        pl.insert(std::make\_pair("w32\_keyboard", "DISCL\_NONEXCLUSIVE"));  
    }

    mInputManager = OIS::InputManager::createInputSystem(pl);

    createInputDevices();      // create the specific input devices

    mMouse->setEventCallback(this);  
    mKeyboard->setEventCallback(this);

    windowResized(mWindow);    // do an initial adjustment of mouse area

}

//按键事件  
virtual bool keyPressed(const OIS::KeyEvent& evt);  
virtual bool keyReleased(const OIS::KeyEvent& evt);  
virtual bool mouseMoved(const OIS::MouseEvent& evt);  
virtual bool mousePressed(const OIS::MouseEvent& evt, OIS::MouseButtonID id);  
virtual bool mouseReleased(const OIS::MouseEvent& evt, OIS::MouseButtonID id)  
{  
    //if (mCurrentSample && !mSamplePaused) return mCurrentSample->mouseReleased(evt, id);  
    return true;  
}

protected:

private:
virtual void createInputDevices()
{
OIS::Object* obj = mInputManager->createInputObject(OIS::OISKeyboard, true);
mKeyboard = static_cast(obj);
mMouse = static_cast(mInputManager->createInputObject(OIS::OISMouse, true));

    mKeyboard->setEventCallback(this);

    mMouse->setEventCallback(this);

}

};

#endif

ExampleFrameListener.cpp

#include "StdAfx.h"
#include "ExampleApplication.h"

bool ExampleFrameListener::frameRenderingQueued(const FrameEvent& evt)
{
if(mWindow->isClosed()) return false;
eapp->update(evt.timeSinceLastFrame);
return true;
}

bool ExampleFrameListener::keyPressed(const OIS::KeyEvent& evt)
{
eapp->injectKeyDown(evt);
return true;
}

bool ExampleFrameListener::keyReleased(const OIS::KeyEvent& evt)
{
eapp->injectKeyUp(evt);
return true;
}

bool ExampleFrameListener::mouseMoved(const OIS::MouseEvent& evt)
{
eapp->injectMouseMove(evt);
return true;
}

bool ExampleFrameListener::mousePressed(const OIS::MouseEvent& evt, OIS::MouseButtonID id)
{
eapp->injectMouseDown(evt,id);
return true;
}

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章