diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10BoneWithAxis.cs b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10BoneWithAxis.cs index e131d2d1a..da931757a 100644 --- a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10BoneWithAxis.cs +++ b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10BoneWithAxis.cs @@ -56,6 +56,7 @@ namespace UniVRM10 public static Vrm10BoneWithAxis Build(UniHumanoid.Humanoid humanoid, Dictionary boneMap) { var hips = new Vrm10BoneWithAxis(humanoid.Hips, Quaternion.identity, HumanBodyBones.Hips); + boneMap.Add(HumanBodyBones.Hips, hips); foreach (Transform child in humanoid.Hips) { @@ -93,12 +94,7 @@ namespace UniVRM10 /// public void ApplyRecursive(Quaternion worldParentRotation) { - // var pose = InitialLocalRotation * Normalized.localRotation * Quaternion.Inverse(InitialLocalRotation); - // var pose = Quaternion.Inverse(InitialLocalRotation) * Normalized.localRotation * InitialLocalRotation; Target.localRotation = InitialLocalRotation * Quaternion.Inverse(ToLocal) * Normalized.localRotation * ToLocal; - // Target.localRotation = InitialLocalRotation * Normalized.localRotation; // * Quaternion.Inverse(InitialLocalRotation); - // Target.localRotation = InitialLocalRotation; - foreach (var child in Children) { child.ApplyRecursive(Normalized.rotation); diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10FkRetarget.cs b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10FkRetarget.cs index 1b08b21b5..f91d4bcda 100644 --- a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10FkRetarget.cs +++ b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10FkRetarget.cs @@ -9,12 +9,13 @@ namespace UniVRM10 Dictionary m_boneMap = new Dictionary(); - Vector3 m_initialHipsPosition; + public readonly float InitialHipsHeight; public Vrm10FkRetarget(UniHumanoid.Humanoid humanoid) { m_root = Vrm10BoneWithAxis.Build(humanoid, m_boneMap); - m_initialHipsPosition = m_root.Target.position; + InitialHipsHeight = m_root.Target.position.y; + Debug.Log($"InitialHipsHeight: {InitialHipsHeight}"); } public void Apply() diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10RuntimeLookAt.cs b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10RuntimeLookAt.cs index 7aa88d374..36ba102f8 100644 --- a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10RuntimeLookAt.cs +++ b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10RuntimeLookAt.cs @@ -107,16 +107,15 @@ namespace UniVRM10 gaze.SetParent(m_head); gaze.localPosition = Vector3.forward; } - switch (m_lookat.LookAtType) + + // bone が無いときのエラー防止。マイグレーション失敗? + if (m_lookat.LookAtType == LookAtType.bone && m_leftEye != null && m_rightEye != null) { - case LookAtType.bone: - _eyeDirectionApplicable = new LookAtEyeDirectionApplicableToBone(m_leftEye, m_rightEye, m_lookat.HorizontalOuter, m_lookat.HorizontalInner, m_lookat.VerticalDown, m_lookat.VerticalUp); - break; - case LookAtType.expression: - _eyeDirectionApplicable = new LookAtEyeDirectionApplicableToExpression(m_lookat.HorizontalOuter, m_lookat.HorizontalInner, m_lookat.VerticalDown, m_lookat.VerticalUp); - break; - default: - throw new ArgumentOutOfRangeException(); + _eyeDirectionApplicable = new LookAtEyeDirectionApplicableToBone(m_leftEye, m_rightEye, m_lookat.HorizontalOuter, m_lookat.HorizontalInner, m_lookat.VerticalDown, m_lookat.VerticalUp); + } + else + { + _eyeDirectionApplicable = new LookAtEyeDirectionApplicableToExpression(m_lookat.HorizontalOuter, m_lookat.HorizontalInner, m_lookat.VerticalDown, m_lookat.VerticalUp); } } diff --git a/Assets/VRM10_Samples/VRM10Viewer/VRM10ViewerUI.cs b/Assets/VRM10_Samples/VRM10Viewer/VRM10ViewerUI.cs index 7b56b4676..00ca86a68 100644 --- a/Assets/VRM10_Samples/VRM10Viewer/VRM10ViewerUI.cs +++ b/Assets/VRM10_Samples/VRM10Viewer/VRM10ViewerUI.cs @@ -39,7 +39,7 @@ namespace UniVRM10.VRM10Viewer [Header("Runtime")] [SerializeField] - HumanPoseTransfer m_src = default; + Animator m_src = default; [SerializeField] GameObject m_target = default; @@ -200,7 +200,7 @@ namespace UniVRM10.VRM10Viewer var texts = GameObject.FindObjectsOfType(); m_version = texts.First(x => x.name == "Version"); - m_src = GameObject.FindObjectOfType(); + m_src = GameObject.FindObjectOfType(); m_target = GameObject.FindObjectOfType().gameObject; } @@ -208,7 +208,7 @@ namespace UniVRM10.VRM10Viewer class Loaded : IDisposable { RuntimeGltfInstance m_instance; - HumanPoseTransfer m_pose; + bool m_useBvh; Vrm10Instance m_controller; VRM10AIUEO m_lipSync; @@ -256,7 +256,7 @@ namespace UniVRM10.VRM10Viewer } } - public Loaded(RuntimeGltfInstance instance, HumanPoseTransfer src, Transform lookAtTarget) + public Loaded(RuntimeGltfInstance instance, Transform lookAtTarget) { m_instance = instance; @@ -266,10 +266,6 @@ namespace UniVRM10.VRM10Viewer // VRM m_controller.UpdateType = Vrm10Instance.UpdateTypes.LateUpdate; // after HumanPoseTransfer's setPose { - m_pose = instance.gameObject.AddComponent(); - m_pose.Source = src; - m_pose.SourceType = HumanPoseTransfer.HumanPoseTransferSourceType.HumanPoseTransfer; - m_lipSync = instance.gameObject.AddComponent(); m_blink = instance.gameObject.AddComponent(); m_autoExpression = instance.gameObject.AddComponent(); @@ -293,22 +289,57 @@ namespace UniVRM10.VRM10Viewer GameObject.Destroy(m_instance.gameObject); } - public void EnableBvh(HumanPoseTransfer src) + public void EnableBvh() { - if (m_pose != null) - { - m_pose.Source = src; - m_pose.SourceType = HumanPoseTransfer.HumanPoseTransferSourceType.HumanPoseTransfer; - } + m_useBvh = true; } - public void EnableTPose(HumanPoseClip pose) + public void EnableTPose() { - if (m_pose != null) + m_useBvh = false; + } + + public void UpdatePose(Animator pose) + { + var fkRetarget = m_controller.Runtime.GetOrCreateFkRetarget(); + foreach (HumanBodyBones bone in Enum.GetValues(typeof(HumanBodyBones))) { - m_pose.PoseClip = pose; - m_pose.SourceType = HumanPoseTransfer.HumanPoseTransferSourceType.HumanPoseClip; + if (bone == HumanBodyBones.LastBone) + { + continue; + } + + var dst = fkRetarget.GetBoneTransform(bone); + if (dst == null) + { + continue; + } + + if (m_useBvh) + { + var src = pose.GetBoneTransform(bone); + if (src != null) + { + // set normalized pose + dst.localRotation = src.localRotation; + } + + if (bone == HumanBodyBones.Hips) + { + dst.position = src.position * fkRetarget.InitialHipsHeight; + } + } + else + { + // set TPose + dst.localRotation = Quaternion.identity; + if (bone == HumanBodyBones.Hips) + { + dst.position = Vector3.up * fkRetarget.InitialHipsHeight; + } + } } + fkRetarget.Apply(); } } Loaded m_loaded; @@ -344,7 +375,7 @@ namespace UniVRM10.VRM10Viewer var context = new UniHumanoid.BvhImporterContext(); context.Parse("tmp.bvh", source); context.Load(); - SetMotion(context.Root.GetComponent()); + SetMotion(context.Root.GetComponent()); } private void Update() @@ -369,7 +400,12 @@ namespace UniVRM10.VRM10Viewer } } - m_ui.UpdateToggle(() => m_loaded?.EnableBvh(m_src), () => m_loaded?.EnableTPose(m_pose)); + m_ui.UpdateToggle(() => m_loaded?.EnableBvh(), () => m_loaded?.EnableTPose()); + + if (m_loaded != null) + { + m_loaded.UpdatePose(m_src); + } } void OnOpenClicked() @@ -506,17 +542,15 @@ namespace UniVRM10.VRM10Viewer instance.ShowMeshes(); instance.EnableUpdateWhenOffscreen(); - m_loaded = new Loaded(instance, m_src, m_target.transform); + m_loaded = new Loaded(instance, m_target.transform); } - void SetMotion(HumanPoseTransfer src) + void SetMotion(Animator src) { m_src = src; - src.GetComponent().enabled = false; - if (m_loaded != null) { - m_loaded.EnableBvh(m_src); + m_loaded.EnableBvh(); } } }