Ogre中的動(dòng)畫(huà)混合(AnimationBlender)_第1頁(yè)
Ogre中的動(dòng)畫(huà)混合(AnimationBlender)_第2頁(yè)
Ogre中的動(dòng)畫(huà)混合(AnimationBlender)_第3頁(yè)
Ogre中的動(dòng)畫(huà)混合(AnimationBlender)_第4頁(yè)
Ogre中的動(dòng)畫(huà)混合(AnimationBlender)_第5頁(yè)
已閱讀5頁(yè),還剩3頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、Ogre中的動(dòng)畫(huà)混合(AnimationBlender) 網(wǎng)上Ogre的中文資料真的是很少啊,把自己學(xué)到的分享出來(lái),希望能對(duì)初學(xué)者有所幫助。Ogre中實(shí)現(xiàn)骨骼動(dòng)畫(huà)真的是再簡(jiǎn)單不過(guò)了,就兩個(gè)函數(shù):getAnimationState,addTime。OK,人物就可以動(dòng)起來(lái)了。這個(gè)AnimationBlender類可以實(shí)現(xiàn)以多種方式從一個(gè)動(dòng)畫(huà)淡入到另一個(gè)動(dòng)畫(huà),來(lái)自于Ogre網(wǎng)站上的一篇文章。但那位老外只貼出了代碼,沒(méi)有講解,甚至代碼中也沒(méi)有詳盡的注釋,像我這樣的菜鳥(niǎo)就只能慢慢品味了。下面是AnimationBlender類的定義:#pragma once#ifndef AnimationB

2、lender_Incl#define AnimationBlender_Incl#include <Ogre.h>using namespace Ogre;class AnimationBlenderpublic: enum BlendingTransition  /不同的混合方式   BlendSwitch,         / 直接切換到目標(biāo)動(dòng)畫(huà)  BlendWhileAnimating,   / 交

3、叉淡入淡出(源動(dòng)畫(huà)比例縮小,同時(shí)目標(biāo)動(dòng)畫(huà)比例增大)  BlendThenAnimate      / 淡出源動(dòng)畫(huà)到目標(biāo)動(dòng)畫(huà)第一幀,然后開(kāi)始目標(biāo)動(dòng)畫(huà)  private: Entity *mEntity; AnimationState *mSource; AnimationState *mTarget; BlendingTransition mTransition; bool loop; /是否循環(huán) AnimationBlender() public: 

4、60;Real mTimeleft, mDuration; /持續(xù)時(shí)間 bool complete; void blend( const String &animation, BlendingTransition transition, Real duration, bool l ); void addTime( Real ); Real getProgress() return mTimeleft/ mDuration;  AnimationState *getSource() return mSource;  A

5、nimationState *getTarget() return mTarget;  AnimationBlender( Entity *); void init( const String &animation );#endif這里定義了幾種混合方式,所產(chǎn)生的不同效果運(yùn)行后就能看到了。構(gòu)造函數(shù)接受一個(gè)Entity的指針,以后我們就可以操作這個(gè)Entity中的Animation了。AnimationBlender類的實(shí)現(xiàn):#include "AnimationBlender.h"void AnimationBlender:init(const

