青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

posts - 311, comments - 0, trackbacks - 0, articles - 0
  C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

英文原文: http://test.ogitor.org/tiki/AnimationBlender

動畫混合 -- 實現兩個動畫的切換, 一個動畫逐漸消逝, 另一個動畫逐漸顯示來實現. 主要通過動畫狀態的權重來實現
通過三種方式來實現兩個動畫的混合:
    - BlendSwitch - 直接切換至目標動畫
    - BlendWhileAnimating - 混合的過程中目標動畫也更新幀, 實現動畫
    - BlendThenAnimate - 用源動畫的當前幀混合目標動畫的第一個幀

源碼理解, 主要代碼位于下面兩個函數
AnimationBlender::blend函數 根據傳入的參數設置新轉換的源動畫和目標動畫
AnimationBlender::add函數則更新源動畫和目標動畫(如存在)的狀態和權重

AnimationBlender::blend函數
1. 如果動畫轉換類型為 AnimationBlender::BlendSwitch
    直接將源動畫轉換成目標動畫
2. 如果不是這個轉換類型 AnimationBlender::BlendSwitch
    如果上次的動畫轉換還未完成
        如果新的目標動畫等于上次轉換的源動畫
            則反向轉換
        如果新的目標動畫不等于上次轉換的源動畫和目標動畫
            根據上次轉換的剩余時間設置是顯示上次轉換的源動畫還是目標動畫, 并將其設置為新轉換的源動畫
            顯示新轉換的目標動畫, 并設置其權重
    假設上次的動畫轉換已經完成了轉換
        設置轉換時間, 轉換類型, 目標動畫和其權重

AnimationBlender::addTime 函數
1. 如有動畫在運行
    如果存在轉換
        更新剩余時間
            如剩余時間小于0
                禁止源動畫
                將目標動畫設置為源動畫, 繼續運行
            如剩余時間不小于0
                更新源動畫和目標動畫的權重
                如轉換類型為AnimationBlender::BlendWhileAnimating
                    更新目標動畫
    判斷動畫是否完成
        更新源動畫

完整代碼和Demo代碼

AnimationBlender.h

 

#ifndef __ANIMATION_BLENDER_H__   
#define __ANIMATION_BLENDER_H__   
#include 
<Ogre.h>   
using namespace Ogre;   
class AnimationBlender   
{   
public:   
    
enum BlendingTransition   
    {   
        BlendSwitch,         
// stop source and start dest   
        BlendWhileAnimating,   // cross fade, blend source animation out while blending destination animation in   
        BlendThenAnimate      // blend source to first frame of dest, when done, start dest anim   
    };   
private:   
    Entity 
*mEntity;   
    AnimationState 
*mSource;   
    AnimationState 
*mTarget;   
    BlendingTransition mTransition;   
    
bool loop;   
    
~AnimationBlender() {}   
public:    
    Real mTimeleft, mDuration;   
    
bool complete;   
    
void blend( const String &animation, BlendingTransition transition, Real duration, bool l=true );   
    
void addTime( Real );   
    Real getProgress() { 
return mTimeleft/ mDuration; }   
    AnimationState 
*getSource() { return mSource; }   
    AnimationState 
*getTarget() { return mTarget; }   
    AnimationBlender( Entity 
*);   
    
void init( const String &animation, bool l=true );   
};   
#endif 

AnimationBlender.cpp

