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

            永遠(yuǎn)也不完美的程序

            不斷學(xué)習(xí),不斷實(shí)踐,不斷的重構(gòu)……

            常用鏈接

            統(tǒng)計(jì)

            積分與排名

            好友鏈接

            最新評(píng)論

            Ogre骨骼動(dòng)畫融合(轉(zhuǎn))

            轉(zhuǎn)自http://www.guibian.com/article.asp?id=50

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

            Ogre其實(shí)也支持動(dòng)畫的融合,只是Ogre并沒(méi)有給出代碼級(jí)的支持。
            PS:Ogre很有意思,他天然支持很多東西,但是都沒(méi)有實(shí)現(xiàn)出來(lái),需要你來(lái)實(shí)現(xiàn)。

            好的,下面來(lái)通過(guò)代碼看看如果進(jìn)行一個(gè)簡(jiǎn)單的骨骼動(dòng)畫融合。
            程序代碼 程序代碼


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

            private:
                Entity *mEntity;
                AnimationState *mSource;
                AnimationState *mTarget;

                BlendingTransition mTransition;

                bool loop; //是否循環(huán)

                ~AnimationBlender() {}

            public:
                Real mTimeleft, mDuration; //持續(xù)時(shí)間

                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 );
            };


            實(shí)現(xiàn)的代碼
            程序代碼 程序代碼

            void AnimationBlender::init(const String &animation)
            {
                //初始化所有動(dòng)作的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; //設(shè)置是否需要循環(huán)
                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
                {
                    //先取得新的動(dòng)畫狀態(tài)
                    AnimationState *newTarget = mEntity->getAnimationState( animation );
                    if( mTimeleft > 0 ) //前一次的混合尚未結(jié)束
                    {
                        if( newTarget == mTarget )
                        {
                            // 新的目標(biāo)就是正在混合中的目標(biāo),什么也不做
                        }
                        else if( newTarget == mSource )
                        {
                            // 新的目標(biāo)是源動(dòng)畫,直接go back
                            mSource = mTarget;
                            mTarget = newTarget;
                            mTimeleft = mDuration - mTimeleft;
                        }
                        else
                        {
                            // 現(xiàn)在newTarget是真的新的動(dòng)畫了
                            if( mTimeleft < mDuration * 0.5 ) //上一次的混合進(jìn)度還未超過(guò)一半
                            {
                                // 簡(jiǎn)單替換Target就行了
                                mTarget->setEnabled(false);
                                mTarget->setWeight(0);
                            }
                            else //如果已經(jīng)過(guò)半,舊的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 //上次的混合已經(jīng)結(jié)束,當(dāng)前未處于混合狀態(tài)中
                    {
                        mTransition = transition;
                        mTimeleft = mDuration = duration;
                        mTarget = newTarget;
                        mTarget->setEnabled(true);
                        mTarget->setWeight(0);
                        mTarget->setTimePosition(0);
                    }
                }
            }
            void AnimationBlender::addTime( Real time )
            {
                if( mSource != 0 ) //若無(wú)AnimationState則不進(jìn)行操作
                {
                    if( mTimeleft > 0 ) //兩個(gè)動(dòng)畫仍在混合過(guò)程中
                    {
                        mTimeleft -= time;
                        if( mTimeleft < 0 )
                        {
                            // 混合完畢,切換到目標(biāo)動(dòng)畫
                            mSource->setEnabled(false);
                            mSource->setWeight(0);
                            mSource = mTarget;
                            mSource->setEnabled(true);
                            mSource->setWeight(1);
                            mTarget = 0;
                        }
                        else
                        {
                            // 仍然處于混合狀態(tài)中,改變兩個(gè)動(dòng)畫的權(quán)值
                            mSource->setWeight(mTimeleft / mDuration);
                            mTarget->setWeight(1.0 - mTimeleft / mDuration);
                            //在這種混合方式下,需要為目標(biāo)動(dòng)畫增加時(shí)間
                            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){}



            哈哈,相信你已經(jīng)看出來(lái),這段代碼有很多很多的不足。比如只有骨骼動(dòng)畫的融合,
            而且還是寫死的,必須0.5。

            我現(xiàn)在已經(jīng)擴(kuò)展了這些功能,包括做到了骨骼動(dòng)畫與定點(diǎn)動(dòng)畫的融合,變形動(dòng)畫的融合等等。而且可以精確控制融合的時(shí)機(jī)。你有什么好想法也歡迎與我討論

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

            評(píng)論

            # re: Ogre骨骼動(dòng)畫融合(轉(zhuǎn)) 2011-06-01 09:09 ruibin

            正在研究相關(guān)知識(shí),能否將你實(shí)現(xiàn)的代碼傳一份,謝謝?。。?!
            郵箱:653396438@qq.com  回復(fù)  更多評(píng)論   

            国产成人无码精品久久久免费| 成人久久综合网| 久久人人爽人人精品视频| 久久人妻少妇嫩草AV无码蜜桃 | 精品永久久福利一区二区| 99re久久精品国产首页2020| 久久99热国产这有精品| 欧美国产成人久久精品| 一本色道久久88精品综合| 狠狠狠色丁香婷婷综合久久五月 | 久久综合久久综合久久综合| 久久播电影网| 久久婷婷国产综合精品| 久久国产视屏| 精品久久久噜噜噜久久久| 久久亚洲高清综合| 99热成人精品热久久669| 久久伊人精品一区二区三区| 久久精品男人影院| 色欲av伊人久久大香线蕉影院| 精品久久人人做人人爽综合| 久久国产亚洲精品无码| 久久久久久精品无码人妻| 99热精品久久只有精品| 国产精品美女久久久| 亚洲欧美国产精品专区久久| 国产午夜福利精品久久| 69SEX久久精品国产麻豆| 久久人与动人物a级毛片| 欧美久久天天综合香蕉伊| 亚洲欧美日韩精品久久| 久久亚洲国产午夜精品理论片 | 99久久精品久久久久久清纯| 久久久久亚洲AV无码网站| 亚洲午夜久久久久久噜噜噜| 亚洲国产日韩综合久久精品| 久久人妻少妇嫩草AV无码蜜桃| 欧美与黑人午夜性猛交久久久| 久久这里有精品视频| 狠狠色丁香婷婷久久综合五月| 色诱久久av|