zoukankan      html  css  js  c++  java
  • Ogre 简易角色Demo

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

    遗留一个问题

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


    3个类

    NMain.cpp:入口类

    #include "stdafx.h"
    #include <iostream>
    #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 <OIS/OIS.h>
    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<OIS::Keyboard*>(obj);
    		mMouse = static_cast<OIS::Mouse*>(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;
    }




  • 相关阅读:
    js回车键事件
    legend3---15、像粉丝数、关注数、课程数等数量数据如何处理
    Jquery.Data()和HTML标签的data-*属性
    php判断两个数组是否相等
    安卓Android控件ListView获取item中EditText值
    ubuntu安装和查看已安装
    Remove “System Program Problem Detected” Messages From Ubuntu
    Genymotion
    Genymotion中文手册
    sudo apt-get install lib32stdc++6
  • 原文地址:https://www.cnblogs.com/nafio/p/9137685.html
Copyright © 2011-2022 走看看