VRM10Retarget 実装実験から ITPoseProvider, INormalizedPoseProvider, INormalizedPoseApplicable を整理

This commit is contained in:
ousttrue 2023-02-21 17:29:18 +09:00
parent a310e2dcf5
commit 2e29b7da65
7 changed files with 37 additions and 42 deletions

View File

@ -73,7 +73,7 @@ namespace UniVRM10
}
#region INormalizedPoseApplicable
public void SetHipsPosition(Vector3 position)
public void SetRawHipsPosition(Vector3 position)
{
var world = _controlRigRoot.TransformPoint(position);
_hipBone.ControlBone.position = world;
@ -102,7 +102,7 @@ namespace UniVRM10
}
#region ITPoseProvider
public IEnumerable<(HumanBodyBones Head, HumanBodyBones Parent)> EnumerateBones()
public IEnumerable<(HumanBodyBones Head, HumanBodyBones Parent)> EnumerateBoneParentPairs()
{
foreach (var headParent in Traverse(_hipBone))
{
@ -112,12 +112,12 @@ namespace UniVRM10
public Vector3 HipTPoseWorldPosition { get; }
public Quaternion GetBoneTPoseWorldRotation(HumanBodyBones bone)
public Quaternion GetBoneWorldRotation(HumanBodyBones bone)
{
return Quaternion.identity;
}
public Vector3 GetBoneTPoseWorldPosition(HumanBodyBones bone)
public Vector3 GetBoneWorldPosition(HumanBodyBones bone)
{
return _bones[bone].InitialTargetGlobalPosition;
}

View File

@ -55,7 +55,7 @@ namespace UniVRM10
}
}
public Vector3 GetHipsPosition()
public Vector3 GetRawHipsPosition()
{
// TODO: from model root ?
return m_animator.GetBoneTransform(HumanBodyBones.Hips).localPosition;
@ -65,17 +65,17 @@ namespace UniVRM10
#region ITPoseProvider
public Vector3 HipTPoseWorldPosition { get; }
public Quaternion GetBoneTPoseWorldRotation(HumanBodyBones bone)
public Quaternion GetBoneWorldRotation(HumanBodyBones bone)
{
throw new System.NotImplementedException();
}
public IEnumerable<(HumanBodyBones Head, HumanBodyBones Parent)> EnumerateBones()
public IEnumerable<(HumanBodyBones Head, HumanBodyBones Parent)> EnumerateBoneParentPairs()
{
throw new System.NotImplementedException();
}
public Vector3 GetBoneTPoseWorldPosition(HumanBodyBones bone)
public Vector3 GetBoneWorldPosition(HumanBodyBones bone)
{
return m_posMap[bone];
}

View File

@ -5,7 +5,7 @@ namespace UniVRM10
{
public interface INormalizedPoseApplicable
{
void SetHipsPosition(Vector3 position);
void SetRawHipsPosition(Vector3 position);
void SetNormalizedLocalRotation(HumanBodyBones bone, Quaternion normalizedLocalRotation);
}

View File

@ -7,7 +7,7 @@ namespace UniVRM10
/// <summary>
/// Get hips position in model root space
/// </summary>
Vector3 GetHipsPosition();
Vector3 GetRawHipsPosition();
/// <summary>
/// Get normalized local rotation

View File

@ -5,31 +5,26 @@ namespace UniVRM10
{
public interface ITPoseProvider
{
/// <summary>
/// * world は ModelRoot を意図していることに注意
/// </summary>
Vector3 HipTPoseWorldPosition { get; }
/// <summary>
/// * world は ModelRoot を意図していることに注意
/// * bone 無いときは Quaternion.Identity ?
/// </summary>
/// <param name="bone"></param>
/// <returns></returns>
Quaternion GetBoneTPoseWorldRotation(HumanBodyBones bone);
/// <summary>
/// * world は ModelRoot を意図していることに注意
/// * bone 無いときは Vector3.zero ?
/// </summary>
/// <param name="bone"></param>
/// <returns></returns>
Vector3 GetBoneTPoseWorldPosition(HumanBodyBones bone);
/// <summary>
/// ボーンを親ボーンとセットで列挙する</returns>
/// </summary>
/// <returns>hips の場合は parent は HumanBodyBones.LastBone で null を表す</returns>
IEnumerable<(HumanBodyBones Head, HumanBodyBones Parent)> EnumerateBones();
IEnumerable<(HumanBodyBones Head, HumanBodyBones Parent)> EnumerateBoneParentPairs();
/// <summary>
/// * bone 無いときは throw するべし
/// * EnumerateBoneParentPairs で事前に有無を確認できる
/// </summary>
/// <param name="bone"></param>
/// <returns></returns>
Quaternion GetBoneWorldRotation(HumanBodyBones bone);
/// <summary>
/// * bone 無いときは throw するべし
/// * EnumerateBoneParentPairs で事前に有無を確認できる
/// </summary>
/// <param name="bone"></param>
/// <returns></returns>
Vector3 GetBoneWorldPosition(HumanBodyBones bone);
}
}

View File

@ -44,7 +44,7 @@ namespace UniVRM10
}
}
public Vector3 GetHipsPosition()
public Vector3 GetRawHipsPosition()
{
if (m_hips.parent == m_root)
{
@ -56,17 +56,17 @@ namespace UniVRM10
}
}
public Quaternion GetBoneTPoseWorldRotation(HumanBodyBones bone)
public Quaternion GetBoneWorldRotation(HumanBodyBones bone)
{
throw new System.NotImplementedException();
}
public IEnumerable<(HumanBodyBones Head, HumanBodyBones Parent)> EnumerateBones()
public IEnumerable<(HumanBodyBones Head, HumanBodyBones Parent)> EnumerateBoneParentPairs()
{
throw new System.NotImplementedException();
}
public Vector3 GetBoneTPoseWorldPosition(HumanBodyBones bone)
public Vector3 GetBoneWorldPosition(HumanBodyBones bone)
{
throw new System.NotImplementedException();
}

