diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/ControlRig/Vrm10ControlBone.cs b/Assets/VRM10/Runtime/Components/Vrm10Runtime/ControlRig/Vrm10ControlBone.cs
index 7c022fc3a..f6b441c5c 100644
--- a/Assets/VRM10/Runtime/Components/Vrm10Runtime/ControlRig/Vrm10ControlBone.cs
+++ b/Assets/VRM10/Runtime/Components/Vrm10Runtime/ControlRig/Vrm10ControlBone.cs
@@ -5,99 +5,94 @@ using UnityEngine;
namespace UniVRM10
{
///
+ /// The control bone of the control rig.
+ ///
/// このクラスのヒエラルキーが 正規化された TPose を表している。
/// 同時に、元のヒエラルキーの初期回転を保持する。
/// Apply 関数で、再帰的に正規化済みのローカル回転から初期回転を加味したローカル回転を作って適用する。
///
- public class Vrm10ControlBone
+ public sealed class Vrm10ControlBone
{
- public readonly HumanBodyBones Bone;
+ ///
+ /// このボーンに紐づく種類。
+ ///
+ public HumanBodyBones BoneType { get; }
///
- /// 元のヒエラルキーの対応ボーン
+ /// コントロール対象のボーン Transform。
///
- public readonly Transform Target;
+ public Transform ControlTarget { get; }
///
- /// 回転と拡大縮小を除去した(正規化された)ボーン。
- /// このボーンに対して localRotation を代入する。
+ /// コントロールのためのボーン Transform。
+ ///
+ /// VRM の T-Pose 姿勢をしているときに、回転とスケールが初期値になっている(正規化)。
+ /// このボーンに対して localRotation を代入し、コントロールを行う。
///
- public readonly Transform Normalized;
+ public Transform ControlBone { get; }
- ///
- /// 元のボーンの初期回転。
- ///
- public readonly Quaternion InitialLocalRotation;
+ private readonly Quaternion _initialTargetLocalRotation;
+ private readonly Quaternion _initialTargetGlobalRotation;
+ private readonly List _children = new List();
- public readonly Quaternion ToLocal;
-
- public List Children = new List();
-
- public Vrm10ControlBone(Transform current, Quaternion parentInverse, HumanBodyBones bone)
+ internal Vrm10ControlBone(Transform controlTarget, HumanBodyBones boneType)
{
- if (bone == HumanBodyBones.LastBone)
+ if (boneType == HumanBodyBones.LastBone)
{
throw new ArgumentNullException();
}
- if (current == null)
+ if (controlTarget == null)
{
throw new ArgumentNullException();
}
- Bone = bone;
- Target = current;
- Normalized = new GameObject(bone.ToString()).transform;
- Normalized.position = current.position;
- // InitialLocalRotation = parentInverse * current.rotation;
- InitialLocalRotation = current.localRotation;
- // InitialLocalRotation = current.rotation;
- ToLocal = current.rotation;
+
+ BoneType = boneType;
+ ControlTarget = controlTarget;
+ ControlBone = new GameObject(boneType.ToString()).transform;
+ ControlBone.position = controlTarget.position;
+ _initialTargetLocalRotation = controlTarget.localRotation;
+ _initialTargetGlobalRotation = controlTarget.rotation;
+ }
+
+ ///
+ /// 親から再帰的にNormalized の ローカル回転を初期回転を加味して Target に適用する。
+ ///
+ internal void ProcessRecursively()
+ {
+ ControlTarget.localRotation = _initialTargetLocalRotation * Quaternion.Inverse(_initialTargetGlobalRotation) * ControlBone.localRotation * _initialTargetGlobalRotation;
+ foreach (var child in _children)
+ {
+ child.ProcessRecursively();
+ }
}
public static Vrm10ControlBone Build(UniHumanoid.Humanoid humanoid, Dictionary boneMap)
{
- var hips = new Vrm10ControlBone(humanoid.Hips, Quaternion.identity, HumanBodyBones.Hips);
+ var hips = new Vrm10ControlBone(humanoid.Hips, HumanBodyBones.Hips);
boneMap.Add(HumanBodyBones.Hips, hips);
foreach (Transform child in humanoid.Hips)
{
- Traverse(humanoid, child, hips, boneMap);
+ BuildRecursively(humanoid, child, hips, boneMap);
}
return hips;
}
- private static void Traverse(UniHumanoid.Humanoid humanoid, Transform current, Vrm10ControlBone parent, Dictionary boneMap)
+ private static void BuildRecursively(UniHumanoid.Humanoid humanoid, Transform current, Vrm10ControlBone parent, Dictionary boneMap)
{
if (humanoid.TryGetBoneForTransform(current, out var bone))
{
-
- // ヒューマンボーンだけを対象にするので、
- // parent が current の直接の親でない場合がある。
- // ワールド回転 parent^-1 * current からローカル回転を算出する。
- var parentInverse = Quaternion.Inverse(parent.Target.rotation);
-
- var newBone = new Vrm10ControlBone(current, parentInverse, bone);
- newBone.Normalized.SetParent(parent.Normalized, true);
- parent.Children.Add(newBone);
+ var newBone = new Vrm10ControlBone(current, bone);
+ newBone.ControlBone.SetParent(parent.ControlBone, true);
+ parent._children.Add(newBone);
parent = newBone;
boneMap.Add(bone, newBone);
}
foreach (Transform child in current)
{
- Traverse(humanoid, child, parent, boneMap);
- }
- }
-
- ///
- /// 親から再帰的にNormalized の ローカル回転を初期回転を加味して Target に適用する。
- ///
- public void ApplyRecursive(Quaternion worldParentRotation)
- {
- Target.localRotation = InitialLocalRotation * Quaternion.Inverse(ToLocal) * Normalized.localRotation * ToLocal;
- foreach (var child in Children)
- {
- child.ApplyRecursive(Normalized.rotation);
+ BuildRecursively(humanoid, child, parent, boneMap);
}
}
}
diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10Runtime.cs b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10Runtime.cs
index 8f555e2c0..12a474a89 100644
--- a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10Runtime.cs
+++ b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10Runtime.cs
@@ -9,7 +9,14 @@ using UniVRM10.FastSpringBones.System;
namespace UniVRM10
{
///
- /// Play時 と Editorからの参照情報置き場
+ /// VRM モデルインスタンスを、状態をもって、元の状態から操作・変更するためのクラス。
+ /// また、仕様に従ってその操作を行う。
+ ///
+ /// 操作対象としては以下が挙げられる。
+ /// - ControlRig
+ /// - Constraint
+ /// - LookAt
+ /// - Expression
///
public class Vrm10Runtime : IDisposable
{
diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10RuntimeControlRig.cs b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10RuntimeControlRig.cs
index 65224f4f2..bfd70716c 100644
--- a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10RuntimeControlRig.cs
+++ b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10RuntimeControlRig.cs
@@ -10,31 +10,31 @@ namespace UniVRM10
/// Create a control rig for the VRM 1.0 model instance.
/// This provides the normalized operation of bones, like VRM 0.x.
///
- public class Vrm10RuntimeControlRig
+ public sealed class Vrm10RuntimeControlRig
{
private readonly Vrm10ControlBone _rootBone;
private readonly Dictionary _bones = new Dictionary();
- public readonly float InitialHipsHeight;
+ public float InitialHipsHeight { get; }
public Vrm10RuntimeControlRig(UniHumanoid.Humanoid humanoid)
{
_rootBone = Vrm10ControlBone.Build(humanoid, _bones);
- InitialHipsHeight = _rootBone.Target.position.y;
+ InitialHipsHeight = _rootBone.ControlTarget.position.y;
Debug.Log($"InitialHipsHeight: {InitialHipsHeight}");
}
public void Process()
{
- _rootBone.Target.position = _rootBone.Normalized.position;
- _rootBone.ApplyRecursive(Quaternion.identity);
+ _rootBone.ControlTarget.position = _rootBone.ControlBone.position;
+ _rootBone.ProcessRecursively();
}
public Transform GetBoneTransform(HumanBodyBones bone)
{
if (_bones.TryGetValue(bone, out var value))
{
- return value.Normalized;
+ return value.ControlBone;
}
else
{