From e4041895f472a0bbb2f8961915d476a889d79004 Mon Sep 17 00:00:00 2001 From: Masataka SUMI Date: Tue, 6 Sep 2022 21:19:27 +0900 Subject: [PATCH] add EnforceTPose method to ControlRig --- .../ControlRig/Vrm10ControlBone.cs | 19 ++++++++++++++++--- .../Components/Vrm10Runtime/Vrm10Runtime.cs | 16 +++++++--------- .../Vrm10Runtime/Vrm10RuntimeControlRig.cs | 18 +++++++++++++++--- 3 files changed, 38 insertions(+), 15 deletions(-) diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/ControlRig/Vrm10ControlBone.cs b/Assets/VRM10/Runtime/Components/Vrm10Runtime/ControlRig/Vrm10ControlBone.cs index f6b441c5c..c43f742f1 100644 --- a/Assets/VRM10/Runtime/Components/Vrm10Runtime/ControlRig/Vrm10ControlBone.cs +++ b/Assets/VRM10/Runtime/Components/Vrm10Runtime/ControlRig/Vrm10ControlBone.cs @@ -14,7 +14,7 @@ namespace UniVRM10 public sealed class Vrm10ControlBone { /// - /// このボーンに紐づく種類。 + /// このコントロールボーンに紐づくボーンの種類。 /// public HumanBodyBones BoneType { get; } @@ -24,13 +24,23 @@ namespace UniVRM10 public Transform ControlTarget { get; } /// - /// コントロールのためのボーン Transform。 + /// コントロールボーンの Transform。 /// /// VRM の T-Pose 姿勢をしているときに、回転とスケールが初期値になっている(正規化)。 /// このボーンに対して localRotation を代入し、コントロールを行う。 /// public Transform ControlBone { get; } + /// + /// コントロールボーンの初期ローカル位置。 + /// + public Vector3 InitialControlBoneLocalPosition { get; } + + /// + /// コントロールボーンの初期ローカル回転。 + /// + public Quaternion InitialControlBoneLocalRotation { get; } + private readonly Quaternion _initialTargetLocalRotation; private readonly Quaternion _initialTargetGlobalRotation; private readonly List _children = new List(); @@ -50,6 +60,8 @@ namespace UniVRM10 ControlTarget = controlTarget; ControlBone = new GameObject(boneType.ToString()).transform; ControlBone.position = controlTarget.position; + InitialControlBoneLocalPosition = ControlBone.localPosition; + InitialControlBoneLocalRotation = ControlBone.localRotation; _initialTargetLocalRotation = controlTarget.localRotation; _initialTargetGlobalRotation = controlTarget.rotation; } @@ -66,9 +78,10 @@ namespace UniVRM10 } } - public static Vrm10ControlBone Build(UniHumanoid.Humanoid humanoid, Dictionary boneMap) + public static Vrm10ControlBone Build(UniHumanoid.Humanoid humanoid, out Dictionary boneMap) { var hips = new Vrm10ControlBone(humanoid.Hips, HumanBodyBones.Hips); + boneMap = new Dictionary(); boneMap.Add(HumanBodyBones.Hips, hips); foreach (Transform child in humanoid.Hips) diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10Runtime.cs b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10Runtime.cs index 93cf66f26..6383f8f51 100644 --- a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10Runtime.cs +++ b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10Runtime.cs @@ -46,12 +46,6 @@ namespace UniVRM10 LookAt = new Vrm10RuntimeLookAt(target.Vrm.LookAt, target.Humanoid, m_head, target.LookAtTargetType, target.Gaze); Expression = new Vrm10RuntimeExpression(target, LookAt, LookAt.EyeDirectionApplicable); - if (!Application.isPlaying) - { - // for UnitTest - return; - } - var instance = target.GetComponent(); if (instance != null) { @@ -65,9 +59,13 @@ namespace UniVRM10 .ToDictionary(tf => tf, tf => new TransformState(tf)); } - m_fastSpringBoneService = FastSpringBoneService.Instance; - m_fastSpringBoneBuffer = CreateFastSpringBoneBuffer(m_target.SpringBone); - m_fastSpringBoneService.BufferCombiner.Register(m_fastSpringBoneBuffer); + // NOTE: FastSpringBoneService は UnitTest などでは動作しない + if (Application.isPlaying) + { + m_fastSpringBoneService = FastSpringBoneService.Instance; + m_fastSpringBoneBuffer = CreateFastSpringBoneBuffer(m_target.SpringBone); + m_fastSpringBoneService.BufferCombiner.Register(m_fastSpringBoneBuffer); + } } /// diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10RuntimeControlRig.cs b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10RuntimeControlRig.cs index 7c487b1be..9adbeb807 100644 --- a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10RuntimeControlRig.cs +++ b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10RuntimeControlRig.cs @@ -13,15 +13,18 @@ namespace UniVRM10 public sealed class Vrm10RuntimeControlRig { private readonly Vrm10ControlBone _rootBone; - private readonly Dictionary _bones = new Dictionary(); + private readonly Dictionary _bones; public float InitialHipsHeight { get; } + /// + /// コンストラクタ。 + /// humanoid は VRM T-Pose でなければならない。 + /// public Vrm10RuntimeControlRig(UniHumanoid.Humanoid humanoid) { - _rootBone = Vrm10ControlBone.Build(humanoid, _bones); + _rootBone = Vrm10ControlBone.Build(humanoid, out _bones); InitialHipsHeight = _rootBone.ControlTarget.position.y; - Debug.Log($"InitialHipsHeight: {InitialHipsHeight}"); } internal void Process() @@ -41,5 +44,14 @@ namespace UniVRM10 return null; } } + + public void EnforceTPose() + { + foreach (var bone in _bones.Values) + { + bone.ControlBone.localPosition = bone.InitialControlBoneLocalPosition; + bone.ControlBone.localRotation = bone.InitialControlBoneLocalRotation; + } + } } }