6、String &animation) /初始化所有動(dòng)作的AnimationState AnimationStateSet *set = mEntity->getAllAnimationStates(); AnimationStateIterator it = set->getAnimationStateIterator(); while(it.hasMoreElements()   AnimationState *anim = it.getNext();  anim->setEn

7、abled(false);  anim->setWeight(0);  anim->setTimePosition(0);  /初始化mSource mSource = mEntity->getAnimationState( animation ); mSource->setEnabled(true); mSource->setWeight(1); mTimeleft = 0; mDuration = 1; mTarget = 0; c

8、omplete=false; void AnimationBlender:blend( const String &animation, BlendingTransition transition, Real duration, bool l ) loop=l; /設(shè)置是否需要循環(huán) if( transition = AnimationBlender:BlendSwitch ) /如果混合方式為直接切換,改變mSource 即可  if( mSource != 0 )   mSource->s

9、etEnabled(false);  mSource = mEntity->getAnimationState( animation );  mSource->setEnabled(true);  mSource->setWeight(1);  mSource->setTimePosition(0);  mTimeleft = 0;   else     /先取得新的動(dòng)畫(huà)狀態(tài)  AnimationSta

10、te *newTarget = mEntity->getAnimationState( animation );  if( mTimeleft > 0 ) /前一次的混合尚未結(jié)束     if( newTarget = mTarget )       / 新的目標(biāo)就是正在混合中的目標(biāo),什么也不做      else if( newTarget = mSource ) 

11、0;     / 新的目標(biāo)是源動(dòng)畫(huà),直接go back    mSource = mTarget;    mTarget = newTarget;    mTimeleft = mDuration - mTimeleft;       else       / 現(xiàn)在newTarget是真的新的動(dòng)畫(huà)了

12、    if( mTimeleft < mDuration * 0.5 ) /上一次的混合進(jìn)度還未超過(guò)一半         / 簡(jiǎn)單替換Target就行了     mTarget->setEnabled(false);     mTarget->setWeight(0);      

13、;  else /如果已經(jīng)過(guò)半,舊的target成為新的source              mSource->setEnabled(false);     mSource->setWeight(0);     mSource = mTarget;      

14、60;  mTarget = newTarget;    mTarget->setEnabled(true);    mTarget->setWeight( 1.0 - mTimeleft / mDuration );    mTarget->setTimePosition(0);       else /上次的混合已經(jīng)結(jié)束,當(dāng)前未處于混合狀態(tài)中 &

15、#160;   mTransition = transition;   mTimeleft = mDuration = duration;   mTarget = newTarget;   mTarget->setEnabled(true);   mTarget->setWeight(0);   mTarget->setTimePosition(0);   void A

16、nimationBlender:addTime( Real time ) if( mSource != 0 ) /若無(wú)AnimationState則不進(jìn)行操作   if( mTimeleft > 0 ) /兩個(gè)動(dòng)畫(huà)仍在混合過(guò)程中     mTimeleft -= time;    if( mTimeleft < 0 )       / 混合完畢,切換到目標(biāo)動(dòng)畫(huà)

17、60;   mSource->setEnabled(false);    mSource->setWeight(0);    mSource = mTarget;    mSource->setEnabled(true);    mSource->setWeight(1);    mTarget = 0;   &#

18、160;  else       / 仍然處于混合狀態(tài)中,改變兩個(gè)動(dòng)畫(huà)的權(quán)值    mSource->setWeight(mTimeleft / mDuration);    mTarget->setWeight(1.0 - mTimeleft / mDuration);    /在這種混合方式下,需要為目標(biāo)動(dòng)畫(huà)增加時(shí)間    if(m

19、Transition = AnimationBlender:BlendWhileAnimating)     mTarget->addTime(time);       if (mSource->getTimePosition() >= mSource->getLength()     complete=true;    else   

20、;  complete=false;    mSource->addTime(time);  mSource->setLoop(loop); AnimationBlender:AnimationBlender( Entity *entity ) : mEntity(entity)來(lái)試著用一下這個(gè)AnimationBlender類先聲明一個(gè)全局的blender實(shí)例AnimationBlender * blender;在createScene中我們來(lái)初始化它/實(shí)例化一個(gè)blender并將Entit

21、y傳入blender=new AnimationBlender(ninjaHead);/設(shè)置一個(gè)初始動(dòng)作blender->init("Idle1");在frameStarted中為blender加時(shí)間blender->addTime(evt.timeSinceLastFrame);現(xiàn)在ninja已經(jīng)可以動(dòng)起來(lái)了。然后我們用鍵盤(pán)來(lái)控制動(dòng)畫(huà):在FrameListener中覆蓋父類的鍵盤(pán)輸入函數(shù)virtual bool processUnbufferedKeyInput(const FrameEvent& evt)  if (mInputD

22、evice->isKeyDown(KC_T)     blender->blend("Attack1",AnimationBlender:BlendWhileAnimating,1.0,false);    if (mInputDevice->isKeyDown(KC_J)     blender->blend("Jump",AnimationBlender:BlendWhileAnimati

23、ng,1.0,false);    if (mInputDevice->isKeyDown(KC_I)     blender->blend("Idle1",AnimationBlender:BlendWhileAnimating,1.0,false);    /記得調(diào)用父類的鍵盤(pán)處理,以使WASD仍然可用  return ExampleFrameListener:processUnbufferedKeyInput

24、(evt);可以看到效果了,你還可以試一下別的混合方式。完整代碼如下:#ifndef _AnimBlender_h_#define _AnimBlender_h_#include "ExampleApplication.h"#include ".AnimationBlender.h"AnimationBlender * blender;class AnimBlenderFrameListener : public ExampleFrameListenerprivate: SceneManager* mSceneMgr;public: 

25、AnimBlenderFrameListener(SceneManager *sceneMgr, RenderWindow* win, Camera* cam)  : ExampleFrameListener(win, cam),  mSceneMgr(sceneMgr)   bool frameStarted(const FrameEvent& evt)   bool ret = ExampleFrameListener:frameStarted(evt);  bl

26、ender->addTime(evt.timeSinceLastFrame);    return ret;  /覆蓋父類的鍵盤(pán)輸入函數(shù) virtual bool processUnbufferedKeyInput(const FrameEvent& evt)   if (mInputDevice->isKeyDown(KC_T)     blender->blend("Attack1",Animat

27、ionBlender:BlendWhileAnimating,1.0,false);    if (mInputDevice->isKeyDown(KC_J)     blender->blend("Jump",AnimationBlender:BlendWhileAnimating,1.0,false);    if (mInputDevice->isKeyDown(KC_I)    &

28、#160;blender->blend("Idle1",AnimationBlender:BlendWhileAnimating,1.0,false);    /記得調(diào)用父類的鍵盤(pán)處理,以使WASD仍然可用  return ExampleFrameListener:processUnbufferedKeyInput(evt);  class AnimBlenderApp : public ExampleApplicationpublic: AnimBlenderApp()

29、0; AnimBlenderApp()  protected: virtual void createCamera(void)   / Create the camera  mCamera = mSceneMgr->createCamera("PlayerCam");  / Position it at 500 in Z direction  mCamera->setPosition(Vector3(0,0,180);  / Look back along -Z  mCamera->lookAt(Vector3(0,0,-300);  mCamera->setNearClipDistance(5);   / Just override the mandatory create scene method virtual void crea

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論