#include "AnimationBlender.h"   
void AnimationBlender::init(const String &animation, bool l)   
{   
    
// 初始化, 將所有的動畫禁止, 只允許參數中的動畫運行.   
    AnimationStateSet *set = mEntity->getAllAnimationStates();   
    AnimationStateIterator it 
= set->getAnimationStateIterator();   
    
while(it.hasMoreElements())   
    {   
        AnimationState 
*anim = it.getNext();   
        anim
->setEnabled(false);   
        anim
->setWeight(0);   
        anim
->setTimePosition(0);   
    }   
    mSource 
= mEntity->getAnimationState( animation );   
    mSource
->setEnabled(true);   
    mSource
->setWeight(1);   
    mTimeleft 
= 0;   
    mDuration 
= 1;   
    mTarget 
= 0;   
    complete 
= false;   
    loop 
= l;   
}    
void AnimationBlender::blend( const String &animation, BlendingTransition transition, Real duration, bool l )   
{   
    loop 
= l;   
    
if( transition == AnimationBlender::BlendSwitch )   
    {   
        
if( mSource != 0 )   
            mSource
->setEnabled(false);   
        mSource 
= mEntity->getAnimationState( animation );   
        mSource
->setEnabled(true);   
        mSource
->setWeight(1);   
        mSource
->setTimePosition(0);   
        mTimeleft 
= 0;   
    }    
    
else    
    {    
        AnimationState 
*newTarget = mEntity->getAnimationState( animation );   
        
if( mTimeleft > 0 )   
        {   
            
// oops, weren't finished yet   
            if( newTarget == mTarget )   
            {   
                
// nothing to do! (ignoring duration here)   
            }   
            
else if( newTarget == mSource )   
            {   
                
// going back to the source state, so let's switch   
                mSource = mTarget;   
                mTarget 
= newTarget;   
                mTimeleft 
= mDuration - mTimeleft; // i'm ignoring the new duration here   
            }   
            
else  
            {   
                
// ok, newTarget is really new, so either we simply replace the target with this one, or   
                
// we make the target the new source   
                if( mTimeleft < mDuration * 0.5 )   
                {   
                    
// simply replace the target with this one   
                    mTarget->setEnabled(false);   
                    mTarget
->setWeight(0);   
                }   
                
else  
                {   
                    
// old target becomes new source   
                    mSource->setEnabled(false);   
                    mSource
->setWeight(0);   
                    mSource 
= mTarget;   
                }    
                mTarget 
= newTarget;   
                mTarget
->setEnabled(true);   
                mTarget
->setWeight( 1.0 - mTimeleft / mDuration );   
                mTarget
->setTimePosition(0);   
            }   
        }   
        
else  
        {   
            
// assert( target == 0, "target should be 0 when not blending" )   
            
// mSource->setEnabled(true);   
            
// mSource->setWeight(1);   
            mTransition = transition;   
            mTimeleft 
= mDuration = duration;   
            mTarget 
= newTarget;   
            mTarget
->setEnabled(true);   
            mTarget
->setWeight(0);   
            mTarget
->setTimePosition(0);   
        }   
    }   
}   
void AnimationBlender::addTime( Real time )   
{   
    
if( mSource != 0 )   
    {   
        
if( mTimeleft > 0 )   
        {   
            mTimeleft 
-= time;   
            
if( mTimeleft < 0 )   
            {   
                
// finish blending   
                mSource->setEnabled(false);   
                mSource
->setWeight(0);   
                mSource 
= mTarget;   
                mSource
->setEnabled(true);   
                mSource
->setWeight(1);   
                mTarget 
= 0;   
            }   
            
else  
            {   
                
// still blending, advance weights   
                mSource->setWeight(mTimeleft / mDuration);   
                mTarget
->setWeight(1.0 - mTimeleft / mDuration);   
                
if(mTransition == AnimationBlender::BlendWhileAnimating)   
                    mTarget
->addTime(time);   
            }   
        }   
        
if (mSource->getTimePosition() >= mSource->getLength())   
        {   
            complete 
= true;   
        }   
        
else  
        {   
            complete 
= false;   
        }   
        mSource
->addTime(time);   
        mSource
->setLoop(loop);   
    }   
}   
AnimationBlender::AnimationBlender( Entity 
*entity ) : mEntity(entity)    
{   

AnimationBlenderDemo.h

#ifndef __ANIMATIONBLENDER_DEMO_H__   
#define __ANIMATIONBLENDER_DEMO_H__   
#include 
"ExampleApplication.h"   
#include 
"AnimationBlender.h"   
class AnimationBlenderDemoFrameListener : public ExampleFrameListener   
{   
protected:   
    Entity
* mNinjaEnt;   
    AnimationBlender
* mAnimationBlender;   
    
bool walking, jumping;   
public:   
    AnimationBlenderDemoFrameListener(RenderWindow
* mWin, Camera* mCam, Entity* ent)   
        : ExampleFrameListener(mWin, mCam, 
falsefalse), mNinjaEnt(ent)   
    {   
        mAnimationBlender 
= new AnimationBlender(mNinjaEnt);   
        mAnimationBlender
->init("Walk"true);   
        walking 
= false;   
        jumping 
= false;   
    }   
    
virtual ~AnimationBlenderDemoFrameListener()   
    {   
        
if(mAnimationBlender)   
        {   
//          delete mAnimationBlender;   
        }   
    }   
    
bool frameRenderingQueued(const FrameEvent& evt)   
    {   
        
if (!ExampleFrameListener::frameRenderingQueued(evt))   
        {   
            
return false;   
        }   
        
if (!walking)   
        {   
            mAnimationBlender
->blend( "Walk",AnimationBlender::BlendWhileAnimating, 0.2true );   
            walking
=true;   
        }   
        
if (mKeyboard->isKeyDown( OIS::KC_SPACE ) && !jumping)   
        {   
            jumping
=true;   
            mAnimationBlender
->blend("Jump",AnimationBlender::BlendWhileAnimating, 0.2false );   
        }   
        
if (jumping)   
        {   
            
if (mAnimationBlender->complete)   
            {   
                mAnimationBlender
->blend( "Idle1",AnimationBlender::BlendWhileAnimating, 0.02true );   
                jumping
=false;   
            }   
        }   
        mAnimationBlender
->addTime(evt.timeSinceLastFrame);   
        
return true;   
    }   
};   
class AnimationBlenderDemoApp : public ExampleApplication   
{   
public:   
    AnimationBlenderDemoApp() {}   
protected:   
    Entity
* mNinjaEnt;   
    
void createScene();   
    
void createFrameListener()   
    {   
        mFrameListener 
= new AnimationBlenderDemoFrameListener(mWindow, mCamera, mNinjaEnt);   
        mRoot
->addFrameListener(mFrameListener);   
    }   
};   
#endif  


AnimationBlenderDemo.cpp

#include "AnimationBlenderDemo.h"   
#include <OgreStringConverter.h>   
void AnimationBlenderDemoApp::createScene()   
{   
    mSceneMgr->setAmbientLight(ColourValue(1.0, 1.0, 1.0));   
    mNinjaEnt = mSceneMgr->createEntity("Ninja", "ninja.mesh");   
    SceneNode* node = mSceneMgr->getRootSceneNode()->createChildSceneNode();   
    node->attachObject(mNinjaEnt);   
}   
#ifdef __cplusplus   
extern "C" {   
#endif   
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32   
#define WIN32_LEAN_AND_MEAN   
#include "windows.h"   
    INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )   
#else   
    int main(int argc, char **argv)   
#endif   
    {   
        AnimationBlenderDemoApp app;   
        try {   
            app.go();   
        } catch( Ogre::Exception& e ) {   
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32   
            MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL );   
#else   
            std::cerr << "An exception has occured: " << e.getFullDescription();   
#endif   
        }   
        return 0;   
    }   
