UE4源码阅读_骨骼模型与动画系统_动画节点

0. 写在前面

本文为个人学习的笔记整理,如有错误,望不吝指出。

1. 动画播放:FAnimNode_SequencePlayer

相关参数:

  1. UAnimSequenceBase Sequence:动画片段
  2. PlayRateBasis:播放速率基数,被PlayRate除
  3. PlayRate:播放速率,可以是负数,表示反向播
  4. PlayRateScaleBiasClamp:对PlayRate额外的处理(缩放,偏移和Clamp),在除Basis后操作
  5. StartPosition:该动画节点的启动位置
  6. bLoopAnimation:是否循环动画

1.1 UAnimSequence

继承自UAnimSequenceBase,保存动画序列的关键帧数据,并包含若干个轨道数据
1.主要数据:
TArray RawAnimationData; 原始未压缩的动画关键帧数据
TArray SourceRawAnimationData; RawAnimationData的复件,只在初始化时被修改
Struct FRawAnimSequenceTrack:单个关键帧数据,包含平移、旋转和缩放。
TArray<FVector> PosKeys; TArray<FQuat> RotKeys; TArray<FVector> ScaleKeys;

2.资源设置
a. Compression Set:动画压缩设置
详细内容见动画压缩篇

在这里插入图片描述

b. Addtive Set:叠加设置
在这里插入图片描述

  • TEnumAsByte AdditiveAnimType; 叠加动画的类型
    AAT_None
    AAT_LocalSpaceBase 基于局部关节空间
    AAT_RotationOffsetMeshSpace 旋转基于模型空间,平移基于局部关节空间
  • TEnumAsByte RefPoseType; 基础姿势的类型
    ABPT_None UMETA(DisplayName = “None”),
    ABPT_RefPose UMETA(DisplayName = “Skeleton Reference Pose”),
    ABPT_AnimScaled UMETA(DisplayName = “Selected animation scaled”),
    ABPT_AnimFrame UMETA(DisplayName = “Selected animation frame”),
    在这里插入图片描述

c. RootMotion Set
在这里插入图片描述

3.主要函数 【TODO】

  • GetAnimationPose
  • GetBonePose
  • AnimCompressionTypes:: DecompressPose
  • GetBonePose_Additive

2. RootMotion

2.1 RootMotionMontage

UAnimMontage:
1.ExtractRootMotionFromTrackRange:从Montage动画轨道中的一定范围内提取RootMotion数据

  • ExtractRootMotionFromTrack:
    StartTrackPosition、EndTrackPosition:
    从指定的开始时间到结束时间提取Montage内的RootMotion数据,最后输出到FRootMotionMovementParams对象

  • GetRootMotionExtractionStepsForTrackRange:
    由于一个Montage的动画轨道可能由多个动画序列组成,所以按照逐动画序列的方式提取RootMotion数据,存在TArray中。
    FRootMotionExtractionStep:其中存着一个动画序列(UAnimSequence)和提取RootMotion数据的范围(开始位置和结束位置)
    可能会遇到回环播放的情况(StartTrackPosition>EndTrackPosition),需要按正确的顺序提取。
    如果是回环播放,该动画轨道有多个动画序列的情况下需要从末位往前遍历。
    否则就正常按顺序遍历动画序列列表。
    在这里插入图片描述

  • FAnimSegment::GetRootMotionExtractionStepsForTrackRange
    检查起始时间和结束时间是否落在该动画序列范围内,如果是的话加入到Step列表

  • ExtractRootMotionFromTrack:

    • 计算完Step动画集合后,遍历Step
    • 判断其中的动画是否开启了RootMotion。
    • 对于开启RootMotion的Step(AnimSequence)
      调用AnimSequence->ExtractRootMotionFromRange提取位移数据
      FTransform StartTransform = ExtractRootTrackTransform(StartTrackPosition, NULL);
      FTransform EndTransform = ExtractRootTrackTransform(EndTrackPosition, NULL);
      =》UAnimSequence::GetBoneTransform
      =》AnimEncodingLegacyBase::GetBoneAtom 最后调到该接口提取
  • 然后将提取后的位移数据(DeltaTransform)存到FRootMotionMovementParams对象中
    RootMotion.Accumulate(DeltaTransform),该函数是不输入权重的,直接1比1的融合出最终位移
    在这里插入图片描述

2.2 RootMotion Anim

FAnimInstanceProxy::TickAssetPlayerInstances:
当RootMotion模式为RootMotionFromEverything时,在该函数中,根据权重将RootMotion数据提取到FRootMotionMovementParams对象中

2.3 RootMotion应用和同步

见移动同步篇。

3. 动画叠加:FAnimNode_ApplyAdditive

1.主要变量:
FPoseLink Base: 连接base动画节点
FPoseLink Additive: 连接叠加动画节点
float Alpha: 叠加权重

2.主要接口:

  • FAnimNode_ApplyAdditive::Evaluate_AnyThread
    • 获取Base节点和叠加节点的两个动画姿势
      Base.Evaluate(Output);
      const bool bExpectsAdditivePose = true;
      FPoseContext AdditiveEvalContext(Output, bExpectsAdditivePose);
      Additive.Evaluate(AdditiveEvalContext);
    • 计算叠加后的结果姿势
      FAnimationRuntime::AccumulateAdditivePose
  • FAnimationRuntime::AccumulateAdditivePose
    • 根据叠加的类型,选择不同接口计算
      局部空间叠加:AccumulateLocalSpaceAdditivePoseInternal
      网格体空间叠加:AccumulateMeshSpaceRotationAdditiveToLocalPoseInternal
    • 如果是曲线动画
      BaseCurve.Accumulate(AdditiveCurve, Weight);
  • FAnimationRuntime::AccumulateLocalSpaceAdditivePoseInternal
    • 遍历BasePose的每根骨骼:
      根据叠加权重,对每根骨骼进行叠加计算
      叠加权重为1时:
      BasePose[BoneIndex].AccumulateWithAdditiveScale(AdditivePose[BoneIndex], VBlendWeight);
      叠加权重小于1时:
      FTransform Additive = AdditivePose[BoneIndex];
      FTransform::BlendFromIdentityAndAccumulate(BasePose[BoneIndex], Additive, VBlendWeight);
  • AccumulateWithAdditiveScale:计算叠加后的Rotation、Translation、Scale数据
    Atom:要叠加的姿势数据
    • 处理旋转:旋转的叠加,用四元数乘法:
      const VectorRegister BlendedRotation = VectorMultiply(Atom.Rotation, BlendWeight.Value);
      Rotation = VectorQuaternionMultiply2(BlendedRotation, Rotation);
    • 处理平移:向量相加即可
      const VectorRegister BlendedTranslation = VectorMultiply(Atom.Translation, BlendWeight.Value);
      Translation = VectorAdd(Translation, BlendedTranslation);
    • 处理缩放:
      Scale3D = Base_Scale3D * (Default + (Atom_Scale3D * wight))
  • BlendFromIdentityAndAccumulate:同样是计算叠加后的Rotation、Translation、Scale数据
    • 平移和缩放的处理上面一致
      虽然用的是Lerp,但(0,0,0)和Atom按Weight做插值,实际上就是Atom * Weight的结果
      在这里插入图片描述
    • 旋转的处理
      在这里插入图片描述

4. 动画混合:BlendSpace

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值