ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

动作融合

2022-08-07 21:04:16  阅读:202  来源: 互联网

标签:动作 weight 插值 deltaTime 融合 trans bone


只要有playercontroll的游戏都会有人物动作,比如idel、walk、run等,动画师只会针对每种动作做一系列动画,一组动画称为一组clips,里面k的每帧动画称为一个clip。

当我们按下方向键时,希望看到角色是从一个动作到另一个动作自然过度的,可是动画师并没有做过度动画,这时就需要“动作融合”。

动作融合,简单来说需要2步插值,第一步是两个动作每个clip分别插值,第二步是根据deltaTime在时间线上找到融合后的2个clip插值。

以“走”和“跑”2个动作融合为例

【准备】

1.动画师准备好walk-clips和run-clips。帧数需要一样,比如都是58帧,即58个clip,且间隔比例要一直;长度可以不同,比如walk一个循环是5秒,run开一个循环是10秒。

2.物理系统返回每帧deltaTime,例如1秒30帧,返回的deltaTime大概是0.33s。

【第一步】

当玩家按下跑步键,角色从走路变成跑步的过程中,物理系统返回speed会不断发生改变。

每次speed改变,都重新计算权重。

根据权重对动作AB的每个骨骼的58个clip分别做插值,插值的属性包括骨骼的translate/scale/rotation,translate和scale用线性插值lerp,rotation用四元数插值nlerp。

 

 

 

 

void AnimationPose::blend(const AnimationPose& pose)
{
    for (int i = 0; i < m_bone_poses.size(); i++)
    {
        auto&       bone_trans_one = m_bone_poses[i];
        const auto& bone_trans_two = pose.m_bone_poses[i];

        float sum_weight = m_weight.m_blend_weight[i] + pose.m_weight.m_blend_weight[i];
        if (sum_weight != 0)
        {
            float cur_weight = pose.m_weight.m_blend_weight[i]; // 动作2权重
            m_weight.m_blend_weight[i] = 1.0f - cur_weight;     // 动作1权重
            bone_trans_one.m_position = Vector3::lerp(bone_trans_one.m_position, bone_trans_two.m_position, cur_weight);
            bone_trans_one.m_scale     = Vector3::lerp(bone_trans_one.m_scale, bone_trans_two.m_scale, cur_weight);
            bone_trans_one.m_rotation  = Quaternion::nLerp(
                cur_weight, bone_trans_one.m_rotation, bone_trans_two.m_rotation, true);
        }
    }
}

【第二步】

每帧输入deltaTime根据此刻的物理速度、权重,分别算出walk和run的deltaTime(或者算出融合后的deltaTime)。

根据deltaTime选取2个融合后的clip做插值。

 

 

 

 至此,就能自然的表现从“走”到“跑”的过度了。

 

标签:动作,weight,插值,deltaTime,融合,trans,bone
来源: https://www.cnblogs.com/alphaGo/p/16559827.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有