From 6d24603bf05756ee17df3084892fd5df76bee03c Mon Sep 17 00:00:00 2001 From: dexy Date: Fri, 12 Jul 2024 12:36:32 +1000 Subject: [PATCH] PR #241 but maybe slightly optimized --- CodeWalker/Rendering/Renderable.cs | 110 ++++++++++++++++------------- 1 file changed, 59 insertions(+), 51 deletions(-) diff --git a/CodeWalker/Rendering/Renderable.cs b/CodeWalker/Rendering/Renderable.cs index 63de708..9aedf5b 100644 --- a/CodeWalker/Rendering/Renderable.cs +++ b/CodeWalker/Rendering/Renderable.cs @@ -87,6 +87,8 @@ namespace CodeWalker.Rendering public Dictionary ModelBoneLinks; public bool EnableRootMotion = false; //used to toggle whether or not to include root motion when playing animations + public Vector3 RootMotionPosition; + public Quaternion RootMotionRotation; public ClothInstance Cloth; @@ -483,6 +485,8 @@ namespace CodeWalker.Rendering } private void UpdateAnim(ClipMapEntry cme) { + RootMotionPosition = Vector3.Zero; + RootMotionRotation = Quaternion.Identity; var clipanim = cme.Clip as ClipAnimation; if (clipanim?.Animation != null) @@ -500,6 +504,57 @@ namespace CodeWalker.Rendering } } + var bonesmap = Skeleton?.BonesMap; + var bones = Skeleton?.BonesSorted; + if (bones != null) + { + for (int i = 0; i < bones.Length; i++) + { + var bone = bones[i]; + var tag = bone.Tag; + switch (bone.Tag) + { + case 23639: tag = 58271; break; //RB_L_ThighRoll: SKEL_L_Thigh + case 6442: tag = 51826; break; //RB_R_ThighRoll: SKEL_R_Thigh + //case 61007: tag = 61163; break; //RB_L_ForeArmRoll: SKEL_L_Forearm //NOT GOOD + //case 5232: tag = 45509; break; //RB_L_ArmRoll: SKEL_L_UpperArm + } + if ((tag != bone.Tag) && (tag != bone.Parent?.Tag)) + { + if ((bonesmap != null) && bonesmap.TryGetValue(tag, out var obone)) + { + bone.AnimRotation = obone.AnimRotation; + } + } + } + for (int i = 0; i < bones.Length; i++) + { + var bone = bones[i]; + + if (EnableRootMotion && (bone.Tag == 0)) + { + bone.AnimTranslation = RootMotionPosition + RootMotionRotation.Multiply(bone.AnimTranslation); + bone.AnimRotation = RootMotionRotation * bone.AnimRotation; + } + + bone.UpdateAnimTransform(); + bone.UpdateSkinTransform(); + + //update model's transform from animated bone + RenderableModel bmodel = null; + ModelBoneLinks?.TryGetValue(bone.Tag, out bmodel); + + + if (bmodel == null) + { continue; } + if (bmodel.IsSkinMesh) //don't transform model for skin mesh + { continue; } + + bmodel.Transform = bone.AnimTransform; + + } + } + } private void UpdateAnim(Animation anim, float t) { @@ -570,18 +625,12 @@ namespace CodeWalker.Rendering bone.AnimScale = v.XYZ(); break; case 5://root motion vector - if (EnableRootMotion) - { - v = anim.EvaluateVector4(frame, i, interpolate); - bone.AnimTranslation += v.XYZ(); - } + v = anim.EvaluateVector4(frame, i, interpolate); + RootMotionPosition += v.XYZ(); break; case 6://quaternion... root rotation - if (EnableRootMotion) - { - q = anim.EvaluateQuaternion(frame, i, interpolate); - bone.AnimRotation = q * bone.AnimRotation; - } + q = anim.EvaluateQuaternion(frame, i, interpolate); + RootMotionRotation *= q; break; case 7://vector3... (camera position?) break; @@ -620,47 +669,6 @@ namespace CodeWalker.Rendering } } - for (int i = 0; i < bones.Length; i++) - { - var bone = bones[i]; - var tag = bone.Tag; - switch (bone.Tag) - { - case 23639: tag = 58271; break; //RB_L_ThighRoll: SKEL_L_Thigh - case 6442: tag = 51826; break; //RB_R_ThighRoll: SKEL_R_Thigh - //case 61007: tag = 61163; break; //RB_L_ForeArmRoll: SKEL_L_Forearm //NOT GOOD - //case 5232: tag = 45509; break; //RB_L_ArmRoll: SKEL_L_UpperArm - } - if ((tag != bone.Tag) && (tag != bone.Parent?.Tag)) - { - var obone = bone; - if (skel.BonesMap.TryGetValue(tag, out obone)) - { - bone.AnimRotation = obone.AnimRotation; - } - } - } - - for (int i = 0; i < bones.Length; i++) - { - var bone = bones[i]; - bone.UpdateAnimTransform(); - bone.UpdateSkinTransform(); - - //update model's transform from animated bone - RenderableModel bmodel = null; - ModelBoneLinks?.TryGetValue(bone.Tag, out bmodel); - - - if (bmodel == null) - { continue; } - if (bmodel.IsSkinMesh) //don't transform model for skin mesh - { continue; } - - bmodel.Transform = bone.AnimTransform; - - } - } private void UpdateAnimUV(ClipMapEntry cme, RenderableGeometry rgeom = null)