• <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>

            永遠也不完美的程序

            不斷學習,不斷實踐,不斷的重構……

            常用鏈接

            統計

            積分與排名

            好友鏈接

            最新評論

            Ogre骨骼動畫融合(轉)

            轉自http://www.guibian.com/article.asp?id=50

            很多商業引擎都支持骨骼動畫融合這個功能。
            融合可以讓你的動畫自然過渡到下一個動畫,你可以精確控制下一個動畫播放時間等信息。

            Ogre其實也支持動畫的融合,只是Ogre并沒有給出代碼級的支持。
            PS:Ogre很有意思,他天然支持很多東西,但是都沒有實現出來,需要你來實現。

            好的,下面來通過代碼看看如果進行一個簡單的骨骼動畫融合。
            程序代碼 程序代碼


            class AnimationBlender
            {
            public:
                enum BlendingTransition  //不同的混合方式
                {
                    BlendSwitch,         // 直接切換到目標動畫
                    BlendWhileAnimating,   // 交叉淡入淡出(源動畫比例縮小,同時目標動畫比例增大)
                    BlendThenAnimate      // 淡出源動畫到目標動畫第一幀,然后開始目標動畫
                };

            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 );
                void addTime( Real );
                Real getProgress() { return mTimeleft/ mDuration; }
                AnimationState *getSource() { return mSource; }
                AnimationState *getTarget() { return mTarget; }
                AnimationBlender( Entity *);
                void init( const String &animation );
            };


            實現的代碼
            程序代碼 程序代碼

            void AnimationBlender::init(const String &animation)
            {
                //初始化所有動作的AnimationState
                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
                mSource = mEntity->getAnimationState( animation );
                mSource->setEnabled(true);
                mSource->setWeight(1);
                mTimeleft = 0;
                mDuration = 1;
                mTarget = 0;
                complete=false;
            }
            void AnimationBlender::blend( const String &animation, BlendingTransition transition, Real duration, bool l )
            {
                loop=l; //設置是否需要循環
                if( transition == AnimationBlender::BlendSwitch )
                {//如果混合方式為直接切換,改變mSource 即可
                    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 ) //前一次的混合尚未結束
                    {
                        if( newTarget == mTarget )
                        {
                            // 新的目標就是正在混合中的目標,什么也不做
                        }
                        else if( newTarget == mSource )
                        {
                            // 新的目標是源動畫,直接go back
                            mSource = mTarget;
                            mTarget = newTarget;
                            mTimeleft = mDuration - mTimeleft;
                        }
                        else
                        {
                            // 現在newTarget是真的新的動畫了
                            if( mTimeleft < mDuration * 0.5 ) //上一次的混合進度還未超過一半
                            {
                                // 簡單替換Target就行了
                                mTarget->setEnabled(false);
                                mTarget->setWeight(0);
                            }
                            else //如果已經過半,舊的target成為新的source
                            {

                                mSource->setEnabled(false);
                                mSource->setWeight(0);
                                mSource = mTarget;
                            }
                            mTarget = newTarget;
                            mTarget->setEnabled(true);
                            mTarget->setWeight( 1.0 - mTimeleft / mDuration );
                            mTarget->setTimePosition(0);
                        }
                    }
                    else //上次的混合已經結束,當前未處于混合狀態中
                    {
                        mTransition = transition;
                        mTimeleft = mDuration = duration;
                        mTarget = newTarget;
                        mTarget->setEnabled(true);
                        mTarget->setWeight(0);
                        mTarget->setTimePosition(0);
                    }
                }
            }
            void AnimationBlender::addTime( Real time )
            {
                if( mSource != 0 ) //若無AnimationState則不進行操作
                {
                    if( mTimeleft > 0 ) //兩個動畫仍在混合過程中
                    {
                        mTimeleft -= time;
                        if( mTimeleft < 0 )
                        {
                            // 混合完畢,切換到目標動畫
                            mSource->setEnabled(false);
                            mSource->setWeight(0);
                            mSource = mTarget;
                            mSource->setEnabled(true);
                            mSource->setWeight(1);
                            mTarget = 0;
                        }
                        else
                        {
                            // 仍然處于混合狀態中,改變兩個動畫的權值
                            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){}



            哈哈,相信你已經看出來,這段代碼有很多很多的不足。比如只有骨骼動畫的融合,
            而且還是寫死的,必須0.5。

            我現在已經擴展了這些功能,包括做到了骨骼動畫與定點動畫的融合,變形動畫的融合等等。而且可以精確控制融合的時機。你有什么好想法也歡迎與我討論

            posted on 2010-01-18 10:47 狂爛球 閱讀(2349) 評論(1)  編輯 收藏 引用 所屬分類: 圖形編程

            評論

            # re: Ogre骨骼動畫融合(轉) 2011-06-01 09:09 ruibin

            正在研究相關知識,能否將你實現的代碼傳一份,謝謝!!!!
            郵箱:653396438@qq.com  回復  更多評論   

            国产日韩欧美久久| 色综合久久中文字幕无码| 久久久久久国产精品美女| 国内精品综合久久久40p| 国产精品久久久久影院色| 久久精品成人一区二区三区| 久久亚洲AV成人无码| 久久精品成人免费网站| 久久精品国产亚洲AV不卡| 久久精品国产久精国产| 奇米影视7777久久精品人人爽| WWW婷婷AV久久久影片| 亚洲AV伊人久久青青草原| 久久夜色精品国产亚洲| 久久亚洲美女精品国产精品| 老司机午夜网站国内精品久久久久久久久| 色综合久久夜色精品国产| 久久99久久99小草精品免视看| 精品久久久久久久国产潘金莲| 国产精品成人久久久久三级午夜电影| 日韩AV无码久久一区二区| 亚洲精品国产综合久久一线| 久久国产成人午夜aⅴ影院| 久久久久免费精品国产 | 国产亚洲婷婷香蕉久久精品| 九九久久精品无码专区| 久久91精品国产91久久小草| 久久国产免费观看精品3| 国产aⅴ激情无码久久| 久久精品国产精品亚洲精品 | 久久免费99精品国产自在现线| 国产91色综合久久免费分享| 色欲久久久天天天综合网精品| 狠狠色婷婷久久综合频道日韩| 伊人久久大香线蕉综合5g| 亚洲一级Av无码毛片久久精品| 女同久久| 综合久久国产九一剧情麻豆| 久久亚洲欧美国产精品| 成人久久精品一区二区三区| 99国产欧美精品久久久蜜芽|