| 756 | } |
| 757 | |
| 758 | static void DoAnimate(HRigContext context, RigInstance* instance, float dt) |
| 759 | { |
| 760 | // NOTE we previously checked for (!instance->m_Enabled || !instance->m_AddedToUpdate) here also |
| 761 | if (!instance->m_MorphSlots.Empty()) |
| 762 | { |
| 763 | ResetMorphWeights(instance); |
| 764 | } |
| 765 | |
| 766 | if (!IsAnimating(instance)) |
| 767 | { |
| 768 | // Skinned meshes sample the pose matrix cache every frame. If we skip the cache write while |
| 769 | // idle, the vertex shader falls back to non-skinned positions which can cause a disparity |
| 770 | // between authoring tools and animated result. Instead, we write the non-animated |
| 771 | // current non-playing pose whenever this instance owns cache space. |
| 772 | if (instance->m_Skeleton && instance->m_PoseMatrixCacheIndex != INVALID_POSE_MATRIX_CACHE_ENTRY) |
| 773 | { |
| 774 | dmArray<BonePose>& pose = instance->m_Pose; |
| 775 | UpdatePoseTransforms(instance->m_Skeleton, pose); |
| 776 | CommitPoseMatrixToCache(context, instance); |
| 777 | } |
| 778 | return; |
| 779 | } |
| 780 | |
| 781 | RigPlayer* player = GetPlayer(instance); |
| 782 | const dmRigDDF::Skeleton* skeleton = instance->m_Skeleton; |
| 783 | |
| 784 | dmArray<BonePose>& pose = instance->m_Pose; |
| 785 | ResetPose(skeleton, pose); |
| 786 | |
| 787 | // Reset IK animation |
| 788 | dmArray<IKAnimation>& ik_animation = instance->m_IKAnimation; |
| 789 | uint32_t ik_animation_count = ik_animation.Size(); |
| 790 | for (uint32_t ii = 0; ii < ik_animation_count; ++ii) |
| 791 | { |
| 792 | const dmRigDDF::IK* ik = &skeleton->m_Iks[ii]; |
| 793 | ik_animation[ii].m_Mix = ik->m_Mix; |
| 794 | ik_animation[ii].m_Positive = ik->m_Positive; |
| 795 | } |
| 796 | |
| 797 | UpdateBlend(instance, dt); |
| 798 | |
| 799 | if (instance->m_Blending) |
| 800 | { |
| 801 | float fade_rate = instance->m_BlendTimer / instance->m_BlendDuration; |
| 802 | // How much to blend the pose, 1 first time to overwrite the bind pose, either fade_rate or 1 - fade_rate second depending on which one is the current player |
| 803 | float alpha = 1.0f; |
| 804 | for (uint32_t pi = 0; pi < 2; ++pi) |
| 805 | { |
| 806 | RigPlayer* p = &instance->m_Players[pi]; |
| 807 | // How much relative blending between the two players |
| 808 | float blend_weight = fade_rate; |
| 809 | if (player != p) { |
| 810 | blend_weight = 1.0f - fade_rate; |
| 811 | } |
| 812 | |
| 813 | UpdatePlayer(instance, p, dt, blend_weight); |
| 814 | ApplyAnimation(instance, p, pose, ik_animation, alpha); |
| 815 | ApplyMorphAnimation(instance, p, alpha); |
no test coverage detected