From 2a992950a609010b88889befb2824a36f279ba4f Mon Sep 17 00:00:00 2001 From: ousttrue Date: Tue, 18 Oct 2022 15:08:35 +0900 Subject: [PATCH 1/8] =?UTF-8?q?joint=20=E3=81=A8=20collider=20=E3=82=92?= =?UTF-8?q?=E3=82=AF=E3=83=AA=E3=83=83=E3=82=AF=E9=81=B8=E6=8A=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/SpringBone/SpringBoneEditor.cs | 5 +- .../SpringBone/SpringBoneTreeView.cs | 114 ++++++++++++-- Assets/VRM10/Editor/Components/VRM10Window.cs | 141 +++++++++--------- 3 files changed, 174 insertions(+), 86 deletions(-) diff --git a/Assets/VRM10/Editor/Components/SpringBone/SpringBoneEditor.cs b/Assets/VRM10/Editor/Components/SpringBone/SpringBoneEditor.cs index 36faf4958..a06fe694f 100644 --- a/Assets/VRM10/Editor/Components/SpringBone/SpringBoneEditor.cs +++ b/Assets/VRM10/Editor/Components/SpringBone/SpringBoneEditor.cs @@ -48,7 +48,10 @@ namespace UniVRM10 public static void Draw3D(Vrm10Instance target, SerializedObject so) { var tree = GetTree(target, so); - tree.Draw3D(); + if (tree != null && target != null) + { + tree.Draw3D(target.SpringBone); + } } } } diff --git a/Assets/VRM10/Editor/Components/SpringBone/SpringBoneTreeView.cs b/Assets/VRM10/Editor/Components/SpringBone/SpringBoneTreeView.cs index a9788ed8c..00072502f 100644 --- a/Assets/VRM10/Editor/Components/SpringBone/SpringBoneTreeView.cs +++ b/Assets/VRM10/Editor/Components/SpringBone/SpringBoneTreeView.cs @@ -37,24 +37,30 @@ namespace UniVRM10 // load _map = new Dictionary(); - for (var i = 0; i < target.SpringBone.ColliderGroups.Count; ++i) + if (target?.SpringBone?.ColliderGroups != null) { - var colliderGroup = target.SpringBone.ColliderGroups[i]; - var name = colliderGroup.GUIName(i); - var id = _nextNodeID++; - var item = new TreeViewItem(id, 2, name); - _map.Add(id, colliderGroup); - _colliderGroups.AddChild(item); + for (var i = 0; i < target.SpringBone.ColliderGroups.Count; ++i) + { + var colliderGroup = target.SpringBone.ColliderGroups[i]; + var name = colliderGroup.GUIName(i); + var id = _nextNodeID++; + var item = new TreeViewItem(id, 2, name); + _map.Add(id, colliderGroup); + _colliderGroups.AddChild(item); + } } - for (var i = 0; i < target.SpringBone.Springs.Count; ++i) + if (target?.SpringBone?.Springs != null) { - var spring = target.SpringBone.Springs[i]; - var name = spring.GUIName(i); - var id = _nextNodeID++; - var item = new TreeViewItem(id, 2, name); - _map.Add(id, spring); - _springs.AddChild(item); + for (var i = 0; i < target.SpringBone.Springs.Count; ++i) + { + var spring = target.SpringBone.Springs[i]; + var name = spring.GUIName(i); + var id = _nextNodeID++; + var item = new TreeViewItem(id, 2, name); + _map.Add(id, spring); + _springs.AddChild(item); + } } } @@ -107,16 +113,92 @@ namespace UniVRM10 } } - public void Draw3D() + Color s_selectedColor = new Color(0.5f, 0, 0, 0.5f); + Color s_Color = new Color(0.6f, 0.6f, 0.6f, 0.5f); + + public void Draw3D(Vrm10InstanceSpringBone springBone) { if (_selected is SelectedColliderGroupGUI colliderGroup) { - colliderGroup.Draw3D(); + // colliderGroup.Draw3D(); } else if (_selected is SelectedSpringGUI spring) { // TODO } + + foreach (var group in springBone.ColliderGroups) + { + foreach (var collider in group.Colliders) + { + var color = collider.gameObject == Selection.activeObject ? s_selectedColor : s_Color; + if (DrawCollider(collider, color)) + { + Selection.activeObject = collider.gameObject; + } + } + } + foreach (var spring in springBone.Springs) + { + for (int i = 1; i < spring.Joints.Count; ++i) + { + var head = spring.Joints[i - 1]; + var tail = spring.Joints[i]; + var color = tail.gameObject == Selection.activeObject ? s_selectedColor : s_Color; + if (DrawJoint(head, tail, color)) + { + Selection.activeObject = tail.gameObject; + } + } + } + } + + static bool IsLeftDown() + { + return Event.current.type == EventType.MouseDown && Event.current.button == 0; + } + + bool DrawCollider(VRM10SpringBoneCollider collider, Color color) + { + if (Event.current.type == EventType.Repaint || Event.current.type == EventType.Layout) + { + Handles.matrix = collider.transform.localToWorldMatrix; + Handles.color = color; + switch (collider.ColliderType) + { + case VRM10SpringBoneColliderTypes.Sphere: + // Handles.color = Color.magenta; + Handles.SphereHandleCap(collider.gameObject.GetInstanceID(), collider.Offset, Quaternion.identity, collider.Radius * 2, Event.current.type); + break; + + case VRM10SpringBoneColliderTypes.Capsule: + // Handles.color = Color.cyan; + Handles.SphereHandleCap(collider.gameObject.GetInstanceID(), collider.Offset, Quaternion.identity, collider.Radius * 2, Event.current.type); + Handles.SphereHandleCap(collider.gameObject.GetInstanceID(), collider.Tail, Quaternion.identity, collider.Radius * 2, Event.current.type); + Handles.DrawLine(collider.Offset, collider.Tail); + break; + } + Handles.matrix = Matrix4x4.identity; + } + else if (IsLeftDown()) + { + return HandleUtility.nearestControl == collider.gameObject.GetInstanceID(); + } + return false; + } + + bool DrawJoint(VRM10SpringBoneJoint head, VRM10SpringBoneJoint tail, Color color) + { + if (Event.current.type == EventType.Repaint || Event.current.type == EventType.Layout) + { + Handles.color = color; + Handles.SphereHandleCap(tail.gameObject.GetInstanceID(), tail.transform.position, Quaternion.identity, tail.m_jointRadius * 2, Event.current.type); + } + else if (IsLeftDown()) + { + return HandleUtility.nearestControl == tail.gameObject.GetInstanceID(); + } + return false; } } } diff --git a/Assets/VRM10/Editor/Components/VRM10Window.cs b/Assets/VRM10/Editor/Components/VRM10Window.cs index 476a50ce6..f7aca7c2b 100644 --- a/Assets/VRM10/Editor/Components/VRM10Window.cs +++ b/Assets/VRM10/Editor/Components/VRM10Window.cs @@ -59,7 +59,7 @@ namespace UniVRM10 } m_root = id; m_so = value != null ? new SerializedObject(value) : null; - m_constraints = null; + // m_constraints = null; if (Root != null) { @@ -71,28 +71,28 @@ namespace UniVRM10 Transform m_head; - public IVrm10Constraint[] m_constraints; + // public IVrm10Constraint[] m_constraints; ScrollView m_scrollView = new ScrollView(); - enum VRMSceneUI - { - Constraints, - SpringBone, - } - static VRMSceneUI s_ui = default; - static string[] s_selection; - static string[] Selection - { - get - { - if (s_selection == null) - { - s_selection = Enum.GetNames(typeof(VRMSceneUI)); - } - return s_selection; - } - } + // enum VRMSceneUI + // { + // Constraints, + // SpringBone, + // } + // static VRMSceneUI s_ui = default; + // static string[] s_selection; + // static string[] Selection + // { + // get + // { + // if (s_selection == null) + // { + // s_selection = Enum.GetNames(typeof(VRMSceneUI)); + // } + // return s_selection; + // } + // } /// /// public entry point @@ -100,20 +100,22 @@ namespace UniVRM10 /// void OnSceneGUI(SceneView sceneView) { - switch (s_ui) - { - case VRMSceneUI.Constraints: - Tools.hidden = false; - break; + // switch (s_ui) + // { + // case VRMSceneUI.Constraints: + // Tools.hidden = false; + // break; - case VRMSceneUI.SpringBone: - Tools.hidden = true; - SpringBoneEditor.Draw3D(Root, m_so); - break; + // case VRMSceneUI.SpringBone: + // Tools.hidden = true; + // SpringBoneEditor.Draw3D(Root, m_so); + // break; - default: - throw new NotImplementedException(); - } + // default: + // throw new NotImplementedException(); + // } + Tools.hidden = true; + SpringBoneEditor.Draw3D(Root, m_so); } // @@ -137,12 +139,12 @@ namespace UniVRM10 return; } - var ui = (VRMSceneUI)GUILayout.SelectionGrid((int)s_ui, Selection, 3); - if (s_ui != ui) - { - s_ui = ui; - SceneView.RepaintAll(); - } + // var ui = (VRMSceneUI)GUILayout.SelectionGrid((int)s_ui, Selection, 3); + // if (s_ui != ui) + // { + // s_ui = ui; + // SceneView.RepaintAll(); + // } if (m_so == null) { @@ -154,43 +156,44 @@ namespace UniVRM10 } m_so.Update(); - switch (s_ui) - { - case VRMSceneUI.Constraints: - m_scrollView.Draw(this.position.y, DrawConstraints, Repaint); - break; + // switch (s_ui) + // { + // case VRMSceneUI.Constraints: + // m_scrollView.Draw(this.position.y, DrawConstraints, Repaint); + // break; - case VRMSceneUI.SpringBone: - SpringBoneEditor.Draw2D(Root, m_so); - break; + // case VRMSceneUI.SpringBone: + // SpringBoneEditor.Draw2D(Root, m_so); + // break; - default: - throw new NotImplementedException(); - } + // default: + // throw new NotImplementedException(); + // } + SpringBoneEditor.Draw2D(Root, m_so); m_so.ApplyModifiedProperties(); } - void DrawConstraints() - { - if (Root != null) - { - if (m_constraints == null) - { - m_constraints = Root.GetComponentsInChildren(); - } - } + // void DrawConstraints() + // { + // if (Root != null) + // { + // if (m_constraints == null) + // { + // m_constraints = Root.GetComponentsInChildren(); + // } + // } - using (new EditorGUI.DisabledScope(true)) - { - if (m_constraints != null) - { - foreach (var c in m_constraints) - { - EditorGUILayout.ObjectField(c.ConstraintTarget, typeof(MonoBehaviour), true); - } - } - } - } + // using (new EditorGUI.DisabledScope(true)) + // { + // if (m_constraints != null) + // { + // foreach (var c in m_constraints) + // { + // EditorGUILayout.ObjectField(c.ConstraintTarget, typeof(MonoBehaviour), true); + // } + // } + // } + // } } } From 61a0a28c93324d95f5245fe386e81fca2db21d0e Mon Sep 17 00:00:00 2001 From: ousttrue Date: Thu, 20 Oct 2022 19:25:34 +0900 Subject: [PATCH 2/8] =?UTF-8?q?collider=20=E3=81=AE=20offset=20=E6=93=8D?= =?UTF-8?q?=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/SpringBone/SpringBoneEditor.cs | 4 +- .../SpringBone/SpringBoneTreeView.cs | 51 ++++++++++-- Assets/VRM10/Editor/Components/VRM10Window.cs | 81 ++----------------- 3 files changed, 54 insertions(+), 82 deletions(-) diff --git a/Assets/VRM10/Editor/Components/SpringBone/SpringBoneEditor.cs b/Assets/VRM10/Editor/Components/SpringBone/SpringBoneEditor.cs index a06fe694f..36765b466 100644 --- a/Assets/VRM10/Editor/Components/SpringBone/SpringBoneEditor.cs +++ b/Assets/VRM10/Editor/Components/SpringBone/SpringBoneEditor.cs @@ -27,6 +27,8 @@ namespace UniVRM10 s_treeView = null; } + public static MonoBehaviour Active; + /// /// 2D の GUI 描画 /// @@ -50,7 +52,7 @@ namespace UniVRM10 var tree = GetTree(target, so); if (tree != null && target != null) { - tree.Draw3D(target.SpringBone); + Active = tree.Draw3D(target.SpringBone); } } } diff --git a/Assets/VRM10/Editor/Components/SpringBone/SpringBoneTreeView.cs b/Assets/VRM10/Editor/Components/SpringBone/SpringBoneTreeView.cs index 00072502f..f1de1080d 100644 --- a/Assets/VRM10/Editor/Components/SpringBone/SpringBoneTreeView.cs +++ b/Assets/VRM10/Editor/Components/SpringBone/SpringBoneTreeView.cs @@ -116,8 +116,17 @@ namespace UniVRM10 Color s_selectedColor = new Color(0.5f, 0, 0, 0.5f); Color s_Color = new Color(0.6f, 0.6f, 0.6f, 0.5f); - public void Draw3D(Vrm10InstanceSpringBone springBone) + Vrm10InstanceSpringBone last = null; + MonoBehaviour Active = null; + + public MonoBehaviour Draw3D(Vrm10InstanceSpringBone springBone) { + if (springBone != last) + { + Active = null; + last = springBone; + } + if (_selected is SelectedColliderGroupGUI colliderGroup) { // colliderGroup.Draw3D(); @@ -127,14 +136,15 @@ namespace UniVRM10 // TODO } + MonoBehaviour newActive = null; foreach (var group in springBone.ColliderGroups) { foreach (var collider in group.Colliders) { - var color = collider.gameObject == Selection.activeObject ? s_selectedColor : s_Color; + var color = collider == Active ? s_selectedColor : s_Color; if (DrawCollider(collider, color)) { - Selection.activeObject = collider.gameObject; + newActive = collider; } } } @@ -144,13 +154,44 @@ namespace UniVRM10 { var head = spring.Joints[i - 1]; var tail = spring.Joints[i]; - var color = tail.gameObject == Selection.activeObject ? s_selectedColor : s_Color; + var color = head == Active ? s_selectedColor : s_Color; if (DrawJoint(head, tail, color)) { - Selection.activeObject = tail.gameObject; + newActive = head; } } } + + if (Active is VRM10SpringBoneCollider activeCollider) + { + EditorGUI.BeginChangeCheck(); + Handles.matrix = activeCollider.transform.localToWorldMatrix; + var offset = Handles.PositionHandle(activeCollider.Offset, Quaternion.identity); + var tail = Vector3.zero; + if (activeCollider.ColliderType == VRM10SpringBoneColliderTypes.Capsule) + { + tail = Handles.PositionHandle(activeCollider.Tail, Quaternion.identity); + } + var offsetChanged = EditorGUI.EndChangeCheck(); + if (offsetChanged) + { + // apply + Undo.RecordObject(activeCollider, "activeCollider"); + activeCollider.Offset = offset; + if (activeCollider.ColliderType == VRM10SpringBoneColliderTypes.Capsule) + { + activeCollider.Tail = tail; + } + } + } + + if (newActive != null) + { + Selection.activeObject = newActive.gameObject; + Active = newActive; + } + + return Active; } static bool IsLeftDown() diff --git a/Assets/VRM10/Editor/Components/VRM10Window.cs b/Assets/VRM10/Editor/Components/VRM10Window.cs index f7aca7c2b..331db7550 100644 --- a/Assets/VRM10/Editor/Components/VRM10Window.cs +++ b/Assets/VRM10/Editor/Components/VRM10Window.cs @@ -71,49 +71,14 @@ namespace UniVRM10 Transform m_head; - // public IVrm10Constraint[] m_constraints; - ScrollView m_scrollView = new ScrollView(); - // enum VRMSceneUI - // { - // Constraints, - // SpringBone, - // } - // static VRMSceneUI s_ui = default; - // static string[] s_selection; - // static string[] Selection - // { - // get - // { - // if (s_selection == null) - // { - // s_selection = Enum.GetNames(typeof(VRMSceneUI)); - // } - // return s_selection; - // } - // } - /// /// public entry point /// /// void OnSceneGUI(SceneView sceneView) { - // switch (s_ui) - // { - // case VRMSceneUI.Constraints: - // Tools.hidden = false; - // break; - - // case VRMSceneUI.SpringBone: - // Tools.hidden = true; - // SpringBoneEditor.Draw3D(Root, m_so); - // break; - - // default: - // throw new NotImplementedException(); - // } Tools.hidden = true; SpringBoneEditor.Draw3D(Root, m_so); } @@ -133,18 +98,17 @@ namespace UniVRM10 } } + // Root Root = (Vrm10Instance)EditorGUILayout.ObjectField("vrm1", Root, typeof(Vrm10Instance), true); if (Root == null) { return; } - // var ui = (VRMSceneUI)GUILayout.SelectionGrid((int)s_ui, Selection, 3); - // if (s_ui != ui) - // { - // s_ui = ui; - // SceneView.RepaintAll(); - // } + // active + EditorGUI.BeginDisabledGroup(true); + EditorGUILayout.ObjectField("joint or collider", SpringBoneEditor.Active, typeof(MonoBehaviour), true); + EditorGUI.EndDisabledGroup(); if (m_so == null) { @@ -156,44 +120,9 @@ namespace UniVRM10 } m_so.Update(); - // switch (s_ui) - // { - // case VRMSceneUI.Constraints: - // m_scrollView.Draw(this.position.y, DrawConstraints, Repaint); - // break; - - // case VRMSceneUI.SpringBone: - // SpringBoneEditor.Draw2D(Root, m_so); - // break; - - // default: - // throw new NotImplementedException(); - // } SpringBoneEditor.Draw2D(Root, m_so); m_so.ApplyModifiedProperties(); } - - // void DrawConstraints() - // { - // if (Root != null) - // { - // if (m_constraints == null) - // { - // m_constraints = Root.GetComponentsInChildren(); - // } - // } - - // using (new EditorGUI.DisabledScope(true)) - // { - // if (m_constraints != null) - // { - // foreach (var c in m_constraints) - // { - // EditorGUILayout.ObjectField(c.ConstraintTarget, typeof(MonoBehaviour), true); - // } - // } - // } - // } } } From 916e4751c8e7caaea7492bf3acfb93782d626523 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Fri, 21 Oct 2022 17:10:26 +0900 Subject: [PATCH 3/8] WINDOW_TITLE to VRM1.0 Model Editor --- Assets/VRM10/Editor/Components/VRM10Window.cs | 6 +++-- Assets/VRM10/Editor/Vrm10InstanceEditor.cs | 23 ++++++++++++------- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/Assets/VRM10/Editor/Components/VRM10Window.cs b/Assets/VRM10/Editor/Components/VRM10Window.cs index 331db7550..ad2125531 100644 --- a/Assets/VRM10/Editor/Components/VRM10Window.cs +++ b/Assets/VRM10/Editor/Components/VRM10Window.cs @@ -10,13 +10,15 @@ namespace UniVRM10 /// public class VRM10Window : EditorWindow { - const string WINDOW_TITLE = "VRM1 Window"; - public static void Open() + public const string WINDOW_TITLE = "VRM1.0 Model Editor"; + + public static VRM10Window Open() { var window = (VRM10Window)GetWindow(typeof(VRM10Window)); window.titleContent = new GUIContent(WINDOW_TITLE); window.Show(); window.Root = UnityEditor.Selection.activeTransform?.GetComponent(); + return window; } void OnEnable() diff --git a/Assets/VRM10/Editor/Vrm10InstanceEditor.cs b/Assets/VRM10/Editor/Vrm10InstanceEditor.cs index 878bbf029..26b2ac7bd 100644 --- a/Assets/VRM10/Editor/Vrm10InstanceEditor.cs +++ b/Assets/VRM10/Editor/Vrm10InstanceEditor.cs @@ -115,14 +115,8 @@ namespace UniVRM10 return loaded; } - void Setup(Vrm10Instance instance) + void SetupVRM10Object(Vrm10Instance instance) { - if (instance.Vrm != null) - { - // OK - return; - } - if (!CheckHumanoid(instance.gameObject)) { // can not @@ -162,9 +156,22 @@ namespace UniVRM10 public override void OnInspectorGUI() { + if (target is Vrm10Instance instance) { - Setup(instance); + if (instance.Vrm == null) + { + SetupVRM10Object(instance); + } + + if (instance.Vrm != null) + { + EditorGUILayout.HelpBox("SpringBone utility", MessageType.Info); + if (GUILayout.Button("Open " + VRM10Window.WINDOW_TITLE)) + { + VRM10Window.Open(); + } + } } base.OnInspectorGUI(); From f77f0dc6f585d8bc9f0a640b511d032c6e27ae31 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Fri, 21 Oct 2022 17:25:45 +0900 Subject: [PATCH 4/8] =?UTF-8?q?=E3=82=B3=E3=83=BC=E3=83=89=E6=95=B4?= =?UTF-8?q?=E7=90=86=E3=80=82SpringBoneEditor=20=E3=82=92=20VRM10Window=20?= =?UTF-8?q?=E3=81=AB=E7=B5=B1=E5=90=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 元は Constraint などのエディタもあったのだけど、削った。量が減ったので合体 --- .../Components/SpringBone/SpringBoneEditor.cs | 59 ------------- .../SpringBone/SpringBoneEditor.cs.meta | 11 --- Assets/VRM10/Editor/Components/VRM10Window.cs | 84 ++++++++++++------- Assets/VRM10/Editor/Vrm10InstanceEditor.cs | 2 +- 4 files changed, 54 insertions(+), 102 deletions(-) delete mode 100644 Assets/VRM10/Editor/Components/SpringBone/SpringBoneEditor.cs delete mode 100644 Assets/VRM10/Editor/Components/SpringBone/SpringBoneEditor.cs.meta diff --git a/Assets/VRM10/Editor/Components/SpringBone/SpringBoneEditor.cs b/Assets/VRM10/Editor/Components/SpringBone/SpringBoneEditor.cs deleted file mode 100644 index 36765b466..000000000 --- a/Assets/VRM10/Editor/Components/SpringBone/SpringBoneEditor.cs +++ /dev/null @@ -1,59 +0,0 @@ -using UnityEditor; -using UnityEditor.IMGUI.Controls; -using UnityEngine; - -namespace UniVRM10 -{ - /// - /// TreeView でアクティブな SpringBone, ColliderGroup を管理して、 - /// アクティブな SpringBone と ColliderGroup を SceneHandle で Edit する。 - /// - public static class SpringBoneEditor - { - static SpringBoneTreeView s_treeView; - static SpringBoneTreeView GetTree(Vrm10Instance target, SerializedObject so) - { - if (s_treeView == null || s_treeView.Target != target) - { - var state = new TreeViewState(); - s_treeView = new SpringBoneTreeView(state, target, so); - s_treeView.Reload(); - } - return s_treeView; - } - - public static void Disable() - { - s_treeView = null; - } - - public static MonoBehaviour Active; - - /// - /// 2D の GUI 描画 - /// - public static void Draw2D(Vrm10Instance target, SerializedObject so) - { - var tree = GetTree(target, so); - if (GUILayout.Button("Reload")) - { - Disable(); - return; - } - - tree.Draw2D(); - } - - /// - /// 3D の Handle 描画 - /// - public static void Draw3D(Vrm10Instance target, SerializedObject so) - { - var tree = GetTree(target, so); - if (tree != null && target != null) - { - Active = tree.Draw3D(target.SpringBone); - } - } - } -} diff --git a/Assets/VRM10/Editor/Components/SpringBone/SpringBoneEditor.cs.meta b/Assets/VRM10/Editor/Components/SpringBone/SpringBoneEditor.cs.meta deleted file mode 100644 index 3e25de41b..000000000 --- a/Assets/VRM10/Editor/Components/SpringBone/SpringBoneEditor.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 33ca35799b1168949bb4466aae13dfd4 -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 ad2125531..4701bf76f 100644 --- a/Assets/VRM10/Editor/Components/VRM10Window.cs +++ b/Assets/VRM10/Editor/Components/VRM10Window.cs @@ -32,7 +32,7 @@ namespace UniVRM10 void OnDisable() { - SpringBoneEditor.Disable(); + s_treeView = null; SceneView.duringSceneGui -= OnSceneGUI; // Debug.Log("OnDisable"); @@ -61,31 +61,28 @@ namespace UniVRM10 } m_root = id; m_so = value != null ? new SerializedObject(value) : null; - // m_constraints = null; - - if (Root != null) - { - var animator = Root.GetComponent(); - m_head = animator.GetBoneTransform(HumanBodyBones.Head); - } } } - Transform m_head; - - ScrollView m_scrollView = new ScrollView(); - /// - /// public entry point + /// Scene 上の 3D 表示 + /// + /// * Joint/Collider の Picker + /// /// - /// void OnSceneGUI(SceneView sceneView) { Tools.hidden = true; - SpringBoneEditor.Draw3D(Root, m_so); + Draw3D(Root, m_so); } - // + /// + /// Window 上の GUI + /// + /// * 対象 VRM の保持 + /// * 選択 Joint/Collider の表示 + /// + /// private void OnGUI() { if (Root == null) @@ -101,7 +98,7 @@ namespace UniVRM10 } // Root - Root = (Vrm10Instance)EditorGUILayout.ObjectField("vrm1", Root, typeof(Vrm10Instance), true); + Root = (Vrm10Instance)EditorGUILayout.ObjectField("Editing Model", Root, typeof(Vrm10Instance), true); if (Root == null) { return; @@ -109,22 +106,47 @@ namespace UniVRM10 // active EditorGUI.BeginDisabledGroup(true); - EditorGUILayout.ObjectField("joint or collider", SpringBoneEditor.Active, typeof(MonoBehaviour), true); + EditorGUILayout.ObjectField("Selected Object", Active, typeof(MonoBehaviour), true); EditorGUI.EndDisabledGroup(); - if (m_so == null) - { - m_so = new SerializedObject(Root); - } - if (m_so == null) - { - return; - } - - m_so.Update(); - SpringBoneEditor.Draw2D(Root, m_so); - - m_so.ApplyModifiedProperties(); + // if (m_so == null) + // { + // m_so = new SerializedObject(Root); + // } + // if (m_so == null) + // { + // return; + // } + // m_so.Update(); + // SpringBoneEditor.Draw2D(Root, m_so); + // m_so.ApplyModifiedProperties(); } + + SpringBoneTreeView s_treeView; + SpringBoneTreeView GetTree(Vrm10Instance target, SerializedObject so) + { + if (s_treeView == null || s_treeView.Target != target) + { + var state = new UnityEditor.IMGUI.Controls.TreeViewState(); + s_treeView = new SpringBoneTreeView(state, target, so); + s_treeView.Reload(); + } + return s_treeView; + } + + public MonoBehaviour Active; + + /// + /// 3D の Handle 描画 + /// + public void Draw3D(Vrm10Instance target, SerializedObject so) + { + var tree = GetTree(target, so); + if (tree != null && target != null) + { + Active = tree.Draw3D(target.SpringBone); + } + } + } } diff --git a/Assets/VRM10/Editor/Vrm10InstanceEditor.cs b/Assets/VRM10/Editor/Vrm10InstanceEditor.cs index 26b2ac7bd..3e17cb698 100644 --- a/Assets/VRM10/Editor/Vrm10InstanceEditor.cs +++ b/Assets/VRM10/Editor/Vrm10InstanceEditor.cs @@ -166,7 +166,7 @@ namespace UniVRM10 if (instance.Vrm != null) { - EditorGUILayout.HelpBox("SpringBone utility", MessageType.Info); + EditorGUILayout.HelpBox("SpringBone gizmo etc...", MessageType.Info); if (GUILayout.Button("Open " + VRM10Window.WINDOW_TITLE)) { VRM10Window.Open(); From 938e6f74903a33f558e2b68ccbe303e4eaa9f72f Mon Sep 17 00:00:00 2001 From: ousttrue Date: Fri, 21 Oct 2022 18:47:17 +0900 Subject: [PATCH 5/8] fix picker --- .../SpringBone/SpringBoneTreeView.cs | 118 +++++++++++++----- .../VRM10SpringBoneColliderEditor.cs | 11 +- Assets/VRM10/Editor/Components/VRM10Window.cs | 9 +- 3 files changed, 97 insertions(+), 41 deletions(-) diff --git a/Assets/VRM10/Editor/Components/SpringBone/SpringBoneTreeView.cs b/Assets/VRM10/Editor/Components/SpringBone/SpringBoneTreeView.cs index f1de1080d..00cb6e773 100644 --- a/Assets/VRM10/Editor/Components/SpringBone/SpringBoneTreeView.cs +++ b/Assets/VRM10/Editor/Components/SpringBone/SpringBoneTreeView.cs @@ -114,16 +114,35 @@ namespace UniVRM10 } Color s_selectedColor = new Color(0.5f, 0, 0, 0.5f); + Color s_hoverColor = new Color(0.5f, 0.5f, 0, 0.5f); Color s_Color = new Color(0.6f, 0.6f, 0.6f, 0.5f); - Vrm10InstanceSpringBone last = null; - MonoBehaviour Active = null; - - public MonoBehaviour Draw3D(Vrm10InstanceSpringBone springBone) + Color GetColor(MonoBehaviour target) { + if (target == Active) + { + return s_selectedColor; + } + if (target == Hover) + { + return s_hoverColor; + } + return s_Color; + } + + Vrm10InstanceSpringBone last = null; + MonoBehaviour Hover = null; + public MonoBehaviour Active = null; + + public bool Draw3D(Vrm10InstanceSpringBone springBone) + { + var lastActive = Active; + var lastHover = Hover; + if (springBone != last) { Active = null; + Hover = null; last = springBone; } @@ -137,33 +156,53 @@ namespace UniVRM10 } MonoBehaviour newActive = null; + + // + // collider + // foreach (var group in springBone.ColliderGroups) { foreach (var collider in group.Colliders) { - var color = collider == Active ? s_selectedColor : s_Color; - if (DrawCollider(collider, color)) + var color = GetColor(collider); + var (isActive, isHover) = DrawCollider(collider, color); + if (isActive) { newActive = collider; } + if (isHover) + { + Hover = collider; + } } } + + // + // joint + // foreach (var spring in springBone.Springs) { - for (int i = 1; i < spring.Joints.Count; ++i) + VRM10SpringBoneJoint head = null; + for (int i = 0; i < spring.Joints.Count; ++i) { - var head = spring.Joints[i - 1]; - var tail = spring.Joints[i]; - var color = head == Active ? s_selectedColor : s_Color; - if (DrawJoint(head, tail, color)) + var joint = spring.Joints[i]; + var color = GetColor(joint); + var (isActive, isHover) = DrawJoint(joint, color, head); + if (isActive) { - newActive = head; + newActive = joint; } + if (isHover) + { + Hover = joint; + } + head = joint; } } if (Active is VRM10SpringBoneCollider activeCollider) { + // Active な collider の移動ハンドル(Offset, Tail) EditorGUI.BeginChangeCheck(); Handles.matrix = activeCollider.transform.localToWorldMatrix; var offset = Handles.PositionHandle(activeCollider.Offset, Quaternion.identity); @@ -190,8 +229,13 @@ namespace UniVRM10 Selection.activeObject = newActive.gameObject; Active = newActive; } + if (Hover != null) + { + Handles.matrix = Matrix4x4.identity; + Handles.Label(Hover.transform.position, Hover.name); + } - return Active; + return lastActive != Active || lastHover != Hover; } static bool IsLeftDown() @@ -199,7 +243,7 @@ namespace UniVRM10 return Event.current.type == EventType.MouseDown && Event.current.button == 0; } - bool DrawCollider(VRM10SpringBoneCollider collider, Color color) + (bool IsActive, bool IsHover) DrawCollider(VRM10SpringBoneCollider collider, Color color) { if (Event.current.type == EventType.Repaint || Event.current.type == EventType.Layout) { @@ -209,37 +253,51 @@ namespace UniVRM10 { case VRM10SpringBoneColliderTypes.Sphere: // Handles.color = Color.magenta; - Handles.SphereHandleCap(collider.gameObject.GetInstanceID(), collider.Offset, Quaternion.identity, collider.Radius * 2, Event.current.type); + Handles.SphereHandleCap(collider.GetInstanceID(), collider.Offset, Quaternion.identity, collider.Radius * 2, Event.current.type); break; case VRM10SpringBoneColliderTypes.Capsule: // Handles.color = Color.cyan; - Handles.SphereHandleCap(collider.gameObject.GetInstanceID(), collider.Offset, Quaternion.identity, collider.Radius * 2, Event.current.type); - Handles.SphereHandleCap(collider.gameObject.GetInstanceID(), collider.Tail, Quaternion.identity, collider.Radius * 2, Event.current.type); + Handles.SphereHandleCap(collider.GetInstanceID(), collider.Offset, Quaternion.identity, collider.Radius * 2, Event.current.type); + Handles.SphereHandleCap(collider.GetInstanceID(), collider.Tail, Quaternion.identity, collider.Radius * 2, Event.current.type); Handles.DrawLine(collider.Offset, collider.Tail); break; } Handles.matrix = Matrix4x4.identity; } - else if (IsLeftDown()) - { - return HandleUtility.nearestControl == collider.gameObject.GetInstanceID(); - } - return false; + + var isHover = HandleUtility.nearestControl == collider.GetInstanceID(); + return (IsLeftDown() && isHover, isHover); } - bool DrawJoint(VRM10SpringBoneJoint head, VRM10SpringBoneJoint tail, Color color) + (bool IsActive, bool IsHover) DrawJoint(VRM10SpringBoneJoint joint, Color color, VRM10SpringBoneJoint head) { if (Event.current.type == EventType.Repaint || Event.current.type == EventType.Layout) { - Handles.color = color; - Handles.SphereHandleCap(tail.gameObject.GetInstanceID(), tail.transform.position, Quaternion.identity, tail.m_jointRadius * 2, Event.current.type); + + if (head == null) + { + // 先頭 + Handles.color = color; + Handles.CubeHandleCap(joint.GetInstanceID(), joint.transform.position, joint.transform.rotation, + // head の radius + joint.m_jointRadius, Event.current.type); + } + else + { + // line + Handles.color = Color.green; + Handles.DrawLine(joint.transform.position, head.transform.position); + // joint + Handles.color = color; + Handles.SphereHandleCap(joint.GetInstanceID(), joint.transform.position, joint.transform.rotation, + // head の radius + head.m_jointRadius * 2, Event.current.type); + } } - else if (IsLeftDown()) - { - return HandleUtility.nearestControl == tail.gameObject.GetInstanceID(); - } - return false; + + var isHover = HandleUtility.nearestControl == joint.GetInstanceID(); + return (IsLeftDown() && isHover, isHover); } } } diff --git a/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneColliderEditor.cs b/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneColliderEditor.cs index b8e064bc0..07069f9b2 100644 --- a/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneColliderEditor.cs +++ b/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneColliderEditor.cs @@ -6,17 +6,12 @@ namespace UniVRM10 [CustomEditor(typeof(VRM10SpringBoneCollider))] class VRM10SpringBoneColliderEditor : Editor { - VRM10SpringBoneCollider _target; - void OnEnable() - { - _target = target as VRM10SpringBoneCollider; - } - public override void OnInspectorGUI() { - if (_target.GetInstanceID() == VRM10SpringBoneCollider.SelectedGuid) + if (VRM10Window.Active == target) { - GUI.backgroundColor = Color.red; + GUI.backgroundColor = Color.green; + Repaint(); } base.OnInspectorGUI(); } diff --git a/Assets/VRM10/Editor/Components/VRM10Window.cs b/Assets/VRM10/Editor/Components/VRM10Window.cs index 4701bf76f..fb1eea07d 100644 --- a/Assets/VRM10/Editor/Components/VRM10Window.cs +++ b/Assets/VRM10/Editor/Components/VRM10Window.cs @@ -134,7 +134,7 @@ namespace UniVRM10 return s_treeView; } - public MonoBehaviour Active; + public static MonoBehaviour Active; /// /// 3D の Handle 描画 @@ -144,9 +144,12 @@ namespace UniVRM10 var tree = GetTree(target, so); if (tree != null && target != null) { - Active = tree.Draw3D(target.SpringBone); + if (tree.Draw3D(target.SpringBone)) + { + Repaint(); + } + Active = tree.Active; } } - } } From 028cd81c193bf6b7291a07307d1bd7798bbca79d Mon Sep 17 00:00:00 2001 From: ousttrue Date: Fri, 21 Oct 2022 18:57:34 +0900 Subject: [PATCH 6/8] =?UTF-8?q?=E6=9C=AA=E4=BD=BF=E7=94=A8=E5=89=8A?= =?UTF-8?q?=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../VRMSpringBoneColliderGroupEditor.cs | 24 ------ .../SpringBone/SpringBoneTreeView.cs | 2 +- .../VRM10SpringBoneColliderEditor.cs | 2 +- .../VRM10SpringBoneColliderEditorTool.cs | 86 ------------------- .../VRM10SpringBoneColliderEditorTool.cs.meta | 11 --- 5 files changed, 2 insertions(+), 123 deletions(-) delete mode 100644 Assets/VRM10/Editor/EditorTool/VRM10SpringBoneColliderEditorTool.cs delete mode 100644 Assets/VRM10/Editor/EditorTool/VRM10SpringBoneColliderEditorTool.cs.meta diff --git a/Assets/VRM/Editor/SpringBone/VRMSpringBoneColliderGroupEditor.cs b/Assets/VRM/Editor/SpringBone/VRMSpringBoneColliderGroupEditor.cs index 9c2576196..fee110aa3 100644 --- a/Assets/VRM/Editor/SpringBone/VRMSpringBoneColliderGroupEditor.cs +++ b/Assets/VRM/Editor/SpringBone/VRMSpringBoneColliderGroupEditor.cs @@ -16,30 +16,6 @@ namespace VRM m_target = (VRMSpringBoneColliderGroup)target; } - private void OnSceneGUI() - { - Undo.RecordObject(m_target, "VRMSpringBoneColliderGroupEditor"); - - Handles.matrix = m_target.transform.localToWorldMatrix; - Gizmos.color = Color.green; - - bool changed = false; - - foreach (var x in m_target.Colliders) - { - var offset = Handles.PositionHandle(x.Offset, Quaternion.identity); - if (offset != x.Offset) - { - changed = true; - x.Offset = offset; - } - } - - if (changed) - { - EditorUtility.SetDirty(m_target); - } - } override public void OnInspectorGUI() { diff --git a/Assets/VRM10/Editor/Components/SpringBone/SpringBoneTreeView.cs b/Assets/VRM10/Editor/Components/SpringBone/SpringBoneTreeView.cs index 00cb6e773..b30379b61 100644 --- a/Assets/VRM10/Editor/Components/SpringBone/SpringBoneTreeView.cs +++ b/Assets/VRM10/Editor/Components/SpringBone/SpringBoneTreeView.cs @@ -222,6 +222,7 @@ namespace UniVRM10 activeCollider.Tail = tail; } } + Handles.matrix = Matrix4x4.identity; } if (newActive != null) @@ -231,7 +232,6 @@ namespace UniVRM10 } if (Hover != null) { - Handles.matrix = Matrix4x4.identity; Handles.Label(Hover.transform.position, Hover.name); } diff --git a/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneColliderEditor.cs b/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneColliderEditor.cs index 07069f9b2..adb525d6a 100644 --- a/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneColliderEditor.cs +++ b/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneColliderEditor.cs @@ -10,7 +10,7 @@ namespace UniVRM10 { if (VRM10Window.Active == target) { - GUI.backgroundColor = Color.green; + GUI.backgroundColor = Color.cyan; Repaint(); } base.OnInspectorGUI(); diff --git a/Assets/VRM10/Editor/EditorTool/VRM10SpringBoneColliderEditorTool.cs b/Assets/VRM10/Editor/EditorTool/VRM10SpringBoneColliderEditorTool.cs deleted file mode 100644 index 036fb4098..000000000 --- a/Assets/VRM10/Editor/EditorTool/VRM10SpringBoneColliderEditorTool.cs +++ /dev/null @@ -1,86 +0,0 @@ -using UnityEditor; -using UnityEditor.EditorTools; -using UnityEngine; - -namespace UniVRM10 -{ - [EditorTool("vrm-1.0/SpringBoneCollider", typeof(UniVRM10.VRM10SpringBoneCollider))] - class VRM10SpringBoneColliderEditorTool : EditorTool - { - static GUIContent s_cachedIcon; - public override GUIContent toolbarIcon - { - get - { - if (s_cachedIcon == null) - { - s_cachedIcon = EditorGUIUtility.IconContent("d_editcollision_32", "|vrm-1.0 SpringBoneCollider"); - } - return s_cachedIcon; - } - } - - void OnEnable() - { - ToolManager.activeToolChanged += ActiveToolDidChange; - } - - void OnDisable() - { - ToolManager.activeToolChanged -= ActiveToolDidChange; - } - - void ActiveToolDidChange() - { - if (!ToolManager.IsActiveTool(this)) - { - return; - } - } - - public override void OnToolGUI(EditorWindow window) - { - if (Selection.activeTransform == null) - { - return; - } - var collider = Selection.activeTransform.GetComponent(); - if (collider == null) - { - return; - } - - Handles.matrix = collider.transform.localToWorldMatrix; - { - Handles.Label(collider.Offset, "Head"); - EditorGUI.BeginChangeCheck(); - var offset = Handles.PositionHandle(collider.Offset, Quaternion.identity); - var offsetChanged = EditorGUI.EndChangeCheck(); - if (offsetChanged) - { - Undo.RecordObject(collider, "SpringBoneCollider"); - - var delta = offset - collider.Offset; - collider.Offset = offset; - if (collider.ColliderType == VRM10SpringBoneColliderTypes.Capsule) - { - collider.Tail += delta; - } - } - - if (collider.ColliderType == VRM10SpringBoneColliderTypes.Capsule) - { - Handles.Label(collider.Tail, "Tail"); - EditorGUI.BeginChangeCheck(); - var tail = Handles.PositionHandle(collider.Tail, Quaternion.identity); - var tailChanged = EditorGUI.EndChangeCheck(); - if (tailChanged) - { - Undo.RecordObject(collider, "SpringBoneCollider"); - collider.Tail = tail; - } - } - } - } - } -} \ No newline at end of file diff --git a/Assets/VRM10/Editor/EditorTool/VRM10SpringBoneColliderEditorTool.cs.meta b/Assets/VRM10/Editor/EditorTool/VRM10SpringBoneColliderEditorTool.cs.meta deleted file mode 100644 index 77b9d0140..000000000 --- a/Assets/VRM10/Editor/EditorTool/VRM10SpringBoneColliderEditorTool.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: eb79df70485ab8548bdd417c7fcbe04a -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: From 0b2e9b7707c370948e123de095e385acbccb9c54 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Mon, 24 Oct 2022 15:24:01 +0900 Subject: [PATCH 7/8] =?UTF-8?q?gizmo=20=E8=89=B2=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Joint => wires yellow(0.xと同じ) * collider sphere => magenta(0.xと同じ) * collider capsule => orange 赤系 --- .../SpringBone/VRM10SpringBoneCollider.cs | 2 +- .../SpringBone/VRM10SpringBoneJoint.cs | 25 +++---------------- 2 files changed, 5 insertions(+), 22 deletions(-) diff --git a/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneCollider.cs b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneCollider.cs index 578784f76..e0d257405 100644 --- a/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneCollider.cs +++ b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneCollider.cs @@ -38,7 +38,7 @@ namespace UniVRM10 break; case VRM10SpringBoneColliderTypes.Capsule: - Gizmos.color = Color.cyan; + Gizmos.color = new Color(1.0f, 0.1f, 0.1f); Gizmos.DrawWireSphere(Offset, Radius); Gizmos.DrawWireSphere(Tail, Radius); Gizmos.DrawLine(Offset, Tail); diff --git a/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneJoint.cs b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneJoint.cs index 5a990c9ae..289087dda 100644 --- a/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneJoint.cs +++ b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneJoint.cs @@ -26,9 +26,6 @@ namespace UniVRM10 [SerializeField, Range(0, 0.5f), Header("Collision")] public float m_jointRadius = 0.02f; - [SerializeField] - public Color m_gizmoColor = Color.green; - void AddJointRecursive(Transform t, VRM10SpringBoneJoint src) { var joint = t.gameObject.GetComponent(); @@ -139,38 +136,24 @@ namespace UniVRM10 return; } - Gizmos.color = m_gizmoColor; - - // draw head - // Gizmos.DrawSphere(transform.position, m_jointRadius); - var (spring, joint_index) = FindTail(vrm, this); if (spring == null) { return; } - + if (spring.Joints != null && joint_index + 1 < spring.Joints.Count) { var tail = spring.Joints[joint_index + 1]; if (tail != null) { // draw tail - Gizmos.DrawSphere(tail.transform.position, tail.m_jointRadius); + Gizmos.color = Color.yellow; + // tail の radius は head の m_jointRadius で決まる + Gizmos.DrawWireSphere(tail.transform.position, m_jointRadius); Gizmos.DrawLine(transform.position, tail.transform.position); } } - - foreach (var colliderGroup in spring.ColliderGroups) - { - foreach (var collider in colliderGroup.Colliders) - { - if (collider != null) - { - collider.OnDrawGizmosSelected(); - } - } - } } } } From e6f0369edaaec57549298d44a0e6f358315c5832 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Tue, 25 Oct 2022 16:30:17 +0900 Subject: [PATCH 8/8] UnityEngine.Object?. --- .../SpringBone/SpringBoneTreeView.cs | 41 ++++++++++--------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/Assets/VRM10/Editor/Components/SpringBone/SpringBoneTreeView.cs b/Assets/VRM10/Editor/Components/SpringBone/SpringBoneTreeView.cs index b30379b61..03ec1f6d6 100644 --- a/Assets/VRM10/Editor/Components/SpringBone/SpringBoneTreeView.cs +++ b/Assets/VRM10/Editor/Components/SpringBone/SpringBoneTreeView.cs @@ -1,8 +1,6 @@ using System.Collections.Generic; -using System.Linq; using UnityEditor; using UnityEditor.IMGUI.Controls; -using UnityEditorInternal; using UnityEngine; namespace UniVRM10 @@ -37,29 +35,32 @@ namespace UniVRM10 // load _map = new Dictionary(); - if (target?.SpringBone?.ColliderGroups != null) + if (target != null) { - for (var i = 0; i < target.SpringBone.ColliderGroups.Count; ++i) + if (target.SpringBone?.ColliderGroups != null) { - var colliderGroup = target.SpringBone.ColliderGroups[i]; - var name = colliderGroup.GUIName(i); - var id = _nextNodeID++; - var item = new TreeViewItem(id, 2, name); - _map.Add(id, colliderGroup); - _colliderGroups.AddChild(item); + for (var i = 0; i < target.SpringBone.ColliderGroups.Count; ++i) + { + var colliderGroup = target.SpringBone.ColliderGroups[i]; + var name = colliderGroup.GUIName(i); + var id = _nextNodeID++; + var item = new TreeViewItem(id, 2, name); + _map.Add(id, colliderGroup); + _colliderGroups.AddChild(item); + } } - } - if (target?.SpringBone?.Springs != null) - { - for (var i = 0; i < target.SpringBone.Springs.Count; ++i) + if (target.SpringBone?.Springs != null) { - var spring = target.SpringBone.Springs[i]; - var name = spring.GUIName(i); - var id = _nextNodeID++; - var item = new TreeViewItem(id, 2, name); - _map.Add(id, spring); - _springs.AddChild(item); + for (var i = 0; i < target.SpringBone.Springs.Count; ++i) + { + var spring = target.SpringBone.Springs[i]; + var name = spring.GUIName(i); + var id = _nextNodeID++; + var item = new TreeViewItem(id, 2, name); + _map.Add(id, spring); + _springs.AddChild(item); + } } } }