• <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 狂爛球 閱讀(2336) 評論(1)  編輯 收藏 引用 所屬分類: 圖形編程

            評論

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

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

            国内精品久久久久影院日本 | 亚洲人AV永久一区二区三区久久| 亚洲精品乱码久久久久久久久久久久| 久久93精品国产91久久综合| 国产一级做a爰片久久毛片| 成人妇女免费播放久久久| 99精品国产综合久久久久五月天| 香蕉久久夜色精品国产2020| 久久中文字幕视频、最近更新 | 久久夜色撩人精品国产小说| 99久久国产热无码精品免费久久久久| 麻豆精品久久精品色综合| 精品精品国产自在久久高清| 99999久久久久久亚洲| 国产精品九九久久免费视频| 国产精品99久久久久久www| 国产亚州精品女人久久久久久 | 国产高潮久久免费观看| 久久亚洲精品无码观看不卡| 综合网日日天干夜夜久久| 日韩久久久久久中文人妻| 香蕉久久一区二区不卡无毒影院| 久久国产精品-久久精品| 久久99国产亚洲高清观看首页 | 伊人久久大香线蕉综合5g| 99久久国产精品免费一区二区| 国产亚洲综合久久系列| 久久精品二区| 久久久久久国产精品免费无码 | 国产精品午夜久久| 欧美伊人久久大香线蕉综合| 久久精品无码午夜福利理论片| 青青国产成人久久91网| 伊人热热久久原色播放www| 国产偷久久久精品专区| 国产成人久久精品区一区二区| 久久国产高清一区二区三区| 亚洲国产精品无码久久SM| 国产A级毛片久久久精品毛片| 精品久久亚洲中文无码| 日韩精品国产自在久久现线拍|