View File

@ -6,26 +6,26 @@ namespace UniVRM10
{
public static void Retarget((INormalizedPoseProvider Pose, ITPoseProvider TPose) source, (INormalizedPoseApplicable Pose, ITPoseProvider TPose) sink)
{
foreach (var (head, parent) in sink.TPose.EnumerateBones())
foreach (var (head, parent) in sink.TPose.EnumerateBoneParentPairs())
{
var q = source.Pose.GetNormalizedLocalRotation(head, parent);
sink.Pose.SetNormalizedLocalRotation(head, q);
}
// scaling hips position
var scaling = sink.TPose.GetBoneTPoseWorldPosition(HumanBodyBones.LeftUpperLeg).y / source.TPose.GetBoneTPoseWorldPosition(HumanBodyBones.LeftUpperLeg).y;
var delta = source.Pose.GetHipsPosition() - source.TPose.HipTPoseWorldPosition;
sink.Pose.SetHipsPosition(sink.TPose.HipTPoseWorldPosition + delta * scaling);
var scaling = sink.TPose.GetBoneWorldPosition(HumanBodyBones.LeftUpperLeg).y / source.TPose.GetBoneWorldPosition(HumanBodyBones.LeftUpperLeg).y;
var delta = source.Pose.GetRawHipsPosition() - source.TPose.GetBoneWorldPosition(HumanBodyBones.Hips);
sink.Pose.SetRawHipsPosition(sink.TPose.GetBoneWorldPosition(HumanBodyBones.Hips) + delta * scaling);
}
public static void EnforceTPose((INormalizedPoseApplicable Pose, ITPoseProvider TPose) sink)
{
foreach (var (head, parent) in sink.TPose.EnumerateBones())
foreach (var (head, parent) in sink.TPose.EnumerateBoneParentPairs())
{
sink.Pose.SetNormalizedLocalRotation(head, Quaternion.identity);
}
sink.Pose.SetHipsPosition(sink.TPose.HipTPoseWorldPosition);
sink.Pose.SetRawHipsPosition(sink.TPose.GetBoneWorldPosition(HumanBodyBones.Hips));
}
}
}