永远也不完美的程序

不断学习,不断实践,不断的重构……

常用链接

统计

积分与排名

好友链接

最新评论

骨骼动画平滑过渡的实现

    很久没写技术文章,今天写一下骨骼动画的过渡,也当是复习一下。骨骼动画的过渡在游戏中很常见,由一个动作切换到另一个动作有个过渡时间,这个过程其实是动作混合的过程。骨骼动画的原理不多说了,网上很多相关文章。下面先简单介绍一下骨骼动画的实现。
    实现骨骼动画,我定义如下几个类:
    class AnimationState,表示一个模型的动画状态,记录了动画的时间,权值等。
    class SkeletonAnimation,骨骼动画,记录了所有骨的关键帧位置和骨骼关系。
    class Bone,表示模型中的具体一条骨,记录了骨的位置,旋转和缩放。   
    class Model,表示一个模型,包括所有顶点数据。
    骨骼动画的流程大概如下:
    AnimationState:Update(),更新动画时间。
    SkeletonAnimation:ApplyToNode(float timePos, Bone* pBone, float weight),计算每条骨在当前时间的位置。
    Bone:GetTransform(),获得骨的矩阵,对受其影响的顶点进行蒙皮。
    当然实现起来没这么简单,具体可以参考ogre,基本上也是这个流程。
    知道了这个流程后,其实动作过渡就很简单了。关键是SkeletonAnimation:ApplyToNode这个函数,利用参数weight的变化就可以实现了。原理就是当前动作的weight是1.0->0.0,目标动作的weight是0.0->1.0。
    下面是这个过程实现的伪代码。
    SkeletonAnimation animCur;   //当前动画
    SkeletonAnimation animDest;  //目标动画
    AnimationState    stateCur;  //当前动画状态
    AnimationState    stateDest; //目标动画状态
    float blendTime = 0.5;   //混合时间,这里假设是0.5秒
    float blendRemain = 0.5; //剩余时间
    Bone bones[BONES_NUM];   //骨骼数组
    function Blend(float timeElapse)
    {
        blendRemain -= timeElapse;
        bool bBlending = blendRemain >= 0;
        if (bBlending)
        {
            float fSrcWeight = blendRemain / blendTime;
            stateCur.SetWeight(fSrcWeight);
            stateDest.SetWeight(1 - fSrcWeight);
        }
    }

    function Caculatebones(state)
    {
        for (int i = 0; i < BONES_NUM; ++i)
        {
            state.GetAnimation().ApplyToNode(state.GetTimePos(), bones[i], state.GetWeight());
        }
    }
   
    CaculateBones(stateCur);
    CaculateBones(stateDest);
   
    基本上这样就完成了过渡混合,其实动作混合也是这样做,如果有N个动画同时混合,把上面的代码改成如下:
    for (int i = 0; i < N; ++i)
    {
        AnimationState state = CurrentStates[i];
        Caculatebones(state);
    } 
    这样就完成了N个动画的同时混合。
    详细实现可以参考OGRE。

posted on 2011-05-13 10:41 狂烂球 阅读(3518) 评论(2)  编辑 收藏 引用 所属分类: 图形编程

评论

# re: 骨骼动画平滑过渡的实现 2011-05-13 14:05 scarpe adidas

I agree with Mike New year is to make things ready for every one.  回复  更多评论   

# re: 骨骼动画平滑过渡的实现 2011-05-14 14:23 parker schweiz

Great article, lots of smart tips. I am going to show my buddies and ask them what they think.  回复  更多评论   


只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理