add EnforceTPose method to ControlRig

This commit is contained in:
Masataka SUMI 2022-09-06 21:19:27 +09:00
parent 3753c6cde7
commit e4041895f4
3 changed files with 38 additions and 15 deletions

View File

@ -14,7 +14,7 @@ namespace UniVRM10
public sealed class Vrm10ControlBone
{
/// <summary>
/// このボーンに紐づく種類。
/// このコントロールボーンに紐づくボーンの種類。
/// </summary>
public HumanBodyBones BoneType { get; }
@ -24,13 +24,23 @@ namespace UniVRM10
public Transform ControlTarget { get; }
/// <summary>
/// コントロールのためのボーン Transform。
/// コントロールボーン Transform。
///
/// VRM の T-Pose 姿勢をしているときに、回転とスケールが初期値になっている(正規化)。
/// このボーンに対して localRotation を代入し、コントロールを行う。
/// </summary>
public Transform ControlBone { get; }
/// <summary>
/// コントロールボーンの初期ローカル位置。
/// </summary>
public Vector3 InitialControlBoneLocalPosition { get; }
/// <summary>
/// コントロールボーンの初期ローカル回転。
/// </summary>
public Quaternion InitialControlBoneLocalRotation { get; }
private readonly Quaternion _initialTargetLocalRotation;
private readonly Quaternion _initialTargetGlobalRotation;
private readonly List<Vrm10ControlBone> _children = new List<Vrm10ControlBone>();
@ -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<HumanBodyBones, Vrm10ControlBone> boneMap)
public static Vrm10ControlBone Build(UniHumanoid.Humanoid humanoid, out Dictionary<HumanBodyBones, Vrm10ControlBone> boneMap)
{
var hips = new Vrm10ControlBone(humanoid.Hips, HumanBodyBones.Hips);
boneMap = new Dictionary<HumanBodyBones, Vrm10ControlBone>();
boneMap.Add(HumanBodyBones.Hips, hips);
foreach (Transform child in humanoid.Hips)

View File

@ -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<RuntimeGltfInstance>();
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);
}
}
/// <summary>

View File

@ -13,15 +13,18 @@ namespace UniVRM10
public sealed class Vrm10RuntimeControlRig
{
private readonly Vrm10ControlBone _rootBone;
private readonly Dictionary<HumanBodyBones, Vrm10ControlBone> _bones = new Dictionary<HumanBodyBones, Vrm10ControlBone>();
private readonly Dictionary<HumanBodyBones, Vrm10ControlBone> _bones;
public float InitialHipsHeight { get; }
/// <summary>
/// コンストラクタ。
/// humanoid は VRM T-Pose でなければならない。
/// </summary>
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;
}
}
}
}