#ifdef __cplusplus   
}   
#endif  
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            国产精品国产三级国产普通话三级| 亚洲小说欧美另类社区| 午夜精品久久| 91久久夜色精品国产网站| 卡通动漫国产精品| 亚洲亚洲精品三区日韩精品在线视频| 免费在线亚洲欧美| 久久久久久自在自线| 欧美一级成年大片在线观看| 99在线热播精品免费| 极品日韩久久| 国产一区二区三区视频在线观看| 欧美日韩国产影片| 亚洲福利视频二区| 欧美中文字幕精品| 亚洲免费小视频| 亚洲欧美不卡| 欧美一区二区视频在线| 久久久久久久一区二区| 久久激五月天综合精品| 一区二区三区www| 亚洲综合精品四区| 亚洲男人的天堂在线观看 | 久久精品日产第一区二区三区 | 久久影视三级福利片| 久久久久综合网| 久久另类ts人妖一区二区| 久久精品噜噜噜成人av农村| 久久人人爽人人爽| 欧美夫妇交换俱乐部在线观看| 麻豆成人在线观看| 欧美黑人多人双交| 亚洲美女免费精品视频在线观看| 99精品国产高清一区二区| 亚洲精品视频免费在线观看| 99热在这里有精品免费| 午夜精品一区二区三区在线播放 | 久久青草欧美一区二区三区| 蜜臀久久久99精品久久久久久| 久久性天堂网| 亚洲黑丝在线| 亚洲欧美精品一区| 久久精品水蜜桃av综合天堂| 久久一区视频| 国产精品久久91| 永久免费精品影视网站| 曰本成人黄色| 亚洲一区二区三区国产| 久久久久一区| 日韩午夜在线观看视频| 久久久久**毛片大全| 国产精品ⅴa在线观看h| 亚洲国产日韩欧美在线图片| 亚洲午夜在线视频| 欧美激情精品久久久久久| 欧美国产日韩精品免费观看| 亚洲国产精品一区| 欧美在线不卡| 欧美 日韩 国产一区二区在线视频 | 国产精品男女猛烈高潮激情| 1769国内精品视频在线播放| 欧美中文在线视频| 欧美视频四区| 亚洲另类视频| 欧美成人网在线| 亚洲午夜一区| 欧美日韩日本网| 亚洲六月丁香色婷婷综合久久| 久热综合在线亚洲精品| 亚洲欧美日本在线| 国产精品国产三级国产专区53 | 亚洲精品久久久久久久久久久久久| 午夜精品视频在线观看一区二区| 亚洲国产你懂的| 麻豆成人精品| 国产精品一二三| 影音先锋日韩有码| 欧美不卡视频| 毛片基地黄久久久久久天堂| 经典三级久久| 美女在线一区二区| 欧美一级片在线播放| 国产精品女主播在线观看 | 精品成人一区二区三区| 久久久噜噜噜久久人人看| 亚洲欧美日韩综合国产aⅴ| 国产精品嫩草久久久久| 国产亚洲va综合人人澡精品| 欧美主播一区二区三区美女 久久精品人 | 欧美日韩国语| 亚洲精选中文字幕| 亚洲在线视频观看| 欧美一区二区三区在| 国产精品va在线| 午夜精品久久99蜜桃的功能介绍| 一区二区三区四区五区在线 | 日韩亚洲精品视频| 久久国产精品72免费观看| 国产精品亚洲аv天堂网| 亚洲国产欧美日韩| 久久久久国产精品一区二区| 亚洲最快最全在线视频| 欧美ab在线视频| 久久久久久网站| 亚洲一区在线观看视频| 免费观看成人鲁鲁鲁鲁鲁视频| 小处雏高清一区二区三区| 亚洲韩国日本中文字幕| 久久精品国产综合精品| 欧美一区二区视频网站| 一本色道88久久加勒比精品| 亚洲靠逼com| 在线电影国产精品| 久久久久久97三级| 亚洲男人的天堂在线观看| 国产精品系列在线播放| 久久精品国产v日韩v亚洲 | 欧美成人午夜影院| 欧美日韩国产a| 亚洲一区二区精品视频| 久久久亚洲综合| 欧美在线免费观看亚洲| 欧美日韩精品一区二区三区四区| 久久天天躁狠狠躁夜夜av| 欧美天堂亚洲电影院在线观看| 欧美本精品男人aⅴ天堂| 国产婷婷成人久久av免费高清 | 欧美在线视频日韩| 欧美在线3区| 国产精品免费一区豆花| 一二三区精品福利视频| 亚洲视频免费在线| 欧美日韩免费网站| 亚洲欧洲日韩在线| 亚洲国产日韩精品| 久热精品视频在线观看| 另类综合日韩欧美亚洲| 激情懂色av一区av二区av| 午夜精彩视频在线观看不卡| 欧美一区二区三区在线播放| 国产精品久久久一区麻豆最新章节| 亚洲精品一区在线观看香蕉| 一本到12不卡视频在线dvd| 欧美韩日一区二区三区| 日韩视频在线一区二区三区| 一区二区日韩精品| 国产精品99一区| 性色av香蕉一区二区| 久久婷婷亚洲| 伊人久久噜噜噜躁狠狠躁 | 国产一区亚洲| 久久久综合精品| 欧美国产日韩一二三区| 亚洲裸体俱乐部裸体舞表演av| 欧美精品激情在线| 一区二区不卡在线视频 午夜欧美不卡'| 亚洲专区国产精品| 国外成人网址| 欧美xxx在线观看| 正在播放亚洲一区| 久久免费国产精品1| 亚洲久久在线| 国产精品私人影院| 久久在线免费| 夜夜嗨av一区二区三区免费区| 欧美怡红院视频| 亚洲国产美女| 国产精品久久一级| 男男成人高潮片免费网站| 亚洲特色特黄| 欧美激情一区二区久久久| 午夜精品福利电影| 亚洲国产成人久久综合一区| 国产精品久久久久久久7电影 | 韩日欧美一区| 欧美成人免费网| 亚洲制服av| 午夜精品免费视频| 欧美日韩国产一区二区三区| 久久久国产精品一区| 久久国产天堂福利天堂| 在线免费一区三区| 国产精品久久久久久亚洲调教| 欧美一级大片在线免费观看| 亚洲第一精品在线| 欧美一区二区三区免费观看| 日韩一级在线| 精品999在线播放| 国产欧美成人| 欧美视频网址| 欧美精品久久一区二区| 久久久久久久久久久久久久一区| 亚洲视频一二| 99av国产精品欲麻豆| 亚洲第一二三四五区| 久久久久成人网| 西瓜成人精品人成网站| 亚洲视频电影在线| 亚洲视频一起| 一区二区三区成人精品|