diff --git a/Assets/VRM10/Editor/Components/Constraint/VRM10PositionConstraintEditor.cs b/Assets/VRM10/Editor/Components/Constraint/VRM10PositionConstraintEditor.cs new file mode 100644 index 000000000..897497304 --- /dev/null +++ b/Assets/VRM10/Editor/Components/Constraint/VRM10PositionConstraintEditor.cs @@ -0,0 +1,71 @@ +using System.Text; +using UnityEditor; +using UnityEngine; + +namespace UniVRM10 +{ + [CustomEditor(typeof(VRM10PositionConstraint))] + public class VRM10PositionConstraintEditor : Editor + { + VRM10PositionConstraint m_target; + + void OnEnable() + { + m_target = (VRM10PositionConstraint)target; + } + + static GUIStyle s_style; + static GUIStyle Style + { + get + { + if (s_style == null) + { + s_style = new GUIStyle("box"); + } + return s_style; + } + } + + public void OnSceneGUI() + { + if (m_target.Source == null) + { + return; + } + + // this to target line + Handles.color = Color.yellow; + Handles.DrawLine(m_target.Source.position, m_target.transform.position); + + var delta = m_target.Delta; + + // show source + { + var sb = new StringBuilder(); + sb.AppendLine(); + sb.AppendLine(); + sb.AppendLine($"source: {m_target.SourceCoordinate}"); + sb.AppendLine($"{delta.x:0.00}"); + sb.AppendLine($"{delta.y:0.00}"); + sb.Append($"{delta.z:0.00}"); + Handles.Label(m_target.Source.position, sb.ToString(), Style); + } + + // show dst + { + var sb = new StringBuilder(); + sb.AppendLine($"constraint: {m_target.DestinationCoordinate}"); + sb.AppendLine(m_target.FreezeAxes.HasFlag(AxisMask.X) ? $"freeze" : $"{delta.x:0.}"); + sb.AppendLine(m_target.FreezeAxes.HasFlag(AxisMask.Y) ? $"freeze" : $"{delta.y:0.}"); + sb.Append(m_target.FreezeAxes.HasFlag(AxisMask.Z) ? $"freeze" : $"{delta.z:0.}"); + Handles.Label(m_target.transform.position, sb.ToString(), Style); + } + + m_target.DrawSourceCoords(); + m_target.DrawSourceCurrent(); + m_target.DrawDstCoords(); + m_target.DrawDstCurrent(); + } + } +} diff --git a/Assets/VRM10/Editor/Components/Constraint/VRM10PositionConstraintEditor.cs.meta b/Assets/VRM10/Editor/Components/Constraint/VRM10PositionConstraintEditor.cs.meta new file mode 100644 index 000000000..7abff9c34 --- /dev/null +++ b/Assets/VRM10/Editor/Components/Constraint/VRM10PositionConstraintEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d4c6d6f5f37e41e47bd02bdf1dbda864 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/VRM10/Runtime/Components/Constraint/TR.cs b/Assets/VRM10/Runtime/Components/Constraint/TR.cs index c5c968c91..14466898f 100644 --- a/Assets/VRM10/Runtime/Components/Constraint/TR.cs +++ b/Assets/VRM10/Runtime/Components/Constraint/TR.cs @@ -29,6 +29,10 @@ namespace UniVRM10 { } + public TR(Vector3 t) : this(Quaternion.identity, t) + { + } + public Matrix4x4 TRS(float s) => Matrix4x4.TRS(Translation, Rotation, new Vector3(s, s, s)); public static TR operator *(TR a, TR b) => new TR(a.Rotation * b.Rotation, a.Rotation * b.Translation + a.Translation); diff --git a/Assets/VRM10/Runtime/Components/Constraint/VRM10PositionConstraint.cs b/Assets/VRM10/Runtime/Components/Constraint/VRM10PositionConstraint.cs index e69466a26..cf8bfa5a3 100644 --- a/Assets/VRM10/Runtime/Components/Constraint/VRM10PositionConstraint.cs +++ b/Assets/VRM10/Runtime/Components/Constraint/VRM10PositionConstraint.cs @@ -1,4 +1,5 @@ -using UniGLTF.Extensions.VRMC_node_constraint; +using System; +using UniGLTF.Extensions.VRMC_node_constraint; using UnityEngine; namespace UniVRM10 @@ -7,7 +8,7 @@ namespace UniVRM10 /// 対象の初期位置と現在位置の差分(delta)を、自身の初期位置に対してWeightを乗算して加算する。 /// [DisallowMultipleComponent] - public class VRM10PositionConstraint : VRM10Constraint + public class VRM10PositionConstraint : VRM10Constraint, IVRM10ConstraintSourceDestination { [SerializeField] public Transform Source = default; @@ -30,8 +31,116 @@ namespace UniVRM10 ConstraintSource m_src; + public TR GetSourceCoords() + { + if (Source == null) + { + throw new ConstraintException(ConstraintException.ExceptionTypes.NoSource); + } + + switch (SourceCoordinate) + { + case ObjectSpace.model: + { + if (ModelRoot == null) + { + throw new ConstraintException(ConstraintException.ExceptionTypes.NoModelWithModelSpace); + } + + if (m_src == null) + { + return new TR(ModelRoot.rotation, Source.position); + } + + // runtime + return new TR(ModelRoot.rotation, m_src.ModelInitial.Translation); + } + + case ObjectSpace.local: + { + if (m_src == null) + { + return TR.FromWorld(Source); + } + + // runtime + var parent = TR.Identity; + if (Source.parent != null) + { + parent = TR.FromWorld(Source.parent); + } + return parent * m_src.LocalInitial; + } + + default: + throw new NotImplementedException(); + } + } + + public TR GetSourceCurrent() + { + var coords = GetSourceCoords(); + if (m_src == null) + { + return coords; + } + + return new TR(Delta) * coords; + } + + public Vector3 Delta + { + get; + private set; + } + ConstraintDestination m_dst; + public TR GetDstCoords() + { + switch (DestinationCoordinate) + { + case ObjectSpace.model: + { + if (ModelRoot == null) + { + throw new ConstraintException(ConstraintException.ExceptionTypes.NoModelWithModelSpace); + } + return new TR(ModelRoot.rotation, transform.position); + } + + case ObjectSpace.local: + { + if (m_src == null) + { + return TR.FromWorld(transform); + } + + // runtime + var parent = TR.Identity; + if (transform.parent != null) + { + parent = TR.FromWorld(transform.parent); + } + return parent * m_dst.LocalInitial; + } + + default: + throw new NotImplementedException(); + } + } + + public TR GetDstCurrent() + { + var coords = GetDstCoords(); + if (m_src == null) + { + return coords; + } + + return new TR(Delta) * coords; + } + /// /// Editorで設定値の変更を反映するために、クリアする /// @@ -75,8 +184,8 @@ namespace UniVRM10 m_dst = new ConstraintDestination(transform, ModelRoot); } - var delta = FreezeAxes.Freeze(m_src.TranslationDelta(SourceCoordinate)); - m_dst.ApplyTranslation(delta, Weight, DestinationCoordinate, ModelRoot); + Delta = FreezeAxes.Freeze(m_src.TranslationDelta(SourceCoordinate)); + m_dst.ApplyTranslation(Delta, Weight, DestinationCoordinate, ModelRoot); } } }