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

            評論

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

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

            日日噜噜夜夜狠狠久久丁香五月 | 国产农村妇女毛片精品久久| 蜜臀av性久久久久蜜臀aⅴ麻豆| 久久人人爽人人爽人人AV| 久久精品国产亚洲AV香蕉| 91精品免费久久久久久久久| 久久亚洲欧洲国产综合| 天天爽天天狠久久久综合麻豆| 国产精品久久网| 亚洲人成无码久久电影网站| 久久精品中文无码资源站| 日本一区精品久久久久影院| 亚洲欧洲精品成人久久曰影片| 97久久精品无码一区二区天美 | 久久精品青青草原伊人| 久久99国产综合精品免费| 久久国内免费视频| 精品欧美一区二区三区久久久| 欧美午夜精品久久久久免费视| 久久久网中文字幕| 国产99久久久久久免费看| 亚洲精品无码久久久久sm| 色悠久久久久久久综合网| 国产精品久久久99| 91视频国产91久久久| 97精品伊人久久久大香线蕉| 久久久久香蕉视频| 国产精品无码久久四虎| 久久精品嫩草影院| 国产精品18久久久久久vr| 亚洲国产美女精品久久久久∴ | 久久精品www人人爽人人| 久久久久se色偷偷亚洲精品av| 亚洲精品乱码久久久久久蜜桃| 国产精品无码久久四虎| 精品久久综合1区2区3区激情| 亚洲嫩草影院久久精品| 国产成人精品久久一区二区三区av| 日本久久久精品中文字幕| 丁香久久婷婷国产午夜视频| 国产激情久久久久影院|