diff --git a/Assets/VRM10/Editor/Components/Constraint/IVRM10ConstraintSourceDestinationExtensions.cs b/Assets/VRM10/Editor/Components/Constraint/IVRM10ConstraintSourceDestinationExtensions.cs
index 38e3c6a0b..2fc95decd 100644
--- a/Assets/VRM10/Editor/Components/Constraint/IVRM10ConstraintSourceDestinationExtensions.cs
+++ b/Assets/VRM10/Editor/Components/Constraint/IVRM10ConstraintSourceDestinationExtensions.cs
@@ -3,9 +3,9 @@ using UnityEngine;
namespace UniVRM10
{
- public static class IVRM10ConstraintSourceDestinationExtensions
+ public static class VRM10PositionRotationConstraintBaseExtensions
{
- public static void DrawSourceCoords(this IVRM10ConstraintSourceDestination self)
+ public static void DrawSourceCoords(this VRM10RotationPositionConstraintBase self)
{
try
{
@@ -16,7 +16,7 @@ namespace UniVRM10
}
}
- public static void DrawSourceCurrent(this IVRM10ConstraintSourceDestination self)
+ public static void DrawSourceCurrent(this VRM10RotationPositionConstraintBase self)
{
try
{
@@ -30,7 +30,7 @@ namespace UniVRM10
}
}
- public static void DrawDstCoords(this IVRM10ConstraintSourceDestination self)
+ public static void DrawDstCoords(this VRM10RotationPositionConstraintBase self)
{
try
{
@@ -42,7 +42,7 @@ namespace UniVRM10
}
}
- public static void DrawDstCurrent(this IVRM10ConstraintSourceDestination self)
+ public static void DrawDstCurrent(this VRM10RotationPositionConstraintBase self)
{
try
{
diff --git a/Assets/VRM10/Editor/Components/Constraint/VRM10PositionConstraintEditor.cs b/Assets/VRM10/Editor/Components/Constraint/VRM10PositionConstraintEditor.cs
index 897497304..78e9653c5 100644
--- a/Assets/VRM10/Editor/Components/Constraint/VRM10PositionConstraintEditor.cs
+++ b/Assets/VRM10/Editor/Components/Constraint/VRM10PositionConstraintEditor.cs
@@ -5,67 +5,7 @@ using UnityEngine;
namespace UniVRM10
{
[CustomEditor(typeof(VRM10PositionConstraint))]
- public class VRM10PositionConstraintEditor : Editor
+ public class VRM10PositionConstraintEditor : VRM10PositionRotationConstraintEditorBase
{
- 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/VRM10PostionRotationConstraintEditorBase.cs b/Assets/VRM10/Editor/Components/Constraint/VRM10PostionRotationConstraintEditorBase.cs
new file mode 100644
index 000000000..35b6f5f50
--- /dev/null
+++ b/Assets/VRM10/Editor/Components/Constraint/VRM10PostionRotationConstraintEditorBase.cs
@@ -0,0 +1,113 @@
+using System.Text;
+using UnityEditor;
+using UnityEngine;
+
+namespace UniVRM10
+{
+ public abstract class VRM10PositionRotationConstraintEditorBase : Editor
+ {
+ VRM10RotationPositionConstraintBase m_target;
+
+ void OnEnable()
+ {
+ m_target = (VRM10RotationPositionConstraintBase)target;
+ }
+
+ static GUIStyle s_style;
+ static GUIStyle Style
+ {
+ get
+ {
+ if (s_style == null)
+ {
+ s_style = new GUIStyle("box");
+ }
+ return s_style;
+ }
+ }
+
+ ///
+ /// Euler各を +- 180 にクランプする
+ ///
+ ///
+ ///
+ static Vector3 Clamp180(Vector3 v)
+ {
+ var x = v.x;
+ while (x < -180) x += 360;
+ while (x > 180) x -= 360;
+ var y = v.y;
+ while (y < -180) y += 360;
+ while (y > 180) y -= 360;
+ var z = v.z;
+ while (z < -180) z += 360;
+ while (z > 180) z -= 360;
+ return new Vector3(x, y, z);
+ }
+
+ public void OnSceneGUI()
+ {
+ if (m_target.GetSource() == null)
+ {
+ return;
+ }
+
+ // source offset
+ if (!Application.isPlaying)
+ {
+ EditorGUI.BeginChangeCheck();
+ Quaternion offset = Handles.RotationHandle(m_target.SourceOffset, m_target.GetSource().position);
+ if (EditorGUI.EndChangeCheck())
+ {
+ Undo.RecordObject(m_target.GetComponent(), "source offset");
+ m_target.SourceOffset = offset;
+ }
+ }
+
+ // dest offset
+ if (!Application.isPlaying)
+ {
+ EditorGUI.BeginChangeCheck();
+ Quaternion offset = Handles.RotationHandle(m_target.DestinationOffset, m_target.GetComponent().transform.position);
+ if (EditorGUI.EndChangeCheck())
+ {
+ Undo.RecordObject(m_target.GetComponent(), "dest offset");
+ m_target.DestinationOffset = offset;
+ }
+ }
+
+ // this to target line
+ Handles.color = Color.yellow;
+ Handles.DrawLine(m_target.GetSource().position, m_target.GetComponent().transform.position);
+
+ var delta = Clamp180(m_target.Delta);
+
+ // show source
+ {
+ var sb = new StringBuilder();
+ sb.AppendLine();
+ sb.AppendLine();
+ sb.AppendLine($"source: {m_target.SourceCoordinate}");
+ sb.AppendLine($"{delta.x:0.}");
+ sb.AppendLine($"{delta.y:0.}");
+ sb.Append($"{delta.z:0.}");
+ Handles.Label(m_target.GetSource().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.GetComponent().transform.position, sb.ToString(), Style);
+ }
+
+ m_target.DrawSourceCoords();
+ m_target.DrawSourceCurrent();
+ m_target.DrawDstCoords();
+ m_target.DrawDstCurrent();
+ }
+ }
+}
diff --git a/Assets/VRM10/Runtime/Components/Constraint/IVRM10SourceDestination.cs.meta b/Assets/VRM10/Editor/Components/Constraint/VRM10PostionRotationConstraintEditorBase.cs.meta
similarity index 83%
rename from Assets/VRM10/Runtime/Components/Constraint/IVRM10SourceDestination.cs.meta
rename to Assets/VRM10/Editor/Components/Constraint/VRM10PostionRotationConstraintEditorBase.cs.meta
index ff49caec8..c162c586c 100644
--- a/Assets/VRM10/Runtime/Components/Constraint/IVRM10SourceDestination.cs.meta
+++ b/Assets/VRM10/Editor/Components/Constraint/VRM10PostionRotationConstraintEditorBase.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 4d1ea0f0f4d95a2499f9aa5a1d7a2235
+guid: 46c1f13688fee134aa37a39a72433217
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Assets/VRM10/Editor/Components/Constraint/VRM10RotationConstraintEditor.cs b/Assets/VRM10/Editor/Components/Constraint/VRM10RotationConstraintEditor.cs
index ebd7d4c5e..870cb2f28 100644
--- a/Assets/VRM10/Editor/Components/Constraint/VRM10RotationConstraintEditor.cs
+++ b/Assets/VRM10/Editor/Components/Constraint/VRM10RotationConstraintEditor.cs
@@ -5,110 +5,7 @@ using UnityEngine;
namespace UniVRM10
{
[CustomEditor(typeof(VRM10RotationConstraint))]
- public class VRM10RotationConstraintEditor : Editor
+ public class VRM10RotationConstraintEditor : VRM10PositionRotationConstraintEditorBase
{
- VRM10RotationConstraint m_target;
-
- void OnEnable()
- {
- m_target = (VRM10RotationConstraint)target;
- }
-
- static GUIStyle s_style;
- static GUIStyle Style
- {
- get
- {
- if (s_style == null)
- {
- s_style = new GUIStyle("box");
- }
- return s_style;
- }
- }
-
- ///
- /// Euler各を +- 180 にクランプする
- ///
- ///
- ///
- static Vector3 Clamp180(Vector3 v)
- {
- var x = v.x;
- while (x < -180) x += 360;
- while (x > 180) x -= 360;
- var y = v.y;
- while (y < -180) y += 360;
- while (y > 180) y -= 360;
- var z = v.z;
- while (z < -180) z += 360;
- while (z > 180) z -= 360;
- return new Vector3(x, y, z);
- }
-
- public void OnSceneGUI()
- {
- if (m_target.Source == null)
- {
- return;
- }
-
- // source offset
- if (!Application.isPlaying)
- {
- EditorGUI.BeginChangeCheck();
- Quaternion offset = Handles.RotationHandle(m_target.SourceOffset.Rotation, m_target.Source.position);
- if (EditorGUI.EndChangeCheck())
- {
- Undo.RecordObject(m_target, "source offset");
- m_target.SourceOffset.Rotation = offset;
- }
- }
-
- // dest offset
- if (!Application.isPlaying)
- {
- EditorGUI.BeginChangeCheck();
- Quaternion offset = Handles.RotationHandle(m_target.DestinationOffset.Rotation, m_target.transform.position);
- if (EditorGUI.EndChangeCheck())
- {
- Undo.RecordObject(m_target, "dest offset");
- m_target.DestinationOffset.Rotation = offset;
- }
- }
-
- // this to target line
- Handles.color = Color.yellow;
- Handles.DrawLine(m_target.Source.position, m_target.transform.position);
-
- var delta = Clamp180(m_target.Delta.eulerAngles);
-
- // show source
- {
- var sb = new StringBuilder();
- sb.AppendLine();
- sb.AppendLine();
- sb.AppendLine($"source: {m_target.SourceCoordinate}");
- sb.AppendLine($"{delta.x:0.}");
- sb.AppendLine($"{delta.y:0.}");
- sb.Append($"{delta.z:0.}");
- 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/Runtime/Components/Constraint/ConstraintDestination.cs b/Assets/VRM10/Runtime/Components/Constraint/ConstraintDestination.cs
index 034130aeb..f7c5b14c1 100644
--- a/Assets/VRM10/Runtime/Components/Constraint/ConstraintDestination.cs
+++ b/Assets/VRM10/Runtime/Components/Constraint/ConstraintDestination.cs
@@ -4,7 +4,7 @@ using UnityEngine;
namespace UniVRM10
{
- class ConstraintDestination
+ public class ConstraintDestination
{
readonly Transform m_transform;
readonly TR m_modelInitial;
diff --git a/Assets/VRM10/Runtime/Components/Constraint/ConstraintSource.cs b/Assets/VRM10/Runtime/Components/Constraint/ConstraintSource.cs
index 15d6f1178..8b88f3c59 100644
--- a/Assets/VRM10/Runtime/Components/Constraint/ConstraintSource.cs
+++ b/Assets/VRM10/Runtime/Components/Constraint/ConstraintSource.cs
@@ -4,7 +4,7 @@ using UniGLTF.Extensions.VRMC_node_constraint;
namespace UniVRM10
{
- class ConstraintSource
+ public class ConstraintSource
{
public readonly Transform ModelRoot;
readonly Transform m_transform;
diff --git a/Assets/VRM10/Runtime/Components/Constraint/IVRM10SourceDestination.cs b/Assets/VRM10/Runtime/Components/Constraint/IVRM10SourceDestination.cs
deleted file mode 100644
index d6aa2ca89..000000000
--- a/Assets/VRM10/Runtime/Components/Constraint/IVRM10SourceDestination.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-namespace UniVRM10
-{
- public interface IVRM10ConstraintSourceDestination
- {
- TR GetSourceCoords();
- TR GetSourceCurrent();
-
- TR GetDstCoords();
- TR GetDstCurrent();
- }
-}
diff --git a/Assets/VRM10/Runtime/Components/Constraint/VRM10Constraint.cs b/Assets/VRM10/Runtime/Components/Constraint/VRM10Constraint.cs
index 7e6f11f0f..fe63c3d35 100644
--- a/Assets/VRM10/Runtime/Components/Constraint/VRM10Constraint.cs
+++ b/Assets/VRM10/Runtime/Components/Constraint/VRM10Constraint.cs
@@ -5,9 +5,7 @@ namespace UniVRM10
{
public abstract class VRM10Constraint : MonoBehaviour
{
- public virtual void Process()
- {
+ public abstract void Process();
- }
}
}
diff --git a/Assets/VRM10/Runtime/Components/Constraint/VRM10PositionConstraint.cs b/Assets/VRM10/Runtime/Components/Constraint/VRM10PositionConstraint.cs
index 15c42b97d..32177527e 100644
--- a/Assets/VRM10/Runtime/Components/Constraint/VRM10PositionConstraint.cs
+++ b/Assets/VRM10/Runtime/Components/Constraint/VRM10PositionConstraint.cs
@@ -8,169 +8,12 @@ namespace UniVRM10
/// 対象の初期位置と現在位置の差分(delta)を、自身の初期位置に対してWeightを乗算して加算する。
///
[DisallowMultipleComponent]
- public class VRM10PositionConstraint : VRM10Constraint, IVRM10ConstraintSourceDestination
+ public class VRM10PositionConstraint : VRM10RotationPositionConstraintBase
{
- [SerializeField]
- public Transform Source = default;
+ Vector3 m_delta;
+ public override Vector3 Delta => m_delta;
- [SerializeField]
- public ObjectSpace SourceCoordinate = default;
-
- [SerializeField]
- public VRM10RotationOffset SourceOffset = VRM10RotationOffset.Identity;
-
- [SerializeField]
- public ObjectSpace DestinationCoordinate = default;
-
- [SerializeField]
- public AxisMask FreezeAxes = default;
-
- [SerializeField]
- [Range(0, 10.0f)]
- public float Weight = 1.0f;
-
- [SerializeField]
- public Transform ModelRoot = default;
-
- 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で設定値の変更を反映するために、クリアする
- ///
- void OnValidate()
- {
- // Debug.Log("Validate");
- if (m_src != null && m_src.ModelRoot != ModelRoot)
- {
- m_src = null;
- }
- if (m_dst != null && m_dst.ModelRoot != ModelRoot)
- {
- m_dst = null;
- }
- }
-
- void Reset()
- {
- var current = transform;
- while (current.parent != null)
- {
- current = current.parent;
- }
- ModelRoot = current;
- }
-
- public override void Process()
+ protected override void UpdateDelta()
{
if (Source == null)
{
@@ -187,8 +30,30 @@ namespace UniVRM10
m_dst = new ConstraintDestination(transform, ModelRoot);
}
- Delta = FreezeAxes.Freeze(m_src.TranslationDelta(SourceCoordinate));
+ m_delta = FreezeAxes.Freeze(m_src.TranslationDelta(SourceCoordinate));
m_dst.ApplyTranslation(Delta, Weight, DestinationCoordinate, ModelRoot);
}
+
+ public override TR GetSourceCurrent()
+ {
+ var coords = GetSourceCoords();
+ if (m_src == null)
+ {
+ return coords;
+ }
+
+ return new TR(Delta) * coords;
+ }
+
+ public override TR GetDstCurrent()
+ {
+ var coords = GetDstCoords();
+ if (m_src == null)
+ {
+ return coords;
+ }
+
+ return new TR(Delta) * coords;
+ }
}
}
diff --git a/Assets/VRM10/Runtime/Components/Constraint/VRM10RotationConstraint.cs b/Assets/VRM10/Runtime/Components/Constraint/VRM10RotationConstraint.cs
index f3eeea7d3..0dd4801e6 100644
--- a/Assets/VRM10/Runtime/Components/Constraint/VRM10RotationConstraint.cs
+++ b/Assets/VRM10/Runtime/Components/Constraint/VRM10RotationConstraint.cs
@@ -1,6 +1,4 @@
-using System;
-using UniGLTF.Extensions.VRMC_node_constraint;
-using UnityEngine;
+using UnityEngine;
namespace UniVRM10
@@ -9,78 +7,18 @@ namespace UniVRM10
/// 対象の初期回転と現在回転の差分(delta)を、自身の初期回転と自身の初期回転にdeltaを乗算したものに対してWeightでSlerpする。
///
[DisallowMultipleComponent]
- public class VRM10RotationConstraint : VRM10Constraint, IVRM10ConstraintSourceDestination
+ public class VRM10RotationConstraint : VRM10RotationPositionConstraintBase
{
- [SerializeField]
- [EnumFlags]
- public AxisMask FreezeAxes = default;
+ Quaternion m_delta;
- [SerializeField]
- [Range(0, 10.0f)]
- public float Weight = 1.0f;
+ public override Vector3 Delta => m_delta.eulerAngles;
- [SerializeField]
- public Transform ModelRoot = default;
-
- [Header("Source")]
- [SerializeField]
- public Transform Source = default;
-
- [SerializeField]
- public ObjectSpace SourceCoordinate = default;
-
- [SerializeField]
- public VRM10RotationOffset SourceOffset = VRM10RotationOffset.Identity;
-
- [Header("Destination")]
- [SerializeField]
- public ObjectSpace DestinationCoordinate = default;
-
- [SerializeField]
- public VRM10RotationOffset DestinationOffset = VRM10RotationOffset.Identity;
-
- ConstraintSource m_src;
-
- public TR GetSourceCoords()
+ protected override void UpdateDelta()
{
- if (Source == null)
- {
- throw new ConstraintException(ConstraintException.ExceptionTypes.NoSource);
- }
-
- switch (SourceCoordinate)
- {
- case ObjectSpace.model:
- {
- if (ModelRoot == null)
- {
- throw new ConstraintException(ConstraintException.ExceptionTypes.NoModelWithModelSpace);
- }
- return new TR(ModelRoot.rotation * SourceOffset.Rotation, Source.position);
- }
-
- case ObjectSpace.local:
- {
- if (m_src == null)
- {
- return new TR(Source.rotation * SourceOffset.Rotation, Source.position);
- }
-
- // runtime
- var parent = Quaternion.identity;
- if (Source.parent != null)
- {
- parent = Source.parent.rotation;
- }
- return new TR(parent * m_src.LocalInitial.Rotation * SourceOffset.Rotation, Source.position);
- }
-
- default:
- throw new NotImplementedException();
- }
+ m_delta = m_src.RotationDelta(SourceCoordinate, SourceOffset);
}
- public TR GetSourceCurrent()
+ public override TR GetSourceCurrent()
{
var coords = GetSourceCoords();
if (m_src == null)
@@ -88,51 +26,10 @@ namespace UniVRM10
return coords;
}
- return coords * new TR(Delta);
+ return coords * new TR(m_delta);
}
- public Quaternion 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 * DestinationOffset.Rotation, transform.position);
- }
-
- case ObjectSpace.local:
- {
- if (m_src == null)
- {
- return new TR(transform.rotation * DestinationOffset.Rotation, transform.position);
- }
-
- // runtime
- var parent = Quaternion.identity;
- if (transform.parent != null)
- {
- parent = transform.parent.rotation;
- }
- return new TR(parent * m_dst.LocalInitial.Rotation * DestinationOffset.Rotation, transform.position);
- }
-
- default:
- throw new NotImplementedException();
- }
- }
-
- public TR GetDstCurrent()
+ public override TR GetDstCurrent()
{
var coords = GetDstCoords();
if (m_src == null)
@@ -140,62 +37,7 @@ namespace UniVRM10
return coords;
}
- return coords * new TR(Delta);
- }
-
- ///
- /// Editorで設定値の変更を反映するために、クリアする
- ///
- void OnValidate()
- {
- // Debug.Log("Validate");
- if (m_src != null && m_src.ModelRoot != ModelRoot)
- {
- m_src = null;
- }
- if (m_dst != null && m_dst.ModelRoot != ModelRoot)
- {
- m_dst = null;
- }
- }
-
- void Reset()
- {
- var current = transform;
- while (current.parent != null)
- {
- current = current.parent;
- }
- ModelRoot = current;
- }
-
- public override void Process()
- {
- if (Source == null)
- {
- enabled = false;
- return;
- }
-
- if (m_src == null)
- {
- m_src = new ConstraintSource(Source, ModelRoot);
- }
- if (m_dst == null)
- {
- m_dst = new ConstraintDestination(transform, ModelRoot);
- }
-
- // 回転差分
- Delta = m_src.RotationDelta(SourceCoordinate, SourceOffset.Rotation);
-
- // 軸制限
- var fleezed = FreezeAxes.Freeze(Delta.eulerAngles);
- var rotation = Quaternion.Euler(fleezed);
-
- // Debug.Log($"{delta} => {rotation}");
- // オイラー角を再度Quaternionへ。weight を加味してSlerpする
- m_dst.ApplyRotation(DestinationOffset.Rotation * rotation, Weight, DestinationCoordinate, ModelRoot);
+ return coords * new TR(m_delta);
}
}
}
diff --git a/Assets/VRM10/Runtime/Components/Constraint/VRM10RotationPositionConstraintBase.cs b/Assets/VRM10/Runtime/Components/Constraint/VRM10RotationPositionConstraintBase.cs
new file mode 100644
index 000000000..9988312c7
--- /dev/null
+++ b/Assets/VRM10/Runtime/Components/Constraint/VRM10RotationPositionConstraintBase.cs
@@ -0,0 +1,218 @@
+using System;
+using UniGLTF.Extensions.VRMC_node_constraint;
+using UnityEngine;
+
+namespace UniVRM10
+{
+ public abstract class VRM10RotationPositionConstraintBase : VRM10Constraint
+ {
+ [SerializeField]
+ [EnumFlags]
+ AxisMask m_freezeAxes = default;
+ public AxisMask FreezeAxes
+ {
+ get => m_freezeAxes;
+ set => m_freezeAxes = value;
+ }
+
+ [SerializeField]
+ [Range(0, 10.0f)]
+ public float Weight = 1.0f;
+
+ [SerializeField]
+ public Transform ModelRoot = default;
+
+ #region Source
+ [Header("Source")]
+ [SerializeField]
+ public Transform Source = default;
+
+ public Transform GetSource() => Source;
+
+ [SerializeField]
+ ObjectSpace m_sourceCoordinate = default;
+ public ObjectSpace SourceCoordinate
+ {
+ get => m_sourceCoordinate;
+ set => m_sourceCoordinate = value;
+ }
+
+ [SerializeField]
+ VRM10RotationOffset m_sourceOffset = VRM10RotationOffset.Identity;
+
+ public Quaternion SourceOffset
+ {
+ get => m_sourceOffset.Rotation;
+ set => m_sourceOffset.Rotation = value;
+ }
+ #endregion
+
+
+ #region Destination
+ [Header("Destination")]
+ [SerializeField]
+ ObjectSpace m_destinationCoordinate = default;
+ public ObjectSpace DestinationCoordinate
+ {
+ get => m_destinationCoordinate;
+ set => m_destinationCoordinate = value;
+ }
+
+ [SerializeField]
+ public VRM10RotationOffset m_destinationOffset = VRM10RotationOffset.Identity;
+
+ public Quaternion DestinationOffset
+ {
+ get => m_destinationOffset.Rotation;
+ set => m_destinationOffset.Rotation = value;
+ }
+ #endregion
+
+ public abstract Vector3 Delta { get; }
+
+ protected 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);
+ }
+ return new TR(ModelRoot.rotation * SourceOffset, Source.position);
+ }
+
+ case ObjectSpace.local:
+ {
+ if (m_src == null)
+ {
+ return new TR(Source.rotation * SourceOffset, Source.position);
+ }
+
+ // runtime
+ var parent = Quaternion.identity;
+ if (Source.parent != null)
+ {
+ parent = Source.parent.rotation;
+ }
+ return new TR(parent * m_src.LocalInitial.Rotation * SourceOffset, Source.position);
+ }
+
+ default:
+ throw new NotImplementedException();
+ }
+ }
+
+ public abstract TR GetSourceCurrent();
+
+ protected 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 * DestinationOffset, transform.position);
+ }
+
+ case ObjectSpace.local:
+ {
+ if (m_src == null)
+ {
+ return new TR(transform.rotation * DestinationOffset, transform.position);
+ }
+
+ // runtime
+ var parent = Quaternion.identity;
+ if (transform.parent != null)
+ {
+ parent = transform.parent.rotation;
+ }
+ return new TR(parent * m_dst.LocalInitial.Rotation * DestinationOffset, transform.position);
+ }
+
+ default:
+ throw new NotImplementedException();
+ }
+ }
+
+ public abstract TR GetDstCurrent();
+
+
+ ///
+ /// Editorで設定値の変更を反映するために、クリアする
+ ///
+ void OnValidate()
+ {
+ // Debug.Log("Validate");
+ if (m_src != null && m_src.ModelRoot != ModelRoot)
+ {
+ m_src = null;
+ }
+ if (m_dst != null && m_dst.ModelRoot != ModelRoot)
+ {
+ m_dst = null;
+ }
+ }
+
+ void Reset()
+ {
+ var current = transform;
+ while (current.parent != null)
+ {
+ current = current.parent;
+ }
+ ModelRoot = current;
+ }
+
+ public Component GetComponent()
+ {
+ return this;
+ }
+
+ protected abstract void UpdateDelta();
+
+ public override void Process()
+ {
+ if (Source == null)
+ {
+ enabled = false;
+ return;
+ }
+
+ if (m_src == null)
+ {
+ m_src = new ConstraintSource(Source, ModelRoot);
+ }
+ if (m_dst == null)
+ {
+ m_dst = new ConstraintDestination(transform, ModelRoot);
+ }
+
+ // 回転差分
+ UpdateDelta();
+
+ // 軸制限
+ var fleezed = FreezeAxes.Freeze(Delta);
+ var rotation = Quaternion.Euler(fleezed);
+
+ // Debug.Log($"{delta} => {rotation}");
+ // オイラー角を再度Quaternionへ。weight を加味してSlerpする
+ m_dst.ApplyRotation(DestinationOffset * rotation, Weight, DestinationCoordinate, ModelRoot);
+
+ }
+ }
+}
diff --git a/Assets/VRM10/Runtime/Components/Constraint/VRM10RotationPositionConstraintBase.cs.meta b/Assets/VRM10/Runtime/Components/Constraint/VRM10RotationPositionConstraintBase.cs.meta
new file mode 100644
index 000000000..bac4e2e09
--- /dev/null
+++ b/Assets/VRM10/Runtime/Components/Constraint/VRM10RotationPositionConstraintBase.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 07919df684c7a4c47a9492a2de417f66
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant: