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

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>
            亚洲激情电影在线| 欧美激情国产精品| 性xx色xx综合久久久xx| 1204国产成人精品视频| 久久久噜久噜久久综合| 亚洲国产另类 国产精品国产免费| 国产精品视频福利| 午夜国产精品视频| 欧美激情bt| 亚洲精品少妇30p| 欧美成人激情视频| 亚洲综合视频在线| 久久国产精品高清| 美女尤物久久精品| 亚洲国产精品成人| 久久免费99精品久久久久久| 99热在这里有精品免费| 国产日韩欧美高清免费| 欧美日韩国产影院| 亚洲一区二区久久| 欧美成人免费小视频| 美女爽到呻吟久久久久| 久久伊伊香蕉| 亚洲精品小视频在线观看| 亚洲欧美日韩区| 国产免费一区二区三区香蕉精| 欧美不卡一区| 欧美高清视频在线| 黄色成人精品网站| 欧美日韩中文精品| 久久久www| 久久综合给合久久狠狠色| 亚洲国产精品久久久久秋霞不卡| 国产专区欧美精品| 国产毛片一区二区| 国产日韩亚洲欧美| 国产伦精品一区二区三区| 亚洲一区三区电影在线观看| 中文欧美字幕免费| 美女精品网站| 亚洲欧美综合网| 欧美黄色成人网| 国产精品区二区三区日本| 理论片一区二区在线| 国产精品午夜视频| 亚洲二区在线| 久久精品视频在线播放| 欧美成人一区二免费视频软件| 日韩视频―中文字幕| 亚洲欧洲在线观看| 性欧美办公室18xxxxhd| 欧美成人一区二区在线| 一本一本久久a久久精品综合妖精| 久久国产主播| 国际精品欧美精品| 一区二区三区.www| 在线综合亚洲欧美在线视频| 欧美影院在线| 久久久久久亚洲精品中文字幕 | 宅男精品视频| 久久深夜福利| 欧美一区二区三区四区视频| 99国产精品久久久久老师| 免播放器亚洲一区| 日韩一级在线观看| 亚洲最新中文字幕| 欧美午夜一区二区三区免费大片| 亚洲黄色av一区| 欧美国产日本| 久久琪琪电影院| 99视频在线精品国自产拍免费观看| 免费日韩一区二区| 欧美日韩精品免费观看| 国产视频一区二区在线观看| 久久国产精品72免费观看| 精品91视频| 伊人狠狠色j香婷婷综合| 久久精品国产精品亚洲综合| 一本大道av伊人久久综合| 欧美华人在线视频| 久久久久久香蕉网| 国产精自产拍久久久久久| 亚洲国产日韩精品| 尤物网精品视频| 亚洲一区二区三区精品在线| 日韩视频精品在线| 免费成人av在线| 亚洲国产精品ⅴa在线观看 | 久久av一区| 美女脱光内衣内裤视频久久网站| 久久久久国产一区二区| 国产精品网站在线观看| 午夜精品一区二区三区在线| 久久久久一区二区| 亚洲激情啪啪| 欧美日韩在线亚洲一区蜜芽| 国产精品99久久久久久宅男| 亚洲一区二区三区国产| 国产午夜精品理论片a级探花| 欧美一区二区免费观在线| 久久永久免费| 亚洲网站视频福利| 国产亚洲精品bt天堂精选| 模特精品在线| 午夜在线a亚洲v天堂网2018| 麻豆成人精品| 亚洲四色影视在线观看| 国产亚洲一区在线播放| aa成人免费视频| 国产精品在线看| 欧美日韩精品在线观看| 久久激情五月激情| 亚洲一区二区三区视频播放| 亚洲电影欧美电影有声小说| 久久电影一区| 久久国产免费| 欧美中文字幕在线观看| 亚洲一区二区高清| 亚洲精品午夜精品| 欧美视频中文一区二区三区在线观看| 久久手机精品视频| 一区二区三区|亚洲午夜| 韩国欧美国产1区| 欧美日韩美女在线| 老妇喷水一区二区三区| 亚洲免费小视频| 一二三区精品| 亚洲视频图片小说| 亚洲无线视频| 在线中文字幕日韩| 羞羞色国产精品| 理论片一区二区在线| 欧美精品 国产精品| 国产精品久久国产愉拍| 国产精品欧美在线| 在线不卡免费欧美| 99国产精品| 久久精品网址| 亚洲精品一区二区三区不| 亚洲特级片在线| 久久亚洲国产成人| 国产精品国产三级国产专区53| 国产一区激情| 亚洲私人影院在线观看| 麻豆av一区二区三区久久| 日韩午夜三级在线| 欧美一区免费视频| 欧美天天在线| 在线亚洲一区| 在线观看一区二区精品视频| 亚洲日本欧美| 免费不卡在线视频| 亚洲欧美在线高清| 欧美99久久| 欧美精品一区二区三区高清aⅴ| 国产精品区一区二区三区| 亚洲精品国产精品久久清纯直播| 久久aⅴ国产欧美74aaa| 一区二区国产在线观看| 欧美wwwwww| 亚洲美女在线国产| 亚洲高清中文字幕| 欧美激情精品久久久久久| 亚洲日本一区二区| 亚洲精品综合| 国产精品免费区二区三区观看| 亚洲一区二区三区四区在线观看| 亚洲精选中文字幕| 国产精品一区二区男女羞羞无遮挡| 一区二区三区视频观看| 这里只有精品在线播放| 国产精品亚洲不卡a| 欧美有码视频| 久久亚洲一区| 99视频国产精品免费观看| 夜夜嗨av一区二区三区中文字幕 | 久久女同精品一区二区| 久久国产欧美日韩精品| 美日韩丰满少妇在线观看| 99视频有精品| 久久国产精品一区二区三区| 亚洲精品欧美| 久久国产免费看| 亚洲在线一区二区| 欧美成人国产一区二区| 欧美中日韩免费视频| 欧美精品97| 久久夜色精品亚洲噜噜国产mv| 亚洲激情成人在线| 国产午夜亚洲精品理论片色戒| 亚洲国产成人av| 在线电影一区| 亚洲国产精品久久久久久女王| 亚洲九九精品| 一区二区不卡在线视频 午夜欧美不卡在 | 久久av免费一区| 欧美福利专区| 欧美国产日韩在线| 日韩视频二区| 国产精品你懂得|