模型動畫:簡單人物動畫
實作簡單的人物動畫:
1、 設定動畫狀态:AnimationState
Ogre::AnimationState* _aniState;
2、 擷取模型實體的動畫效果:getAnimationState
_aniState = mEntity->getAnimationState(“Dance”);//以Sinbad模型為例,其含有Dance動作,mEntity為Entity類型
3、 動畫效果開啟:setEnabled
_aniState->setEnabled(true);//開啟
//也可添加動作循環執行
_aniState->setLoop(true);
4、 添加動畫執行時間:addTime
在frameStarted()中添加事件:_aniState->addTime(evt.timeSinceLastFrame);
動畫的運動時間:evt.timeSinceLastFrame是指自上一幀到現在過去的時間,如果我們将其*0.1,則表示動畫運動的時間變少,其會放慢執行,即實作了慢動作。
代碼:(代碼是不斷添加的,它會包含上面章節的内容,要看注釋以确定代碼位置及作用)
#include "ExampleApplication.h"
using namespace Ogre;
class MyFrameListener : public Ogre::FrameListener
{
private:
SceneNode*mNode;
Entity*_ent;
AnimationState*_aniState;
OIS::InputManager*_man;
OIS::Keyboard*_key;
OIS::Mouse*_mouse;
Camera*_Camera;
PolygonMode_PolyMode;
Timer _timer;
public:
MyFrameListener(SceneNode*node, RenderWindow* win, Camera* cam, Entity* ent)
{
mNode= node;
_Camera= cam;
_ent= ent;
size_twindowHnd = 0;
std::stringstreamwindowHndStr;
win->getCustomAttribute("WINDOW",&windowHnd);
windowHndStr<< windowHnd;//類型轉換
//建立輸入系統
OIS::ParamListpl;
pl.insert(std::make_pair(std::string("WINDOW"),windowHndStr.str()));
_man= OIS::InputManager::createInputSystem(pl);
_key= static_cast<OIS::Keyboard*>(_man->createInputObject(OIS::OISKeyboard,false));
_mouse= static_cast<OIS::Mouse*>(_man->createInputObject(OIS::OISMouse, false));
//設定渲染模式
_PolyMode= Ogre::PolygonMode::PM_SOLID;
//計時器
_timer.reset();
//添加動畫
addAnimation(_ent);
}
~MyFrameListener()
{
_man->destroyInputObject(_key);//銷毀鍵盤
_man->destroyInputObject(_mouse);//銷毀滑鼠
OIS::InputManager::destroyInputSystem(_man);
}
void changePolygonMode(OIS::KeyCodekeynum = OIS::KC_R)
{
if(_key->isKeyDown(keynum) && _timer.getMilliseconds() > 250)//大于0.25秒
{
_timer.reset();
switch(_PolyMode)
{
casePM_SOLID: _PolyMode = Ogre::PolygonMode::PM_WIREFRAME;
break;
casePM_WIREFRAME: _PolyMode = Ogre::PolygonMode::PM_POINTS;
break;
casePM_POINTS: _PolyMode = Ogre::PolygonMode::PM_SOLID;
break;
default:
break;
}
}
_Camera->setPolygonMode(_PolyMode);
}
void addAnimation(Entity*ent)
{
_aniState= ent->getAnimationState("Dance");
_aniState->setEnabled(true);
_aniState->setLoop(true);
}
bool frameStarted(constOgre::FrameEvent &evt)
{
_key->capture();
_mouse->capture();
//Mousestate
floatrotX = _mouse->getMouseState().X.rel * evt.timeSinceLastFrame * -1;
floatrotY = _mouse->getMouseState().Y.rel * evt.timeSinceLastFrame * -1;
//changethe Camera position
_Camera->yaw(Ogre::Radian(rotX));
_Camera->pitch(Ogre::Radian(rotY));
//_Camera->moveRelative(Vector3(10,0,0)* evt.timeSinceLastFrame * 10);
if(_key->isKeyDown(OIS::KC_ESCAPE))
{
returnfalse;
}
//改變渲染模式
changePolygonMode();
//模型節點更新位置
//mNode->translate(Vector3(10,0,0)* evt.timeSinceLastFrame);
//動畫
_aniState->addTime(evt.timeSinceLastFrame);
returntrue;
}
};
class example1 : public ExampleApplication
{
public:
example1()
{
mFrameListener= NULL;
}
~example1()
{
if(mFrameListener)
{
deletemFrameListener;
}
}
protected:
void createScene()
{
//add a plane
Planeplane(Vector3::UNIT_Y, -10);
Ogre::MeshManager::getSingleton().createPlane("plane",ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, 1500, 1500, 200,200, true,1, 5,5,Vector3::UNIT_Z);
Entity*ent = mSceneMgr->createEntity("LightPlaneEntity","plane");
mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent);
ent->setMaterialName("Examples/BeachStones");
//adda light
Light*light = mSceneMgr->createLight("Light1");
light->setType(Ogre::Light::LT_DIRECTIONAL);
light->setDirection(Vector3(1,-1,0));
//addModel
SceneNode*node = mSceneMgr->createSceneNode("Node1");
mSceneMgr->getRootSceneNode()->addChild(node);
mSinbad= mSceneMgr->createEntity("Sinbad", "Sinbad.mesh");
mSinbadNode= node->createChildSceneNode("SinbadNode");
mSinbadNode->setScale(3.0f,3.0f,3.0f);
mSinbadNode->setPosition(Vector3(0,4.0f,0));
mSinbadNode->attachObject(mSinbad);
//addShadow
mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_ADDITIVE);
}
void createCamera()
{
mCamera= mSceneMgr->createCamera("MyCamera1");
mCamera->setPosition(0,100,200);
mCamera->lookAt(0,0,0);
mCamera->setNearClipDistance(5);
}
void createFrameListener()
{
mFrameListener= new MyFrameListener(mSinbadNode, mWindow, mCamera, mSinbad);
mRoot->addFrameListener(mFrameListener);
}
private:
Entity*mSinbad;
SceneNode*mSinbadNode;
FrameListener*mFrameListener;
};
int main()
{
example1ex1;
ex1.go();
return 0;
}