From 54998b3a3e9b47dfa6c4213ac175fb0537ee1aeb Mon Sep 17 00:00:00 2001 From: ousttrue Date: Fri, 8 Apr 2022 14:58:41 +0900 Subject: [PATCH 1/5] =?UTF-8?q?=E4=BB=95=E6=A7=98=E3=82=92=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E3=80=81=E3=82=B3=E3=83=BC=E3=83=89=E3=82=92=E5=86=8D?= =?UTF-8?q?=E7=94=9F=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Format/Constraints/Deserializer.g.cs | 110 +++++++++++++++--- .../Runtime/Format/Constraints/Format.g.cs | 72 +++++++++++- .../Format/Constraints/Serializer.g.cs | 103 +++++++++++++--- Assets/VRM10/Runtime/IO/Vrm10Exporter.cs | 2 +- Assets/VRM10/Runtime/IO/Vrm10Importer.cs | 2 +- vrm-specification | 2 +- 6 files changed, 251 insertions(+), 40 deletions(-) diff --git a/Assets/VRM10/Runtime/Format/Constraints/Deserializer.g.cs b/Assets/VRM10/Runtime/Format/Constraints/Deserializer.g.cs index 0788569ea..c68ee4494 100644 --- a/Assets/VRM10/Runtime/Format/Constraints/Deserializer.g.cs +++ b/Assets/VRM10/Runtime/Format/Constraints/Deserializer.g.cs @@ -79,6 +79,16 @@ public static Constraint Deserialize_Constraint(JsonNode parsed) continue; } + if(key=="roll"){ + value.Roll = __constraint_Deserialize_Roll(kv.Value); + continue; + } + + if(key=="aim"){ + value.Aim = __constraint_Deserialize_Aim(kv.Value); + continue; + } + if(key=="rotation"){ value.Rotation = __constraint_Deserialize_Rotation(kv.Value); continue; @@ -88,6 +98,90 @@ public static Constraint Deserialize_Constraint(JsonNode parsed) return value; } +public static RollConstraint __constraint_Deserialize_Roll(JsonNode parsed) +{ + var value = new RollConstraint(); + + foreach(var kv in parsed.ObjectItems()) + { + var key = kv.Key.GetString(); + + if(key=="extensions"){ + value.Extensions = new glTFExtensionImport(kv.Value); + continue; + } + + if(key=="extras"){ + value.Extras = new glTFExtensionImport(kv.Value); + continue; + } + + if(key=="name"){ + value.Name = kv.Value.GetString(); + continue; + } + + if(key=="source"){ + value.Source = kv.Value.GetInt32(); + continue; + } + + if(key=="rollAxis"){ + value.RollAxis = (RollAxis)Enum.Parse(typeof(RollAxis), kv.Value.GetString(), true); + continue; + } + + if(key=="weight"){ + value.Weight = kv.Value.GetSingle(); + continue; + } + + } + return value; +} + +public static AimConstraint __constraint_Deserialize_Aim(JsonNode parsed) +{ + var value = new AimConstraint(); + + foreach(var kv in parsed.ObjectItems()) + { + var key = kv.Key.GetString(); + + if(key=="extensions"){ + value.Extensions = new glTFExtensionImport(kv.Value); + continue; + } + + if(key=="extras"){ + value.Extras = new glTFExtensionImport(kv.Value); + continue; + } + + if(key=="name"){ + value.Name = kv.Value.GetString(); + continue; + } + + if(key=="source"){ + value.Source = kv.Value.GetInt32(); + continue; + } + + if(key=="aimAxis"){ + value.AimAxis = (AimAxis)Enum.Parse(typeof(AimAxis), kv.Value.GetString(), true); + continue; + } + + if(key=="weight"){ + value.Weight = kv.Value.GetSingle(); + continue; + } + + } + return value; +} + public static RotationConstraint __constraint_Deserialize_Rotation(JsonNode parsed) { var value = new RotationConstraint(); @@ -116,11 +210,6 @@ public static RotationConstraint __constraint_Deserialize_Rotation(JsonNode pars continue; } - if(key=="axes"){ - value.Axes = __constraint__rotation_Deserialize_Axes(kv.Value); - continue; - } - if(key=="weight"){ value.Weight = kv.Value.GetSingle(); continue; @@ -130,16 +219,5 @@ public static RotationConstraint __constraint_Deserialize_Rotation(JsonNode pars return value; } -public static bool[] __constraint__rotation_Deserialize_Axes(JsonNode parsed) -{ - var value = new bool[parsed.GetArrayCount()]; - int i=0; - foreach(var x in parsed.ArrayItems()) - { - value[i++] = x.GetBoolean(); - } - return value; -} - } // GltfDeserializer } // UniGLTF diff --git a/Assets/VRM10/Runtime/Format/Constraints/Format.g.cs b/Assets/VRM10/Runtime/Format/Constraints/Format.g.cs index 3f54d5ead..d9981025f 100644 --- a/Assets/VRM10/Runtime/Format/Constraints/Format.g.cs +++ b/Assets/VRM10/Runtime/Format/Constraints/Format.g.cs @@ -6,6 +6,67 @@ using System.Collections.Generic; namespace UniGLTF.Extensions.VRMC_node_constraint { + public enum RollAxis + { + X, + Y, + Z, + + } + + public class RollConstraint + { + // Dictionary object with extension-specific objects. + public object Extensions; + + // Application-specific data. + public object Extras; + + // The user-defined name of this object. + public string Name; + + // The index of the node constrains the node. + public int? Source; + + // The roll axis of the constraint. + public RollAxis RollAxis; + + // The weight of the constraint. + public float? Weight; + } + + public enum AimAxis + { + PositiveX, + NegativeX, + PositiveY, + NegativeY, + PositiveZ, + NegativeZ, + + } + + public class AimConstraint + { + // Dictionary object with extension-specific objects. + public object Extensions; + + // Application-specific data. + public object Extras; + + // The user-defined name of this object. + public string Name; + + // The index of the node constrains the node. + public int? Source; + + // The aim axis of the constraint. + public AimAxis AimAxis; + + // The weight of the constraint. + public float? Weight; + } + public class RotationConstraint { // Dictionary object with extension-specific objects. @@ -20,9 +81,6 @@ namespace UniGLTF.Extensions.VRMC_node_constraint // The index of the node constrains the node. public int? Source; - // Axes be constrained by this constraint, in X-Y-Z order. - public bool[] Axes; - // The weight of the constraint. public float? Weight; } @@ -35,6 +93,12 @@ namespace UniGLTF.Extensions.VRMC_node_constraint // Application-specific data. public object Extras; + // A constraint that transfers a rotation around one axis of a source. + public RollConstraint Roll; + + // A constraint that makes it look at a source object. + public AimConstraint Aim; + // A constraint that links the rotation with a source. public RotationConstraint Rotation; } @@ -52,7 +116,7 @@ namespace UniGLTF.Extensions.VRMC_node_constraint // Specification version of VRMC_node_constraint public string SpecVersion; - // Contains position, rotation, or aim + // Contains roll, aim, or rotation public Constraint Constraint; } } diff --git a/Assets/VRM10/Runtime/Format/Constraints/Serializer.g.cs b/Assets/VRM10/Runtime/Format/Constraints/Serializer.g.cs index 4a88b27fb..0828fd008 100644 --- a/Assets/VRM10/Runtime/Format/Constraints/Serializer.g.cs +++ b/Assets/VRM10/Runtime/Format/Constraints/Serializer.g.cs @@ -71,6 +71,16 @@ public static void Serialize_Constraint(JsonFormatter f, Constraint value) (value.Extras as glTFExtension).Serialize(f); } + if(value.Roll!=null){ + f.Key("roll"); + __constraint_Serialize_Roll(f, value.Roll); + } + + if(value.Aim!=null){ + f.Key("aim"); + __constraint_Serialize_Aim(f, value.Aim); + } + if(value.Rotation!=null){ f.Key("rotation"); __constraint_Serialize_Rotation(f, value.Rotation); @@ -79,6 +89,82 @@ public static void Serialize_Constraint(JsonFormatter f, Constraint value) f.EndMap(); } +public static void __constraint_Serialize_Roll(JsonFormatter f, RollConstraint value) +{ + f.BeginMap(); + + + if(value.Extensions!=null){ + f.Key("extensions"); + (value.Extensions as glTFExtension).Serialize(f); + } + + if(value.Extras!=null){ + f.Key("extras"); + (value.Extras as glTFExtension).Serialize(f); + } + + if(!string.IsNullOrEmpty(value.Name)){ + f.Key("name"); + f.Value(value.Name); + } + + if(value.Source.HasValue){ + f.Key("source"); + f.Value(value.Source.GetValueOrDefault()); + } + + if(true){ + f.Key("rollAxis"); + f.Value(value.RollAxis.ToString()); + } + + if(value.Weight.HasValue){ + f.Key("weight"); + f.Value(value.Weight.GetValueOrDefault()); + } + + f.EndMap(); +} + +public static void __constraint_Serialize_Aim(JsonFormatter f, AimConstraint value) +{ + f.BeginMap(); + + + if(value.Extensions!=null){ + f.Key("extensions"); + (value.Extensions as glTFExtension).Serialize(f); + } + + if(value.Extras!=null){ + f.Key("extras"); + (value.Extras as glTFExtension).Serialize(f); + } + + if(!string.IsNullOrEmpty(value.Name)){ + f.Key("name"); + f.Value(value.Name); + } + + if(value.Source.HasValue){ + f.Key("source"); + f.Value(value.Source.GetValueOrDefault()); + } + + if(true){ + f.Key("aimAxis"); + f.Value(value.AimAxis.ToString()); + } + + if(value.Weight.HasValue){ + f.Key("weight"); + f.Value(value.Weight.GetValueOrDefault()); + } + + f.EndMap(); +} + public static void __constraint_Serialize_Rotation(JsonFormatter f, RotationConstraint value) { f.BeginMap(); @@ -104,11 +190,6 @@ public static void __constraint_Serialize_Rotation(JsonFormatter f, RotationCons f.Value(value.Source.GetValueOrDefault()); } - if(value.Axes!=null&&value.Axes.Count()>=3){ - f.Key("axes"); - __constraint__rotation_Serialize_Axes(f, value.Axes); - } - if(value.Weight.HasValue){ f.Key("weight"); f.Value(value.Weight.GetValueOrDefault()); @@ -117,17 +198,5 @@ public static void __constraint_Serialize_Rotation(JsonFormatter f, RotationCons f.EndMap(); } -public static void __constraint__rotation_Serialize_Axes(JsonFormatter f, bool[] value) -{ - f.BeginList(); - - foreach(var item in value) - { - f.Value(item); - - } - f.EndList(); -} - } // class } // namespace diff --git a/Assets/VRM10/Runtime/IO/Vrm10Exporter.cs b/Assets/VRM10/Runtime/IO/Vrm10Exporter.cs index fb47fc8a7..6e98d2308 100644 --- a/Assets/VRM10/Runtime/IO/Vrm10Exporter.cs +++ b/Assets/VRM10/Runtime/IO/Vrm10Exporter.cs @@ -443,7 +443,7 @@ namespace UniVRM10 Rotation = new UniGLTF.Extensions.VRMC_node_constraint.RotationConstraint { Source = model.Nodes.IndexOf(converter.Nodes[c.Source.gameObject]), - Axes = ToArray(c.Axes), + // Axes = ToArray(c.Axes), Weight = c.Weight, }, }, diff --git a/Assets/VRM10/Runtime/IO/Vrm10Importer.cs b/Assets/VRM10/Runtime/IO/Vrm10Importer.cs index aa78c595e..50b510a91 100644 --- a/Assets/VRM10/Runtime/IO/Vrm10Importer.cs +++ b/Assets/VRM10/Runtime/IO/Vrm10Importer.cs @@ -666,7 +666,7 @@ namespace UniVRM10 var r = constraint.Rotation; var rotationConstraint = node.gameObject.AddComponent(); rotationConstraint.Source = Nodes[r.Source.Value]; - rotationConstraint.Axes = ConstraintAxes(r.Axes); + // rotationConstraint.Axes = ConstraintAxes(r.Axes); rotationConstraint.Weight = r.Weight.Value; rotationConstraint.ModelRoot = Root.transform; } diff --git a/vrm-specification b/vrm-specification index 084c4fd3a..e93a3a077 160000 --- a/vrm-specification +++ b/vrm-specification @@ -1 +1 @@ -Subproject commit 084c4fd3a19f4a94b854c35661151c23d526d26a +Subproject commit e93a3a0776660e38bbced4c8219217c21f743628 From 325fe98980a0afad740556dd7a94d2f0a2ea846b Mon Sep 17 00:00:00 2001 From: ousttrue Date: Tue, 12 Apr 2022 13:44:23 +0900 Subject: [PATCH 2/5] =?UTF-8?q?=E6=96=B0=E4=BB=95=E6=A7=98=E3=81=AB?= =?UTF-8?q?=E5=90=88=E3=82=8F=E3=81=9B=E3=81=A6=E6=97=A7=E3=82=B3=E3=83=B3?= =?UTF-8?q?=E3=83=9D=E3=83=BC=E3=83=8D=E3=83=B3=E3=83=88=E3=82=92=E6=95=B4?= =?UTF-8?q?=E7=90=86=E3=80=82Vrm10AimConstraint,=20Vrm10RollConstraint,=20?= =?UTF-8?q?VRM10RotationConstraint=20=E3=81=AE=E3=82=B3=E3=83=B3=E3=83=9D?= =?UTF-8?q?=E3=83=BC=E3=83=8D=E3=83=B3=E3=83=88(placeholder),=20Import,=20?= =?UTF-8?q?Export=20=E3=82=92=E5=AE=9F=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../VRM10/Editor/Components/Constraint.meta | 8 -- .../Components/Constraint/TRExtensions.cs | 32 ----- .../Constraint/TRExtensions.cs.meta | 11 -- ...RM10PostionRotationConstraintEditorBase.cs | 122 ------------------ .../VRM10RotationConstraintEditor.cs | 9 -- .../VRM10RotationConstraintEditor.cs.meta | 11 -- Assets/VRM10/Editor/Components/VRM10Window.cs | 6 +- .../Components/Constraint/VRM10Constraint.cs | 87 +------------ .../Constraint/VRM10RotationConstraint.cs | 37 ++---- .../VRM10RotationPositionConstraintBase.cs | 105 --------------- .../Constraint/Vrm10AimConstraint.cs | 26 ++++ ...ase.cs.meta => Vrm10AimConstraint.cs.meta} | 2 +- .../Constraint/Vrm10RollConstraint.cs | 26 ++++ .../Constraint/Vrm10RollConstraint.cs.meta} | 2 +- .../Components/Vrm10Runtime/Vrm10Runtime.cs | 4 +- Assets/VRM10/Runtime/IO/Vrm10Exporter.cs | 53 +++++--- Assets/VRM10/Runtime/IO/Vrm10Importer.cs | 43 +++++- 17 files changed, 140 insertions(+), 444 deletions(-) delete mode 100644 Assets/VRM10/Editor/Components/Constraint.meta delete mode 100644 Assets/VRM10/Editor/Components/Constraint/TRExtensions.cs delete mode 100644 Assets/VRM10/Editor/Components/Constraint/TRExtensions.cs.meta delete mode 100644 Assets/VRM10/Editor/Components/Constraint/VRM10PostionRotationConstraintEditorBase.cs delete mode 100644 Assets/VRM10/Editor/Components/Constraint/VRM10RotationConstraintEditor.cs delete mode 100644 Assets/VRM10/Editor/Components/Constraint/VRM10RotationConstraintEditor.cs.meta delete mode 100644 Assets/VRM10/Runtime/Components/Constraint/VRM10RotationPositionConstraintBase.cs create mode 100644 Assets/VRM10/Runtime/Components/Constraint/Vrm10AimConstraint.cs rename Assets/VRM10/Runtime/Components/Constraint/{VRM10RotationPositionConstraintBase.cs.meta => Vrm10AimConstraint.cs.meta} (83%) create mode 100644 Assets/VRM10/Runtime/Components/Constraint/Vrm10RollConstraint.cs rename Assets/VRM10/{Editor/Components/Constraint/VRM10PostionRotationConstraintEditorBase.cs.meta => Runtime/Components/Constraint/Vrm10RollConstraint.cs.meta} (83%) diff --git a/Assets/VRM10/Editor/Components/Constraint.meta b/Assets/VRM10/Editor/Components/Constraint.meta deleted file mode 100644 index 2a1fd51d0..000000000 --- a/Assets/VRM10/Editor/Components/Constraint.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 7b369ee7eb21d1047bb03e139faa7eda -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/VRM10/Editor/Components/Constraint/TRExtensions.cs b/Assets/VRM10/Editor/Components/Constraint/TRExtensions.cs deleted file mode 100644 index 1365ea074..000000000 --- a/Assets/VRM10/Editor/Components/Constraint/TRExtensions.cs +++ /dev/null @@ -1,32 +0,0 @@ -using UnityEditor; -using UnityEngine; - -namespace UniVRM10 -{ - public static class TRExtensions - { - public static void Draw(this TR tr, float size) - { - Handles.matrix = tr.TRS(size); - - // Handles.CubeHandleCap(0, Vector3.zero, Quaternion.identity, size, EventType.Repaint); - Handles.color = Color.red; - Handles.DrawLine(Vector3.zero, Vector3.right); - Handles.color = Color.green; - Handles.DrawLine(Vector3.zero, Vector3.up); - Handles.color = Color.blue; - Handles.DrawLine(Vector3.zero, Vector3.forward); - - Handles.color = Color.white; - // xy - Handles.DrawLine(Vector3.right + Vector3.up, Vector3.right); - Handles.DrawLine(Vector3.right + Vector3.up, Vector3.up); - // yz - Handles.DrawLine(Vector3.up + Vector3.forward, Vector3.forward); - Handles.DrawLine(Vector3.up + Vector3.forward, Vector3.up); - // zx - Handles.DrawLine(Vector3.forward + Vector3.right, Vector3.forward); - Handles.DrawLine(Vector3.forward + Vector3.right, Vector3.right); - } - } -} diff --git a/Assets/VRM10/Editor/Components/Constraint/TRExtensions.cs.meta b/Assets/VRM10/Editor/Components/Constraint/TRExtensions.cs.meta deleted file mode 100644 index d86fabc8d..000000000 --- a/Assets/VRM10/Editor/Components/Constraint/TRExtensions.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: f2d422c6e760aca49841f8acf44c0434 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/VRM10/Editor/Components/Constraint/VRM10PostionRotationConstraintEditorBase.cs b/Assets/VRM10/Editor/Components/Constraint/VRM10PostionRotationConstraintEditorBase.cs deleted file mode 100644 index fcd5e8c6b..000000000 --- a/Assets/VRM10/Editor/Components/Constraint/VRM10PostionRotationConstraintEditorBase.cs +++ /dev/null @@ -1,122 +0,0 @@ -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.Source == null) - { - return; - } - - // source offset - if (!Application.isPlaying) - { - EditorGUI.BeginChangeCheck(); - Quaternion offset = Handles.RotationHandle(m_target.SourceOffset, m_target.Source.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.Source.position, m_target.GetComponent().transform.position); - - var delta = Clamp180(m_target.Delta); - - // show source - { - var sb = new StringBuilder(); - sb.AppendLine(); - sb.AppendLine(); - 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(m_target.Axes.HasFlag(AxisMask.X) ? $"{delta.x:0.00}" : "----"); - sb.AppendLine(m_target.Axes.HasFlag(AxisMask.Y) ? $"{delta.y:0.00}" : "----"); - sb.Append(m_target.Axes.HasFlag(AxisMask.Z) ? $"{delta.z:0.00}" : "----"); - Handles.Label(m_target.GetComponent().transform.position, sb.ToString(), Style); - } - - m_target.GetSourceCoords().Draw(0.2f); - if (Application.isPlaying) - { - Handles.matrix = m_target.GetSourceCurrent().TRS(0.05f); - Handles.color = Color.yellow; - Handles.DrawWireCube(Vector3.zero, Vector3.one); - } - - m_target.GetDstCoords().Draw(0.2f); - if (Application.isPlaying) - { - Handles.matrix = m_target.GetDstCurrent().TRS(0.05f); - Handles.color = Color.yellow; - Handles.DrawWireCube(Vector3.zero, Vector3.one); - } - } - } -} diff --git a/Assets/VRM10/Editor/Components/Constraint/VRM10RotationConstraintEditor.cs b/Assets/VRM10/Editor/Components/Constraint/VRM10RotationConstraintEditor.cs deleted file mode 100644 index 0b8140aec..000000000 --- a/Assets/VRM10/Editor/Components/Constraint/VRM10RotationConstraintEditor.cs +++ /dev/null @@ -1,9 +0,0 @@ -using UnityEditor; - -namespace UniVRM10 -{ - [CustomEditor(typeof(VRM10RotationConstraint))] - public class VRM10RotationConstraintEditor : VRM10PositionRotationConstraintEditorBase - { - } -} diff --git a/Assets/VRM10/Editor/Components/Constraint/VRM10RotationConstraintEditor.cs.meta b/Assets/VRM10/Editor/Components/Constraint/VRM10RotationConstraintEditor.cs.meta deleted file mode 100644 index ada1c4062..000000000 --- a/Assets/VRM10/Editor/Components/Constraint/VRM10RotationConstraintEditor.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: cd4ca141215a42c45a0036791f2f8a4d -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/VRM10/Editor/Components/VRM10Window.cs b/Assets/VRM10/Editor/Components/VRM10Window.cs index 3612409eb..613ec0a7e 100644 --- a/Assets/VRM10/Editor/Components/VRM10Window.cs +++ b/Assets/VRM10/Editor/Components/VRM10Window.cs @@ -71,7 +71,7 @@ namespace UniVRM10 Transform m_head; - public VRM10Constraint[] m_constraints; + public Vrm10Constraint[] m_constraints; ScrollView m_scrollView = new ScrollView(); @@ -177,7 +177,7 @@ namespace UniVRM10 { if (m_constraints == null) { - m_constraints = Root.GetComponentsInChildren(); + m_constraints = Root.GetComponentsInChildren(); } } @@ -187,7 +187,7 @@ namespace UniVRM10 { foreach (var c in m_constraints) { - EditorGUILayout.ObjectField(c, typeof(VRM10Constraint), true); + EditorGUILayout.ObjectField(c, typeof(Vrm10Constraint), true); } } } diff --git a/Assets/VRM10/Runtime/Components/Constraint/VRM10Constraint.cs b/Assets/VRM10/Runtime/Components/Constraint/VRM10Constraint.cs index 8b91193e9..fb04b9de9 100644 --- a/Assets/VRM10/Runtime/Components/Constraint/VRM10Constraint.cs +++ b/Assets/VRM10/Runtime/Components/Constraint/VRM10Constraint.cs @@ -1,92 +1,9 @@ -using System; -using UniGLTF.Extensions.VRMC_node_constraint; using UnityEngine; namespace UniVRM10 { - public abstract class VRM10Constraint : MonoBehaviour + public abstract class Vrm10Constraint : MonoBehaviour { - [SerializeField] - [Range(0, 10.0f)] - public float Weight = 1.0f; - - [SerializeField] - public Transform ModelRoot = default; - - protected virtual void Reset() - { - var current = transform; - while (true) - { - current = current.parent; - if (current.parent == null) - { - // root - break; - } - if (current.GetComponent() != null) - { - // model root - break; - } - } - ModelRoot = current; - } - - #region Source - public abstract Transform Source { get; set; } - - public ConstraintSource m_src; - - protected TR SourceInitialCoords() - { - if (m_src == null) - { - return TR.FromWorld(Source); - } - else - { - return TR.FromParent(Source) * m_src.LocalInitial; - } - } - #endregion - - #region Destination - protected ConstraintDestination m_dst; - - protected TR DestinationInitialCoords() - { - if (m_dst == null) - { - return TR.FromWorld(transform); - } - else - { - return TR.FromParent(transform) * m_dst.LocalInitial; - } - } - #endregion - - public 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); - } - - OnProcess(); - } - - public abstract void OnProcess(); + public abstract void Process(); } } diff --git a/Assets/VRM10/Runtime/Components/Constraint/VRM10RotationConstraint.cs b/Assets/VRM10/Runtime/Components/Constraint/VRM10RotationConstraint.cs index ba762d967..cdb0ada3f 100644 --- a/Assets/VRM10/Runtime/Components/Constraint/VRM10RotationConstraint.cs +++ b/Assets/VRM10/Runtime/Components/Constraint/VRM10RotationConstraint.cs @@ -1,40 +1,23 @@ -using System; -using UniGLTF.Extensions.VRMC_node_constraint; -using UnityEngine; +using UnityEngine; namespace UniVRM10 { /// - /// 対象の初期回転と現在回転の差分(delta)を、自身の初期回転と自身の初期回転にdeltaを乗算したものに対してWeightでSlerpする。 + /// https://github.com/vrm-c/vrm-specification/blob/master/specification/VRMC_node_constraint-1.0_draft/schema/VRMC_node_constraint.rotationConstraint.schema.json /// [DisallowMultipleComponent] - public class VRM10RotationConstraint : VRM10RotationPositionConstraintBase + public class Vrm10RotationConstraint : Vrm10Constraint { - public override Vector3 Delta => Axes.Mask(Quaternion.Slerp(Quaternion.identity, m_delta.Rotation, Weight).eulerAngles); + [SerializeField] + public Transform Source = default; - public override TR GetSourceCurrent() - { - var coords = GetSourceCoords(); - if (m_src == null) - { - return coords; - } - return coords * new TR(m_delta.Rotation); - } + [SerializeField] + [Range(0, 10.0f)] + public float Weight = 1.0f; - public override TR GetDstCurrent() + public override void Process() { - var coords = GetDstCoords(); - if (m_src == null) - { - return coords; - } - return coords * new TR(m_delta.Rotation); - } - - protected override void ApplyDelta() - { - m_dst.ApplyLocal(m_dst.LocalInitial * new TR(DestinationOffset) * new TR(Quaternion.Euler(Delta))); + throw new System.NotImplementedException(); } } } diff --git a/Assets/VRM10/Runtime/Components/Constraint/VRM10RotationPositionConstraintBase.cs b/Assets/VRM10/Runtime/Components/Constraint/VRM10RotationPositionConstraintBase.cs deleted file mode 100644 index 7c4cf74e8..000000000 --- a/Assets/VRM10/Runtime/Components/Constraint/VRM10RotationPositionConstraintBase.cs +++ /dev/null @@ -1,105 +0,0 @@ -using System; -using UniGLTF.Extensions.VRMC_node_constraint; -using UnityEngine; - -namespace UniVRM10 -{ - public abstract class VRM10RotationPositionConstraintBase : VRM10Constraint - { - [SerializeField] - [EnumFlags] - AxisMask m_axes = AxisMask.X | AxisMask.Y | AxisMask.Z; - public AxisMask Axes - { - get => m_axes; - set => m_axes = value; - } - - #region Source - [Header("Source")] - [SerializeField] - Transform m_source = default; - public override Transform Source - { - get => m_source; - set => m_source = 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] - public VRM10RotationOffset m_destinationOffset = VRM10RotationOffset.Identity; - - public Quaternion DestinationOffset - { - get => m_destinationOffset.Rotation; - set => m_destinationOffset.Rotation = value; - } - #endregion - - public TR GetSourceCoords() - { - if (Source == null) - { - throw new ConstraintException(ConstraintException.ExceptionTypes.NoSource); - } - - var init = SourceInitialCoords(); - return new TR(init.Rotation * SourceOffset, init.Translation); - } - - public abstract TR GetSourceCurrent(); - - public TR GetDstCoords() - { - var init = DestinationInitialCoords(); - return new TR(init.Rotation * DestinationOffset, init.Translation); - } - - 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; - } - } - - public Component GetComponent() - { - return this; - } - - protected TR m_delta; - public abstract Vector3 Delta { get; } - - protected abstract void ApplyDelta(); - - public override void OnProcess() - { - m_delta = m_src.Delta(SourceOffset); - ApplyDelta(); - } - } -} diff --git a/Assets/VRM10/Runtime/Components/Constraint/Vrm10AimConstraint.cs b/Assets/VRM10/Runtime/Components/Constraint/Vrm10AimConstraint.cs new file mode 100644 index 000000000..87d7405f7 --- /dev/null +++ b/Assets/VRM10/Runtime/Components/Constraint/Vrm10AimConstraint.cs @@ -0,0 +1,26 @@ +using UnityEngine; + +namespace UniVRM10 +{ + /// + /// https://github.com/vrm-c/vrm-specification/blob/master/specification/VRMC_node_constraint-1.0_draft/schema/VRMC_node_constraint.aimConstraint.schema.json + /// + [DisallowMultipleComponent] + public class Vrm10AimConstraint : Vrm10Constraint + { + [SerializeField] + public Transform Source = default; + + [SerializeField] + [Range(0, 10.0f)] + public float Weight = 1.0f; + + [SerializeField] + public UniGLTF.Extensions.VRMC_node_constraint.AimAxis AimAxis; + + public override void Process() + { + throw new System.NotImplementedException(); + } + } +} diff --git a/Assets/VRM10/Runtime/Components/Constraint/VRM10RotationPositionConstraintBase.cs.meta b/Assets/VRM10/Runtime/Components/Constraint/Vrm10AimConstraint.cs.meta similarity index 83% rename from Assets/VRM10/Runtime/Components/Constraint/VRM10RotationPositionConstraintBase.cs.meta rename to Assets/VRM10/Runtime/Components/Constraint/Vrm10AimConstraint.cs.meta index bac4e2e09..205e03dc4 100644 --- a/Assets/VRM10/Runtime/Components/Constraint/VRM10RotationPositionConstraintBase.cs.meta +++ b/Assets/VRM10/Runtime/Components/Constraint/Vrm10AimConstraint.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 07919df684c7a4c47a9492a2de417f66 +guid: 37b0507e4ae49724898ca17cc3db6f1a MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/VRM10/Runtime/Components/Constraint/Vrm10RollConstraint.cs b/Assets/VRM10/Runtime/Components/Constraint/Vrm10RollConstraint.cs new file mode 100644 index 000000000..199d14a7b --- /dev/null +++ b/Assets/VRM10/Runtime/Components/Constraint/Vrm10RollConstraint.cs @@ -0,0 +1,26 @@ +using UnityEngine; + +namespace UniVRM10 +{ + /// + /// https://github.com/vrm-c/vrm-specification/blob/master/specification/VRMC_node_constraint-1.0_draft/schema/VRMC_node_constraint.rollConstraint.schema.json + /// + [DisallowMultipleComponent] + public class Vrm10RollConstraint : Vrm10Constraint + { + [SerializeField] + public Transform Source = default; + + [SerializeField] + [Range(0, 10.0f)] + public float Weight = 1.0f; + + [SerializeField] + public UniGLTF.Extensions.VRMC_node_constraint.RollAxis RollAxis; + + public override void Process() + { + throw new System.NotImplementedException(); + } + } +} diff --git a/Assets/VRM10/Editor/Components/Constraint/VRM10PostionRotationConstraintEditorBase.cs.meta b/Assets/VRM10/Runtime/Components/Constraint/Vrm10RollConstraint.cs.meta similarity index 83% rename from Assets/VRM10/Editor/Components/Constraint/VRM10PostionRotationConstraintEditorBase.cs.meta rename to Assets/VRM10/Runtime/Components/Constraint/Vrm10RollConstraint.cs.meta index c162c586c..4c6dc5979 100644 --- a/Assets/VRM10/Editor/Components/Constraint/VRM10PostionRotationConstraintEditorBase.cs.meta +++ b/Assets/VRM10/Runtime/Components/Constraint/Vrm10RollConstraint.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 46c1f13688fee134aa37a39a72433217 +guid: 1e864293edac89b40b9f79c23e7aa547 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10Runtime.cs b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10Runtime.cs index 7bcad98b1..d446c917d 100644 --- a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10Runtime.cs +++ b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10Runtime.cs @@ -12,7 +12,7 @@ namespace UniVRM10 public class Vrm10Runtime : IDisposable { private readonly Vrm10Instance m_target; - private readonly VRM10Constraint[] m_constraints; + private readonly Vrm10Constraint[] m_constraints; private readonly Transform m_head; private readonly FastSpringBoneService m_fastSpringBoneService; @@ -39,7 +39,7 @@ namespace UniVRM10 if (m_constraints == null) { - m_constraints = target.GetComponentsInChildren(); + m_constraints = target.GetComponentsInChildren(); } if (!Application.isPlaying) diff --git a/Assets/VRM10/Runtime/IO/Vrm10Exporter.cs b/Assets/VRM10/Runtime/IO/Vrm10Exporter.cs index 6e98d2308..fefa6ec2a 100644 --- a/Assets/VRM10/Runtime/IO/Vrm10Exporter.cs +++ b/Assets/VRM10/Runtime/IO/Vrm10Exporter.cs @@ -401,14 +401,43 @@ namespace UniVRM10 static void ExportConstraints(Vrm10Instance vrmController, Model model, ModelExporter converter, List nodes) { - var constraints = vrmController.GetComponentsInChildren(); + var constraints = vrmController.GetComponentsInChildren(); foreach (var constraint in constraints) { - UniGLTF.Extensions.VRMC_node_constraint.VRMC_node_constraint vrmConstraint = default; + var vrmConstraint = new UniGLTF.Extensions.VRMC_node_constraint.VRMC_node_constraint + { + SpecVersion = NODE_CONSTRAINT_SPEC_VERSION, + Constraint = new UniGLTF.Extensions.VRMC_node_constraint.Constraint + { + }, + }; + switch (constraint) { - case VRM10RotationConstraint rotationConstraint: - vrmConstraint = ExportRotationConstraint(rotationConstraint, model, converter); + case Vrm10AimConstraint aimConstraint: + vrmConstraint.Constraint.Aim = new UniGLTF.Extensions.VRMC_node_constraint.AimConstraint + { + Source = model.Nodes.IndexOf(converter.Nodes[aimConstraint.Source.gameObject]), + Weight = aimConstraint.Weight, + AimAxis = aimConstraint.AimAxis, + }; + break; + + case Vrm10RollConstraint rollConstraint: + vrmConstraint.Constraint.Roll = new UniGLTF.Extensions.VRMC_node_constraint.RollConstraint + { + Source = model.Nodes.IndexOf(converter.Nodes[rollConstraint.Source.gameObject]), + Weight = rollConstraint.Weight, + RollAxis = rollConstraint.RollAxis, + }; + break; + + case Vrm10RotationConstraint rotationConstraint: + vrmConstraint.Constraint.Rotation = new UniGLTF.Extensions.VRMC_node_constraint.RotationConstraint + { + Source = model.Nodes.IndexOf(converter.Nodes[rotationConstraint.Source.gameObject]), + Weight = rotationConstraint.Weight, + }; break; default: @@ -433,22 +462,6 @@ namespace UniVRM10 }; } - static UniGLTF.Extensions.VRMC_node_constraint.VRMC_node_constraint ExportRotationConstraint(VRM10RotationConstraint c, Model model, ModelExporter converter) - { - return new UniGLTF.Extensions.VRMC_node_constraint.VRMC_node_constraint - { - SpecVersion = NODE_CONSTRAINT_SPEC_VERSION, - Constraint = new UniGLTF.Extensions.VRMC_node_constraint.Constraint - { - Rotation = new UniGLTF.Extensions.VRMC_node_constraint.RotationConstraint - { - Source = model.Nodes.IndexOf(converter.Nodes[c.Source.gameObject]), - // Axes = ToArray(c.Axes), - Weight = c.Weight, - }, - }, - }; - } static UniGLTF.Extensions.VRMC_vrm.MeshAnnotation ExportMeshAnnotation(RendererFirstPersonFlags flags, Transform root, Func getIndex) { diff --git a/Assets/VRM10/Runtime/IO/Vrm10Importer.cs b/Assets/VRM10/Runtime/IO/Vrm10Importer.cs index 50b510a91..355b1fc47 100644 --- a/Assets/VRM10/Runtime/IO/Vrm10Importer.cs +++ b/Assets/VRM10/Runtime/IO/Vrm10Importer.cs @@ -652,6 +652,17 @@ namespace UniVRM10 return v; } + /// + /// https://github.com/vrm-c/vrm-specification/tree/master/specification/VRMC_node_constraint-1.0_draft + /// + /// * roll + /// * aim + /// * rotaton + /// + /// + /// + /// + /// async Task LoadConstraintAsync(IAwaitCaller awaitCaller, Vrm10Instance controller) { for (int i = 0; i < Data.GLTF.nodes.Count; ++i) @@ -661,14 +672,32 @@ namespace UniVRM10 { var constraint = ext.Constraint; var node = Nodes[i]; - if (constraint.Rotation != null) + if (constraint.Roll != null) { - var r = constraint.Rotation; - var rotationConstraint = node.gameObject.AddComponent(); - rotationConstraint.Source = Nodes[r.Source.Value]; - // rotationConstraint.Axes = ConstraintAxes(r.Axes); - rotationConstraint.Weight = r.Weight.Value; - rotationConstraint.ModelRoot = Root.transform; + var roll = constraint.Roll; + var component = node.gameObject.AddComponent(); + component.Source = Nodes[roll.Source.Value]; + component.Weight = roll.Weight.Value; + component.RollAxis = roll.RollAxis; + } + else if (constraint.Aim != null) + { + var aim = constraint.Aim; + var component = node.gameObject.AddComponent(); + component.Source = Nodes[aim.Source.Value]; + component.Weight = aim.Weight.Value; + component.AimAxis = aim.AimAxis; + } + else if (constraint.Rotation != null) + { + var rotation = constraint.Rotation; + var component = node.gameObject.AddComponent(); + component.Source = Nodes[rotation.Source.Value]; + component.Weight = rotation.Weight.Value; + } + else + { + throw new NotImplementedException(); } } } From d2f17b925772a46416e69cf4f839911bda603f09 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Tue, 12 Apr 2022 15:04:12 +0900 Subject: [PATCH 3/5] =?UTF-8?q?=E4=BB=95=E6=A7=98=E3=81=AB=E6=BA=96?= =?UTF-8?q?=E6=8B=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../VRM10/Editor/VRM10RotationOffsetDrawer.cs | 28 --------- .../Editor/VRM10RotationOffsetDrawer.cs.meta | 11 ---- .../Constraint/VRM10RotationConstraint.cs | 31 +++++++++- .../Constraint/VRM10RotationOffset.cs | 17 ----- .../Constraint/VRM10RotationOffset.cs.meta | 11 ---- .../Constraint/Vrm10AimConstraint.cs | 58 ++++++++++++++++- .../Constraint/Vrm10RollConstraint.cs | 62 ++++++++++++++++++- 7 files changed, 144 insertions(+), 74 deletions(-) delete mode 100644 Assets/VRM10/Editor/VRM10RotationOffsetDrawer.cs delete mode 100644 Assets/VRM10/Editor/VRM10RotationOffsetDrawer.cs.meta delete mode 100644 Assets/VRM10/Runtime/Components/Constraint/VRM10RotationOffset.cs delete mode 100644 Assets/VRM10/Runtime/Components/Constraint/VRM10RotationOffset.cs.meta diff --git a/Assets/VRM10/Editor/VRM10RotationOffsetDrawer.cs b/Assets/VRM10/Editor/VRM10RotationOffsetDrawer.cs deleted file mode 100644 index a893ecbe7..000000000 --- a/Assets/VRM10/Editor/VRM10RotationOffsetDrawer.cs +++ /dev/null @@ -1,28 +0,0 @@ - -using UnityEditor; -using UnityEngine; - -namespace UniVRM10 -{ - [CustomPropertyDrawer(typeof(VRM10RotationOffset))] - public class IngredientDrawer : PropertyDrawer - { - public override float GetPropertyHeight(SerializedProperty property, GUIContent label) - { - return 16f + 18f; - } - - // Draw the property inside the given rect - void DrawEuler(Rect position, SerializedProperty property) - { - Vector3 euler = property.quaternionValue.eulerAngles; - euler = EditorGUI.Vector3Field(position, "Offset", euler); - property.quaternionValue = Quaternion.Euler(euler); - } - - public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) - { - DrawEuler(position, property.FindPropertyRelative(nameof(VRM10RotationOffset.Rotation))); - } - } -} diff --git a/Assets/VRM10/Editor/VRM10RotationOffsetDrawer.cs.meta b/Assets/VRM10/Editor/VRM10RotationOffsetDrawer.cs.meta deleted file mode 100644 index 2f04a1587..000000000 --- a/Assets/VRM10/Editor/VRM10RotationOffsetDrawer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 615a7cbd2c3cd5d42ab2719d6e74c1b8 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/VRM10/Runtime/Components/Constraint/VRM10RotationConstraint.cs b/Assets/VRM10/Runtime/Components/Constraint/VRM10RotationConstraint.cs index cdb0ada3f..e395506bf 100644 --- a/Assets/VRM10/Runtime/Components/Constraint/VRM10RotationConstraint.cs +++ b/Assets/VRM10/Runtime/Components/Constraint/VRM10RotationConstraint.cs @@ -15,9 +15,38 @@ namespace UniVRM10 [Range(0, 10.0f)] public float Weight = 1.0f; + Quaternion _srcRestLocalQuatInverse; + Quaternion _dstRestLocalQuat; + + void Awake() + { + if (Source == null) + { + this.enabled = false; + return; + } + + _srcRestLocalQuatInverse = Quaternion.Inverse(Source.localRotation); + _dstRestLocalQuat = transform.localRotation; + } + + /// + /// https://github.com/vrm-c/vrm-specification/blob/master/specification/VRMC_node_constraint-1.0_draft/README.ja.md#example-of-implementation-2 + /// + /// srcDeltaQuat = srcRestQuat.inverse * srcQuat + /// targetQuat = Quaternion.slerp( + /// dstRestQuat, + /// dstRestQuat * srcDeltaQuat, + /// weight + /// ) + /// public override void Process() { - throw new System.NotImplementedException(); + if (Source == null) return; + + // local coords + var srcDeltaLocalQuat = _srcRestLocalQuatInverse * Source.localRotation; + transform.localRotation = Quaternion.SlerpUnclamped(_dstRestLocalQuat, _dstRestLocalQuat * srcDeltaLocalQuat, Weight); } } } diff --git a/Assets/VRM10/Runtime/Components/Constraint/VRM10RotationOffset.cs b/Assets/VRM10/Runtime/Components/Constraint/VRM10RotationOffset.cs deleted file mode 100644 index a6382b5f1..000000000 --- a/Assets/VRM10/Runtime/Components/Constraint/VRM10RotationOffset.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using UnityEngine; - -namespace UniVRM10 -{ - [Serializable] - public struct VRM10RotationOffset - { - [SerializeField] - public Quaternion Rotation; - - public static VRM10RotationOffset Identity => new VRM10RotationOffset - { - Rotation = Quaternion.identity, - }; - } -} diff --git a/Assets/VRM10/Runtime/Components/Constraint/VRM10RotationOffset.cs.meta b/Assets/VRM10/Runtime/Components/Constraint/VRM10RotationOffset.cs.meta deleted file mode 100644 index 4fc95a462..000000000 --- a/Assets/VRM10/Runtime/Components/Constraint/VRM10RotationOffset.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 5b8a5228a8756d64684e8dca601ccafc -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/VRM10/Runtime/Components/Constraint/Vrm10AimConstraint.cs b/Assets/VRM10/Runtime/Components/Constraint/Vrm10AimConstraint.cs index 87d7405f7..433693389 100644 --- a/Assets/VRM10/Runtime/Components/Constraint/Vrm10AimConstraint.cs +++ b/Assets/VRM10/Runtime/Components/Constraint/Vrm10AimConstraint.cs @@ -1,4 +1,6 @@ -using UnityEngine; +using System; +using UniGLTF.Extensions.VRMC_node_constraint; +using UnityEngine; namespace UniVRM10 { @@ -16,11 +18,61 @@ namespace UniVRM10 public float Weight = 1.0f; [SerializeField] - public UniGLTF.Extensions.VRMC_node_constraint.AimAxis AimAxis; + public AimAxis AimAxis; + Vector3 GetAxisVector() + { + switch (AimAxis) + { + case AimAxis.PositiveX: return Vector3.right; + case AimAxis.NegativeX: return Vector3.left; + case AimAxis.PositiveY: return Vector3.up; + case AimAxis.NegativeY: return Vector3.down; + case AimAxis.PositiveZ: return Vector3.forward; + case AimAxis.NegativeZ: return Vector3.back; + default: throw new NotImplementedException(); + } + } + + Quaternion _dstRestLocalQuat; + + void Awake() + { + if (Source == null) + { + this.enabled = false; + return; + } + + _dstRestLocalQuat = transform.localRotation; + } + /// + /// https://github.com/vrm-c/vrm-specification/blob/master/specification/VRMC_node_constraint-1.0_draft/README.ja.md#example-of-implementation-1 + /// + /// fromVec = aimAxis.applyQuaternion( dstParentWorldQuat * dstRestQuat ) + /// toVec = ( srcWorldPos - dstWorldPos ).normalized + /// fromToQuat = Quaternion.fromToRotation( fromVec, toVec ) + /// targetQuat = Quaternion.slerp( + /// dstRestQuat, + /// dstParentWorldQuat.inverse * fromToQuat * dstParentWorldQuat * dstRestQuat, + /// weight + /// ) + /// public override void Process() { - throw new System.NotImplementedException(); + if (Source == null) return; + + // world coords + var dstParentWorldQuat = transform.parent != null ? transform.parent.rotation : Quaternion.identity; + var fromVec = (dstParentWorldQuat * _dstRestLocalQuat) * GetAxisVector(); + var toVec = (Source.position - transform.position).normalized; + var fromToQuat = Quaternion.FromToRotation(fromVec, toVec); + + transform.rotation = Quaternion.SlerpUnclamped( + _dstRestLocalQuat, + Quaternion.Inverse(dstParentWorldQuat) * fromToQuat * dstParentWorldQuat * _dstRestLocalQuat, + Weight + ); } } } diff --git a/Assets/VRM10/Runtime/Components/Constraint/Vrm10RollConstraint.cs b/Assets/VRM10/Runtime/Components/Constraint/Vrm10RollConstraint.cs index 199d14a7b..cc75b75e8 100644 --- a/Assets/VRM10/Runtime/Components/Constraint/Vrm10RollConstraint.cs +++ b/Assets/VRM10/Runtime/Components/Constraint/Vrm10RollConstraint.cs @@ -1,4 +1,6 @@ -using UnityEngine; +using System; +using UniGLTF.Extensions.VRMC_node_constraint; +using UnityEngine; namespace UniVRM10 { @@ -16,11 +18,65 @@ namespace UniVRM10 public float Weight = 1.0f; [SerializeField] - public UniGLTF.Extensions.VRMC_node_constraint.RollAxis RollAxis; + public RollAxis RollAxis; + Vector3 GetRollVector() + { + switch (RollAxis) + { + case RollAxis.X: return Vector3.right; + case RollAxis.Y: return Vector3.up; + case RollAxis.Z: return Vector3.forward; + default: throw new NotImplementedException(); + } + } + Quaternion _srcRestLocalQuat; + Quaternion _dstRestLocalQuat; + + void Awake() + { + if (Source == null) + { + this.enabled = false; + return; + } + + _srcRestLocalQuat = Source.localRotation; + _dstRestLocalQuat = transform.localRotation; + } + /// + /// https://github.com/vrm-c/vrm-specification/blob/master/specification/VRMC_node_constraint-1.0_draft/README.ja.md#example-of-implementation + /// + /// deltaSrcQuat = srcRestQuat.inverse * srcQuat + /// deltaSrcQuatInParent = srcRestQuat * deltaSrcQuat * srcRestQuat.inverse // source to parent + /// deltaSrcQuatInDst = dstRestQuat.inverse * deltaSrcQuatInWorld * dstRestQuat // parent to destination + /// + /// toVec = rollAxis.applyQuaternion( deltaSrcQuatInDst ) + /// fromToQuat = Quaternion.fromToRotation( rollAxis, toVec ) + /// + /// targetQuat = Quaternion.slerp( + /// dstRestQuat, + /// dstRestQuat * fromToQuat.inverse * deltaSrcQuatInDst, + /// weight + /// ) + /// public override void Process() { - throw new System.NotImplementedException(); + if (Source == null) return; + + var deltaSrcQuat = Quaternion.Inverse(_srcRestLocalQuat) * Source.localRotation; + var deltaSrcQuatInParent = _srcRestLocalQuat * deltaSrcQuat * Quaternion.Inverse(_srcRestLocalQuat); // source to parent + var deltaSrcQuatInDst = Quaternion.Inverse(_dstRestLocalQuat) * deltaSrcQuatInParent * _dstRestLocalQuat; // parent to destination + + var rollAxis = GetRollVector(); + var toVec = deltaSrcQuatInDst * rollAxis; + var fromToQuat = Quaternion.FromToRotation(rollAxis, toVec); + + transform.localRotation = Quaternion.SlerpUnclamped( + _dstRestLocalQuat, + _dstRestLocalQuat * Quaternion.Inverse(fromToQuat) * deltaSrcQuatInDst, + Weight + ); } } } From a12ce042fb679413b8179d0c5f6c4ab5b7347e1f Mon Sep 17 00:00:00 2001 From: ousttrue Date: Tue, 19 Apr 2022 13:43:55 +0900 Subject: [PATCH 4/5] IVRM10Constraint.cs abstract class to interface --- Assets/VRM10/Editor/Components/VRM10Window.cs | 6 +++--- .../Runtime/Components/Constraint/IVRM10Constraint.cs | 11 +++++++++++ ...M10Constraint.cs.meta => IVRM10Constraint.cs.meta} | 2 +- .../Runtime/Components/Constraint/VRM10Constraint.cs | 9 --------- .../Components/Constraint/VRM10RotationConstraint.cs | 6 ++++-- .../Components/Constraint/Vrm10AimConstraint.cs | 6 ++++-- .../Components/Constraint/Vrm10RollConstraint.cs | 6 ++++-- .../Runtime/Components/Vrm10Runtime/Vrm10Runtime.cs | 4 ++-- Assets/VRM10/Runtime/IO/Vrm10Exporter.cs | 4 ++-- 9 files changed, 31 insertions(+), 23 deletions(-) create mode 100644 Assets/VRM10/Runtime/Components/Constraint/IVRM10Constraint.cs rename Assets/VRM10/Runtime/Components/Constraint/{VRM10Constraint.cs.meta => IVRM10Constraint.cs.meta} (83%) delete mode 100644 Assets/VRM10/Runtime/Components/Constraint/VRM10Constraint.cs diff --git a/Assets/VRM10/Editor/Components/VRM10Window.cs b/Assets/VRM10/Editor/Components/VRM10Window.cs index 613ec0a7e..507ed3067 100644 --- a/Assets/VRM10/Editor/Components/VRM10Window.cs +++ b/Assets/VRM10/Editor/Components/VRM10Window.cs @@ -71,7 +71,7 @@ namespace UniVRM10 Transform m_head; - public Vrm10Constraint[] m_constraints; + public IVrm10Constraint[] m_constraints; ScrollView m_scrollView = new ScrollView(); @@ -177,7 +177,7 @@ namespace UniVRM10 { if (m_constraints == null) { - m_constraints = Root.GetComponentsInChildren(); + m_constraints = Root.GetComponentsInChildren(); } } @@ -187,7 +187,7 @@ namespace UniVRM10 { foreach (var c in m_constraints) { - EditorGUILayout.ObjectField(c, typeof(Vrm10Constraint), true); + EditorGUILayout.ObjectField(c.GameObject, typeof(MonoBehaviour), true); } } } diff --git a/Assets/VRM10/Runtime/Components/Constraint/IVRM10Constraint.cs b/Assets/VRM10/Runtime/Components/Constraint/IVRM10Constraint.cs new file mode 100644 index 000000000..366003317 --- /dev/null +++ b/Assets/VRM10/Runtime/Components/Constraint/IVRM10Constraint.cs @@ -0,0 +1,11 @@ +using UnityEngine; + +namespace UniVRM10 +{ + public interface IVrm10Constraint + { + void Process(); + + GameObject GameObject { get; } + } +} diff --git a/Assets/VRM10/Runtime/Components/Constraint/VRM10Constraint.cs.meta b/Assets/VRM10/Runtime/Components/Constraint/IVRM10Constraint.cs.meta similarity index 83% rename from Assets/VRM10/Runtime/Components/Constraint/VRM10Constraint.cs.meta rename to Assets/VRM10/Runtime/Components/Constraint/IVRM10Constraint.cs.meta index 37ffe7564..e14d79e8d 100644 --- a/Assets/VRM10/Runtime/Components/Constraint/VRM10Constraint.cs.meta +++ b/Assets/VRM10/Runtime/Components/Constraint/IVRM10Constraint.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: ded8c4db12c688b46814cf0bf925cacf +guid: c859e278c34a69b438db39275ce25556 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/VRM10/Runtime/Components/Constraint/VRM10Constraint.cs b/Assets/VRM10/Runtime/Components/Constraint/VRM10Constraint.cs deleted file mode 100644 index fb04b9de9..000000000 --- a/Assets/VRM10/Runtime/Components/Constraint/VRM10Constraint.cs +++ /dev/null @@ -1,9 +0,0 @@ -using UnityEngine; - -namespace UniVRM10 -{ - public abstract class Vrm10Constraint : MonoBehaviour - { - public abstract void Process(); - } -} diff --git a/Assets/VRM10/Runtime/Components/Constraint/VRM10RotationConstraint.cs b/Assets/VRM10/Runtime/Components/Constraint/VRM10RotationConstraint.cs index e395506bf..5fb3a915a 100644 --- a/Assets/VRM10/Runtime/Components/Constraint/VRM10RotationConstraint.cs +++ b/Assets/VRM10/Runtime/Components/Constraint/VRM10RotationConstraint.cs @@ -6,8 +6,10 @@ namespace UniVRM10 /// https://github.com/vrm-c/vrm-specification/blob/master/specification/VRMC_node_constraint-1.0_draft/schema/VRMC_node_constraint.rotationConstraint.schema.json /// [DisallowMultipleComponent] - public class Vrm10RotationConstraint : Vrm10Constraint + public class Vrm10RotationConstraint : MonoBehaviour, IVrm10Constraint { + public GameObject GameObject => gameObject; + [SerializeField] public Transform Source = default; @@ -40,7 +42,7 @@ namespace UniVRM10 /// weight /// ) /// - public override void Process() + public void Process() { if (Source == null) return; diff --git a/Assets/VRM10/Runtime/Components/Constraint/Vrm10AimConstraint.cs b/Assets/VRM10/Runtime/Components/Constraint/Vrm10AimConstraint.cs index 433693389..c1ba95896 100644 --- a/Assets/VRM10/Runtime/Components/Constraint/Vrm10AimConstraint.cs +++ b/Assets/VRM10/Runtime/Components/Constraint/Vrm10AimConstraint.cs @@ -8,8 +8,10 @@ namespace UniVRM10 /// https://github.com/vrm-c/vrm-specification/blob/master/specification/VRMC_node_constraint-1.0_draft/schema/VRMC_node_constraint.aimConstraint.schema.json /// [DisallowMultipleComponent] - public class Vrm10AimConstraint : Vrm10Constraint + public class Vrm10AimConstraint : MonoBehaviour, IVrm10Constraint { + public GameObject GameObject => gameObject; + [SerializeField] public Transform Source = default; @@ -58,7 +60,7 @@ namespace UniVRM10 /// weight /// ) /// - public override void Process() + public void Process() { if (Source == null) return; diff --git a/Assets/VRM10/Runtime/Components/Constraint/Vrm10RollConstraint.cs b/Assets/VRM10/Runtime/Components/Constraint/Vrm10RollConstraint.cs index cc75b75e8..292757d73 100644 --- a/Assets/VRM10/Runtime/Components/Constraint/Vrm10RollConstraint.cs +++ b/Assets/VRM10/Runtime/Components/Constraint/Vrm10RollConstraint.cs @@ -8,8 +8,10 @@ namespace UniVRM10 /// https://github.com/vrm-c/vrm-specification/blob/master/specification/VRMC_node_constraint-1.0_draft/schema/VRMC_node_constraint.rollConstraint.schema.json /// [DisallowMultipleComponent] - public class Vrm10RollConstraint : Vrm10Constraint + public class Vrm10RollConstraint : MonoBehaviour, IVrm10Constraint { + public GameObject GameObject => gameObject; + [SerializeField] public Transform Source = default; @@ -60,7 +62,7 @@ namespace UniVRM10 /// weight /// ) /// - public override void Process() + public void Process() { if (Source == null) return; diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10Runtime.cs b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10Runtime.cs index d446c917d..1f18f0e81 100644 --- a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10Runtime.cs +++ b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10Runtime.cs @@ -12,7 +12,7 @@ namespace UniVRM10 public class Vrm10Runtime : IDisposable { private readonly Vrm10Instance m_target; - private readonly Vrm10Constraint[] m_constraints; + private readonly IVrm10Constraint[] m_constraints; private readonly Transform m_head; private readonly FastSpringBoneService m_fastSpringBoneService; @@ -39,7 +39,7 @@ namespace UniVRM10 if (m_constraints == null) { - m_constraints = target.GetComponentsInChildren(); + m_constraints = target.GetComponentsInChildren(); } if (!Application.isPlaying) diff --git a/Assets/VRM10/Runtime/IO/Vrm10Exporter.cs b/Assets/VRM10/Runtime/IO/Vrm10Exporter.cs index fefa6ec2a..aace371d0 100644 --- a/Assets/VRM10/Runtime/IO/Vrm10Exporter.cs +++ b/Assets/VRM10/Runtime/IO/Vrm10Exporter.cs @@ -401,7 +401,7 @@ namespace UniVRM10 static void ExportConstraints(Vrm10Instance vrmController, Model model, ModelExporter converter, List nodes) { - var constraints = vrmController.GetComponentsInChildren(); + var constraints = vrmController.GetComponentsInChildren(); foreach (var constraint in constraints) { var vrmConstraint = new UniGLTF.Extensions.VRMC_node_constraint.VRMC_node_constraint @@ -445,7 +445,7 @@ namespace UniVRM10 } // serialize to gltfNode - var node = converter.Nodes[constraint.gameObject]; + var node = converter.Nodes[constraint.GameObject]; var nodeIndex = model.Nodes.IndexOf(node); var gltfNode = nodes[nodeIndex]; UniGLTF.Extensions.VRMC_node_constraint.GltfSerializer.SerializeTo(ref gltfNode.extensions, vrmConstraint); From 83c16805d9e2384b8daaf73ae4263c359fcad99f Mon Sep 17 00:00:00 2001 From: ousttrue Date: Tue, 19 Apr 2022 13:48:38 +0900 Subject: [PATCH 5/5] =?UTF-8?q?prefix=20VRM10=20=E3=81=AE=E8=A1=A8?= =?UTF-8?q?=E8=A8=98=E3=83=96=E3=83=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Constraint/{IVRM10Constraint.cs => IVrm10Constraint.cs} | 0 .../{IVRM10Constraint.cs.meta => IVrm10Constraint.cs.meta} | 0 .../{VRM10RotationConstraint.cs => Vrm10RotationConstraint.cs} | 0 ...RotationConstraint.cs.meta => Vrm10RotationConstraint.cs.meta} | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename Assets/VRM10/Runtime/Components/Constraint/{IVRM10Constraint.cs => IVrm10Constraint.cs} (100%) rename Assets/VRM10/Runtime/Components/Constraint/{IVRM10Constraint.cs.meta => IVrm10Constraint.cs.meta} (100%) rename Assets/VRM10/Runtime/Components/Constraint/{VRM10RotationConstraint.cs => Vrm10RotationConstraint.cs} (100%) rename Assets/VRM10/Runtime/Components/Constraint/{VRM10RotationConstraint.cs.meta => Vrm10RotationConstraint.cs.meta} (100%) diff --git a/Assets/VRM10/Runtime/Components/Constraint/IVRM10Constraint.cs b/Assets/VRM10/Runtime/Components/Constraint/IVrm10Constraint.cs similarity index 100% rename from Assets/VRM10/Runtime/Components/Constraint/IVRM10Constraint.cs rename to Assets/VRM10/Runtime/Components/Constraint/IVrm10Constraint.cs diff --git a/Assets/VRM10/Runtime/Components/Constraint/IVRM10Constraint.cs.meta b/Assets/VRM10/Runtime/Components/Constraint/IVrm10Constraint.cs.meta similarity index 100% rename from Assets/VRM10/Runtime/Components/Constraint/IVRM10Constraint.cs.meta rename to Assets/VRM10/Runtime/Components/Constraint/IVrm10Constraint.cs.meta diff --git a/Assets/VRM10/Runtime/Components/Constraint/VRM10RotationConstraint.cs b/Assets/VRM10/Runtime/Components/Constraint/Vrm10RotationConstraint.cs similarity index 100% rename from Assets/VRM10/Runtime/Components/Constraint/VRM10RotationConstraint.cs rename to Assets/VRM10/Runtime/Components/Constraint/Vrm10RotationConstraint.cs diff --git a/Assets/VRM10/Runtime/Components/Constraint/VRM10RotationConstraint.cs.meta b/Assets/VRM10/Runtime/Components/Constraint/Vrm10RotationConstraint.cs.meta similarity index 100% rename from Assets/VRM10/Runtime/Components/Constraint/VRM10RotationConstraint.cs.meta rename to Assets/VRM10/Runtime/Components/Constraint/Vrm10RotationConstraint.cs.meta