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

            評論

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

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

            久久精品免费网站网| 久久99国产精品久久99| 91久久精品91久久性色| 青青草原综合久久| 国产精品久久婷婷六月丁香| 伊人 久久 精品| 久久精品男人影院| 无码8090精品久久一区| 国产精品岛国久久久久| 久久精品亚洲精品国产欧美| 亚洲精品99久久久久中文字幕| 精品久久久中文字幕人妻| 久久这里都是精品| 久久精品亚洲日本波多野结衣 | 秋霞久久国产精品电影院| 超级碰久久免费公开视频| 久久午夜无码鲁丝片| 一本久久a久久精品综合香蕉| 一本久道久久综合狠狠躁AV| 性高湖久久久久久久久| 97久久婷婷五月综合色d啪蜜芽| 国产精品无码久久四虎| 久久久久国色AV免费观看| 亚洲精品无码成人片久久| 久久性精品| 人人狠狠综合久久亚洲| 97久久超碰国产精品旧版| 亚洲中文字幕无码久久2020| 久久久久黑人强伦姧人妻| 亚洲精品高清国产一久久| 久久亚洲国产中v天仙www| 日本强好片久久久久久AAA| 久久免费看黄a级毛片| 亚洲国产成人久久综合野外| 久久国产美女免费观看精品| 国产福利电影一区二区三区久久老子无码午夜伦不 | 天天躁日日躁狠狠久久| 久久人人爽人人人人片av| 无码人妻少妇久久中文字幕 | 77777亚洲午夜久久多喷| 亚洲日本久久久午夜精品|