From 114ee76bdf5e44db711d9502506243cfdb7da375 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Mon, 18 Jan 2021 15:20:27 +0900 Subject: [PATCH 01/22] Authors --- Assets/VRM10/Editor/Vrm10ExportDialog.cs | 1 + .../VRM10/Runtime/Components/Meta/VRM10MetaObject.cs | 12 +++++++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/Assets/VRM10/Editor/Vrm10ExportDialog.cs b/Assets/VRM10/Editor/Vrm10ExportDialog.cs index db9821ad19..2ed34bf75b 100644 --- a/Assets/VRM10/Editor/Vrm10ExportDialog.cs +++ b/Assets/VRM10/Editor/Vrm10ExportDialog.cs @@ -68,6 +68,7 @@ void OnEnable() Selection.selectionChanged += Repaint; m_tmpMeta = ScriptableObject.CreateInstance(); + m_tmpMeta.Authors = new string[] { "" }; m_state = new MeshUtility.ExporterDialogState(); m_state.ExportRootChanged += (root) => diff --git a/Assets/VRM10/Runtime/Components/Meta/VRM10MetaObject.cs b/Assets/VRM10/Runtime/Components/Meta/VRM10MetaObject.cs index 3834870112..d395f1e07c 100644 --- a/Assets/VRM10/Runtime/Components/Meta/VRM10MetaObject.cs +++ b/Assets/VRM10/Runtime/Components/Meta/VRM10MetaObject.cs @@ -79,14 +79,16 @@ public IEnumerable Validate(GameObject _) { yield return Validation.Error("Require Name. "); } - // if (string.IsNullOrEmpty(Version)) - // { - // yield return Validation.Error("Require Version. "); - // } - if (Authors == null || Authors.Length == 0 || Authors.All(x => string.IsNullOrEmpty(x))) + + if (Authors == null || Authors.Length == 0) { yield return Validation.Error("Require at leaset one Author."); } + + if (Authors.All(x => string.IsNullOrWhiteSpace(x))) + { + yield return Validation.Error("All Authors is whitespace"); + } } public void CopyTo(VRM10MetaObject dst) From 0746d8d48b11626189415647da1bfeae5c905690 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Mon, 18 Jan 2021 15:51:55 +0900 Subject: [PATCH 02/22] tabbar to popup menu --- Assets/VRM10/Editor/Components/VRM10ControllerEditor.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Assets/VRM10/Editor/Components/VRM10ControllerEditor.cs b/Assets/VRM10/Editor/Components/VRM10ControllerEditor.cs index bc61fdc028..eff76f3028 100644 --- a/Assets/VRM10/Editor/Components/VRM10ControllerEditor.cs +++ b/Assets/VRM10/Editor/Components/VRM10ControllerEditor.cs @@ -2,7 +2,7 @@ using UnityEditor; using UnityEngine; using System.Linq; - +using System; namespace UniVRM10 { @@ -92,7 +92,10 @@ public override void OnInspectorGUI() { var backup = GUI.enabled; GUI.enabled = true; - _tab = MeshUtility.TabBar.OnGUI(_tab); + + _tab = (Tabs)EditorGUILayout.EnumPopup("Select GUI", _tab); + EditorGUILayout.Separator(); + GUI.enabled = backup; } From 3b0cccdfab3d912aed70e27361d29faaf99f1915 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Mon, 18 Jan 2021 17:59:34 +0900 Subject: [PATCH 03/22] prefix VRM10 --- ...or.cs => VRM10SpringBoneColliderGroupEditor.cs} | 14 +++++++------- ... => VRM10SpringBoneColliderGroupEditor.cs.meta} | 2 +- ...VRMSpringBoneView.cs => VRM10SpringBoneView.cs} | 10 +++++----- .../SpringBone/VRM10SpringBoneView.cs.meta} | 2 +- ...pringBoneWindow.cs => VRM10SpringBoneWindow.cs} | 10 +++++----- ...eView.cs.meta => VRM10SpringBoneWindow.cs.meta} | 2 +- .../VRMSpringBoneColliderGroupEditor.cs.meta | 12 ------------ .../Components/SpringBone/SpringBoneLogic.cs | 6 +++--- .../{VRMSpringBone.cs => VRM10SpringBone.cs} | 14 +++++++------- ...MSpringBone.cs.meta => VRM10SpringBone.cs.meta} | 4 +--- ...gBoneCollider.cs => VRM10SpringBoneCollider.cs} | 6 +++--- .../SpringBone/VRM10SpringBoneCollider.cs.meta | 11 +++++++++++ ...derGroup.cs => VRM10SpringBoneColliderGroup.cs} | 14 +++++++------- .../VRM10SpringBoneColliderGroup.cs.meta | 11 +++++++++++ .../{VRMSpringUtility.cs => VRM10SpringUtility.cs} | 2 +- .../SpringBone/VRM10SpringUtility.cs.meta | 11 +++++++++++ .../SpringBone/VRMSpringBoneColliderGroup.cs.meta | 13 ------------- .../Components/SpringBone/VRMSpringUtility.cs.meta | 12 ------------ Assets/VRM10/Runtime/Components/VRM10Controller.cs | 4 ++-- .../VRM10/Runtime/UnityBuilder/ComponentBuilder.cs | 14 +++++++------- .../Runtime/VRMConverter/RuntimeVrmConverter.cs | 10 +++++----- 21 files changed, 89 insertions(+), 95 deletions(-) rename Assets/VRM10/Editor/Components/SpringBone/{VRMSpringBoneColliderGroupEditor.cs => VRM10SpringBoneColliderGroupEditor.cs} (82%) rename Assets/VRM10/Editor/Components/SpringBone/{VRMSpringBoneWindow.cs.meta => VRM10SpringBoneColliderGroupEditor.cs.meta} (83%) rename Assets/VRM10/Editor/Components/SpringBone/{VRMSpringBoneView.cs => VRM10SpringBoneView.cs} (77%) rename Assets/VRM10/{Runtime/Components/SpringBone/SpringBoneCollider.cs.meta => Editor/Components/SpringBone/VRM10SpringBoneView.cs.meta} (83%) rename Assets/VRM10/Editor/Components/SpringBone/{VRMSpringBoneWindow.cs => VRM10SpringBoneWindow.cs} (91%) rename Assets/VRM10/Editor/Components/SpringBone/{VRMSpringBoneView.cs.meta => VRM10SpringBoneWindow.cs.meta} (83%) delete mode 100644 Assets/VRM10/Editor/Components/SpringBone/VRMSpringBoneColliderGroupEditor.cs.meta rename Assets/VRM10/Runtime/Components/SpringBone/{VRMSpringBone.cs => VRM10SpringBone.cs} (87%) rename Assets/VRM10/Runtime/Components/SpringBone/{VRMSpringBone.cs.meta => VRM10SpringBone.cs.meta} (71%) rename Assets/VRM10/Runtime/Components/SpringBone/{SpringBoneCollider.cs => VRM10SpringBoneCollider.cs} (71%) create mode 100644 Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneCollider.cs.meta rename Assets/VRM10/Runtime/Components/SpringBone/{VRMSpringBoneColliderGroup.cs => VRM10SpringBoneColliderGroup.cs} (88%) create mode 100644 Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneColliderGroup.cs.meta rename Assets/VRM10/Runtime/Components/SpringBone/{VRMSpringUtility.cs => VRM10SpringUtility.cs} (99%) create mode 100644 Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringUtility.cs.meta delete mode 100644 Assets/VRM10/Runtime/Components/SpringBone/VRMSpringBoneColliderGroup.cs.meta delete mode 100644 Assets/VRM10/Runtime/Components/SpringBone/VRMSpringUtility.cs.meta diff --git a/Assets/VRM10/Editor/Components/SpringBone/VRMSpringBoneColliderGroupEditor.cs b/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneColliderGroupEditor.cs similarity index 82% rename from Assets/VRM10/Editor/Components/SpringBone/VRMSpringBoneColliderGroupEditor.cs rename to Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneColliderGroupEditor.cs index b982d82f08..56295eff50 100644 --- a/Assets/VRM10/Editor/Components/SpringBone/VRMSpringBoneColliderGroupEditor.cs +++ b/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneColliderGroupEditor.cs @@ -5,14 +5,14 @@ namespace UniVRM10 { - [CustomEditor(typeof(VRMSpringBoneColliderGroup))] - public class VRMSpringBoneColliderGroupEditor : Editor + [CustomEditor(typeof(VRM10SpringBoneColliderGroup))] + public class VRM10SpringBoneColliderGroupEditor : Editor { - VRMSpringBoneColliderGroup m_target; + VRM10SpringBoneColliderGroup m_target; private void OnEnable() { - m_target = (VRMSpringBoneColliderGroup)target; + m_target = (VRM10SpringBoneColliderGroup)target; } private void OnSceneGUI() @@ -43,7 +43,7 @@ private void OnSceneGUI() [MenuItem("CONTEXT/VRM10SpringBoneColliderGroup/X Mirror")] private static void InvertOffsetX(MenuCommand command) { - var target = command.context as VRMSpringBoneColliderGroup; + var target = command.context as VRM10SpringBoneColliderGroup; if (target == null) return; Undo.RecordObject(target, "X Mirror"); @@ -59,7 +59,7 @@ private static void InvertOffsetX(MenuCommand command) [MenuItem("CONTEXT/VRM10SpringBoneColliderGroup/Sort Colliders by Radius")] private static void SortByRadius(MenuCommand command) { - var target = command.context as VRMSpringBoneColliderGroup; + var target = command.context as VRM10SpringBoneColliderGroup; if (target == null) return; Undo.RecordObject(target, "Sort Colliders by Radius"); @@ -70,7 +70,7 @@ private static void SortByRadius(MenuCommand command) [MenuItem("CONTEXT/VRM10SpringBoneColliderGroup/Sort Colliders by Offset Y")] private static void SortByOffsetY(MenuCommand command) { - var target = command.context as VRMSpringBoneColliderGroup; + var target = command.context as VRM10SpringBoneColliderGroup; if (target == null) return; Undo.RecordObject(target, "Sort Colliders by Offset Y"); diff --git a/Assets/VRM10/Editor/Components/SpringBone/VRMSpringBoneWindow.cs.meta b/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneColliderGroupEditor.cs.meta similarity index 83% rename from Assets/VRM10/Editor/Components/SpringBone/VRMSpringBoneWindow.cs.meta rename to Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneColliderGroupEditor.cs.meta index b92fd0895d..0bd7bfe1b3 100644 --- a/Assets/VRM10/Editor/Components/SpringBone/VRMSpringBoneWindow.cs.meta +++ b/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneColliderGroupEditor.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 6903dd580e905a243b9841fafe3871bb +guid: 280a977934f9b9b449ac58bc0f016959 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/VRM10/Editor/Components/SpringBone/VRMSpringBoneView.cs b/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneView.cs similarity index 77% rename from Assets/VRM10/Editor/Components/SpringBone/VRMSpringBoneView.cs rename to Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneView.cs index e69acddb68..5e9e93c114 100644 --- a/Assets/VRM10/Editor/Components/SpringBone/VRMSpringBoneView.cs +++ b/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneView.cs @@ -3,19 +3,19 @@ namespace UniVRM10 { - class VRMSpringBoneTreeView : TreeView + class VRM10SpringBoneTreeView : TreeView { VRM10Controller m_root; - Dictionary m_boneMap = new Dictionary(); + Dictionary m_boneMap = new Dictionary(); - public bool TryGetSpringBone(int id, out VRMSpringBone bone) + public bool TryGetSpringBone(int id, out VRM10SpringBone bone) { return m_boneMap.TryGetValue(id, out bone); } - public VRMSpringBoneTreeView(TreeViewState treeViewState, VRM10Controller root) + public VRM10SpringBoneTreeView(TreeViewState treeViewState, VRM10Controller root) : base(treeViewState) { m_root = root; @@ -32,7 +32,7 @@ protected override TreeViewItem BuildRoot() m_boneMap.Clear(); var root = new TreeViewItem { id = 0, depth = -1, displayName = m_root.name }; var allItems = new List(); - var bones = m_root.GetComponentsInChildren(); + var bones = m_root.GetComponentsInChildren(); var id = 1; for (int i = 0; i < bones.Length; ++i, ++id) { diff --git a/Assets/VRM10/Runtime/Components/SpringBone/SpringBoneCollider.cs.meta b/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneView.cs.meta similarity index 83% rename from Assets/VRM10/Runtime/Components/SpringBone/SpringBoneCollider.cs.meta rename to Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneView.cs.meta index 5df2bad9d6..6102f48e6b 100644 --- a/Assets/VRM10/Runtime/Components/SpringBone/SpringBoneCollider.cs.meta +++ b/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneView.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: b939a4d43f2f17341b3e28bc9c59f8dd +guid: c012308d77f262b4789f2fee6cdb7105 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/VRM10/Editor/Components/SpringBone/VRMSpringBoneWindow.cs b/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneWindow.cs similarity index 91% rename from Assets/VRM10/Editor/Components/SpringBone/VRMSpringBoneWindow.cs rename to Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneWindow.cs index e4e8aeea9e..ea3df9b27d 100644 --- a/Assets/VRM10/Editor/Components/SpringBone/VRMSpringBoneWindow.cs +++ b/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneWindow.cs @@ -8,12 +8,12 @@ namespace UniVRM10 { - public class VRMSpringBoneWindow : EditorWindow + public class VRM10SpringBoneWindow : EditorWindow { [MenuItem(VRMVersion.MENU + "/VRMSpringBoneWindow")] public static void ShowEditorWindow() { - var wnd = GetWindow(); + var wnd = GetWindow(); wnd.titleContent = new GUIContent("VRMSpringBoneWindow"); } @@ -33,7 +33,7 @@ void OnDisable() [SerializeField] TreeViewState m_treeViewState; - VRMSpringBoneTreeView m_treeView; + VRM10SpringBoneTreeView m_treeView; Rect m_treeRect; Rect m_inspectorRect; @@ -64,7 +64,7 @@ void OnGUI() if (m_treeViewState.selectedIDs.Any()) { // selected な SpringBone の Inspector を描画する - if (m_treeView.TryGetSpringBone(m_treeViewState.selectedIDs[0], out VRMSpringBone bone)) + if (m_treeView.TryGetSpringBone(m_treeViewState.selectedIDs[0], out VRM10SpringBone bone)) { // Debug.Log(bone); using (var inspector = new CustomInspector(new SerializedObject(bone))) @@ -102,7 +102,7 @@ void OnSelectionChanged() // update treeview Debug.Log(m_currentRoot); m_treeViewState = new TreeViewState(); - m_treeView = new VRMSpringBoneTreeView(m_treeViewState, m_currentRoot); + m_treeView = new VRM10SpringBoneTreeView(m_treeViewState, m_currentRoot); } Repaint(); diff --git a/Assets/VRM10/Editor/Components/SpringBone/VRMSpringBoneView.cs.meta b/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneWindow.cs.meta similarity index 83% rename from Assets/VRM10/Editor/Components/SpringBone/VRMSpringBoneView.cs.meta rename to Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneWindow.cs.meta index a68f49acac..228370822c 100644 --- a/Assets/VRM10/Editor/Components/SpringBone/VRMSpringBoneView.cs.meta +++ b/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneWindow.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: cd352799c630a8d49813a5c4d937a847 +guid: 50b4a0f82403ba742b3ae1d7ee14bf05 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/VRM10/Editor/Components/SpringBone/VRMSpringBoneColliderGroupEditor.cs.meta b/Assets/VRM10/Editor/Components/SpringBone/VRMSpringBoneColliderGroupEditor.cs.meta deleted file mode 100644 index 00b5aa5c0b..0000000000 --- a/Assets/VRM10/Editor/Components/SpringBone/VRMSpringBoneColliderGroupEditor.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: a092aa1d5a21feb4db6523a3284ca561 -timeCreated: 1519735770 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/VRM10/Runtime/Components/SpringBone/SpringBoneLogic.cs b/Assets/VRM10/Runtime/Components/SpringBone/SpringBoneLogic.cs index 6eed0936cf..6a72f1f5af 100644 --- a/Assets/VRM10/Runtime/Components/SpringBone/SpringBoneLogic.cs +++ b/Assets/VRM10/Runtime/Components/SpringBone/SpringBoneLogic.cs @@ -65,7 +65,7 @@ Quaternion ParentRotation public struct InternalCollider { - public SpringBoneColliderTypes ColliderTypes; + public VRM10SpringBoneColliderTypes ColliderTypes; public Vector3 WorldPosition; public float Radius; public Vector3 WorldTail; @@ -165,11 +165,11 @@ protected virtual Vector3 Collision(List colliders, Vector3 ne // すべての衝突判定を順番に実行する switch (collider.ColliderTypes) { - case SpringBoneColliderTypes.Sphere: + case VRM10SpringBoneColliderTypes.Sphere: TrySphereCollision(collider.WorldPosition, collider.Radius, ref nextTail); break; - case SpringBoneColliderTypes.Capsule: + case VRM10SpringBoneColliderTypes.Capsule: TryCapsuleCollision(in collider, ref nextTail); break; diff --git a/Assets/VRM10/Runtime/Components/SpringBone/VRMSpringBone.cs b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBone.cs similarity index 87% rename from Assets/VRM10/Runtime/Components/SpringBone/VRMSpringBone.cs rename to Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBone.cs index 8cc409ed0f..071a78b27b 100644 --- a/Assets/VRM10/Runtime/Components/SpringBone/VRMSpringBone.cs +++ b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBone.cs @@ -7,11 +7,11 @@ namespace UniVRM10 /// The base algorithm is http://rocketjump.skr.jp/unity3d/109/ of @ricopin416 /// DefaultExecutionOrder(11000) means calculate springbone after FinalIK( VRIK ) /// - [AddComponentMenu("VRM/VRMSpringBone")] + [AddComponentMenu("VRM10/VRM10SpringBone")] #if UNITY_5_5_OR_NEWER [DefaultExecutionOrder(11000)] #endif - public class VRMSpringBone : MonoBehaviour + public class VRM10SpringBone : MonoBehaviour { [SerializeField] public string m_comment; @@ -44,7 +44,7 @@ public class VRMSpringBone : MonoBehaviour public float m_hitRadius = 0.02f; [SerializeField] - public VRMSpringBoneColliderGroup[] ColliderGroups; + public VRM10SpringBoneColliderGroup[] ColliderGroups; SpringBoneProcessor m_processor = new SpringBoneProcessor(); @@ -74,20 +74,20 @@ public void Process() { switch (collider.ColliderType) { - case SpringBoneColliderTypes.Sphere: + case VRM10SpringBoneColliderTypes.Sphere: m_colliderList.Add(new SpringBoneLogic.InternalCollider { - ColliderTypes = SpringBoneColliderTypes.Sphere, + ColliderTypes = VRM10SpringBoneColliderTypes.Sphere, WorldPosition = group.transform.TransformPoint(collider.Offset), Radius = collider.Radius, }); break; - case SpringBoneColliderTypes.Capsule: + case VRM10SpringBoneColliderTypes.Capsule: m_colliderList.Add(new SpringBoneLogic.InternalCollider { - ColliderTypes = SpringBoneColliderTypes.Capsule, + ColliderTypes = VRM10SpringBoneColliderTypes.Capsule, WorldPosition = group.transform.TransformPoint(collider.Offset), Radius = collider.Radius, WorldTail = group.transform.TransformPoint(collider.Tail) diff --git a/Assets/VRM10/Runtime/Components/SpringBone/VRMSpringBone.cs.meta b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBone.cs.meta similarity index 71% rename from Assets/VRM10/Runtime/Components/SpringBone/VRMSpringBone.cs.meta rename to Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBone.cs.meta index 11d32a3a4a..3e62418a8e 100644 --- a/Assets/VRM10/Runtime/Components/SpringBone/VRMSpringBone.cs.meta +++ b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBone.cs.meta @@ -1,7 +1,5 @@ fileFormatVersion: 2 -guid: 9972432db4ac7af489ee0b864c5baaf9 -timeCreated: 1517224588 -licenseType: Free +guid: 1f440a6e91549e542bda6d6d741b1409 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/VRM10/Runtime/Components/SpringBone/SpringBoneCollider.cs b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneCollider.cs similarity index 71% rename from Assets/VRM10/Runtime/Components/SpringBone/SpringBoneCollider.cs rename to Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneCollider.cs index 54b957d6af..1f5fe5357a 100644 --- a/Assets/VRM10/Runtime/Components/SpringBone/SpringBoneCollider.cs +++ b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneCollider.cs @@ -3,16 +3,16 @@ namespace UniVRM10 { - public enum SpringBoneColliderTypes + public enum VRM10SpringBoneColliderTypes { Sphere, Capsule, } [Serializable] - public class SpringBoneCollider + public class VRM10SpringBoneCollider { - public SpringBoneColliderTypes ColliderType; + public VRM10SpringBoneColliderTypes ColliderType; /// bone local position public Vector3 Offset; diff --git a/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneCollider.cs.meta b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneCollider.cs.meta new file mode 100644 index 0000000000..5d1c1d17de --- /dev/null +++ b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneCollider.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 35bfb658269b2af478e501de243deda6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/VRM10/Runtime/Components/SpringBone/VRMSpringBoneColliderGroup.cs b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneColliderGroup.cs similarity index 88% rename from Assets/VRM10/Runtime/Components/SpringBone/VRMSpringBoneColliderGroup.cs rename to Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneColliderGroup.cs index dc325d55f8..3530ce3204 100644 --- a/Assets/VRM10/Runtime/Components/SpringBone/VRMSpringBoneColliderGroup.cs +++ b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneColliderGroup.cs @@ -4,17 +4,17 @@ namespace UniVRM10 { - [AddComponentMenu("VRM/VRMSpringBoneColliderGroup")] + [AddComponentMenu("VRM10/VRM10SpringBoneColliderGroup")] #if UNITY_5_5_OR_NEWER [DefaultExecutionOrder(11001)] #endif - public class VRMSpringBoneColliderGroup : MonoBehaviour + public class VRM10SpringBoneColliderGroup : MonoBehaviour { [SerializeField] - public SpringBoneCollider[] Colliders = new SpringBoneCollider[]{ - new SpringBoneCollider + public VRM10SpringBoneCollider[] Colliders = new VRM10SpringBoneCollider[]{ + new VRM10SpringBoneCollider { - ColliderType = SpringBoneColliderTypes.Capsule, + ColliderType = VRM10SpringBoneColliderTypes.Capsule, Radius=0.1f } }; @@ -83,11 +83,11 @@ private void OnDrawGizmosSelected() { switch (y.ColliderType) { - case SpringBoneColliderTypes.Sphere: + case VRM10SpringBoneColliderTypes.Sphere: Gizmos.DrawWireSphere(y.Offset, y.Radius); break; - case SpringBoneColliderTypes.Capsule: + case VRM10SpringBoneColliderTypes.Capsule: // Gizmos.DrawWireSphere(y.Offset, y.Radius); // Gizmos.DrawWireSphere(y.Tail, y.Radius); // Gizmos.DrawLine(y.Offset, y.Tail); diff --git a/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneColliderGroup.cs.meta b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneColliderGroup.cs.meta new file mode 100644 index 0000000000..a53d706324 --- /dev/null +++ b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneColliderGroup.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1542d3467a35afa4dbefa2a112058078 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/VRM10/Runtime/Components/SpringBone/VRMSpringUtility.cs b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringUtility.cs similarity index 99% rename from Assets/VRM10/Runtime/Components/SpringBone/VRMSpringUtility.cs rename to Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringUtility.cs index 429063bff6..920e02d55e 100644 --- a/Assets/VRM10/Runtime/Components/SpringBone/VRMSpringUtility.cs +++ b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringUtility.cs @@ -1,7 +1,7 @@ namespace UniVRM10 { - public static class VRMSpringUtility + public static class VRM10SpringUtility { #if false diff --git a/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringUtility.cs.meta b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringUtility.cs.meta new file mode 100644 index 0000000000..844f7c71f6 --- /dev/null +++ b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringUtility.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 61a4226bc18ddab4daf79fc681690fab +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/VRM10/Runtime/Components/SpringBone/VRMSpringBoneColliderGroup.cs.meta b/Assets/VRM10/Runtime/Components/SpringBone/VRMSpringBoneColliderGroup.cs.meta deleted file mode 100644 index ff68b26e7b..0000000000 --- a/Assets/VRM10/Runtime/Components/SpringBone/VRMSpringBoneColliderGroup.cs.meta +++ /dev/null @@ -1,13 +0,0 @@ -fileFormatVersion: 2 -guid: 079b0ee290c8a8d40b07314c753397a1 -timeCreated: 1517984922 -licenseType: Free -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/VRM10/Runtime/Components/SpringBone/VRMSpringUtility.cs.meta b/Assets/VRM10/Runtime/Components/SpringBone/VRMSpringUtility.cs.meta deleted file mode 100644 index 5a48996218..0000000000 --- a/Assets/VRM10/Runtime/Components/SpringBone/VRMSpringUtility.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 59fca440205c8134a898c5164771468c -timeCreated: 1528358605 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/VRM10/Runtime/Components/VRM10Controller.cs b/Assets/VRM10/Runtime/Components/VRM10Controller.cs index 12e8daa1f9..9948c31688 100644 --- a/Assets/VRM10/Runtime/Components/VRM10Controller.cs +++ b/Assets/VRM10/Runtime/Components/VRM10Controller.cs @@ -62,7 +62,7 @@ void OnDestroy() } VRMConstraint[] m_constraints; - VRMSpringBone[] m_springs; + VRM10SpringBone[] m_springs; Transform m_head; public Transform Head @@ -135,7 +135,7 @@ public void Apply() // if (m_springs == null) { - m_springs = GetComponentsInChildren(); + m_springs = GetComponentsInChildren(); } foreach (var spring in m_springs) { diff --git a/Assets/VRM10/Runtime/UnityBuilder/ComponentBuilder.cs b/Assets/VRM10/Runtime/UnityBuilder/ComponentBuilder.cs index 47c078174f..32de9e0a06 100644 --- a/Assets/VRM10/Runtime/UnityBuilder/ComponentBuilder.cs +++ b/Assets/VRM10/Runtime/UnityBuilder/ComponentBuilder.cs @@ -232,30 +232,30 @@ public static void Build10(VrmLib.Model model, ModelAsset asset) // springBone { - var colliders = new Dictionary(); + var colliders = new Dictionary(); if (model.Vrm.SpringBone != null) { foreach (var colliderGroup in model.Vrm.SpringBone.Colliders) { var go = asset.Map.Nodes[colliderGroup.Node]; - var springBoneColliderGroup = go.AddComponent(); + var springBoneColliderGroup = go.AddComponent(); springBoneColliderGroup.Colliders = colliderGroup.Colliders.Select(x => { switch (x.ColliderType) { case VrmLib.VrmSpringBoneColliderTypes.Sphere: - return new UniVRM10.SpringBoneCollider() + return new UniVRM10.VRM10SpringBoneCollider() { - ColliderType = SpringBoneColliderTypes.Sphere, + ColliderType = VRM10SpringBoneColliderTypes.Sphere, Offset = x.Offset.ToUnityVector3(), Radius = x.Radius }; case VrmLib.VrmSpringBoneColliderTypes.Capsule: - return new UniVRM10.SpringBoneCollider() + return new UniVRM10.VRM10SpringBoneCollider() { - ColliderType = SpringBoneColliderTypes.Capsule, + ColliderType = VRM10SpringBoneColliderTypes.Capsule, Offset = x.Offset.ToUnityVector3(), Radius = x.Radius, Tail = x.CapsuleTail.ToUnityVector3(), @@ -286,7 +286,7 @@ public static void Build10(VrmLib.Model model, ModelAsset asset) { foreach (var spring in model.Vrm.SpringBone.Springs) { - var springBoneComponent = springBoneObject.AddComponent(); + var springBoneComponent = springBoneObject.AddComponent(); springBoneComponent.m_comment = spring.Comment; springBoneComponent.m_stiffnessForce = spring.Stiffness; springBoneComponent.m_gravityPower = spring.GravityPower; diff --git a/Assets/VRM10/Runtime/VRMConverter/RuntimeVrmConverter.cs b/Assets/VRM10/Runtime/VRMConverter/RuntimeVrmConverter.cs index e38e53a5b5..59f94a1744 100644 --- a/Assets/VRM10/Runtime/VRMConverter/RuntimeVrmConverter.cs +++ b/Assets/VRM10/Runtime/VRMConverter/RuntimeVrmConverter.cs @@ -343,21 +343,21 @@ public VrmLib.Model ToModelFrom10(GameObject root, VRM10MetaObject metaObject = // springBone { - var springBoneColliderGroups = root.GetComponentsInChildren(); + var springBoneColliderGroups = root.GetComponentsInChildren(); if (springBoneColliderGroups != null) { Model.Vrm.SpringBone = new VrmLib.SpringBoneManager(); - var colliders = new Dictionary(); + var colliders = new Dictionary(); foreach (var colliderGroup in springBoneColliderGroups) { var colliderGroups = colliderGroup.Colliders.Select(x => { switch (x.ColliderType) { - case SpringBoneColliderTypes.Sphere: + case VRM10SpringBoneColliderTypes.Sphere: return VrmLib.VrmSpringBoneCollider.CreateSphere(x.Offset.ToNumericsVector3(), x.Radius); - case SpringBoneColliderTypes.Capsule: + case VRM10SpringBoneColliderTypes.Capsule: return VrmLib.VrmSpringBoneCollider.CreateCapsule(x.Offset.ToNumericsVector3(), x.Radius, x.Tail.ToNumericsVector3()); default: @@ -370,7 +370,7 @@ public VrmLib.Model ToModelFrom10(GameObject root, VRM10MetaObject metaObject = colliders.Add(colliderGroup, vrmColliderGroup); } - var springBones = root.GetComponentsInChildren(); + var springBones = root.GetComponentsInChildren(); foreach (var springBone in springBones) { var vrmSpringBone = new VrmLib.SpringBone() From 2e067a92f5c7f38948c2e4a6373b13fa392e05cc Mon Sep 17 00:00:00 2001 From: ousttrue Date: Mon, 18 Jan 2021 18:10:02 +0900 Subject: [PATCH 04/22] gizmo --- .../SpringBone/VRM10SpringBoneColliderGroup.cs | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneColliderGroup.cs b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneColliderGroup.cs index 3530ce3204..44644bad23 100644 --- a/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneColliderGroup.cs +++ b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneColliderGroup.cs @@ -1,13 +1,12 @@ -using System; using UnityEngine; namespace UniVRM10 { + /// + /// VRMC_node_collider + /// [AddComponentMenu("VRM10/VRM10SpringBoneColliderGroup")] -#if UNITY_5_5_OR_NEWER - [DefaultExecutionOrder(11001)] -#endif public class VRM10SpringBoneColliderGroup : MonoBehaviour { [SerializeField] @@ -19,9 +18,6 @@ public class VRM10SpringBoneColliderGroup : MonoBehaviour } }; - [SerializeField] - Color m_gizmoColor = Color.magenta; - public static void DrawWireCapsule(Vector3 headPos, Vector3 tailPos, float radius) { var headToTail = tailPos - headPos; @@ -70,9 +66,9 @@ private static void DrawWireCircle(Vector3 centerPos, Vector3 xAxis, Vector3 yAx } } - private void OnDrawGizmosSelected() + public void DrawGizmos(Color color) { - Gizmos.color = m_gizmoColor; + Gizmos.color = color; Matrix4x4 mat = transform.localToWorldMatrix; Gizmos.matrix = mat * Matrix4x4.Scale(new Vector3( 1.0f / transform.lossyScale.x, @@ -88,9 +84,6 @@ private void OnDrawGizmosSelected() break; case VRM10SpringBoneColliderTypes.Capsule: - // Gizmos.DrawWireSphere(y.Offset, y.Radius); - // Gizmos.DrawWireSphere(y.Tail, y.Radius); - // Gizmos.DrawLine(y.Offset, y.Tail); DrawWireCapsule(y.Offset, y.Tail, y.Radius); break; } From e05daa1524ef9a28a02886ba57ad5fa734ef1f6b Mon Sep 17 00:00:00 2001 From: ousttrue Date: Mon, 18 Jan 2021 19:38:09 +0900 Subject: [PATCH 05/22] WIP SpringBone MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * JsonSchema更新 * シリアライザ修正 #635 --- .../Components/SpringBone/VRM10SpringBone.cs | 49 +++++----- .../VRM10SpringBoneColliderGroup.cs | 1 + .../Format/SpringBone/Deserializer.g.cs | 84 ++++++++--------- .../Runtime/Format/SpringBone/Format.g.cs | 18 ++-- .../Runtime/Format/SpringBone/Serializer.g.cs | 94 +++++++++---------- Assets/VRM10/Runtime/IO/Vrm10Storage.cs | 80 ++++++++-------- .../VRM10/Runtime/IO/VrmSpringBoneAdapter.cs | 53 +++++------ .../Runtime/UnityBuilder/ComponentBuilder.cs | 34 ++++--- .../VRMConverter/RuntimeVrmConverter.cs | 57 +++++------ .../vrmlib/Runtime/ModelDiffExtensions.cs | 14 ++- .../Runtime/ModelExtensionsForCoordinates.cs | 5 +- .../Runtime/Vrm/ModelExtensionsForNode.cs | 12 +-- .../vrmlib/Runtime/Vrm/SpringBoneManager.cs | 24 +++-- 13 files changed, 252 insertions(+), 273 deletions(-) diff --git a/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBone.cs b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBone.cs index 071a78b27b..64e3f34a9b 100644 --- a/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBone.cs +++ b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBone.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using UnityEngine; @@ -22,26 +23,30 @@ public class VRM10SpringBone : MonoBehaviour [SerializeField] Color m_gizmoColor = Color.yellow; - [SerializeField, Range(0, 4), Header("Settings")] - public float m_stiffnessForce = 1.0f; + [Serializable] + public class VRM10SpringJoint + { + [SerializeField, Range(0, 4), Header("Settings")] + public float m_stiffnessForce = 1.0f; - [SerializeField, Range(0, 2)] - public float m_gravityPower = 0; + [SerializeField, Range(0, 2)] + public float m_gravityPower = 0; - [SerializeField] - public Vector3 m_gravityDir = new Vector3(0, -1.0f, 0); + [SerializeField] + public Vector3 m_gravityDir = new Vector3(0, -1.0f, 0); - [SerializeField, Range(0, 1)] - public float m_dragForce = 0.4f; + [SerializeField, Range(0, 1)] + public float m_dragForce = 0.4f; + + [SerializeField, Range(0, 0.5f), Header("Collision")] + public float m_hitRadius = 0.02f; + } [SerializeField] public Transform m_center; [SerializeField] - public List RootBones = new List(); - - [SerializeField, Range(0, 0.5f), Header("Collision")] - public float m_hitRadius = 0.02f; + public List Joints = new List(); [SerializeField] public VRM10SpringBoneColliderGroup[] ColliderGroups; @@ -57,7 +62,7 @@ public void ResetSpringBone() List m_colliderList = new List(); public void Process() { - if (RootBones == null) + if (Joints == null) { return; } @@ -99,20 +104,20 @@ public void Process() } } - var stiffness = m_stiffnessForce * Time.deltaTime; - var external = m_gravityDir * (m_gravityPower * Time.deltaTime); + // var stiffness = m_stiffnessForce * Time.deltaTime; + // var external = m_gravityDir * (m_gravityPower * Time.deltaTime); - m_processor.Update(RootBones, m_colliderList, - stiffness, m_dragForce, external, - m_hitRadius, m_center); + // m_processor.Update(RootBones, m_colliderList, + // stiffness, m_dragForce, external, + // m_hitRadius, m_center); } private void OnDrawGizmos() { - if (m_drawGizmo) - { - m_processor.DrawGizmos(m_center, m_hitRadius, m_gizmoColor); - } + // if (m_drawGizmo) + // { + // m_processor.DrawGizmos(m_center, m_hitRadius, m_gizmoColor); + // } } } } diff --git a/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneColliderGroup.cs b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneColliderGroup.cs index 44644bad23..7d07deb711 100644 --- a/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneColliderGroup.cs +++ b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneColliderGroup.cs @@ -6,6 +6,7 @@ namespace UniVRM10 /// /// VRMC_node_collider /// + [DisallowMultipleComponent] [AddComponentMenu("VRM10/VRM10SpringBoneColliderGroup")] public class VRM10SpringBoneColliderGroup : MonoBehaviour { diff --git a/Assets/VRM10/Runtime/Format/SpringBone/Deserializer.g.cs b/Assets/VRM10/Runtime/Format/SpringBone/Deserializer.g.cs index 5a363bb619..a45cbec18f 100644 --- a/Assets/VRM10/Runtime/Format/SpringBone/Deserializer.g.cs +++ b/Assets/VRM10/Runtime/Format/SpringBone/Deserializer.g.cs @@ -36,11 +36,6 @@ public static VRMC_springBone Deserialize(ListTreeNode parsed) { var key = kv.Key.GetString(); - if(key=="settings"){ - value.Settings = Deserialize_Settings(kv.Value); - continue; - } - if(key=="springs"){ value.Springs = Deserialize_Springs(kv.Value); continue; @@ -50,41 +45,36 @@ public static VRMC_springBone Deserialize(ListTreeNode parsed) return value; } -public static List Deserialize_Settings(ListTreeNode parsed) +public static List Deserialize_Springs(ListTreeNode parsed) { - var value = new List(); + var value = new List(); foreach(var x in parsed.ArrayItems()) { - value.Add(Deserialize_Settings_ITEM(x)); + value.Add(Deserialize_Springs_ITEM(x)); } return value; } -public static SpringSetting Deserialize_Settings_ITEM(ListTreeNode parsed) +public static Spring Deserialize_Springs_ITEM(ListTreeNode parsed) { - var value = new SpringSetting(); + var value = new Spring(); foreach(var kv in parsed.ObjectItems()) { var key = kv.Key.GetString(); - if(key=="stiffness"){ - value.Stiffness = kv.Value.GetSingle(); + if(key=="name"){ + value.Name = kv.Value.GetString(); continue; } - if(key=="gravityPower"){ - value.GravityPower = kv.Value.GetSingle(); + if(key=="joints"){ + value.Joints = Deserialize_Joints(kv.Value); continue; } - if(key=="gravityDir"){ - value.GravityDir = Deserialize_GravityDir(kv.Value); - continue; - } - - if(key=="dragForce"){ - value.DragForce = kv.Value.GetSingle(); + if(key=="colliders"){ + value.Colliders = Deserialize_Colliders(kv.Value); continue; } @@ -92,57 +82,46 @@ public static SpringSetting Deserialize_Settings_ITEM(ListTreeNode pa return value; } -public static float[] Deserialize_GravityDir(ListTreeNode parsed) -{ - var value = new float[parsed.GetArrayCount()]; - int i=0; - foreach(var x in parsed.ArrayItems()) - { - value[i++] = x.GetSingle(); - } - return value; -} - -public static List Deserialize_Springs(ListTreeNode parsed) +public static List Deserialize_Joints(ListTreeNode parsed) { - var value = new List(); + var value = new List(); foreach(var x in parsed.ArrayItems()) { - value.Add(Deserialize_Springs_ITEM(x)); + value.Add(Deserialize_Joints_ITEM(x)); } return value; } -public static Spring Deserialize_Springs_ITEM(ListTreeNode parsed) +public static SpringBoneJoint Deserialize_Joints_ITEM(ListTreeNode parsed) { - var value = new Spring(); + var value = new SpringBoneJoint(); foreach(var kv in parsed.ObjectItems()) { var key = kv.Key.GetString(); - if(key=="name"){ - value.Name = kv.Value.GetString(); + if(key=="hitRadius"){ + value.HitRadius = kv.Value.GetSingle(); continue; } - if(key=="setting"){ - value.Setting = kv.Value.GetInt32(); + if(key=="stiffness"){ + value.Stiffness = kv.Value.GetSingle(); continue; } - if(key=="springRoot"){ - value.SpringRoot = kv.Value.GetInt32(); + if(key=="gravityPower"){ + value.GravityPower = kv.Value.GetSingle(); continue; } - if(key=="hitRadius"){ - value.HitRadius = kv.Value.GetSingle(); + if(key=="gravityDir"){ + value.GravityDir = Deserialize_GravityDir(kv.Value); continue; } - if(key=="colliders"){ - value.Colliders = Deserialize_Colliders(kv.Value); + if(key=="dragForce"){ + value.DragForce = kv.Value.GetSingle(); continue; } @@ -150,6 +129,17 @@ public static Spring Deserialize_Springs_ITEM(ListTreeNode parsed) return value; } +public static float[] Deserialize_GravityDir(ListTreeNode parsed) +{ + var value = new float[parsed.GetArrayCount()]; + int i=0; + foreach(var x in parsed.ArrayItems()) + { + value[i++] = x.GetSingle(); + } + return value; +} + public static int[] Deserialize_Colliders(ListTreeNode parsed) { var value = new int[parsed.GetArrayCount()]; diff --git a/Assets/VRM10/Runtime/Format/SpringBone/Format.g.cs b/Assets/VRM10/Runtime/Format/SpringBone/Format.g.cs index 9510b42e86..2d7bfee887 100644 --- a/Assets/VRM10/Runtime/Format/SpringBone/Format.g.cs +++ b/Assets/VRM10/Runtime/Format/SpringBone/Format.g.cs @@ -7,8 +7,11 @@ namespace UniGLTF.Extensions.VRMC_springBone { - public class SpringSetting + public class SpringBoneJoint { + // The radius of spring sphere + public float? HitRadius; + // The force to return to the initial pose public float? Stiffness; @@ -27,14 +30,8 @@ public class Spring // Name of the Spring public string Name; - // The index of spring settings - public int? Setting; - - // The node index of spring root - public int? SpringRoot; - - // The radius of spring sphere - public float? HitRadius; + // Joints in this spring. Except for the first element, the parent of the element must be the previous element of the array + public List Joints; // Colliders that detect collision with nodes start from springRoot public int[] Colliders; @@ -45,9 +42,6 @@ public class VRMC_springBone public const string ExtensionName = "VRMC_springBone"; public static readonly Utf8String ExtensionNameUtf8 = Utf8String.From(ExtensionName); - // An array of settings. - public List Settings; - // An array of springs. public List Springs; } diff --git a/Assets/VRM10/Runtime/Format/SpringBone/Serializer.g.cs b/Assets/VRM10/Runtime/Format/SpringBone/Serializer.g.cs index b033f9b26f..bbf867086c 100644 --- a/Assets/VRM10/Runtime/Format/SpringBone/Serializer.g.cs +++ b/Assets/VRM10/Runtime/Format/SpringBone/Serializer.g.cs @@ -33,11 +33,6 @@ public static void Serialize(JsonFormatter f, VRMC_springBone value) f.BeginMap(); - if(value.Settings!=null&&value.Settings.Count()>=0){ - f.Key("settings"); - Serialize_Settings(f, value.Settings); - } - if(value.Springs!=null&&value.Springs.Count()>=0){ f.Key("springs"); Serialize_Springs(f, value.Springs); @@ -46,103 +41,98 @@ public static void Serialize(JsonFormatter f, VRMC_springBone value) f.EndMap(); } -public static void Serialize_Settings(JsonFormatter f, List value) +public static void Serialize_Springs(JsonFormatter f, List value) { f.BeginList(); foreach(var item in value) { - Serialize_Settings_ITEM(f, item); + Serialize_Springs_ITEM(f, item); } f.EndList(); } -public static void Serialize_Settings_ITEM(JsonFormatter f, SpringSetting value) +public static void Serialize_Springs_ITEM(JsonFormatter f, Spring value) { f.BeginMap(); - if(value.Stiffness.HasValue){ - f.Key("stiffness"); - f.Value(value.Stiffness.GetValueOrDefault()); - } - - if(value.GravityPower.HasValue){ - f.Key("gravityPower"); - f.Value(value.GravityPower.GetValueOrDefault()); + if(!string.IsNullOrEmpty(value.Name)){ + f.Key("name"); + f.Value(value.Name); } - if(value.GravityDir!=null&&value.GravityDir.Count()>=3){ - f.Key("gravityDir"); - Serialize_GravityDir(f, value.GravityDir); + if(value.Joints!=null&&value.Joints.Count()>=0){ + f.Key("joints"); + Serialize_Joints(f, value.Joints); } - if(value.DragForce.HasValue){ - f.Key("dragForce"); - f.Value(value.DragForce.GetValueOrDefault()); + if(value.Colliders!=null&&value.Colliders.Count()>=0){ + f.Key("colliders"); + Serialize_Colliders(f, value.Colliders); } f.EndMap(); } -public static void Serialize_GravityDir(JsonFormatter f, float[] value) -{ - f.BeginList(); - - foreach(var item in value) - { - f.Value(item); - - } - f.EndList(); -} - -public static void Serialize_Springs(JsonFormatter f, List value) +public static void Serialize_Joints(JsonFormatter f, List value) { f.BeginList(); foreach(var item in value) { - Serialize_Springs_ITEM(f, item); + Serialize_Joints_ITEM(f, item); } f.EndList(); } -public static void Serialize_Springs_ITEM(JsonFormatter f, Spring value) +public static void Serialize_Joints_ITEM(JsonFormatter f, SpringBoneJoint value) { f.BeginMap(); - if(!string.IsNullOrEmpty(value.Name)){ - f.Key("name"); - f.Value(value.Name); + if(value.HitRadius.HasValue){ + f.Key("hitRadius"); + f.Value(value.HitRadius.GetValueOrDefault()); } - if(value.Setting.HasValue){ - f.Key("setting"); - f.Value(value.Setting.GetValueOrDefault()); + if(value.Stiffness.HasValue){ + f.Key("stiffness"); + f.Value(value.Stiffness.GetValueOrDefault()); } - if(value.SpringRoot.HasValue){ - f.Key("springRoot"); - f.Value(value.SpringRoot.GetValueOrDefault()); + if(value.GravityPower.HasValue){ + f.Key("gravityPower"); + f.Value(value.GravityPower.GetValueOrDefault()); } - if(value.HitRadius.HasValue){ - f.Key("hitRadius"); - f.Value(value.HitRadius.GetValueOrDefault()); + if(value.GravityDir!=null&&value.GravityDir.Count()>=3){ + f.Key("gravityDir"); + Serialize_GravityDir(f, value.GravityDir); } - if(value.Colliders!=null&&value.Colliders.Count()>=0){ - f.Key("colliders"); - Serialize_Colliders(f, value.Colliders); + if(value.DragForce.HasValue){ + f.Key("dragForce"); + f.Value(value.DragForce.GetValueOrDefault()); } f.EndMap(); } +public static void Serialize_GravityDir(JsonFormatter f, float[] value) +{ + f.BeginList(); + + foreach(var item in value) + { + f.Value(item); + + } + f.EndList(); +} + public static void Serialize_Colliders(JsonFormatter f, int[] value) { f.BeginList(); diff --git a/Assets/VRM10/Runtime/IO/Vrm10Storage.cs b/Assets/VRM10/Runtime/IO/Vrm10Storage.cs index 1bc7f17fe8..ae98a4ab8b 100644 --- a/Assets/VRM10/Runtime/IO/Vrm10Storage.cs +++ b/Assets/VRM10/Runtime/IO/Vrm10Storage.cs @@ -710,66 +710,62 @@ public SpringBoneManager CreateVrmSpringBone(List nodes) return null; } - var springBone = new SpringBoneManager(); + var springBoneManager = new SpringBoneManager(); // springs if (gltfVrmSpringBone.Springs != null) { - foreach (var group in gltfVrmSpringBone.Springs.GroupBy(x => x.Setting.Value)) + foreach (var gltfSpring in gltfVrmSpringBone.Springs) { - var sb = new SpringBone(); - sb.Comment = group.First().Name; - sb.HitRadius = group.First().HitRadius.Value; - var setting = gltfVrmSpringBone.Settings[group.Key]; - sb.DragForce = setting.DragForce.Value; - sb.GravityDir = setting.GravityDir.ToVector3(); - sb.GravityPower = setting.GravityPower.Value; - sb.Stiffness = setting.Stiffness.Value; - - foreach (var spring in group) + var springBone = new SpringBone(); + springBone.Comment = gltfSpring.Name; + + // joint + foreach (var gltfJoint in gltfSpring.Joints) { - // root - sb.Bones.Add(nodes[spring.SpringRoot.Value]); - // collider - foreach (var colliderNode in spring.Colliders) + var joint = new SpringJoint(); + joint.HitRadius = gltfJoint.HitRadius.Value; + joint.DragForce = gltfJoint.DragForce.Value; + joint.GravityDir = gltfJoint.GravityDir.ToVector3(); + joint.GravityPower = gltfJoint.GravityPower.Value; + joint.Stiffness = gltfJoint.Stiffness.Value; + springBone.Joints.Add(joint); + } + + // collider + springBone.Colliders.AddRange(gltfSpring.Colliders.Select(colliderNode => + { + if (UniGLTF.Extensions.VRMC_node_collider.GltfDeserializer.TryGet(Gltf.nodes[colliderNode].extensions, + out UniGLTF.Extensions.VRMC_node_collider.VRMC_node_collider extension)) { - var collider = springBone.Colliders.FirstOrDefault(x => x.Node == nodes[colliderNode]); - if (collider == null) + var collider = new SpringBoneColliderGroup(nodes[colliderNode], extension.Shapes.Select(x => { - if (UniGLTF.Extensions.VRMC_node_collider.GltfDeserializer.TryGet(Gltf.nodes[colliderNode].extensions, - out UniGLTF.Extensions.VRMC_node_collider.VRMC_node_collider extension)) + if (x.Sphere != null) + { + return VrmSpringBoneCollider.CreateSphere(x.Sphere.Offset.ToVector3(), x.Sphere.Radius.Value); + } + else if (x.Capsule != null) { - collider = new SpringBoneColliderGroup(nodes[colliderNode], extension.Shapes.Select(x => - { - if (x.Sphere != null) - { - return VrmSpringBoneCollider.CreateSphere(x.Sphere.Offset.ToVector3(), x.Sphere.Radius.Value); - } - else if (x.Capsule != null) - { - return VrmSpringBoneCollider.CreateCapsule(x.Capsule.Offset.ToVector3(), x.Capsule.Radius.Value, x.Capsule.Tail.ToVector3()); - } - else - { - throw new NotImplementedException(); - } - })); - springBone.Colliders.Add(collider); + return VrmSpringBoneCollider.CreateCapsule(x.Capsule.Offset.ToVector3(), x.Capsule.Radius.Value, x.Capsule.Tail.ToVector3()); } else { - throw new Exception("collider not found"); + throw new NotImplementedException(); } - } - sb.Colliders.Add(collider); + })); + return collider; } - } + else + { + return null; + } + }).Where(x => x != null)); - springBone.Springs.Add(sb); + springBoneManager.Springs.Add(springBone); } } - return springBone; + return springBoneManager; } public FirstPerson CreateVrmFirstPerson(List nodes, List meshGroups) diff --git a/Assets/VRM10/Runtime/IO/VrmSpringBoneAdapter.cs b/Assets/VRM10/Runtime/IO/VrmSpringBoneAdapter.cs index 96ee5c1ed1..87d4178354 100644 --- a/Assets/VRM10/Runtime/IO/VrmSpringBoneAdapter.cs +++ b/Assets/VRM10/Runtime/IO/VrmSpringBoneAdapter.cs @@ -10,18 +10,6 @@ namespace UniVRM10 { public static class SpringBoneAdapter { - public static SpringSetting ToGltf(this SpringBone self, List nodes) - { - var setting = new SpringSetting - { - DragForce = self.DragForce, - GravityPower = self.GravityPower, - Stiffness = self.Stiffness, - GravityDir = self.GravityDir.ToFloat3(), - }; - return setting; - } - public static VRMC_springBone ToGltf(this SpringBoneManager self, List nodes, List gltfNodes) { @@ -35,11 +23,11 @@ public static VRMC_springBone ToGltf(this SpringBoneManager self, List nod // // VRMC_node_collider // - foreach (var x in self.Colliders) + foreach (var nodeCollider in self.Springs.SelectMany(x => x.Colliders)) { - var index = nodes.IndexOfThrow(x.Node); - var collider = new VRMC_node_collider(); - foreach (var y in x.Colliders) + var index = nodes.IndexOfThrow(nodeCollider.Node); + var gltfCollider = new VRMC_node_collider(); + foreach (var y in nodeCollider.Colliders) { switch (y.ColliderType) { @@ -50,7 +38,7 @@ public static VRMC_springBone ToGltf(this SpringBoneManager self, List nod Radius = y.Radius, Offset = y.Offset.ToFloat3(), }; - collider.Shapes.Add(new ColliderShape + gltfCollider.Shapes.Add(new ColliderShape { Sphere = sphere, }); @@ -65,7 +53,7 @@ public static VRMC_springBone ToGltf(this SpringBoneManager self, List nod Offset = y.Offset.ToFloat3(), Tail = y.CapsuleTail.ToFloat3(), }; - collider.Shapes.Add(new ColliderShape + gltfCollider.Shapes.Add(new ColliderShape { Capsule = capsule, }); @@ -80,7 +68,7 @@ public static VRMC_springBone ToGltf(this SpringBoneManager self, List nod // // add to node.extensions // - UniGLTF.Extensions.VRMC_node_collider.GltfSerializer.SerializeTo(ref gltfNodes[index].extensions, collider); + UniGLTF.Extensions.VRMC_node_collider.GltfSerializer.SerializeTo(ref gltfNodes[index].extensions, gltfCollider); } // @@ -88,20 +76,25 @@ public static VRMC_springBone ToGltf(this SpringBoneManager self, List nod // foreach (var x in self.Springs) { - var settingIndex = springBone.Settings.Count; - springBone.Settings.Add(x.ToGltf(nodes)); - foreach (var bone in x.Bones) + var spring = new Spring { - var spring = new Spring + Name = x.Comment, + Colliders = x.Colliders.Select(y => nodes.IndexOfThrow(y.Node)).ToArray(), + }; + + foreach (var y in x.Joints) + { + spring.Joints.Add(new SpringBoneJoint { - Name = x.Comment, - HitRadius = x.HitRadius, - SpringRoot = nodes.IndexOfThrow(bone), - Setting = settingIndex, - Colliders = x.Colliders.Select(y => nodes.IndexOfThrow(y.Node)).ToArray(), - }; - springBone.Springs.Add(spring); + HitRadius = y.HitRadius, + DragForce = y.DragForce, + GravityDir = y.GravityDir.ToFloat3(), + GravityPower = y.GravityPower, + Stiffness = y.Stiffness, + }); } + + springBone.Springs.Add(spring); } return springBone; diff --git a/Assets/VRM10/Runtime/UnityBuilder/ComponentBuilder.cs b/Assets/VRM10/Runtime/UnityBuilder/ComponentBuilder.cs index 32de9e0a06..578af2913b 100644 --- a/Assets/VRM10/Runtime/UnityBuilder/ComponentBuilder.cs +++ b/Assets/VRM10/Runtime/UnityBuilder/ComponentBuilder.cs @@ -235,7 +235,7 @@ public static void Build10(VrmLib.Model model, ModelAsset asset) var colliders = new Dictionary(); if (model.Vrm.SpringBone != null) { - foreach (var colliderGroup in model.Vrm.SpringBone.Colliders) + foreach (var colliderGroup in model.Vrm.SpringBone.Springs.SelectMany(x => x.Colliders)) { var go = asset.Map.Nodes[colliderGroup.Node]; var springBoneColliderGroup = go.AddComponent(); @@ -284,21 +284,29 @@ public static void Build10(VrmLib.Model model, ModelAsset asset) springBoneObject.transform.SetParent(asset.Root.transform); if (model.Vrm.SpringBone != null) { - foreach (var spring in model.Vrm.SpringBone.Springs) + foreach (var vrmSpring in model.Vrm.SpringBone.Springs) { - var springBoneComponent = springBoneObject.AddComponent(); - springBoneComponent.m_comment = spring.Comment; - springBoneComponent.m_stiffnessForce = spring.Stiffness; - springBoneComponent.m_gravityPower = spring.GravityPower; - springBoneComponent.m_gravityDir = spring.GravityDir.ToUnityVector3(); - springBoneComponent.m_dragForce = spring.DragForce; - if (spring.Origin != null && asset.Map.Nodes.TryGetValue(spring.Origin, out GameObject origin)) + var springBone = springBoneObject.AddComponent(); + springBone.m_comment = vrmSpring.Comment; + if (vrmSpring.Origin != null && asset.Map.Nodes.TryGetValue(vrmSpring.Origin, out GameObject origin)) { - springBoneComponent.m_center = origin.transform; + springBone.m_center = origin.transform; } - springBoneComponent.RootBones = spring.Bones.Select(x => asset.Map.Nodes[x].transform).ToList(); - springBoneComponent.m_hitRadius = spring.HitRadius; - springBoneComponent.ColliderGroups = spring.Colliders.Select(x => colliders[x]).ToArray(); + + foreach (var vrmJoint in vrmSpring.Joints) + { + var joint = new VRM10SpringBone.VRM10SpringJoint(); + + joint.m_stiffnessForce = vrmJoint.Stiffness; + joint.m_gravityPower = vrmJoint.GravityPower; + joint.m_gravityDir = vrmJoint.GravityDir.ToUnityVector3(); + joint.m_dragForce = vrmJoint.DragForce; + joint.m_hitRadius = vrmJoint.HitRadius; + + springBone.Joints.Add(joint); + } + + springBone.ColliderGroups = vrmSpring.Colliders.Select(x => colliders[x]).ToArray(); } } } diff --git a/Assets/VRM10/Runtime/VRMConverter/RuntimeVrmConverter.cs b/Assets/VRM10/Runtime/VRMConverter/RuntimeVrmConverter.cs index 59f94a1744..a85914f02c 100644 --- a/Assets/VRM10/Runtime/VRMConverter/RuntimeVrmConverter.cs +++ b/Assets/VRM10/Runtime/VRMConverter/RuntimeVrmConverter.cs @@ -343,12 +343,28 @@ public VrmLib.Model ToModelFrom10(GameObject root, VRM10MetaObject metaObject = // springBone { - var springBoneColliderGroups = root.GetComponentsInChildren(); - if (springBoneColliderGroups != null) + var springBones = root.GetComponentsInChildren(); + foreach (var springBone in springBones) { - Model.Vrm.SpringBone = new VrmLib.SpringBoneManager(); - var colliders = new Dictionary(); - foreach (var colliderGroup in springBoneColliderGroups) + var vrmSpringBone = new VrmLib.SpringBone() + { + Comment = springBone.m_comment, + Origin = (springBone.m_center != null) ? Nodes[springBone.m_center.gameObject] : null, + }; + + foreach (var joint in springBone.Joints) + { + vrmSpringBone.Joints.Add(new VrmLib.SpringJoint + { + Stiffness = joint.m_stiffnessForce, + GravityPower = joint.m_gravityPower, + GravityDir = joint.m_gravityDir.ToNumericsVector3(), + DragForce = joint.m_dragForce, + HitRadius = joint.m_hitRadius, + }); + } + + foreach (var colliderGroup in springBone.ColliderGroups) { var colliderGroups = colliderGroup.Colliders.Select(x => { @@ -365,37 +381,10 @@ public VrmLib.Model ToModelFrom10(GameObject root, VRM10MetaObject metaObject = } }); var vrmColliderGroup = new VrmLib.SpringBoneColliderGroup(Nodes[colliderGroup.gameObject], colliderGroups); - Model.Vrm.SpringBone.Colliders.Add(vrmColliderGroup); - - colliders.Add(colliderGroup, vrmColliderGroup); + vrmSpringBone.Colliders.Add(vrmColliderGroup); } - var springBones = root.GetComponentsInChildren(); - foreach (var springBone in springBones) - { - var vrmSpringBone = new VrmLib.SpringBone() - { - Comment = springBone.m_comment, - Stiffness = springBone.m_stiffnessForce, - GravityPower = springBone.m_gravityPower, - GravityDir = springBone.m_gravityDir.ToNumericsVector3(), - DragForce = springBone.m_dragForce, - Origin = (springBone.m_center != null) ? Nodes[springBone.m_center.gameObject] : null, - HitRadius = springBone.m_hitRadius, - }; - - foreach (var rootBone in springBone.RootBones) - { - vrmSpringBone.Bones.Add(Nodes[rootBone.gameObject]); - } - - foreach (var collider in springBone.ColliderGroups) - { - vrmSpringBone.Colliders.Add(colliders[collider]); - } - - Model.Vrm.SpringBone.Springs.Add(vrmSpringBone); - } + Model.Vrm.SpringBone.Springs.Add(vrmSpringBone); } } diff --git a/Assets/VRM10/vrmlib/Runtime/ModelDiffExtensions.cs b/Assets/VRM10/vrmlib/Runtime/ModelDiffExtensions.cs index d64dc2440d..dea18e4692 100644 --- a/Assets/VRM10/vrmlib/Runtime/ModelDiffExtensions.cs +++ b/Assets/VRM10/vrmlib/Runtime/ModelDiffExtensions.cs @@ -384,7 +384,6 @@ static void Vrm(ModelDiffContext context, Model lhs, Model rhs) VrmFirstPerson(context.Enter(nameof(lhs.Vrm.FirstPerson)), lhs.Vrm.FirstPerson, rhs.Vrm.FirstPerson); VrmLookAt(context.Enter(nameof(lhs.Vrm.LookAt)), lhs.Vrm.LookAt, rhs.Vrm.LookAt); ListDiff(context.Enter("SpringBone.Springs"), lhs.Vrm.SpringBone.Springs, rhs.Vrm.SpringBone.Springs, VrmSpringBoneEquals); - ListDiff(context.Enter("SpringBone.Colliders"), lhs.Vrm.SpringBone.Colliders, rhs.Vrm.SpringBone.Colliders, VrmSpringBoneColliderEquals); } static void VrmMeta(ModelDiffContext context, Meta lhs, Meta rhs) @@ -501,19 +500,26 @@ static void VrmLookAtRangeMap(ModelDiffContext context, LookAtRangeMap lhs, Look context.Enter("Curve").Push(lhs.Curve, rhs.Curve); } - static bool VrmSpringBoneEquals(ModelDiffContext context, SpringBone lhs, SpringBone rhs) + static bool VrmSpringBoneJointEquals(ModelDiffContext context, SpringJoint lhs, SpringJoint rhs) { var equals = true; - if (!context.Enter("Comment").Push(lhs.Comment, rhs.Comment)) equals = false; if (!context.Enter("DragForce").Push(lhs.DragForce, rhs.DragForce)) equals = false; if (!context.Enter("GravityDir").Push(lhs.GravityDir, rhs.GravityDir)) equals = false; if (!context.Enter("GravityPower").Push(lhs.GravityPower, rhs.GravityPower)) equals = false; if (!context.Enter("HitRadius").Push(lhs.HitRadius, rhs.HitRadius)) equals = false; - if (!context.Enter("Origin").Push(lhs.Origin, rhs.Origin)) equals = false; if (!context.Enter("Stiffness").Push(lhs.Stiffness, rhs.Stiffness)) equals = false; return equals; } + static bool VrmSpringBoneEquals(ModelDiffContext context, SpringBone lhs, SpringBone rhs) + { + var equals = true; + if (!context.Enter("Comment").Push(lhs.Comment, rhs.Comment)) equals = false; + if (!context.Enter("Origin").Push(lhs.Origin, rhs.Origin)) equals = false; + if (!ListDiff(context.Enter("Joint"), lhs.Joints, rhs.Joints, VrmSpringBoneJointEquals)) equals = false; + return equals; + } + static bool VrmSpringBoneColliderEquals(ModelDiffContext context, VrmSpringBoneCollider lhs, VrmSpringBoneCollider rhs) { var equals = true; diff --git a/Assets/VRM10/vrmlib/Runtime/ModelExtensionsForCoordinates.cs b/Assets/VRM10/vrmlib/Runtime/ModelExtensionsForCoordinates.cs index 45dae6d52c..d38a426754 100644 --- a/Assets/VRM10/vrmlib/Runtime/ModelExtensionsForCoordinates.cs +++ b/Assets/VRM10/vrmlib/Runtime/ModelExtensionsForCoordinates.cs @@ -167,7 +167,10 @@ static void ReverseZAndFlipTriangle(this Model model, bool ignoreVrm) } } - b.GravityDir = b.GravityDir.ReverseZ(); + foreach (var j in b.Joints) + { + j.GravityDir = j.GravityDir.ReverseZ(); + } } } } diff --git a/Assets/VRM10/vrmlib/Runtime/Vrm/ModelExtensionsForNode.cs b/Assets/VRM10/vrmlib/Runtime/Vrm/ModelExtensionsForNode.cs index 482f962fc1..df51eabb81 100644 --- a/Assets/VRM10/vrmlib/Runtime/Vrm/ModelExtensionsForNode.cs +++ b/Assets/VRM10/vrmlib/Runtime/Vrm/ModelExtensionsForNode.cs @@ -105,14 +105,14 @@ public static IEnumerable GetRemoveNodes(this Model model) { foreach (var x in spring.Springs) { - foreach (var y in x.Bones) + foreach (var y in x.Joints) { - nodeUsage[model.Nodes.IndexOf(y)].SpringUse = true; + nodeUsage[model.Nodes.IndexOf(y.Node)].SpringUse = true; + } + foreach (var y in x.Colliders) + { + nodeUsage[model.Nodes.IndexOf(y.Node)].SpringUse = true; } - } - foreach (var x in spring.Colliders) - { - nodeUsage[model.Nodes.IndexOf(x.Node)].SpringUse = true; } } diff --git a/Assets/VRM10/vrmlib/Runtime/Vrm/SpringBoneManager.cs b/Assets/VRM10/vrmlib/Runtime/Vrm/SpringBoneManager.cs index f0afb1e52c..0edd20ec8e 100644 --- a/Assets/VRM10/vrmlib/Runtime/Vrm/SpringBoneManager.cs +++ b/Assets/VRM10/vrmlib/Runtime/Vrm/SpringBoneManager.cs @@ -49,15 +49,9 @@ public SpringBoneColliderGroup(Node node, IEnumerable col } } - public class SpringBone + public class SpringJoint { - public const string ExtensionName = "VRMC_springBone"; - public readonly List Bones = new List(); - public Node Origin; - - public readonly List Colliders = new List(); - - public string Comment = ""; + public readonly Node Node; public float DragForce; @@ -70,9 +64,19 @@ public class SpringBone public float Stiffness; } + public class SpringBone + { + public const string ExtensionName = "VRMC_springBone"; + public readonly List Joints = new List(); + public Node Origin; + + public readonly List Colliders = new List(); + + public string Comment = ""; + } + public class SpringBoneManager { public readonly List Springs = new List(); - public readonly List Colliders = new List(); } -} \ No newline at end of file +} From 0484f02198e58a7a833f2c071175a80cb36fe61a Mon Sep 17 00:00:00 2001 From: ousttrue Date: Tue, 19 Jan 2021 19:28:55 +0900 Subject: [PATCH 06/22] VRM10SpringBoneManager.cs --- .../VRM10SpringBoneColliderGroupEditor.cs | 18 +- .../SpringBone/VRM10SpringBoneView.cs | 56 ----- .../SpringBone/VRM10SpringBoneWindow.cs | 111 ---------- .../SpringBone/VRM10SpringBoneWindow.cs.meta | 11 - .../Components/VRM10ControllerEditor.cs | 86 +++++--- .../Components/SpringBone/VRM10SpringBone.cs | 9 +- .../VRM10SpringBoneColliderGroup.cs | 17 +- .../SpringBone/VRM10SpringBoneManager.cs | 28 +++ .../VRM10SpringBoneManager.cs.meta} | 2 +- .../Runtime/Components/VRM10Controller.cs | 31 ++- .../Runtime/UnityBuilder/ComponentBuilder.cs | 100 +++++---- .../VRMConverter/RuntimeVrmConverter.cs | 199 +++++++++--------- .../Runtime/ImportExport/ModelLoader.cs | 4 +- 13 files changed, 273 insertions(+), 399 deletions(-) delete mode 100644 Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneView.cs delete mode 100644 Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneWindow.cs delete mode 100644 Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneWindow.cs.meta create mode 100644 Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneManager.cs rename Assets/VRM10/{Editor/Components/SpringBone/VRM10SpringBoneView.cs.meta => Runtime/Components/SpringBone/VRM10SpringBoneManager.cs.meta} (83%) diff --git a/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneColliderGroupEditor.cs b/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneColliderGroupEditor.cs index 56295eff50..f97b0f5ccb 100644 --- a/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneColliderGroupEditor.cs +++ b/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneColliderGroupEditor.cs @@ -39,15 +39,15 @@ private void OnSceneGUI() EditorUtility.SetDirty(m_target); } } - + [MenuItem("CONTEXT/VRM10SpringBoneColliderGroup/X Mirror")] private static void InvertOffsetX(MenuCommand command) { var target = command.context as VRM10SpringBoneColliderGroup; if (target == null) return; - + Undo.RecordObject(target, "X Mirror"); - + foreach (var sphereCollider in target.Colliders) { var offset = sphereCollider.Offset; @@ -55,27 +55,27 @@ private static void InvertOffsetX(MenuCommand command) sphereCollider.Offset = offset; } } - + [MenuItem("CONTEXT/VRM10SpringBoneColliderGroup/Sort Colliders by Radius")] private static void SortByRadius(MenuCommand command) { var target = command.context as VRM10SpringBoneColliderGroup; if (target == null) return; - + Undo.RecordObject(target, "Sort Colliders by Radius"); - target.Colliders = target.Colliders.OrderBy(x => -x.Radius).ToArray(); + target.Colliders = target.Colliders.OrderBy(x => -x.Radius).ToList(); } - + [MenuItem("CONTEXT/VRM10SpringBoneColliderGroup/Sort Colliders by Offset Y")] private static void SortByOffsetY(MenuCommand command) { var target = command.context as VRM10SpringBoneColliderGroup; if (target == null) return; - + Undo.RecordObject(target, "Sort Colliders by Offset Y"); - target.Colliders = target.Colliders.OrderBy(x => -x.Offset.y).ToArray(); + target.Colliders = target.Colliders.OrderBy(x => -x.Offset.y).ToList(); } } } diff --git a/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneView.cs b/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneView.cs deleted file mode 100644 index 5e9e93c114..0000000000 --- a/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneView.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System.Collections.Generic; -using UnityEditor.IMGUI.Controls; - -namespace UniVRM10 -{ - class VRM10SpringBoneTreeView : TreeView - - { - VRM10Controller m_root; - - Dictionary m_boneMap = new Dictionary(); - - public bool TryGetSpringBone(int id, out VRM10SpringBone bone) - { - return m_boneMap.TryGetValue(id, out bone); - } - - public VRM10SpringBoneTreeView(TreeViewState treeViewState, VRM10Controller root) - : base(treeViewState) - { - m_root = root; - Reload(); - } - - protected override bool CanMultiSelect(TreeViewItem item) - { - return false; - } - - protected override TreeViewItem BuildRoot() - { - m_boneMap.Clear(); - var root = new TreeViewItem { id = 0, depth = -1, displayName = m_root.name }; - var allItems = new List(); - var bones = m_root.GetComponentsInChildren(); - var id = 1; - for (int i = 0; i < bones.Length; ++i, ++id) - { - var bone = bones[i]; - - m_boneMap.Add(id, bone); - - allItems.Add(new TreeViewItem - { - id = id, - displayName = bone.name, - }); - } - // Utility method that initializes the TreeViewItem.children and -parent for all items. - SetupParentsAndChildrenFromDepths(root, allItems); - - // Return root of the tree - return root; - } - } -} diff --git a/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneWindow.cs b/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneWindow.cs deleted file mode 100644 index ea3df9b27d..0000000000 --- a/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneWindow.cs +++ /dev/null @@ -1,111 +0,0 @@ -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using UnityEditor; -using UnityEditor.IMGUI.Controls; -using UnityEngine; - - -namespace UniVRM10 -{ - public class VRM10SpringBoneWindow : EditorWindow - { - [MenuItem(VRMVersion.MENU + "/VRMSpringBoneWindow")] - public static void ShowEditorWindow() - { - var wnd = GetWindow(); - wnd.titleContent = new GUIContent("VRMSpringBoneWindow"); - } - - void OnEnable() - { - minSize = new Vector2(100, 100); - maxSize = new Vector2(4000, 4000); - Selection.selectionChanged += OnSelectionChanged; - } - - void OnDisable() - { - Selection.selectionChanged -= OnSelectionChanged; - } - - VRM10Controller m_currentRoot; - - [SerializeField] - TreeViewState m_treeViewState; - VRM10SpringBoneTreeView m_treeView; - - Rect m_treeRect; - Rect m_inspectorRect; - Vector2 m_inspectorScrollPos; - - void OnGUI() - { - if (m_treeView is null) - { - return; - } - - // bone selector - Rect fullRect = GUILayoutUtility.GetRect(0, 100000, 0, 10000); - var treeRect = new Rect(fullRect.x, fullRect.y, fullRect.width, EditorGUIUtility.singleLineHeight * 3); - var inspectorRect = new Rect(fullRect.x, treeRect.y + treeRect.height, fullRect.width, fullRect.height - treeRect.height); - if (Event.current.type == EventType.Repaint) - { - m_treeRect = treeRect; - m_inspectorRect = inspectorRect; - // Debug.Log($"{m_treeRect}, {m_inspectorRect}"); - } - - m_treeView.OnGUI(m_treeRect); - - GUILayout.BeginArea(m_inspectorRect); - m_inspectorScrollPos = GUILayout.BeginScrollView(m_inspectorScrollPos, GUI.skin.box); - if (m_treeViewState.selectedIDs.Any()) - { - // selected な SpringBone の Inspector を描画する - if (m_treeView.TryGetSpringBone(m_treeViewState.selectedIDs[0], out VRM10SpringBone bone)) - { - // Debug.Log(bone); - using (var inspector = new CustomInspector(new SerializedObject(bone))) - { - inspector.OnInspectorGUI(); - } - } - } - GUILayout.EndScrollView(); - GUILayout.EndArea(); - } - - void OnSelectionChanged() - { - var go = Selection.activeObject as GameObject; - if (go is null) - { - return; - } - - var meta = go.GetComponentInParent(); - if (meta == m_currentRoot) - { - return; - } - - m_currentRoot = meta; - if (m_currentRoot is null) - { - m_treeViewState = null; - m_treeView = null; - } - else - { - // update treeview - Debug.Log(m_currentRoot); - m_treeViewState = new TreeViewState(); - m_treeView = new VRM10SpringBoneTreeView(m_treeViewState, m_currentRoot); - } - - Repaint(); - } - } -} diff --git a/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneWindow.cs.meta b/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneWindow.cs.meta deleted file mode 100644 index 228370822c..0000000000 --- a/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneWindow.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 50b4a0f82403ba742b3ae1d7ee14bf05 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/VRM10/Editor/Components/VRM10ControllerEditor.cs b/Assets/VRM10/Editor/Components/VRM10ControllerEditor.cs index eff76f3028..0324983ea4 100644 --- a/Assets/VRM10/Editor/Components/VRM10ControllerEditor.cs +++ b/Assets/VRM10/Editor/Components/VRM10ControllerEditor.cs @@ -53,11 +53,12 @@ void OnEnable() { m_metaEditor = Editor.CreateEditor(m_target.Meta); } - m_controller = serializedObject.FindProperty(nameof(m_target.Controller)); - m_expression = serializedObject.FindProperty(nameof(m_target.Expression)); - m_lookAt = serializedObject.FindProperty(nameof(m_target.LookAt)); - m_firstPerson = serializedObject.FindProperty(nameof(m_target.FirstPerson)); - m_asset = serializedObject.FindProperty(nameof(m_target.ModelAsset)); + m_controller = PropGui.FromObject(serializedObject, nameof(m_target.Controller)); + m_expression = PropGui.FromObject(serializedObject, nameof(m_target.Expression)); + m_lookAt = PropGui.FromObject(serializedObject, nameof(m_target.LookAt)); + m_firstPerson = PropGui.FromObject(serializedObject, nameof(m_target.FirstPerson)); + m_springBone = PropGui.FromObject(serializedObject, nameof(m_target.SpringBone)); + m_asset = PropGui.FromObject(serializedObject, nameof(m_target.ModelAsset)); } void OnDisable() @@ -76,16 +77,51 @@ enum Tabs Expression, LookAt, FirstPerson, + SpringBone, Assets, } Tabs _tab; Editor m_metaEditor; - SerializedProperty m_controller; - SerializedProperty m_expression; - SerializedProperty m_lookAt; - SerializedProperty m_firstPerson; - SerializedProperty m_asset; + + class PropGui + { + SerializedProperty m_prop; + + PropGui(SerializedProperty property) + { + m_prop = property; + } + + public static PropGui FromObject(SerializedObject serializedObject, string name) + { + var prop = serializedObject.FindProperty(name); + return new PropGui(prop); + } + + public void RecursiveProperty() + { + var depth = m_prop.depth; + var iterator = m_prop.Copy(); + for (var enterChildren = true; iterator.NextVisible(enterChildren); enterChildren = false) + { + if (iterator.depth < depth) + return; + + depth = iterator.depth; + + using (new EditorGUI.DisabledScope("m_Script" == iterator.propertyPath)) + EditorGUILayout.PropertyField(iterator, true); + } + } + } + + PropGui m_controller; + PropGui m_expression; + PropGui m_lookAt; + PropGui m_firstPerson; + PropGui m_springBone; + PropGui m_asset; public override void OnInspectorGUI() { @@ -109,24 +145,28 @@ public override void OnInspectorGUI() break; case Tabs.Controller: - RecursiveProperty(m_controller); + m_controller.RecursiveProperty(); break; case Tabs.Expression: ExpressionGUI(); - RecursiveProperty(m_expression); + m_expression.RecursiveProperty(); break; case Tabs.LookAt: - RecursiveProperty(m_lookAt); + m_lookAt.RecursiveProperty(); break; case Tabs.FirstPerson: - RecursiveProperty(m_firstPerson); + m_firstPerson.RecursiveProperty(); + break; + + case Tabs.SpringBone: + m_springBone.RecursiveProperty(); break; case Tabs.Assets: - RecursiveProperty(m_asset); + m_asset.RecursiveProperty(); break; } @@ -164,22 +204,6 @@ void ExpressionGUI() } } - static void RecursiveProperty(SerializedProperty property) - { - var depth = property.depth; - var iterator = property.Copy(); - for (var enterChildren = true; iterator.NextVisible(enterChildren); enterChildren = false) - { - if (iterator.depth < depth) - return; - - depth = iterator.depth; - - using (new EditorGUI.DisabledScope("m_Script" == iterator.propertyPath)) - EditorGUILayout.PropertyField(iterator, true); - } - } - void OnSceneGUI() { OnSceneGUIOffset(); diff --git a/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBone.cs b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBone.cs index 64e3f34a9b..7365321487 100644 --- a/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBone.cs +++ b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBone.cs @@ -8,11 +8,8 @@ namespace UniVRM10 /// The base algorithm is http://rocketjump.skr.jp/unity3d/109/ of @ricopin416 /// DefaultExecutionOrder(11000) means calculate springbone after FinalIK( VRIK ) /// - [AddComponentMenu("VRM10/VRM10SpringBone")] -#if UNITY_5_5_OR_NEWER - [DefaultExecutionOrder(11000)] -#endif - public class VRM10SpringBone : MonoBehaviour + [Serializable] + public class VRM10SpringBone { [SerializeField] public string m_comment; @@ -49,7 +46,7 @@ public class VRM10SpringJoint public List Joints = new List(); [SerializeField] - public VRM10SpringBoneColliderGroup[] ColliderGroups; + public List ColliderGroups = new List(); SpringBoneProcessor m_processor = new SpringBoneProcessor(); diff --git a/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneColliderGroup.cs b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneColliderGroup.cs index 7d07deb711..180ca31dd0 100644 --- a/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneColliderGroup.cs +++ b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneColliderGroup.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using UnityEngine; @@ -10,14 +11,18 @@ namespace UniVRM10 [AddComponentMenu("VRM10/VRM10SpringBoneColliderGroup")] public class VRM10SpringBoneColliderGroup : MonoBehaviour { - [SerializeField] - public VRM10SpringBoneCollider[] Colliders = new VRM10SpringBoneCollider[]{ - new VRM10SpringBoneCollider + void Reset() + { + // default shape + Colliders.Add(new VRM10SpringBoneCollider { ColliderType = VRM10SpringBoneColliderTypes.Capsule, - Radius=0.1f - } - }; + Radius = 0.1f + }); + } + + [SerializeField] + public List Colliders = new List(); public static void DrawWireCapsule(Vector3 headPos, Vector3 tailPos, float radius) { diff --git a/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneManager.cs b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneManager.cs new file mode 100644 index 0000000000..369d7a7d09 --- /dev/null +++ b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneManager.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace UniVRM10 +{ + /// + /// すべての SpringBone を管理する。 + /// Humanoid 一体につきひとつだけ存在する。 + /// + [Serializable] + public class VRM10SpringBoneManager + { + [SerializeField] + public List Springs = new List(); + + /// + /// 1フレームに一回呼び出す(VRM10Controllerの仕事) + /// + public void Process() + { + foreach (var spring in Springs) + { + spring.Process(); + } + } + } +} diff --git a/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneView.cs.meta b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneManager.cs.meta similarity index 83% rename from Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneView.cs.meta rename to Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneManager.cs.meta index 6102f48e6b..7a973865ae 100644 --- a/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneView.cs.meta +++ b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneManager.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: c012308d77f262b4789f2fee6cdb7105 +guid: d09e28f7198c42d42bb31fd40e164b2d MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/VRM10/Runtime/Components/VRM10Controller.cs b/Assets/VRM10/Runtime/Components/VRM10Controller.cs index 9948c31688..1759771aee 100644 --- a/Assets/VRM10/Runtime/Components/VRM10Controller.cs +++ b/Assets/VRM10/Runtime/Components/VRM10Controller.cs @@ -15,16 +15,16 @@ namespace UniVRM10 [DisallowMultipleComponent] public class VRM10Controller : MonoBehaviour { - public enum UpdateTypes - { - None, - Update, - LateUpdate, - } - [Serializable] public class VRM10ControllerImpl { + public enum UpdateTypes + { + None, + Update, + LateUpdate, + } + [SerializeField, Header("UpdateSetting")] public UpdateTypes UpdateType = UpdateTypes.LateUpdate; } @@ -44,6 +44,9 @@ public class VRM10ControllerImpl [SerializeField] public VRM10ControllerFirstPerson FirstPerson = new VRM10ControllerFirstPerson(); + [SerializeField] + public VRM10SpringBoneManager SpringBone = new VRM10SpringBoneManager(); + [SerializeField] public ModelAsset ModelAsset; @@ -62,7 +65,6 @@ void OnDestroy() } VRMConstraint[] m_constraints; - VRM10SpringBone[] m_springs; Transform m_head; public Transform Head @@ -133,14 +135,7 @@ public void Apply() // // spring // - if (m_springs == null) - { - m_springs = GetComponentsInChildren(); - } - foreach (var spring in m_springs) - { - spring.Process(); - } + SpringBone.Process(); // // expression @@ -160,7 +155,7 @@ public void Apply() private void Update() { - if (Controller.UpdateType == UpdateTypes.Update) + if (Controller.UpdateType == VRM10ControllerImpl.UpdateTypes.Update) { Apply(); } @@ -168,7 +163,7 @@ private void Update() private void LateUpdate() { - if (Controller.UpdateType == UpdateTypes.LateUpdate) + if (Controller.UpdateType == VRM10ControllerImpl.UpdateTypes.LateUpdate) { Apply(); } diff --git a/Assets/VRM10/Runtime/UnityBuilder/ComponentBuilder.cs b/Assets/VRM10/Runtime/UnityBuilder/ComponentBuilder.cs index 578af2913b..eef5796347 100644 --- a/Assets/VRM10/Runtime/UnityBuilder/ComponentBuilder.cs +++ b/Assets/VRM10/Runtime/UnityBuilder/ComponentBuilder.cs @@ -232,67 +232,67 @@ public static void Build10(VrmLib.Model model, ModelAsset asset) // springBone { - var colliders = new Dictionary(); if (model.Vrm.SpringBone != null) { - foreach (var colliderGroup in model.Vrm.SpringBone.Springs.SelectMany(x => x.Colliders)) + foreach (var vrmSpring in model.Vrm.SpringBone.Springs) { - var go = asset.Map.Nodes[colliderGroup.Node]; - var springBoneColliderGroup = go.AddComponent(); + // create a spring + var springBone = new UniVRM10.VRM10SpringBone(); + springBone.m_comment = vrmSpring.Comment; + if (vrmSpring.Origin != null && asset.Map.Nodes.TryGetValue(vrmSpring.Origin, out GameObject origin)) + { + springBone.m_center = origin.transform; + } + controller.SpringBone.Springs.Add(springBone); - springBoneColliderGroup.Colliders = colliderGroup.Colliders.Select(x => + // create colliders for the spring + foreach (var vrmSpringBoneCollider in vrmSpring.Colliders) { - switch (x.ColliderType) + var go = asset.Map.Nodes[vrmSpringBoneCollider.Node]; + var springBoneColliderGroup = go.GetComponent(); + if (springBoneColliderGroup != null) { - case VrmLib.VrmSpringBoneColliderTypes.Sphere: - return new UniVRM10.VRM10SpringBoneCollider() - { - ColliderType = VRM10SpringBoneColliderTypes.Sphere, - Offset = x.Offset.ToUnityVector3(), - Radius = x.Radius - }; + // already setup + } + else + { + // new collider + springBoneColliderGroup = go.AddComponent(); - case VrmLib.VrmSpringBoneColliderTypes.Capsule: - return new UniVRM10.VRM10SpringBoneCollider() + // add collider shapes + springBoneColliderGroup.Colliders.Clear(); + foreach (var x in vrmSpringBoneCollider.Colliders) + { + switch (x.ColliderType) { - ColliderType = VRM10SpringBoneColliderTypes.Capsule, - Offset = x.Offset.ToUnityVector3(), - Radius = x.Radius, - Tail = x.CapsuleTail.ToUnityVector3(), - }; + case VrmLib.VrmSpringBoneColliderTypes.Sphere: + springBoneColliderGroup.Colliders.Add(new UniVRM10.VRM10SpringBoneCollider() + { + ColliderType = VRM10SpringBoneColliderTypes.Sphere, + Offset = x.Offset.ToUnityVector3(), + Radius = x.Radius + }); + break; - default: - throw new NotImplementedException(); - } - }).ToArray(); ; + case VrmLib.VrmSpringBoneColliderTypes.Capsule: + springBoneColliderGroup.Colliders.Add(new UniVRM10.VRM10SpringBoneCollider() + { + ColliderType = VRM10SpringBoneColliderTypes.Capsule, + Offset = x.Offset.ToUnityVector3(), + Radius = x.Radius, + Tail = x.CapsuleTail.ToUnityVector3(), + }); + break; - colliders.Add(colliderGroup, springBoneColliderGroup); - } - } - - GameObject springBoneObject = null; - var springBoneTransform = asset.Root.transform.GetChildren().FirstOrDefault(x => x.name == "SpringBone"); - if (springBoneTransform == null) - { - springBoneObject = new GameObject("SpringBone"); - } - else - { - springBoneObject = springBoneTransform.gameObject; - } - - springBoneObject.transform.SetParent(asset.Root.transform); - if (model.Vrm.SpringBone != null) - { - foreach (var vrmSpring in model.Vrm.SpringBone.Springs) - { - var springBone = springBoneObject.AddComponent(); - springBone.m_comment = vrmSpring.Comment; - if (vrmSpring.Origin != null && asset.Map.Nodes.TryGetValue(vrmSpring.Origin, out GameObject origin)) - { - springBone.m_center = origin.transform; + default: + throw new NotImplementedException(); + } + } + } + springBone.ColliderGroups.Add(springBoneColliderGroup); } + // create joint for the spring foreach (var vrmJoint in vrmSpring.Joints) { var joint = new VRM10SpringBone.VRM10SpringJoint(); @@ -305,8 +305,6 @@ public static void Build10(VrmLib.Model model, ModelAsset asset) springBone.Joints.Add(joint); } - - springBone.ColliderGroups = vrmSpring.Colliders.Select(x => colliders[x]).ToArray(); } } } diff --git a/Assets/VRM10/Runtime/VRMConverter/RuntimeVrmConverter.cs b/Assets/VRM10/Runtime/VRMConverter/RuntimeVrmConverter.cs index a85914f02c..d3518c5f1f 100644 --- a/Assets/VRM10/Runtime/VRMConverter/RuntimeVrmConverter.cs +++ b/Assets/VRM10/Runtime/VRMConverter/RuntimeVrmConverter.cs @@ -258,133 +258,136 @@ public VrmLib.Model ToModelFrom10(GameObject root, VRM10MetaObject metaObject = // blendShape var controller = root.GetComponent(); + if (controller != null) { - Model.Vrm.ExpressionManager = new VrmLib.ExpressionManager(); - if (controller != null) { - foreach (var clip in controller.Expression.ExpressionAvatar.Clips) + Model.Vrm.ExpressionManager = new VrmLib.ExpressionManager(); + if (controller != null) { - var expression = ToVrmLib(clip, root); - if (expression != null) + foreach (var clip in controller.Expression.ExpressionAvatar.Clips) { - Model.Vrm.ExpressionManager.ExpressionList.Add(expression); + var expression = ToVrmLib(clip, root); + if (expression != null) + { + Model.Vrm.ExpressionManager.ExpressionList.Add(expression); + } } } } - } - // firstPerson - { - var firstPerson = new VrmLib.FirstPerson(); - if (controller != null) + // firstPerson { - foreach (var annotation in controller.FirstPerson.Renderers) + var firstPerson = new VrmLib.FirstPerson(); + if (controller != null) { - firstPerson.Annotations.Add( - new VrmLib.FirstPersonMeshAnnotation(Nodes[annotation.Renderer.gameObject], - annotation.FirstPersonFlag) - ); + foreach (var annotation in controller.FirstPerson.Renderers) + { + firstPerson.Annotations.Add( + new VrmLib.FirstPersonMeshAnnotation(Nodes[annotation.Renderer.gameObject], + annotation.FirstPersonFlag) + ); + } + Model.Vrm.FirstPerson = firstPerson; } - Model.Vrm.FirstPerson = firstPerson; } - } - // lookAt - { - var lookAt = new VrmLib.LookAt(); - if (controller != null) + // lookAt { - if (controller.LookAt.LookAtType == VRM10ControllerLookAt.LookAtTypes.Expression) + var lookAt = new VrmLib.LookAt(); + if (controller != null) { - lookAt.HorizontalInner = new VrmLib.LookAtRangeMap(); - lookAt.HorizontalOuter = new VrmLib.LookAtRangeMap() - { - InputMaxValue = controller.LookAt.HorizontalOuter.CurveXRangeDegree, - OutputScaling = controller.LookAt.HorizontalOuter.CurveYRangeDegree - }; - lookAt.VerticalUp = new VrmLib.LookAtRangeMap() - { - InputMaxValue = controller.LookAt.VerticalUp.CurveXRangeDegree, - OutputScaling = controller.LookAt.VerticalUp.CurveYRangeDegree, - }; - lookAt.VerticalDown = new VrmLib.LookAtRangeMap() + if (controller.LookAt.LookAtType == VRM10ControllerLookAt.LookAtTypes.Expression) { - InputMaxValue = controller.LookAt.VerticalDown.CurveXRangeDegree, - OutputScaling = controller.LookAt.VerticalDown.CurveYRangeDegree, - }; - } - else if (controller.LookAt.LookAtType == VRM10ControllerLookAt.LookAtTypes.Bone) - { - lookAt.HorizontalInner = new VrmLib.LookAtRangeMap() - { - InputMaxValue = controller.LookAt.HorizontalInner.CurveXRangeDegree, - OutputScaling = controller.LookAt.HorizontalInner.CurveYRangeDegree - }; - lookAt.HorizontalOuter = new VrmLib.LookAtRangeMap() - { - InputMaxValue = controller.LookAt.HorizontalOuter.CurveXRangeDegree, - OutputScaling = controller.LookAt.HorizontalOuter.CurveYRangeDegree - }; - lookAt.VerticalUp = new VrmLib.LookAtRangeMap() - { - InputMaxValue = controller.LookAt.VerticalUp.CurveXRangeDegree, - OutputScaling = controller.LookAt.VerticalUp.CurveYRangeDegree, - }; - lookAt.VerticalDown = new VrmLib.LookAtRangeMap() + lookAt.HorizontalInner = new VrmLib.LookAtRangeMap(); + lookAt.HorizontalOuter = new VrmLib.LookAtRangeMap() + { + InputMaxValue = controller.LookAt.HorizontalOuter.CurveXRangeDegree, + OutputScaling = controller.LookAt.HorizontalOuter.CurveYRangeDegree + }; + lookAt.VerticalUp = new VrmLib.LookAtRangeMap() + { + InputMaxValue = controller.LookAt.VerticalUp.CurveXRangeDegree, + OutputScaling = controller.LookAt.VerticalUp.CurveYRangeDegree, + }; + lookAt.VerticalDown = new VrmLib.LookAtRangeMap() + { + InputMaxValue = controller.LookAt.VerticalDown.CurveXRangeDegree, + OutputScaling = controller.LookAt.VerticalDown.CurveYRangeDegree, + }; + } + else if (controller.LookAt.LookAtType == VRM10ControllerLookAt.LookAtTypes.Bone) { - InputMaxValue = controller.LookAt.VerticalDown.CurveXRangeDegree, - OutputScaling = controller.LookAt.VerticalDown.CurveYRangeDegree, - }; + lookAt.HorizontalInner = new VrmLib.LookAtRangeMap() + { + InputMaxValue = controller.LookAt.HorizontalInner.CurveXRangeDegree, + OutputScaling = controller.LookAt.HorizontalInner.CurveYRangeDegree + }; + lookAt.HorizontalOuter = new VrmLib.LookAtRangeMap() + { + InputMaxValue = controller.LookAt.HorizontalOuter.CurveXRangeDegree, + OutputScaling = controller.LookAt.HorizontalOuter.CurveYRangeDegree + }; + lookAt.VerticalUp = new VrmLib.LookAtRangeMap() + { + InputMaxValue = controller.LookAt.VerticalUp.CurveXRangeDegree, + OutputScaling = controller.LookAt.VerticalUp.CurveYRangeDegree, + }; + lookAt.VerticalDown = new VrmLib.LookAtRangeMap() + { + InputMaxValue = controller.LookAt.VerticalDown.CurveXRangeDegree, + OutputScaling = controller.LookAt.VerticalDown.CurveYRangeDegree, + }; + } + lookAt.OffsetFromHeadBone = controller.LookAt.OffsetFromHead.ToNumericsVector3(); } - lookAt.OffsetFromHeadBone = controller.LookAt.OffsetFromHead.ToNumericsVector3(); + Model.Vrm.LookAt = lookAt; } - Model.Vrm.LookAt = lookAt; - } - // springBone - { - var springBones = root.GetComponentsInChildren(); - foreach (var springBone in springBones) + // springBone { - var vrmSpringBone = new VrmLib.SpringBone() - { - Comment = springBone.m_comment, - Origin = (springBone.m_center != null) ? Nodes[springBone.m_center.gameObject] : null, - }; - - foreach (var joint in springBone.Joints) + var springBoneManager = controller.SpringBone; + foreach (var springBone in springBoneManager.Springs) { - vrmSpringBone.Joints.Add(new VrmLib.SpringJoint + var vrmSpringBone = new VrmLib.SpringBone() { - Stiffness = joint.m_stiffnessForce, - GravityPower = joint.m_gravityPower, - GravityDir = joint.m_gravityDir.ToNumericsVector3(), - DragForce = joint.m_dragForce, - HitRadius = joint.m_hitRadius, - }); - } + Comment = springBone.m_comment, + Origin = (springBone.m_center != null) ? Nodes[springBone.m_center.gameObject] : null, + }; - foreach (var colliderGroup in springBone.ColliderGroups) - { - var colliderGroups = colliderGroup.Colliders.Select(x => + foreach (var joint in springBone.Joints) { - switch (x.ColliderType) + vrmSpringBone.Joints.Add(new VrmLib.SpringJoint { - case VRM10SpringBoneColliderTypes.Sphere: - return VrmLib.VrmSpringBoneCollider.CreateSphere(x.Offset.ToNumericsVector3(), x.Radius); + Stiffness = joint.m_stiffnessForce, + GravityPower = joint.m_gravityPower, + GravityDir = joint.m_gravityDir.ToNumericsVector3(), + DragForce = joint.m_dragForce, + HitRadius = joint.m_hitRadius, + }); + } - case VRM10SpringBoneColliderTypes.Capsule: - return VrmLib.VrmSpringBoneCollider.CreateCapsule(x.Offset.ToNumericsVector3(), x.Radius, x.Tail.ToNumericsVector3()); + foreach (var colliderGroup in springBone.ColliderGroups) + { + var colliderGroups = colliderGroup.Colliders.Select(x => + { + switch (x.ColliderType) + { + case VRM10SpringBoneColliderTypes.Sphere: + return VrmLib.VrmSpringBoneCollider.CreateSphere(x.Offset.ToNumericsVector3(), x.Radius); + + case VRM10SpringBoneColliderTypes.Capsule: + return VrmLib.VrmSpringBoneCollider.CreateCapsule(x.Offset.ToNumericsVector3(), x.Radius, x.Tail.ToNumericsVector3()); + + default: + throw new NotImplementedException(); + } + }); + var vrmColliderGroup = new VrmLib.SpringBoneColliderGroup(Nodes[colliderGroup.gameObject], colliderGroups); + vrmSpringBone.Colliders.Add(vrmColliderGroup); + } - default: - throw new NotImplementedException(); - } - }); - var vrmColliderGroup = new VrmLib.SpringBoneColliderGroup(Nodes[colliderGroup.gameObject], colliderGroups); - vrmSpringBone.Colliders.Add(vrmColliderGroup); + Model.Vrm.SpringBone.Springs.Add(vrmSpringBone); } - - Model.Vrm.SpringBone.Springs.Add(vrmSpringBone); } } diff --git a/Assets/VRM10/vrmlib/Runtime/ImportExport/ModelLoader.cs b/Assets/VRM10/vrmlib/Runtime/ImportExport/ModelLoader.cs index 1f5d6f262f..21b5a3a62b 100644 --- a/Assets/VRM10/vrmlib/Runtime/ImportExport/ModelLoader.cs +++ b/Assets/VRM10/vrmlib/Runtime/ImportExport/ModelLoader.cs @@ -97,7 +97,9 @@ static bool LoadVrm(Model model, IVrmStorage storage) return false; } - var Vrm = new Vrm(storage.CreateVrmMeta(model.Textures), storage.VrmExporterVersion, storage.VrmSpecVersion); + var meta = storage.CreateVrmMeta(model.Textures); + + var Vrm = new Vrm(meta, storage.VrmExporterVersion, storage.VrmSpecVersion); model.Vrm = Vrm; storage.LoadVrmHumanoid(model.Nodes); From 505417a964565118f0b3c195fd2cb9e4558390b3 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Tue, 19 Jan 2021 20:19:23 +0900 Subject: [PATCH 07/22] merge VrmLib.GLb to UniGLTF.Glb --- .../Runtime/Extensions/ArrayExtensions.cs | 25 ++ .../Runtime/Extensions/glTFExtensions.cs | 6 +- .../Runtime/UniGLTF/Format/glbTypes.cs | 171 +++++++++++- Assets/VRM10/Editor/VRM10.Editor.asmdef | 3 +- Assets/VRM10/Editor/Vrm10ExportDialog.cs | 2 +- .../VRM10/Runtime/IO/BufferAccessorAdapter.cs | 20 +- Assets/VRM10/Runtime/IO/ImageAdapter.cs | 13 +- Assets/VRM10/Runtime/IO/ModelExtensions.cs | 2 +- Assets/VRM10/Runtime/IO/Vrm10Exporter.cs | 4 +- Assets/VRM10/Runtime/IO/Vrm10Storage.cs | 27 +- .../VRM10/Runtime/Scenes/ExportDebugUtil.cs | 2 +- .../ScriptedImporter/GltfScriptedImporter.cs | 2 +- .../VRM10/Runtime/UnityBuilder/VrmLoader.cs | 2 +- Assets/VRM10/Tests.PlayMode/ApiSampleTests.cs | 2 +- .../VRM10.Tests.PlayMode.asmdef | 3 +- .../Extensions/ArraySegmentExtensions.cs | 29 ++ .../ArraySegmentExtensions.cs.meta} | 2 +- .../VRM10/vrmlib/Runtime/ImportExport/Glb.cs | 263 ------------------ Assets/VRM10/vrmlib/Runtime/SpanLike.cs | 25 -- 19 files changed, 255 insertions(+), 348 deletions(-) create mode 100644 Assets/VRM10/vrmlib/Runtime/Extensions/ArraySegmentExtensions.cs rename Assets/VRM10/vrmlib/Runtime/{ImportExport/Glb.cs.meta => Extensions/ArraySegmentExtensions.cs.meta} (83%) delete mode 100644 Assets/VRM10/vrmlib/Runtime/ImportExport/Glb.cs diff --git a/Assets/UniGLTF/Runtime/Extensions/ArrayExtensions.cs b/Assets/UniGLTF/Runtime/Extensions/ArrayExtensions.cs index 8b0f2774bc..2687025e7d 100644 --- a/Assets/UniGLTF/Runtime/Extensions/ArrayExtensions.cs +++ b/Assets/UniGLTF/Runtime/Extensions/ArrayExtensions.cs @@ -132,4 +132,29 @@ public static void Assign(this List dst, T[] src, Func pred) dst.AddRange(src.Select(pred)); } } + + public static class ArraySegmentExtensions + { + public static ArraySegment Slice(this ArraySegment self, int start, int length) + { + if (start + length > self.Count) + { + throw new ArgumentOutOfRangeException(); + } + return new ArraySegment( + self.Array, + self.Offset + start, + length + ); + } + + public static ArraySegment Slice(this ArraySegment self, int start) + { + if (start > self.Count) + { + throw new ArgumentOutOfRangeException(); + } + return self.Slice(start, self.Count - start); + } + } } diff --git a/Assets/UniGLTF/Runtime/Extensions/glTFExtensions.cs b/Assets/UniGLTF/Runtime/Extensions/glTFExtensions.cs index 05b5582ce7..526706773c 100644 --- a/Assets/UniGLTF/Runtime/Extensions/glTFExtensions.cs +++ b/Assets/UniGLTF/Runtime/Extensions/glTFExtensions.cs @@ -438,11 +438,11 @@ public static byte[] ToGlbBytes(this glTF self) var f = new JsonFormatter(); GltfSerializer.Serialize(f, self); + // remove unused extenions var json = f.ToString().ParseAsJson().ToString(" "); - self.RemoveUnusedExtensions(json); - - return Glb.ToBytes(json, self.buffers[0].GetBytes()); + + return Glb.Create(json, self.buffers[0].GetBytes()).ToBytes(); } public static (string, List) ToGltf(this glTF self, string gltfPath) diff --git a/Assets/UniGLTF/Runtime/UniGLTF/Format/glbTypes.cs b/Assets/UniGLTF/Runtime/UniGLTF/Format/glbTypes.cs index a876b541bd..cb10dd6dfb 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/Format/glbTypes.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/Format/glbTypes.cs @@ -1,5 +1,7 @@ using System; +using System.Collections.Generic; using System.IO; +using System.Linq; using System.Text; namespace UniGLTF @@ -12,14 +14,39 @@ public enum GlbChunkType : uint public struct GlbHeader { + + public static readonly byte[] GLB_MAGIC = new byte[] { 0x67, 0x6C, 0x54, 0x46 }; // "glTF" + public static readonly byte[] GLB_VERSION = new byte[] { 2, 0, 0, 0 }; + public static void WriteTo(Stream s) { - s.WriteByte((Byte)'g'); - s.WriteByte((Byte)'l'); - s.WriteByte((Byte)'T'); - s.WriteByte((Byte)'F'); - var bytes = BitConverter.GetBytes((UInt32)2); - s.Write(bytes, 0, bytes.Length); + s.Write(GLB_MAGIC, 0, GLB_MAGIC.Length); + s.Write(GLB_VERSION, 0, GLB_VERSION.Length); + } + + public static int TryParse(ArraySegment bytes, out int pos, out Exception message) + { + pos = 0; + + if (!bytes.Slice(0, 4).SequenceEqual(GLB_MAGIC)) + { + message = new FormatException("invalid magic"); + return 0; + } + pos += 4; + + if (!bytes.Slice(pos, 4).SequenceEqual(GLB_VERSION)) + { + message = new FormatException("invalid magic"); + return 0; + } + pos += 4; + + var totalLength = BitConverter.ToInt32(bytes.Array, bytes.Offset + pos); + pos += 4; + + message = null; + return totalLength; } } @@ -48,6 +75,21 @@ public GlbChunk(GlbChunkType type, ArraySegment bytes) Bytes = bytes; } + public static GlbChunk CreateJson(string json) + { + return CreateJson(new ArraySegment(Encoding.UTF8.GetBytes(json))); + } + + public static GlbChunk CreateJson(ArraySegment bytes) + { + return new GlbChunk(GlbChunkType.JSON, bytes); + } + + public static GlbChunk CreateBin(ArraySegment bytes) + { + return new GlbChunk(GlbChunkType.BIN, bytes); + } + byte GetPaddingByte() { // chunk type @@ -100,7 +142,7 @@ public int WriteTo(Stream s) // 4byte align var pad = GetPaddingByte(); - for(int i=0; i + /// https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#glb-file-format-specification + /// + public struct Glb { - public static byte[] ToBytes(string json, ArraySegment body) + public readonly GlbChunk Json; + public readonly GlbChunk Binary; + + public Glb(GlbChunk json, GlbChunk binary) + { + if (json.ChunkType != GlbChunkType.JSON) throw new ArgumentException(); + Json = json; + if (binary.ChunkType != GlbChunkType.BIN) throw new ArgumentException(); + Binary = binary; + } + + public static Glb Create(ArraySegment json, ArraySegment bin) + { + return new Glb(GlbChunk.CreateJson(json), GlbChunk.CreateBin(bin)); + } + + public static Glb Create(string json, ArraySegment bin) + { + return new Glb(GlbChunk.CreateJson(json), GlbChunk.CreateBin(bin)); + } + + public byte[] ToBytes() { using (var s = new MemoryStream()) { @@ -123,12 +189,10 @@ public static byte[] ToBytes(string json, ArraySegment body) int size = 12; { - var chunk = new GlbChunk(json); - size += chunk.WriteTo(s); + size += Json.WriteTo(s); } { - var chunk = new GlbChunk(body); - size += chunk.WriteTo(s); + size += Binary.WriteTo(s); } s.Position = pos; @@ -138,5 +202,86 @@ public static byte[] ToBytes(string json, ArraySegment body) return s.ToArray(); } } + + public static GlbChunkType ToChunkType(string src) + { + switch (src) + { + case "BIN": + return GlbChunkType.BIN; + + case "JSON": + return GlbChunkType.JSON; + + default: + throw new FormatException("unknown chunk type: " + src); + } + } + + public static Glb Parse(Byte[] bytes) + { + if (TryParse(bytes, out Glb glb, out Exception ex)) + { + return glb; + } + else + { + throw ex; + } + } + + public static bool TryParse(Byte[] bytes, out Glb glb, out Exception ex) + { + return TryParse(new ArraySegment(bytes), out glb, out ex); + } + + public static bool TryParse(ArraySegment bytes, out Glb glb, out Exception ex) + { + glb = default(Glb); + if (bytes.Count == 0) + { + ex = new Exception("empty bytes"); + return false; + } + + var length = GlbHeader.TryParse(bytes, out int pos, out ex); + if (length == 0) + { + return false; + } + bytes = bytes.Slice(0, length); + + try + { + var chunks = new List(); + while (pos < bytes.Count) + { + var chunkDataSize = BitConverter.ToInt32(bytes.Array, bytes.Offset + pos); + pos += 4; + + //var type = (GlbChunkType)BitConverter.ToUInt32(bytes, pos); + var chunkTypeBytes = bytes.Slice(pos, 4).Where(x => x != 0).ToArray(); + var chunkTypeStr = Encoding.ASCII.GetString(chunkTypeBytes); + var type = ToChunkType(chunkTypeStr); + pos += 4; + + chunks.Add(new GlbChunk + { + ChunkType = type, + Bytes = bytes.Slice(pos, chunkDataSize) + }); + + pos += chunkDataSize; + } + + glb = new Glb(chunks[0], chunks[1]); + return true; + } + catch (Exception _ex) + { + ex = _ex; + return false; + } + } } } diff --git a/Assets/VRM10/Editor/VRM10.Editor.asmdef b/Assets/VRM10/Editor/VRM10.Editor.asmdef index eb354e9902..9d1baa8c85 100644 --- a/Assets/VRM10/Editor/VRM10.Editor.asmdef +++ b/Assets/VRM10/Editor/VRM10.Editor.asmdef @@ -5,7 +5,8 @@ "VrmLib", "MeshUtility", "MeshUtility.Editor", - "UniGLTF.Editor" + "UniGLTF.Editor", + "UniGLTF" ], "optionalUnityReferences": [], "includePlatforms": [ diff --git a/Assets/VRM10/Editor/Vrm10ExportDialog.cs b/Assets/VRM10/Editor/Vrm10ExportDialog.cs index 2ed34bf75b..f6b005117f 100644 --- a/Assets/VRM10/Editor/Vrm10ExportDialog.cs +++ b/Assets/VRM10/Editor/Vrm10ExportDialog.cs @@ -344,7 +344,7 @@ static byte[] GetGlb(VrmLib.Model model) }; var glbBytes10 = exporter.Export(model, option); // ? - var glb10 = VrmLib.Glb.Parse(glbBytes10); + var glb10 = UniGLTF.Glb.Parse(glbBytes10); return glb10.ToBytes(); } diff --git a/Assets/VRM10/Runtime/IO/BufferAccessorAdapter.cs b/Assets/VRM10/Runtime/IO/BufferAccessorAdapter.cs index 4dc9b1fd37..8bc457cdd4 100644 --- a/Assets/VRM10/Runtime/IO/BufferAccessorAdapter.cs +++ b/Assets/VRM10/Runtime/IO/BufferAccessorAdapter.cs @@ -1,9 +1,7 @@ using System; using System.Collections.Generic; using System.Numerics; -using System.Runtime.InteropServices; using UniGLTF; -using VrmLib; namespace UniVRM10 { @@ -31,7 +29,7 @@ public static int TypeCount(this string type) } } - public static int AddViewTo(this BufferAccessor self, + public static int AddViewTo(this VrmLib.BufferAccessor self, Vrm10Storage storage, int bufferIndex, int offset = 0, int count = 0) { @@ -44,7 +42,7 @@ public static int AddViewTo(this BufferAccessor self, return storage.AppendToBuffer(bufferIndex, slice, stride); } - static glTFAccessor CreateGltfAccessor(this BufferAccessor self, + static glTFAccessor CreateGltfAccessor(this VrmLib.BufferAccessor self, int viewIndex, int count = 0, int byteOffset = 0) { if (count == 0) @@ -61,7 +59,7 @@ static glTFAccessor CreateGltfAccessor(this BufferAccessor self, }; } - public static int AddAccessorTo(this BufferAccessor self, + public static int AddAccessorTo(this VrmLib.BufferAccessor self, Vrm10Storage storage, int viewIndex, Action, glTFAccessor> minMax = null, int offset = 0, int count = 0) @@ -77,15 +75,15 @@ public static int AddAccessorTo(this BufferAccessor self, return accessorIndex; } - public static int AddAccessorTo(this BufferAccessor self, + public static int AddAccessorTo(this VrmLib.BufferAccessor self, Vrm10Storage storage, int bufferIndex, // GltfBufferTargetType targetType, bool useSparse, Action, glTFAccessor> minMax = null, int offset = 0, int count = 0) { - if (self.ComponentType == AccessorValueType.FLOAT - && self.AccessorType == AccessorVectorType.VEC3 + if (self.ComponentType == VrmLib.AccessorValueType.FLOAT + && self.AccessorType == VrmLib.AccessorVectorType.VEC3 ) { var values = self.GetSpan(); @@ -107,9 +105,9 @@ public static int AddAccessorTo(this BufferAccessor self, { // use sparse var sparseIndexBin = new ArraySegment(new byte[sparseValuesWithIndex.Count * 4]); - var sparseIndexSpan = SpanLike.Wrap(sparseIndexBin); + var sparseIndexSpan = VrmLib.SpanLike.Wrap(sparseIndexBin); var sparseValueBin = new ArraySegment(new byte[sparseValuesWithIndex.Count * 12]); - var sparseValueSpan = SpanLike.Wrap(sparseValueBin); + var sparseValueSpan = VrmLib.SpanLike.Wrap(sparseValueBin); for (int i = 0; i < sparseValuesWithIndex.Count; ++i) { @@ -132,7 +130,7 @@ public static int AddAccessorTo(this BufferAccessor self, count = sparseValuesWithIndex.Count, indices = new glTFSparseIndices { - componentType = (glComponentType)AccessorValueType.UNSIGNED_INT, + componentType = (glComponentType)VrmLib.AccessorValueType.UNSIGNED_INT, bufferView = sparseIndexView, }, values = new glTFSparseValues diff --git a/Assets/VRM10/Runtime/IO/ImageAdapter.cs b/Assets/VRM10/Runtime/IO/ImageAdapter.cs index d7415c5f92..f678237d95 100644 --- a/Assets/VRM10/Runtime/IO/ImageAdapter.cs +++ b/Assets/VRM10/Runtime/IO/ImageAdapter.cs @@ -1,4 +1,3 @@ -using VrmLib; using System; using UniGLTF; @@ -6,7 +5,7 @@ namespace UniVRM10 { public static class ImageAdapter { - public static Image FromGltf(this glTFImage x, Vrm10Storage storage) + public static VrmLib.Image FromGltf(this glTFImage x, Vrm10Storage storage) { if (x.bufferView == -1) { @@ -19,24 +18,24 @@ public static Image FromGltf(this glTFImage x, Vrm10Storage storage) var buffer = storage.Gltf.buffers[view.buffer]; // テクスチャの用途を調べる - var usage = default(ImageUsage); + var usage = default(VrmLib.ImageUsage); foreach (var material in storage.Gltf.materials) { var colorImage = GetColorImage(storage, material); if (colorImage == x) { - usage |= ImageUsage.Color; + usage |= VrmLib.ImageUsage.Color; } var normalImage = GetNormalImage(storage, material); if (normalImage == x) { - usage |= ImageUsage.Normal; + usage |= VrmLib.ImageUsage.Normal; } } var memory = storage.GetBufferBytes(buffer); - return new Image(x.name, + return new VrmLib.Image(x.name, x.mimeType, usage, memory.Slice(view.byteOffset, view.byteLength)); @@ -86,7 +85,7 @@ static glTFImage GetNormalImage(Vrm10Storage storage, glTFMaterial m) return GetTexture(storage, index); } - public static glTFImage ToGltf(this Image src, Vrm10Storage storage) + public static glTFImage ToGltf(this VrmLib.Image src, Vrm10Storage storage) { var viewIndex = storage.AppendToBuffer(0, src.Bytes, 1); var gltf = storage.Gltf; diff --git a/Assets/VRM10/Runtime/IO/ModelExtensions.cs b/Assets/VRM10/Runtime/IO/ModelExtensions.cs index 97d1cdabc6..7ed669d129 100644 --- a/Assets/VRM10/Runtime/IO/ModelExtensions.cs +++ b/Assets/VRM10/Runtime/IO/ModelExtensions.cs @@ -13,7 +13,7 @@ public static byte[] ToGlb(this VrmLib.Model model) // vrm = false }; var glbBytes10 = exporter10.Export(model, option); - var glb10 = VrmLib.Glb.Parse(glbBytes10); + var glb10 = UniGLTF.Glb.Parse(glbBytes10); return glb10.ToBytes(); } } diff --git a/Assets/VRM10/Runtime/IO/Vrm10Exporter.cs b/Assets/VRM10/Runtime/IO/Vrm10Exporter.cs index 00f4b22afb..1e154dffb6 100644 --- a/Assets/VRM10/Runtime/IO/Vrm10Exporter.cs +++ b/Assets/VRM10/Runtime/IO/Vrm10Exporter.cs @@ -37,9 +37,7 @@ public byte[] ToBytes() UniGLTF.GltfSerializer.Serialize(f, Storage.Gltf); var json = f.GetStoreBytes(); - var glb = new VrmLib.Glb( - new VrmLib.GlbChunk(VrmLib.GlbChunkType.JSON, json), - new VrmLib.GlbChunk(VrmLib.GlbChunkType.BIN, Storage.Buffers[0].Bytes)); + var glb = UniGLTF.Glb.Create(json, Storage.Buffers[0].Bytes); return glb.ToBytes(); } diff --git a/Assets/VRM10/Runtime/IO/Vrm10Storage.cs b/Assets/VRM10/Runtime/IO/Vrm10Storage.cs index ae98a4ab8b..eaf4f26f1b 100644 --- a/Assets/VRM10/Runtime/IO/Vrm10Storage.cs +++ b/Assets/VRM10/Runtime/IO/Vrm10Storage.cs @@ -3,7 +3,6 @@ using System.Linq; using System.Numerics; using System.Runtime.InteropServices; -using UniGLTF; using VrmLib; using UniJSON; @@ -13,7 +12,7 @@ namespace UniVRM10 public class Vrm10Storage : IVrmStorage { public ArraySegment OriginalJson { get; private set; } - public glTF Gltf + public UniGLTF.glTF Gltf { get; private set; @@ -30,7 +29,7 @@ public glTF Gltf /// public Vrm10Storage() { - Gltf = new glTF() + Gltf = new UniGLTF.glTF() { extensionsUsed = new List(), }; @@ -78,7 +77,7 @@ public int AppendToBuffer(int bufferIndex, ArraySegment segment, int strid { Buffers[bufferIndex].Extend(segment, stride, out int offset, out int length); var viewIndex = Gltf.bufferViews.Count; - Gltf.bufferViews.Add(new glTFBufferView + Gltf.bufferViews.Add(new UniGLTF.glTFBufferView { buffer = 0, byteOffset = offset, @@ -176,14 +175,14 @@ public ArraySegment GetAccessorBytes(int accessorIndex) .Slice(sparse.values.byteOffset, accessor.GetStride() * sparse.count); ; - if (sparse.indices.componentType == (glComponentType)AccessorValueType.UNSIGNED_SHORT - && accessor.componentType == (glComponentType)AccessorValueType.FLOAT + if (sparse.indices.componentType == (UniGLTF.glComponentType)AccessorValueType.UNSIGNED_SHORT + && accessor.componentType == (UniGLTF.glComponentType)AccessorValueType.FLOAT && accessor.type == "VEC3") { return RestoreSparseAccessorUInt16(bytes, accessor.count, sparseIndexBytes, sparseValueBytes); } - if (sparse.indices.componentType == (glComponentType)AccessorValueType.UNSIGNED_INT - && accessor.componentType == (glComponentType)AccessorValueType.FLOAT + if (sparse.indices.componentType == (UniGLTF.glComponentType)AccessorValueType.UNSIGNED_INT + && accessor.componentType == (UniGLTF.glComponentType)AccessorValueType.FLOAT && accessor.type == "VEC3") { return RestoreSparseAccessorUInt32(bytes, accessor.count, sparseIndexBytes, sparseValueBytes); @@ -451,7 +450,7 @@ public Image CreateImage(int index) /// /// /// - private (Texture.TextureTypes, glTFMaterial) GetTextureType(int textureIndex) + private (Texture.TextureTypes, UniGLTF.glTFMaterial) GetTextureType(int textureIndex) { foreach (var material in Gltf.materials) { @@ -460,7 +459,7 @@ public Image CreateImage(int index) { if (material.normalTexture?.index == textureIndex) return (Texture.TextureTypes.NormalMap, material); } - else if (glTF_KHR_materials_unlit.IsEnable(material)) + else if (UniGLTF.glTF_KHR_materials_unlit.IsEnable(material)) { } else @@ -495,7 +494,7 @@ private Texture.ColorSpaceTypes GetTextureColorSpaceType(int textureIndex) if (material.normalTexture?.index == textureIndex) return Texture.ColorSpaceTypes.Linear; } - else if (glTF_KHR_materials_unlit.IsEnable(material)) + else if (UniGLTF.glTF_KHR_materials_unlit.IsEnable(material)) { // unlit if (material.pbrMetallicRoughness.baseColorTexture?.index == textureIndex) return Texture.ColorSpaceTypes.Srgb; @@ -522,7 +521,7 @@ public Texture CreateTexture(int index, List images) var sampler = (texture.sampler >= 0 && texture.sampler < Gltf.samplers.Count) ? Gltf.samplers[texture.sampler] - : new glTFTextureSampler() + : new UniGLTF.glTFTextureSampler() ; if (textureType.Item1 == Texture.TextureTypes.MetallicRoughness && textureType.Item2.pbrMetallicRoughness != null) @@ -786,7 +785,7 @@ public LookAt CreateVrmLookAt() return gltfVrm.LookAt.FromGltf(); } - public ArraySegment GetBufferBytes(glTFBufferView bufferView) + public ArraySegment GetBufferBytes(UniGLTF.glTFBufferView bufferView) { if (!bufferView.buffer.TryGetValidIndex(Gltf.buffers.Count, out int bufferViewBufferIndex)) { @@ -795,7 +794,7 @@ public ArraySegment GetBufferBytes(glTFBufferView bufferView) return GetBufferBytes(Gltf.buffers[bufferViewBufferIndex]); } - public ArraySegment GetBufferBytes(glTFBuffer buffer) + public ArraySegment GetBufferBytes(UniGLTF.glTFBuffer buffer) { int index = Gltf.buffers.IndexOf(buffer); return Buffers[index].Bytes; diff --git a/Assets/VRM10/Runtime/Scenes/ExportDebugUtil.cs b/Assets/VRM10/Runtime/Scenes/ExportDebugUtil.cs index a15d106033..f68cc24c0a 100644 --- a/Assets/VRM10/Runtime/Scenes/ExportDebugUtil.cs +++ b/Assets/VRM10/Runtime/Scenes/ExportDebugUtil.cs @@ -28,7 +28,7 @@ public static string GetJsonString(VrmLib.Model model) // vrm = false }; var glbBytes10 = exporter10.Export(model, option); - var glb10 = VrmLib.Glb.Parse(glbBytes10); + var glb10 = UniGLTF.Glb.Parse(glbBytes10); return System.Text.Encoding.UTF8.GetString(glb10.Json.Bytes.Array, glb10.Json.Bytes.Offset, glb10.Json.Bytes.Count); } } diff --git a/Assets/VRM10/Runtime/UnityBuilder/Editor/ScriptedImporter/GltfScriptedImporter.cs b/Assets/VRM10/Runtime/UnityBuilder/Editor/ScriptedImporter/GltfScriptedImporter.cs index f006ab7921..2faf89e8a8 100644 --- a/Assets/VRM10/Runtime/UnityBuilder/Editor/ScriptedImporter/GltfScriptedImporter.cs +++ b/Assets/VRM10/Runtime/UnityBuilder/Editor/ScriptedImporter/GltfScriptedImporter.cs @@ -83,7 +83,7 @@ public override void OnImportAsset(AssetImportContext ctx) private Model CreateGlbModel(string path) { var bytes = File.ReadAllBytes(path); - if (!VrmLib.Glb.TryParse(bytes, out VrmLib.Glb glb, out Exception ex)) + if (!UniGLTF.Glb.TryParse(bytes, out UniGLTF.Glb glb, out Exception ex)) { throw ex; } diff --git a/Assets/VRM10/Runtime/UnityBuilder/VrmLoader.cs b/Assets/VRM10/Runtime/UnityBuilder/VrmLoader.cs index f2889f8f4b..1c01594759 100644 --- a/Assets/VRM10/Runtime/UnityBuilder/VrmLoader.cs +++ b/Assets/VRM10/Runtime/UnityBuilder/VrmLoader.cs @@ -24,7 +24,7 @@ public static Model CreateVrmModel(string path) public static Model CreateVrmModel(byte[] bytes, FileInfo path) { - if (!Glb.TryParse(bytes, out Glb glb, out Exception ex)) + if (!UniGLTF.Glb.TryParse(bytes, out UniGLTF.Glb glb, out Exception ex)) { throw ex; } diff --git a/Assets/VRM10/Tests.PlayMode/ApiSampleTests.cs b/Assets/VRM10/Tests.PlayMode/ApiSampleTests.cs index 3a2a6a527a..c497474bd4 100644 --- a/Assets/VRM10/Tests.PlayMode/ApiSampleTests.cs +++ b/Assets/VRM10/Tests.PlayMode/ApiSampleTests.cs @@ -11,7 +11,7 @@ VrmLib.Model ReadModel(string path) { var bytes = File.ReadAllBytes(path); - if (!VrmLib.Glb.TryParse(bytes, out VrmLib.Glb glb, out Exception ex)) + if (!UniGLTF.Glb.TryParse(bytes, out UniGLTF.Glb glb, out Exception ex)) { Debug.LogError($"fail to Glb.TryParse: {path} => {ex}"); return null; diff --git a/Assets/VRM10/Tests.PlayMode/VRM10.Tests.PlayMode.asmdef b/Assets/VRM10/Tests.PlayMode/VRM10.Tests.PlayMode.asmdef index 337fbe31ce..180062d21c 100644 --- a/Assets/VRM10/Tests.PlayMode/VRM10.Tests.PlayMode.asmdef +++ b/Assets/VRM10/Tests.PlayMode/VRM10.Tests.PlayMode.asmdef @@ -2,7 +2,8 @@ "name": "VRM10.Tests.PlayMode", "references": [ "VrmLib", - "VRM10" + "VRM10", + "UniGLTF" ], "optionalUnityReferences": [ "TestAssemblies" diff --git a/Assets/VRM10/vrmlib/Runtime/Extensions/ArraySegmentExtensions.cs b/Assets/VRM10/vrmlib/Runtime/Extensions/ArraySegmentExtensions.cs new file mode 100644 index 0000000000..a137534d50 --- /dev/null +++ b/Assets/VRM10/vrmlib/Runtime/Extensions/ArraySegmentExtensions.cs @@ -0,0 +1,29 @@ +using System; + +namespace VrmLib +{ + public static class ArraySegmentExtensions + { + public static ArraySegment Slice(this ArraySegment self, int start, int length) + { + if (start + length > self.Count) + { + throw new ArgumentOutOfRangeException(); + } + return new ArraySegment( + self.Array, + self.Offset + start, + length + ); + } + + public static ArraySegment Slice(this ArraySegment self, int start) + { + if (start > self.Count) + { + throw new ArgumentOutOfRangeException(); + } + return self.Slice(start, self.Count - start); + } + } +} diff --git a/Assets/VRM10/vrmlib/Runtime/ImportExport/Glb.cs.meta b/Assets/VRM10/vrmlib/Runtime/Extensions/ArraySegmentExtensions.cs.meta similarity index 83% rename from Assets/VRM10/vrmlib/Runtime/ImportExport/Glb.cs.meta rename to Assets/VRM10/vrmlib/Runtime/Extensions/ArraySegmentExtensions.cs.meta index 6a6b3fe5f7..06000f6f4c 100644 --- a/Assets/VRM10/vrmlib/Runtime/ImportExport/Glb.cs.meta +++ b/Assets/VRM10/vrmlib/Runtime/Extensions/ArraySegmentExtensions.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: e8b6e06dd9822ef41bab155e172fe857 +guid: eb18d59756b3d844d8dddda3ab391541 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/VRM10/vrmlib/Runtime/ImportExport/Glb.cs b/Assets/VRM10/vrmlib/Runtime/ImportExport/Glb.cs deleted file mode 100644 index 7d8b1c7794..0000000000 --- a/Assets/VRM10/vrmlib/Runtime/ImportExport/Glb.cs +++ /dev/null @@ -1,263 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; - -namespace VrmLib -{ - /// https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#glb-file-format-specification - - public static class GlbHeader - { - public static readonly byte[] GLB_MAGIC = new byte[] { 0x67, 0x6C, 0x54, 0x46 }; // "glTF" - public static readonly byte[] GLB_VERSION = new byte[] { 2, 0, 0, 0 }; - - public static void WriteTo(Stream s) - { - s.Write(GLB_MAGIC, 0, GLB_MAGIC.Length); - s.Write(GLB_VERSION, 0, GLB_VERSION.Length); - } - - public static int TryParse(ArraySegment bytes, out int pos, out Exception message) - { - pos = 0; - - if (!bytes.Slice(0, 4).SequenceEqual(GLB_MAGIC)) - { - message = new FormatException("invalid magic"); - return 0; - } - pos += 4; - - if (!bytes.Slice(pos, 4).SequenceEqual(GLB_VERSION)) - { - message = new FormatException("invalid magic"); - return 0; - } - pos += 4; - - var totalLength = BitConverter.ToInt32(bytes.Array, bytes.Offset + pos); - pos += 4; - - message = null; - return totalLength; - } - } - - public enum GlbChunkType : uint - { - JSON = 0x4E4F534A, - BIN = 0x004E4942, - } - - public struct GlbChunk - { - public GlbChunkType ChunkType; - public ArraySegment Bytes; - - public GlbChunk(GlbChunkType type, ArraySegment bytes) - { - ChunkType = type; - Bytes = bytes; - } - - public static GlbChunk CreateJson(string json) - { - return CreateJson(new ArraySegment(Encoding.UTF8.GetBytes(json))); - } - - public static GlbChunk CreateJson(ArraySegment bytes) - { - return new GlbChunk(GlbChunkType.JSON, bytes); - } - - public static GlbChunk CreateBin(ArraySegment bytes) - { - return new GlbChunk(GlbChunkType.BIN, bytes); - } - - byte GetPaddingByte() - { - // chunk type - switch (ChunkType) - { - case GlbChunkType.JSON: - return 0x20; - - case GlbChunkType.BIN: - return 0x00; - - default: - throw new Exception("unknown chunk type: " + ChunkType); - } - } - - public int WriteTo(Stream s) - { - // padding - var paddingValue = Bytes.Count % 4; - var padding = (paddingValue > 0) ? 4 - paddingValue : 0; - - // size - var bytes = BitConverter.GetBytes((int)(Bytes.Count + padding)); - s.Write(bytes, 0, bytes.Length); - - // chunk type - switch (ChunkType) - { - case GlbChunkType.JSON: - s.WriteByte((byte)'J'); - s.WriteByte((byte)'S'); - s.WriteByte((byte)'O'); - s.WriteByte((byte)'N'); - break; - - case GlbChunkType.BIN: - s.WriteByte((byte)'B'); - s.WriteByte((byte)'I'); - s.WriteByte((byte)'N'); - s.WriteByte((byte)0); - break; - - default: - throw new Exception("unknown chunk type: " + ChunkType); - } - - // body - s.Write(Bytes.Array, Bytes.Offset, Bytes.Count); - - // 4byte align - var pad = GetPaddingByte(); - for (int i = 0; i < padding; ++i) - { - s.WriteByte(pad); - } - - return 4 + 4 + Bytes.Count + padding; - } - } - - public struct Glb - { - public readonly GlbChunk Json; - public readonly GlbChunk Binary; - - public Glb(GlbChunk json, GlbChunk binary) - { - if (json.ChunkType != GlbChunkType.JSON) throw new ArgumentException(); - Json = json; - if (binary.ChunkType != GlbChunkType.BIN) throw new ArgumentException(); - Binary = binary; - } - - public byte[] ToBytes() - { - using (var s = new MemoryStream()) - { - GlbHeader.WriteTo(s); - - var pos = s.Position; - s.Position += 4; // skip total size - - int size = 12; - - { - size += Json.WriteTo(s); - } - { - size += Binary.WriteTo(s); - } - - s.Position = pos; - var bytes = BitConverter.GetBytes(size); - s.Write(bytes, 0, bytes.Length); - - return s.ToArray(); - } - } - - public static GlbChunkType ToChunkType(string src) - { - switch (src) - { - case "BIN": - return GlbChunkType.BIN; - - case "JSON": - return GlbChunkType.JSON; - - default: - throw new FormatException("unknown chunk type: " + src); - } - } - - public static Glb Parse(Byte[] bytes) - { - if (TryParse(bytes, out Glb glb, out Exception ex)) - { - return glb; - } - else - { - throw ex; - } - } - - public static bool TryParse(Byte[] bytes, out Glb glb, out Exception ex) - { - return TryParse(new ArraySegment(bytes), out glb, out ex); - } - - public static bool TryParse(ArraySegment bytes, out Glb glb, out Exception ex) - { - glb = default(Glb); - if (bytes.Count == 0) - { - ex = new Exception("empty bytes"); - return false; - } - - var length = GlbHeader.TryParse(bytes, out int pos, out ex); - if (length == 0) - { - return false; - } - bytes = bytes.Slice(0, length); - - try - { - var chunks = new List(); - while (pos < bytes.Count) - { - var chunkDataSize = BitConverter.ToInt32(bytes.Array, bytes.Offset + pos); - pos += 4; - - //var type = (GlbChunkType)BitConverter.ToUInt32(bytes, pos); - var chunkTypeBytes = bytes.Slice(pos, 4).Where(x => x != 0).ToArray(); - var chunkTypeStr = Encoding.ASCII.GetString(chunkTypeBytes); - var type = ToChunkType(chunkTypeStr); - pos += 4; - - chunks.Add(new GlbChunk - { - ChunkType = type, - Bytes = bytes.Slice(pos, chunkDataSize) - }); - - pos += chunkDataSize; - } - - glb = new Glb(chunks[0], chunks[1]); - return true; - } - catch (Exception _ex) - { - ex = _ex; - return false; - } - } - - - } -} diff --git a/Assets/VRM10/vrmlib/Runtime/SpanLike.cs b/Assets/VRM10/vrmlib/Runtime/SpanLike.cs index 7ab5b24bc2..70f128331b 100644 --- a/Assets/VRM10/vrmlib/Runtime/SpanLike.cs +++ b/Assets/VRM10/vrmlib/Runtime/SpanLike.cs @@ -187,31 +187,6 @@ public static void Deconstruct(this KeyValuePair pair, out T key, ou } } - public static class ArraySegmentExtensions - { - public static ArraySegment Slice(this ArraySegment self, int start, int length) - { - if (start + length > self.Count) - { - throw new ArgumentOutOfRangeException(); - } - return new ArraySegment( - self.Array, - self.Offset + start, - length - ); - } - - public static ArraySegment Slice(this ArraySegment self, int start) - { - if (start > self.Count) - { - throw new ArgumentOutOfRangeException(); - } - return self.Slice(start, self.Count - start); - } - } - public struct SpanLike : IEquatable>, IEnumerable where T : struct { From 00b3c26834e94ace0600a6f98de8b9f58709498f Mon Sep 17 00:00:00 2001 From: ousttrue Date: Wed, 20 Jan 2021 15:20:52 +0900 Subject: [PATCH 08/22] init Migration #652 --- .../Runtime/UniGLTF/Format/glbTypes.cs | 5 ++ Assets/VRM10/Runtime/Migration.meta | 8 +++ Assets/VRM10/Runtime/Migration/Migration.cs | 60 +++++++++++++++++++ .../VRM10/Runtime/Migration/Migration.cs.meta | 11 ++++ Assets/VRM10/Tests/MigrationTests.cs | 47 +++++++++++++++ Assets/VRM10/Tests/MigrationTests.cs.meta | 11 ++++ 6 files changed, 142 insertions(+) create mode 100644 Assets/VRM10/Runtime/Migration.meta create mode 100644 Assets/VRM10/Runtime/Migration/Migration.cs create mode 100644 Assets/VRM10/Runtime/Migration/Migration.cs.meta create mode 100644 Assets/VRM10/Tests/MigrationTests.cs create mode 100644 Assets/VRM10/Tests/MigrationTests.cs.meta diff --git a/Assets/UniGLTF/Runtime/UniGLTF/Format/glbTypes.cs b/Assets/UniGLTF/Runtime/UniGLTF/Format/glbTypes.cs index cb10dd6dfb..2b8e0bf4ab 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/Format/glbTypes.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/Format/glbTypes.cs @@ -219,6 +219,11 @@ public static GlbChunkType ToChunkType(string src) } public static Glb Parse(Byte[] bytes) + { + return Parse(new ArraySegment(bytes)); + } + + public static Glb Parse(ArraySegment bytes) { if (TryParse(bytes, out Glb glb, out Exception ex)) { diff --git a/Assets/VRM10/Runtime/Migration.meta b/Assets/VRM10/Runtime/Migration.meta new file mode 100644 index 0000000000..26398a4090 --- /dev/null +++ b/Assets/VRM10/Runtime/Migration.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 475aa606f7fac0648a504be5102a6f16 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/VRM10/Runtime/Migration/Migration.cs b/Assets/VRM10/Runtime/Migration/Migration.cs new file mode 100644 index 0000000000..8f15afb7b5 --- /dev/null +++ b/Assets/VRM10/Runtime/Migration/Migration.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using UniGLTF.Extensions.VRMC_vrm; +using UniJSON; + +namespace UniVRM10 +{ + /// + /// Convert vrm0 binary to vrm1 binary. Json processing + /// + public static class Migration + { + static bool TryGet(this UniGLTF.glTFExtensionImport extensions, string key, out ListTreeNode value) + { + foreach (var kv in extensions.ObjectItems()) + { + if (kv.Key.GetString() == key) + { + value = kv.Value; + return true; + } + } + + value = default; + return false; + } + + public static byte[] Migrate(byte[] src) + { + var glb = UniGLTF.Glb.Parse(src); + var json = glb.Json.Bytes.ParseAsJson(); + + var gltf = UniGLTF.GltfDeserializer.Deserialize(json); + if (!(gltf.extensions is UniGLTF.glTFExtensionImport import)) + { + throw new Exception("not extensions"); + } + if (!import.TryGet("VRM", out ListTreeNode vrm)) + { + throw new Exception("no vrm"); + } + + { + var vrm1 = new VRMC_vrm(); + var f = new JsonFormatter(); + GltfSerializer.Serialize(f, vrm1); + gltf.extensions = new UniGLTF.glTFExtensionExport().Add(VRMC_vrm.ExtensionName, f.GetStoreBytes()); + } + + ArraySegment vrm1Json = default; + { + var f = new JsonFormatter(); + UniGLTF.GltfSerializer.Serialize(f, gltf); + vrm1Json = f.GetStoreBytes(); + } + + return UniGLTF.Glb.Create(vrm1Json, glb.Binary.Bytes).ToBytes(); + } + } +} diff --git a/Assets/VRM10/Runtime/Migration/Migration.cs.meta b/Assets/VRM10/Runtime/Migration/Migration.cs.meta new file mode 100644 index 0000000000..09c3438043 --- /dev/null +++ b/Assets/VRM10/Runtime/Migration/Migration.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ab1292ee15555c249af9108c10133c99 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/VRM10/Tests/MigrationTests.cs b/Assets/VRM10/Tests/MigrationTests.cs new file mode 100644 index 0000000000..fd70d6b45c --- /dev/null +++ b/Assets/VRM10/Tests/MigrationTests.cs @@ -0,0 +1,47 @@ +using System.IO; +using NUnit.Framework; +using UnityEngine; +using UniJSON; + +namespace UniVRM10 +{ + public class MigrationTests + { + static string AliciaPath + { + get + { + return Path.GetFullPath(Application.dataPath + "/../Tests/Models/Alicia_vrm-0.51/AliciaSolid_vrm-0.51.vrm") + .Replace("\\", "/"); + } + } + + UniGLTF.Extensions.VRMC_vrm.VRMC_vrm GetVRM(UniGLTF.glTFExtension extensions) + { + if (extensions is UniGLTF.glTFExtensionImport import) + { + foreach (var kv in import.ObjectItems()) + { + if (kv.Key.GetUtf8String() == UniGLTF.Extensions.VRMC_vrm.VRMC_vrm.ExtensionNameUtf8) + { + return UniGLTF.Extensions.VRMC_vrm.GltfDeserializer.Deserialize(kv.Value); + } + } + } + + return default; + } + + [Test] + public void Migrate0to1() + { + var vrm0 = File.ReadAllBytes(AliciaPath); + var vrm1 = Migration.Migrate(vrm0); + var glb = UniGLTF.Glb.Parse(vrm1); + var json = glb.Json.Bytes.ParseAsJson(); + var gltf = UniGLTF.GltfDeserializer.Deserialize(json); + var vrm = GetVRM(gltf.extensions); + Assert.NotNull(vrm); + } + } +} diff --git a/Assets/VRM10/Tests/MigrationTests.cs.meta b/Assets/VRM10/Tests/MigrationTests.cs.meta new file mode 100644 index 0000000000..2bfe03e08b --- /dev/null +++ b/Assets/VRM10/Tests/MigrationTests.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 856d7b1293642ed4dbce5341b397b74e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From 2d5b5a4cfd6912e9769b454c560ef12b2801a839 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Wed, 20 Jan 2021 21:09:17 +0900 Subject: [PATCH 09/22] WIP MigrateHumanoid --- Assets/VRM10/Runtime/Migration/Migration.cs | 182 ++++++++++++++++++++ Assets/VRM10/Tests/MigrationTests.cs | 23 ++- 2 files changed, 200 insertions(+), 5 deletions(-) diff --git a/Assets/VRM10/Runtime/Migration/Migration.cs b/Assets/VRM10/Runtime/Migration/Migration.cs index 8f15afb7b5..16b042c3e5 100644 --- a/Assets/VRM10/Runtime/Migration/Migration.cs +++ b/Assets/VRM10/Runtime/Migration/Migration.cs @@ -25,6 +25,108 @@ static bool TryGet(this UniGLTF.glTFExtensionImport extensions, string key, out return false; } + // { + // "bone": "hips", + // "node": 14, + // "useDefaultValues": true, + // "min": { + // "x": 0, + // "y": 0, + // "z": 0 + // }, + // "max": { + // "x": 0, + // "y": 0, + // "z": 0 + // }, + // "center": { + // "x": 0, + // "y": 0, + // "z": 0 + // }, + // "axisLength": 0 + // }, + static UniGLTF.Extensions.VRMC_vrm.HumanBone MigrateHumanoidBone(ListTreeNode vrm0) + { + return new HumanBone + { + Node = vrm0["node"].GetInt32(), + }; + } + + static UniGLTF.Extensions.VRMC_vrm.Humanoid MigrateHumanoid(ListTreeNode vrm0) + { + var humanoid = new UniGLTF.Extensions.VRMC_vrm.Humanoid + { + HumanBones = new HumanBones() + }; + + foreach (var humanoidBone in vrm0["humanBones"].ArrayItems()) + { + var boneType = humanoidBone["bone"].GetString(); + switch (boneType) + { + case "hips": humanoid.HumanBones.Hips = MigrateHumanoidBone(humanoidBone); break; + case "leftUpperLeg,": break; + case "rightUpperLeg,": break; + case "leftLowerLeg,": break; + case "rightLowerLeg,": break; + case "leftFoot,": break; + case "rightFoot,": break; + case "spine,": break; + case "chest,": break; + case "neck,": break; + case "head,": break; + case "leftShoulder,": break; + case "rightShoulder,": break; + case "leftUpperArm,": break; + case "rightUpperArm,": break; + case "leftLowerArm,": break; + case "rightLowerArm,": break; + case "leftHand,": break; + case "rightHand,": break; + case "leftToes,": break; + case "rightToes,": break; + case "leftEye,": break; + case "rightEye,": break; + case "jaw,": break; + case "leftThumbProximal,": break; + case "leftThumbIntermediate,": break; + case "leftThumbDistal,": break; + case "leftIndexProximal,": break; + case "leftIndexIntermediate,": break; + case "leftIndexDistal,": break; + case "leftMiddleProximal,": break; + case "leftMiddleIntermediate,": break; + case "leftMiddleDistal,": break; + case "leftRingProximal,": break; + case "leftRingIntermediate,": break; + case "leftRingDistal,": break; + case "leftLittleProximal,": break; + case "leftLittleIntermediate,": break; + case "leftLittleDistal,": break; + case "rightThumbProximal,": break; + case "rightThumbIntermediate,": break; + case "rightThumbDistal,": break; + case "rightIndexProximal,": break; + case "rightIndexIntermediate,": break; + case "rightIndexDistal,": break; + case "rightMiddleProximal,": break; + case "rightMiddleIntermediate,": break; + case "rightMiddleDistal,": break; + case "rightRingProximal,": break; + case "rightRingIntermediate,": break; + case "rightRingDistal,": break; + case "rightLittleProximal,": break; + case "rightLittleIntermediate,": break; + case "rightLittleDistal,": break; + case "upperChest,": break; + } + } + + return humanoid; + } + public static byte[] Migrate(byte[] src) { var glb = UniGLTF.Glb.Parse(src); @@ -42,6 +144,9 @@ public static byte[] Migrate(byte[] src) { var vrm1 = new VRMC_vrm(); + var vrm0 = json["extensions"]["VRM"]; + vrm1.Humanoid = MigrateHumanoid(vrm0["humanoid"]); + var f = new JsonFormatter(); GltfSerializer.Serialize(f, vrm1); gltf.extensions = new UniGLTF.glTFExtensionExport().Add(VRMC_vrm.ExtensionName, f.GetStoreBytes()); @@ -56,5 +161,82 @@ public static byte[] Migrate(byte[] src) return UniGLTF.Glb.Create(vrm1Json, glb.Binary.Bytes).ToBytes(); } + + #region for UnitTest + public static void CheckBone(string bone, ListTreeNode vrm0, UniGLTF.Extensions.VRMC_vrm.HumanBone vrm1) + { + var vrm0NodeIndex = vrm0["node"].GetInt32(); + if (vrm0NodeIndex != vrm1.Node) + { + throw new Exception($"different {bone}: {vrm0NodeIndex} != {vrm1.Node}"); + } + } + + public static void CheckHumanoid(ListTreeNode vrm0, UniGLTF.Extensions.VRMC_vrm.Humanoid vrm1) + { + foreach (var humanoidBone in vrm0["humanBones"].ArrayItems()) + { + var boneType = humanoidBone["bone"].GetString(); + switch (boneType) + { + case "hips": CheckBone(boneType, humanoidBone, vrm1.HumanBones.Hips); break; + case "leftUpperLeg,": break; + case "rightUpperLeg,": break; + case "leftLowerLeg,": break; + case "rightLowerLeg,": break; + case "leftFoot,": break; + case "rightFoot,": break; + case "spine,": break; + case "chest,": break; + case "neck,": break; + case "head,": break; + case "leftShoulder,": break; + case "rightShoulder,": break; + case "leftUpperArm,": break; + case "rightUpperArm,": break; + case "leftLowerArm,": break; + case "rightLowerArm,": break; + case "leftHand,": break; + case "rightHand,": break; + case "leftToes,": break; + case "rightToes,": break; + case "leftEye,": break; + case "rightEye,": break; + case "jaw,": break; + case "leftThumbProximal,": break; + case "leftThumbIntermediate,": break; + case "leftThumbDistal,": break; + case "leftIndexProximal,": break; + case "leftIndexIntermediate,": break; + case "leftIndexDistal,": break; + case "leftMiddleProximal,": break; + case "leftMiddleIntermediate,": break; + case "leftMiddleDistal,": break; + case "leftRingProximal,": break; + case "leftRingIntermediate,": break; + case "leftRingDistal,": break; + case "leftLittleProximal,": break; + case "leftLittleIntermediate,": break; + case "leftLittleDistal,": break; + case "rightThumbProximal,": break; + case "rightThumbIntermediate,": break; + case "rightThumbDistal,": break; + case "rightIndexProximal,": break; + case "rightIndexIntermediate,": break; + case "rightIndexDistal,": break; + case "rightMiddleProximal,": break; + case "rightMiddleIntermediate,": break; + case "rightMiddleDistal,": break; + case "rightRingProximal,": break; + case "rightRingIntermediate,": break; + case "rightRingDistal,": break; + case "rightLittleProximal,": break; + case "rightLittleIntermediate,": break; + case "rightLittleDistal,": break; + case "upperChest,": break; + } + } + } + #endregion } } diff --git a/Assets/VRM10/Tests/MigrationTests.cs b/Assets/VRM10/Tests/MigrationTests.cs index fd70d6b45c..12c6b0e2d6 100644 --- a/Assets/VRM10/Tests/MigrationTests.cs +++ b/Assets/VRM10/Tests/MigrationTests.cs @@ -2,6 +2,7 @@ using NUnit.Framework; using UnityEngine; using UniJSON; +using System; namespace UniVRM10 { @@ -16,7 +17,7 @@ static string AliciaPath } } - UniGLTF.Extensions.VRMC_vrm.VRMC_vrm GetVRM(UniGLTF.glTFExtension extensions) + UniGLTF.Extensions.VRMC_vrm.VRMC_vrm GetVRMC_vrm(UniGLTF.glTFExtension extensions) { if (extensions is UniGLTF.glTFExtensionImport import) { @@ -32,16 +33,28 @@ UniGLTF.Extensions.VRMC_vrm.VRMC_vrm GetVRM(UniGLTF.glTFExtension extensions) return default; } + + static ListTreeNode GetVRM0(byte[] bytes) + { + var glb = UniGLTF.Glb.Parse(bytes); + var json = glb.Json.Bytes.ParseAsJson(); + return json["extensions"]["VRM"]; + } + [Test] public void Migrate0to1() { - var vrm0 = File.ReadAllBytes(AliciaPath); - var vrm1 = Migration.Migrate(vrm0); + var vrm0Bytes = File.ReadAllBytes(AliciaPath); + var vrm0Json = GetVRM0(vrm0Bytes); + + var vrm1 = Migration.Migrate(vrm0Bytes); var glb = UniGLTF.Glb.Parse(vrm1); var json = glb.Json.Bytes.ParseAsJson(); var gltf = UniGLTF.GltfDeserializer.Deserialize(json); - var vrm = GetVRM(gltf.extensions); - Assert.NotNull(vrm); + var VRMC_vrm = GetVRMC_vrm(gltf.extensions); + Assert.NotNull(VRMC_vrm); + + Migration.CheckHumanoid(vrm0Json["humanoid"], VRMC_vrm.Humanoid); } } } From 0c8161d4eff89fd017edddedf1d72fc160f67e27 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Wed, 20 Jan 2021 21:47:26 +0900 Subject: [PATCH 10/22] implement humanoid migration --- Assets/VRM10/Runtime/Migration/Migration.cs | 218 ++++++++++---------- Assets/VRM10/Tests/MigrationTests.cs | 1 - 2 files changed, 110 insertions(+), 109 deletions(-) diff --git a/Assets/VRM10/Runtime/Migration/Migration.cs b/Assets/VRM10/Runtime/Migration/Migration.cs index 16b042c3e5..fca7cc5a64 100644 --- a/Assets/VRM10/Runtime/Migration/Migration.cs +++ b/Assets/VRM10/Runtime/Migration/Migration.cs @@ -67,60 +67,60 @@ static UniGLTF.Extensions.VRMC_vrm.Humanoid MigrateHumanoid(ListTreeNode vrm0, UniGLTF.Extension switch (boneType) { case "hips": CheckBone(boneType, humanoidBone, vrm1.HumanBones.Hips); break; - case "leftUpperLeg,": break; - case "rightUpperLeg,": break; - case "leftLowerLeg,": break; - case "rightLowerLeg,": break; - case "leftFoot,": break; - case "rightFoot,": break; - case "spine,": break; - case "chest,": break; - case "neck,": break; - case "head,": break; - case "leftShoulder,": break; - case "rightShoulder,": break; - case "leftUpperArm,": break; - case "rightUpperArm,": break; - case "leftLowerArm,": break; - case "rightLowerArm,": break; - case "leftHand,": break; - case "rightHand,": break; - case "leftToes,": break; - case "rightToes,": break; - case "leftEye,": break; - case "rightEye,": break; - case "jaw,": break; - case "leftThumbProximal,": break; - case "leftThumbIntermediate,": break; - case "leftThumbDistal,": break; - case "leftIndexProximal,": break; - case "leftIndexIntermediate,": break; - case "leftIndexDistal,": break; - case "leftMiddleProximal,": break; - case "leftMiddleIntermediate,": break; - case "leftMiddleDistal,": break; - case "leftRingProximal,": break; - case "leftRingIntermediate,": break; - case "leftRingDistal,": break; - case "leftLittleProximal,": break; - case "leftLittleIntermediate,": break; - case "leftLittleDistal,": break; - case "rightThumbProximal,": break; - case "rightThumbIntermediate,": break; - case "rightThumbDistal,": break; - case "rightIndexProximal,": break; - case "rightIndexIntermediate,": break; - case "rightIndexDistal,": break; - case "rightMiddleProximal,": break; - case "rightMiddleIntermediate,": break; - case "rightMiddleDistal,": break; - case "rightRingProximal,": break; - case "rightRingIntermediate,": break; - case "rightRingDistal,": break; - case "rightLittleProximal,": break; - case "rightLittleIntermediate,": break; - case "rightLittleDistal,": break; - case "upperChest,": break; + case "leftUpperLeg": CheckBone(boneType, humanoidBone, vrm1.HumanBones.LeftUpperLeg); break; + case "rightUpperLeg": CheckBone(boneType, humanoidBone, vrm1.HumanBones.RightUpperLeg); break; + case "leftLowerLeg": CheckBone(boneType, humanoidBone, vrm1.HumanBones.LeftLowerLeg); break; + case "rightLowerLeg": CheckBone(boneType, humanoidBone, vrm1.HumanBones.RightLowerLeg); break; + case "leftFoot": CheckBone(boneType, humanoidBone, vrm1.HumanBones.LeftFoot); break; + case "rightFoot": CheckBone(boneType, humanoidBone, vrm1.HumanBones.RightFoot); break; + case "spine": CheckBone(boneType, humanoidBone, vrm1.HumanBones.Spine); break; + case "chest": CheckBone(boneType, humanoidBone, vrm1.HumanBones.Chest); break; + case "neck": CheckBone(boneType, humanoidBone, vrm1.HumanBones.Neck); break; + case "head": CheckBone(boneType, humanoidBone, vrm1.HumanBones.Head); break; + case "leftShoulder": CheckBone(boneType, humanoidBone, vrm1.HumanBones.LeftShoulder); break; + case "rightShoulder": CheckBone(boneType, humanoidBone, vrm1.HumanBones.RightShoulder); break; + case "leftUpperArm": CheckBone(boneType, humanoidBone, vrm1.HumanBones.LeftUpperArm); break; + case "rightUpperArm": CheckBone(boneType, humanoidBone, vrm1.HumanBones.RightUpperArm); break; + case "leftLowerArm": CheckBone(boneType, humanoidBone, vrm1.HumanBones.LeftLowerArm); break; + case "rightLowerArm": CheckBone(boneType, humanoidBone, vrm1.HumanBones.RightLowerArm); break; + case "leftHand": CheckBone(boneType, humanoidBone, vrm1.HumanBones.LeftHand); break; + case "rightHand": CheckBone(boneType, humanoidBone, vrm1.HumanBones.RightHand); break; + case "leftToes": CheckBone(boneType, humanoidBone, vrm1.HumanBones.LeftToes); break; + case "rightToes": CheckBone(boneType, humanoidBone, vrm1.HumanBones.RightToes); break; + case "leftEye": CheckBone(boneType, humanoidBone, vrm1.HumanBones.LeftEye); break; + case "rightEye": CheckBone(boneType, humanoidBone, vrm1.HumanBones.RightEye); break; + case "jaw": CheckBone(boneType, humanoidBone, vrm1.HumanBones.Jaw); break; + case "leftThumbProximal": CheckBone(boneType, humanoidBone, vrm1.HumanBones.LeftThumbProximal); break; + case "leftThumbIntermediate": CheckBone(boneType, humanoidBone, vrm1.HumanBones.LeftThumbIntermediate); break; + case "leftThumbDistal": CheckBone(boneType, humanoidBone, vrm1.HumanBones.LeftThumbDistal); break; + case "leftIndexProximal": CheckBone(boneType, humanoidBone, vrm1.HumanBones.LeftIndexProximal); break; + case "leftIndexIntermediate": CheckBone(boneType, humanoidBone, vrm1.HumanBones.LeftIndexIntermediate); break; + case "leftIndexDistal": CheckBone(boneType, humanoidBone, vrm1.HumanBones.LeftIndexDistal); break; + case "leftMiddleProximal": CheckBone(boneType, humanoidBone, vrm1.HumanBones.LeftMiddleProximal); break; + case "leftMiddleIntermediate": CheckBone(boneType, humanoidBone, vrm1.HumanBones.LeftMiddleIntermediate); break; + case "leftMiddleDistal": CheckBone(boneType, humanoidBone, vrm1.HumanBones.LeftMiddleDistal); break; + case "leftRingProximal": CheckBone(boneType, humanoidBone, vrm1.HumanBones.LeftRingProximal); break; + case "leftRingIntermediate": CheckBone(boneType, humanoidBone, vrm1.HumanBones.LeftRingIntermediate); break; + case "leftRingDistal": CheckBone(boneType, humanoidBone, vrm1.HumanBones.LeftRingDistal); break; + case "leftLittleProximal": CheckBone(boneType, humanoidBone, vrm1.HumanBones.LeftLittleProximal); break; + case "leftLittleIntermediate": CheckBone(boneType, humanoidBone, vrm1.HumanBones.LeftLittleIntermediate); break; + case "leftLittleDistal": CheckBone(boneType, humanoidBone, vrm1.HumanBones.LeftLittleDistal); break; + case "rightThumbProximal": CheckBone(boneType, humanoidBone, vrm1.HumanBones.RightThumbProximal); break; + case "rightThumbIntermediate": CheckBone(boneType, humanoidBone, vrm1.HumanBones.RightThumbIntermediate); break; + case "rightThumbDistal": CheckBone(boneType, humanoidBone, vrm1.HumanBones.RightThumbDistal); break; + case "rightIndexProximal": CheckBone(boneType, humanoidBone, vrm1.HumanBones.RightIndexProximal); break; + case "rightIndexIntermediate": CheckBone(boneType, humanoidBone, vrm1.HumanBones.RightIndexIntermediate); break; + case "rightIndexDistal": CheckBone(boneType, humanoidBone, vrm1.HumanBones.RightIndexDistal); break; + case "rightMiddleProximal": CheckBone(boneType, humanoidBone, vrm1.HumanBones.RightMiddleProximal); break; + case "rightMiddleIntermediate": CheckBone(boneType, humanoidBone, vrm1.HumanBones.RightMiddleIntermediate); break; + case "rightMiddleDistal": CheckBone(boneType, humanoidBone, vrm1.HumanBones.RightMiddleDistal); break; + case "rightRingProximal": CheckBone(boneType, humanoidBone, vrm1.HumanBones.RightRingProximal); break; + case "rightRingIntermediate": CheckBone(boneType, humanoidBone, vrm1.HumanBones.RightRingIntermediate); break; + case "rightRingDistal": CheckBone(boneType, humanoidBone, vrm1.HumanBones.RightRingDistal); break; + case "rightLittleProximal": CheckBone(boneType, humanoidBone, vrm1.HumanBones.RightLittleProximal); break; + case "rightLittleIntermediate": CheckBone(boneType, humanoidBone, vrm1.HumanBones.RightLittleIntermediate); break; + case "rightLittleDistal": CheckBone(boneType, humanoidBone, vrm1.HumanBones.RightLittleDistal); break; + case "upperChest": CheckBone(boneType, humanoidBone, vrm1.HumanBones.UpperChest); break; + default: + throw new NotImplementedException($"unknown bone: {boneType}"); } } } diff --git a/Assets/VRM10/Tests/MigrationTests.cs b/Assets/VRM10/Tests/MigrationTests.cs index 12c6b0e2d6..d08d31ae02 100644 --- a/Assets/VRM10/Tests/MigrationTests.cs +++ b/Assets/VRM10/Tests/MigrationTests.cs @@ -33,7 +33,6 @@ UniGLTF.Extensions.VRMC_vrm.VRMC_vrm GetVRMC_vrm(UniGLTF.glTFExtension extension return default; } - static ListTreeNode GetVRM0(byte[] bytes) { var glb = UniGLTF.Glb.Parse(bytes); From 564727e0f5cf12fd947418ecc480b79fa089e1a5 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Wed, 20 Jan 2021 21:47:38 +0900 Subject: [PATCH 11/22] fix --- Assets/VRM10/Runtime/IO/TextureAdapter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Assets/VRM10/Runtime/IO/TextureAdapter.cs b/Assets/VRM10/Runtime/IO/TextureAdapter.cs index 289825d8f6..d5c6f187c7 100644 --- a/Assets/VRM10/Runtime/IO/TextureAdapter.cs +++ b/Assets/VRM10/Runtime/IO/TextureAdapter.cs @@ -11,7 +11,7 @@ public static ImageTexture FromGltf(this glTFTexture x, glTFTextureSampler sampl { var image = images[x.source]; var name = !string.IsNullOrEmpty(x.name) ? x.name : image.Name; - return new ImageTexture(x.name, sampler.FromGltf(), image, colorSpace, textureType); + return new ImageTexture(name, sampler.FromGltf(), image, colorSpace, textureType); } public static TextureSampler FromGltf(this glTFTextureSampler sampler) From 24ff0d3fd1af65334cb599d696f324c01e0750bd Mon Sep 17 00:00:00 2001 From: ousttrue Date: Wed, 20 Jan 2021 21:47:56 +0900 Subject: [PATCH 12/22] MigrationMenu --- Assets/VRM10/Editor/MigrationMenu.cs | 46 +++++++++++++++++++++++ Assets/VRM10/Editor/MigrationMenu.cs.meta | 11 ++++++ 2 files changed, 57 insertions(+) create mode 100644 Assets/VRM10/Editor/MigrationMenu.cs create mode 100644 Assets/VRM10/Editor/MigrationMenu.cs.meta diff --git a/Assets/VRM10/Editor/MigrationMenu.cs b/Assets/VRM10/Editor/MigrationMenu.cs new file mode 100644 index 0000000000..d18c0ef3e9 --- /dev/null +++ b/Assets/VRM10/Editor/MigrationMenu.cs @@ -0,0 +1,46 @@ +using System.IO; +using UnityEditor; +using UnityEngine; + +namespace UniVRM10 +{ + public static class MigrationMenu + { + static string s_lastPath = Application.dataPath; + + const string CONTEXT_MENU = "Assets/Migration: Vrm1"; + + [MenuItem(CONTEXT_MENU, true)] + static bool Enable() + { + var path = UniGLTF.UnityPath.FromAsset(Selection.activeObject); + var isVrm = path.Extension.ToLower() == ".vrm"; + return isVrm; + } + + [MenuItem(CONTEXT_MENU, false)] + static void Exec() + { + var path = UniGLTF.UnityPath.FromAsset(Selection.activeObject); + var isVrm = path.Extension.ToLower() == ".vrm"; + + var vrm1Bytes = Migration.Migrate(File.ReadAllBytes(path.FullPath)); + + var dst = EditorUtility.SaveFilePanel( + "Save vrm1 file", + s_lastPath, + $"{path.FileName}_vrm1", + "vrm"); + if (string.IsNullOrEmpty(dst)) + { + return; + } + + s_lastPath = Path.GetDirectoryName(dst); + File.WriteAllBytes(dst, vrm1Bytes); + + // immediately import for GUI update + UniGLTF.UnityPath.FromFullpath(dst).ImportAsset(); + } + } +} diff --git a/Assets/VRM10/Editor/MigrationMenu.cs.meta b/Assets/VRM10/Editor/MigrationMenu.cs.meta new file mode 100644 index 0000000000..cc4e4ebc94 --- /dev/null +++ b/Assets/VRM10/Editor/MigrationMenu.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c0be718f3aba6ad4282a4b74eae9045b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From 7a9714fff51a3be4db5a7c246380d549b167db30 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Thu, 21 Jan 2021 14:29:04 +0900 Subject: [PATCH 13/22] MigrateMeta --- Assets/VRM10/Editor/MigrationMenu.cs | 5 +- Assets/VRM10/Runtime/Migration/Migration.cs | 103 +++++++++ .../Runtime/UnityBuilder/ComponentBuilder.cs | 200 +++++++++--------- 3 files changed, 208 insertions(+), 100 deletions(-) diff --git a/Assets/VRM10/Editor/MigrationMenu.cs b/Assets/VRM10/Editor/MigrationMenu.cs index d18c0ef3e9..c6f47a4e3f 100644 --- a/Assets/VRM10/Editor/MigrationMenu.cs +++ b/Assets/VRM10/Editor/MigrationMenu.cs @@ -29,14 +29,15 @@ static void Exec() var dst = EditorUtility.SaveFilePanel( "Save vrm1 file", s_lastPath, - $"{path.FileName}_vrm1", + $"{path.FileNameWithoutExtension}_vrm1", "vrm"); if (string.IsNullOrEmpty(dst)) { return; } - s_lastPath = Path.GetDirectoryName(dst); + + // write result File.WriteAllBytes(dst, vrm1Bytes); // immediately import for GUI update diff --git a/Assets/VRM10/Runtime/Migration/Migration.cs b/Assets/VRM10/Runtime/Migration/Migration.cs index fca7cc5a64..0b050fda52 100644 --- a/Assets/VRM10/Runtime/Migration/Migration.cs +++ b/Assets/VRM10/Runtime/Migration/Migration.cs @@ -127,6 +127,105 @@ static UniGLTF.Extensions.VRMC_vrm.Humanoid MigrateHumanoid(ListTreeNode vrm0) + { + var meta = new UniGLTF.Extensions.VRMC_vrm.Meta + { + AllowPoliticalOrReligiousUsage = false, + AllowExcessivelySexualUsage = false, + AllowExcessivelyViolentUsage = false, + AllowRedistribution = false, + AvatarPermission = AvatarPermissionType.onlyAuthor, + CommercialUsage = CommercialUsageType.personalNonProfit, + CreditNotation = CreditNotationType.required, + Modification = ModificationType.prohibited, + }; + + foreach (var kv in vrm0.ObjectItems()) + { + var key = kv.Key.GetString(); + switch (key) + { + case "title": meta.Name = kv.Value.GetString(); break; + case "version": meta.Version = kv.Value.GetString(); break; + case "author": meta.Authors = new List() { kv.Value.GetString() }; break; + case "contactInformation": meta.ContactInformation = kv.Value.GetString(); break; + case "reference": meta.References = new List() { kv.Value.GetString() }; break; + case "texture": meta.ThumbnailImage = kv.Value.GetInt32(); break; + + case "allowedUserName": + { + var allowdUserType = kv.Value.GetString(); + switch (allowdUserType) + { + case "Everyone": meta.AvatarPermission = AvatarPermissionType.everyone; break; + default: throw new NotImplementedException($"allowedUser: {allowdUserType}"); + } + } + break; + + case "violentUssageName": meta.AllowExcessivelyViolentUsage = kv.Value.GetString().ToLower() == "allow"; break; + case "sexualUssageName": meta.AllowExcessivelySexualUsage = kv.Value.GetString().ToLower() == "allow"; break; + case "commercialUssageName": + { + var commercialUssageType = kv.Value.GetString(); + switch (commercialUssageType) + { + case "Allow": meta.CommercialUsage = CommercialUsageType.personalProfit; break; + default: meta.CommercialUsage = CommercialUsageType.personalNonProfit; break; + } + } + break; + + case "otherPermissionUrl": + { + // TODO + // var url = kv.Value.GetString(); + // if (!String.IsNullOrWhiteSpace(url)) + // { + // throw new NotImplementedException("otherPermissionUrl not allowd"); + // } + } + break; + + case "otherLicenseUrl": meta.OtherLicenseUrl = kv.Value.GetString(); break; + + case "licenseName": + { + // TODO + // CreditNotation = CreditNotationType.required, + } + break; + + default: + throw new NotImplementedException(key); + } + } + + return meta; + } + public static byte[] Migrate(byte[] src) { var glb = UniGLTF.Glb.Parse(src); @@ -145,6 +244,10 @@ public static byte[] Migrate(byte[] src) { var vrm1 = new VRMC_vrm(); var vrm0 = json["extensions"]["VRM"]; + + // meta + vrm1.Meta = MigrateMeta(vrm0["meta"]); + // humanoid vrm1.Humanoid = MigrateHumanoid(vrm0["humanoid"]); var f = new JsonFormatter(); diff --git a/Assets/VRM10/Runtime/UnityBuilder/ComponentBuilder.cs b/Assets/VRM10/Runtime/UnityBuilder/ComponentBuilder.cs index eef5796347..33ca9cb1b9 100644 --- a/Assets/VRM10/Runtime/UnityBuilder/ComponentBuilder.cs +++ b/Assets/VRM10/Runtime/UnityBuilder/ComponentBuilder.cs @@ -184,127 +184,131 @@ public static void Build10(VrmLib.Model model, ModelAsset asset) // firstPerson { // VRMFirstPerson - controller.FirstPerson.Renderers = model.Vrm.FirstPerson.Annotations.Select(x => - new UniVRM10.RendererFirstPersonFlags() - { - Renderer = asset.Map.Renderers[x.Node], - FirstPersonFlag = x.FirstPersonFlag - } - ).ToList(); - - // VRMLookAtApplyer - controller.LookAt.OffsetFromHead = model.Vrm.LookAt.OffsetFromHeadBone.ToUnityVector3(); - if (model.Vrm.LookAt.LookAtType == VrmLib.LookAtType.Expression) + if (model.Vrm.FirstPerson != null) { - var lookAtApplyer = controller; - lookAtApplyer.LookAt.LookAtType = VRM10ControllerLookAt.LookAtTypes.Expression; - lookAtApplyer.LookAt.HorizontalOuter = new UniVRM10.CurveMapper( - model.Vrm.LookAt.HorizontalOuter.InputMaxValue, - model.Vrm.LookAt.HorizontalOuter.OutputScaling); - lookAtApplyer.LookAt.VerticalUp = new UniVRM10.CurveMapper( - model.Vrm.LookAt.VerticalUp.InputMaxValue, - model.Vrm.LookAt.VerticalUp.OutputScaling); - lookAtApplyer.LookAt.VerticalDown = new UniVRM10.CurveMapper( - model.Vrm.LookAt.VerticalDown.InputMaxValue, - model.Vrm.LookAt.VerticalDown.OutputScaling); - } - else if (model.Vrm.LookAt.LookAtType == VrmLib.LookAtType.Bone) - { - var lookAtBoneApplyer = controller; - lookAtBoneApplyer.LookAt.HorizontalInner = new UniVRM10.CurveMapper( - model.Vrm.LookAt.HorizontalInner.InputMaxValue, - model.Vrm.LookAt.HorizontalInner.OutputScaling); - lookAtBoneApplyer.LookAt.HorizontalOuter = new UniVRM10.CurveMapper( - model.Vrm.LookAt.HorizontalOuter.InputMaxValue, - model.Vrm.LookAt.HorizontalOuter.OutputScaling); - lookAtBoneApplyer.LookAt.VerticalUp = new UniVRM10.CurveMapper( - model.Vrm.LookAt.VerticalUp.InputMaxValue, - model.Vrm.LookAt.VerticalUp.OutputScaling); - lookAtBoneApplyer.LookAt.VerticalDown = new UniVRM10.CurveMapper( - model.Vrm.LookAt.VerticalDown.InputMaxValue, - model.Vrm.LookAt.VerticalDown.OutputScaling); + controller.FirstPerson.Renderers = model.Vrm.FirstPerson.Annotations.Select(x => + new UniVRM10.RendererFirstPersonFlags() + { + Renderer = asset.Map.Renderers[x.Node], + FirstPersonFlag = x.FirstPersonFlag + } + ).ToList(); } - else + + // VRMLookAtApplyer + if (model.Vrm.LookAt != null) { - throw new NotImplementedException(); + controller.LookAt.OffsetFromHead = model.Vrm.LookAt.OffsetFromHeadBone.ToUnityVector3(); + if (model.Vrm.LookAt.LookAtType == VrmLib.LookAtType.Expression) + { + var lookAtApplyer = controller; + lookAtApplyer.LookAt.LookAtType = VRM10ControllerLookAt.LookAtTypes.Expression; + lookAtApplyer.LookAt.HorizontalOuter = new UniVRM10.CurveMapper( + model.Vrm.LookAt.HorizontalOuter.InputMaxValue, + model.Vrm.LookAt.HorizontalOuter.OutputScaling); + lookAtApplyer.LookAt.VerticalUp = new UniVRM10.CurveMapper( + model.Vrm.LookAt.VerticalUp.InputMaxValue, + model.Vrm.LookAt.VerticalUp.OutputScaling); + lookAtApplyer.LookAt.VerticalDown = new UniVRM10.CurveMapper( + model.Vrm.LookAt.VerticalDown.InputMaxValue, + model.Vrm.LookAt.VerticalDown.OutputScaling); + } + else if (model.Vrm.LookAt.LookAtType == VrmLib.LookAtType.Bone) + { + var lookAtBoneApplyer = controller; + lookAtBoneApplyer.LookAt.HorizontalInner = new UniVRM10.CurveMapper( + model.Vrm.LookAt.HorizontalInner.InputMaxValue, + model.Vrm.LookAt.HorizontalInner.OutputScaling); + lookAtBoneApplyer.LookAt.HorizontalOuter = new UniVRM10.CurveMapper( + model.Vrm.LookAt.HorizontalOuter.InputMaxValue, + model.Vrm.LookAt.HorizontalOuter.OutputScaling); + lookAtBoneApplyer.LookAt.VerticalUp = new UniVRM10.CurveMapper( + model.Vrm.LookAt.VerticalUp.InputMaxValue, + model.Vrm.LookAt.VerticalUp.OutputScaling); + lookAtBoneApplyer.LookAt.VerticalDown = new UniVRM10.CurveMapper( + model.Vrm.LookAt.VerticalDown.InputMaxValue, + model.Vrm.LookAt.VerticalDown.OutputScaling); + } + else + { + throw new NotImplementedException(); + } } } // springBone + if (model.Vrm.SpringBone != null) { - if (model.Vrm.SpringBone != null) + foreach (var vrmSpring in model.Vrm.SpringBone.Springs) { - foreach (var vrmSpring in model.Vrm.SpringBone.Springs) + // create a spring + var springBone = new UniVRM10.VRM10SpringBone(); + springBone.m_comment = vrmSpring.Comment; + if (vrmSpring.Origin != null && asset.Map.Nodes.TryGetValue(vrmSpring.Origin, out GameObject origin)) { - // create a spring - var springBone = new UniVRM10.VRM10SpringBone(); - springBone.m_comment = vrmSpring.Comment; - if (vrmSpring.Origin != null && asset.Map.Nodes.TryGetValue(vrmSpring.Origin, out GameObject origin)) + springBone.m_center = origin.transform; + } + controller.SpringBone.Springs.Add(springBone); + + // create colliders for the spring + foreach (var vrmSpringBoneCollider in vrmSpring.Colliders) + { + var go = asset.Map.Nodes[vrmSpringBoneCollider.Node]; + var springBoneColliderGroup = go.GetComponent(); + if (springBoneColliderGroup != null) { - springBone.m_center = origin.transform; + // already setup } - controller.SpringBone.Springs.Add(springBone); - - // create colliders for the spring - foreach (var vrmSpringBoneCollider in vrmSpring.Colliders) + else { - var go = asset.Map.Nodes[vrmSpringBoneCollider.Node]; - var springBoneColliderGroup = go.GetComponent(); - if (springBoneColliderGroup != null) - { - // already setup - } - else - { - // new collider - springBoneColliderGroup = go.AddComponent(); + // new collider + springBoneColliderGroup = go.AddComponent(); - // add collider shapes - springBoneColliderGroup.Colliders.Clear(); - foreach (var x in vrmSpringBoneCollider.Colliders) + // add collider shapes + springBoneColliderGroup.Colliders.Clear(); + foreach (var x in vrmSpringBoneCollider.Colliders) + { + switch (x.ColliderType) { - switch (x.ColliderType) - { - case VrmLib.VrmSpringBoneColliderTypes.Sphere: - springBoneColliderGroup.Colliders.Add(new UniVRM10.VRM10SpringBoneCollider() - { - ColliderType = VRM10SpringBoneColliderTypes.Sphere, - Offset = x.Offset.ToUnityVector3(), - Radius = x.Radius - }); - break; + case VrmLib.VrmSpringBoneColliderTypes.Sphere: + springBoneColliderGroup.Colliders.Add(new UniVRM10.VRM10SpringBoneCollider() + { + ColliderType = VRM10SpringBoneColliderTypes.Sphere, + Offset = x.Offset.ToUnityVector3(), + Radius = x.Radius + }); + break; - case VrmLib.VrmSpringBoneColliderTypes.Capsule: - springBoneColliderGroup.Colliders.Add(new UniVRM10.VRM10SpringBoneCollider() - { - ColliderType = VRM10SpringBoneColliderTypes.Capsule, - Offset = x.Offset.ToUnityVector3(), - Radius = x.Radius, - Tail = x.CapsuleTail.ToUnityVector3(), - }); - break; + case VrmLib.VrmSpringBoneColliderTypes.Capsule: + springBoneColliderGroup.Colliders.Add(new UniVRM10.VRM10SpringBoneCollider() + { + ColliderType = VRM10SpringBoneColliderTypes.Capsule, + Offset = x.Offset.ToUnityVector3(), + Radius = x.Radius, + Tail = x.CapsuleTail.ToUnityVector3(), + }); + break; - default: - throw new NotImplementedException(); - } + default: + throw new NotImplementedException(); } } - springBone.ColliderGroups.Add(springBoneColliderGroup); } + springBone.ColliderGroups.Add(springBoneColliderGroup); + } - // create joint for the spring - foreach (var vrmJoint in vrmSpring.Joints) - { - var joint = new VRM10SpringBone.VRM10SpringJoint(); + // create joint for the spring + foreach (var vrmJoint in vrmSpring.Joints) + { + var joint = new VRM10SpringBone.VRM10SpringJoint(); - joint.m_stiffnessForce = vrmJoint.Stiffness; - joint.m_gravityPower = vrmJoint.GravityPower; - joint.m_gravityDir = vrmJoint.GravityDir.ToUnityVector3(); - joint.m_dragForce = vrmJoint.DragForce; - joint.m_hitRadius = vrmJoint.HitRadius; + joint.m_stiffnessForce = vrmJoint.Stiffness; + joint.m_gravityPower = vrmJoint.GravityPower; + joint.m_gravityDir = vrmJoint.GravityDir.ToUnityVector3(); + joint.m_dragForce = vrmJoint.DragForce; + joint.m_hitRadius = vrmJoint.HitRadius; - springBone.Joints.Add(joint); - } + springBone.Joints.Add(joint); } } } From ca8359954f514855e4b47026c11fed46f2eb1050 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Thu, 21 Jan 2021 15:26:18 +0900 Subject: [PATCH 14/22] CheckMeta --- Assets/VRM10/Runtime/Migration/Migration.cs | 100 +++++++++++++++++++- Assets/VRM10/Tests/MigrationTests.cs | 1 + 2 files changed, 99 insertions(+), 2 deletions(-) diff --git a/Assets/VRM10/Runtime/Migration/Migration.cs b/Assets/VRM10/Runtime/Migration/Migration.cs index 0b050fda52..41aad6c55a 100644 --- a/Assets/VRM10/Runtime/Migration/Migration.cs +++ b/Assets/VRM10/Runtime/Migration/Migration.cs @@ -121,6 +121,7 @@ static UniGLTF.Extensions.VRMC_vrm.Humanoid MigrateHumanoid(ListTreeNode vrm0 return meta; } + static string GetLicenseUrl(ListTreeNode vrm0) + { + string l0 = default; + string l1 = default; + foreach (var kv in vrm0.ObjectItems()) + { + switch (kv.Key.GetString()) + { + case "otherLicenseUrl": + l0 = kv.Value.GetString(); + break; + + case "otherPermissionUrl": + l1 = kv.Value.GetString(); + break; + } + } + if (!string.IsNullOrWhiteSpace(l0)) + { + return l0; + } + if (!string.IsNullOrWhiteSpace(l1)) + { + return l1; + } + return ""; + } + public static byte[] Migrate(byte[] src) { var glb = UniGLTF.Glb.Parse(src); @@ -266,6 +295,13 @@ public static byte[] Migrate(byte[] src) } #region for UnitTest + public class MigrationException : Exception + { + public MigrationException(string key, string value) : base($"{key}: {value}") + { + } + } + public static void CheckBone(string bone, ListTreeNode vrm0, UniGLTF.Extensions.VRMC_vrm.HumanBone vrm1) { var vrm0NodeIndex = vrm0["node"].GetInt32(); @@ -337,11 +373,71 @@ public static void CheckHumanoid(ListTreeNode vrm0, UniGLTF.Extension case "rightLittleIntermediate": CheckBone(boneType, humanoidBone, vrm1.HumanBones.RightLittleIntermediate); break; case "rightLittleDistal": CheckBone(boneType, humanoidBone, vrm1.HumanBones.RightLittleDistal); break; case "upperChest": CheckBone(boneType, humanoidBone, vrm1.HumanBones.UpperChest); break; - default: - throw new NotImplementedException($"unknown bone: {boneType}"); + default: throw new MigrationException("humanonoid.humanBones[*].bone", boneType); } } } + + static bool IsSingleList(string key, string lhs, List rhs) + { + if (rhs.Count != 1) throw new MigrationException(key, $"{rhs.Count}"); + return lhs == rhs[0]; + } + + static string AvatarPermission(string key, AvatarPermissionType x) + { + switch (x) + { + case AvatarPermissionType.everyone: return "Everyone"; + // case AvatarPermissionType.onlyAuthor: return "OnlyAuthor"; + // case AvatarPermissionType.explicitlyLicensedPerson: return "Explicited"; + } + throw new MigrationException(key, $"{x}"); + } + + public static void CheckMeta(ListTreeNode vrm0, UniGLTF.Extensions.VRMC_vrm.Meta vrm1) + { + if (vrm0["title"].GetString() != vrm1.Name) throw new MigrationException("meta.title", vrm1.Name); + if (vrm0["version"].GetString() != vrm1.Version) throw new MigrationException("meta.version", vrm1.Version); + if (!IsSingleList("meta.author", vrm0["author"].GetString(), vrm1.Authors)) throw new MigrationException("meta.author", $"{vrm1.Authors}"); + if (vrm0["contactInformation"].GetString() != vrm1.ContactInformation) throw new MigrationException("meta.contactInformation", vrm1.ContactInformation); + if (!IsSingleList("meta.reference", vrm0["reference"].GetString(), vrm1.References)) throw new MigrationException("meta.reference", $"{vrm1.References}"); + if (vrm0["texture"].GetInt32() != vrm1.ThumbnailImage) throw new MigrationException("meta.texture", $"{vrm1.ThumbnailImage}"); + + if (vrm0["allowedUserName"].GetString() != AvatarPermission("meta.allowedUserName", vrm1.AvatarPermission)) throw new MigrationException("meta.allowedUserName", $"{vrm1.AvatarPermission}"); + if (vrm0["violentUssageName"].GetString() == "Allow" != vrm1.AllowExcessivelyViolentUsage) throw new MigrationException("meta.violentUssageName", $"{vrm1.AllowExcessivelyViolentUsage}"); + if (vrm0["sexualUssageName"].GetString() == "Allow" != vrm1.AllowExcessivelySexualUsage) throw new MigrationException("meta.sexualUssageName", $"{vrm1.AllowExcessivelyViolentUsage}"); + + if (vrm0["commercialUssageName"].GetString() == "Allow") + { + if (vrm1.CommercialUsage == CommercialUsageType.personalNonProfit) + { + throw new MigrationException("meta.commercialUssageName", $"{vrm1.CommercialUsage}"); + } + } + else + { + if (vrm1.CommercialUsage == CommercialUsageType.corporation || vrm1.CommercialUsage == CommercialUsageType.personalProfit) + { + throw new MigrationException("meta.commercialUssageName", $"{vrm1.CommercialUsage}"); + } + } + + if (GetLicenseUrl(vrm0) != vrm1.OtherLicenseUrl) throw new MigrationException("meta.otherLicenseUrl", vrm1.OtherLicenseUrl); + + switch (vrm0["licenseName"].GetString()) + { + case "Other": + { + if (vrm1.Modification != ModificationType.prohibited) throw new MigrationException("meta.licenceName", $"{vrm1.Modification}"); + if (vrm1.AllowRedistribution.Value) throw new MigrationException("meta.liceneName", $"{vrm1.Modification}"); + break; + } + + default: + throw new NotImplementedException(); + } + } #endregion } } diff --git a/Assets/VRM10/Tests/MigrationTests.cs b/Assets/VRM10/Tests/MigrationTests.cs index d08d31ae02..c58ee5bb15 100644 --- a/Assets/VRM10/Tests/MigrationTests.cs +++ b/Assets/VRM10/Tests/MigrationTests.cs @@ -53,6 +53,7 @@ public void Migrate0to1() var VRMC_vrm = GetVRMC_vrm(gltf.extensions); Assert.NotNull(VRMC_vrm); + Migration.CheckMeta(vrm0Json["meta"], VRMC_vrm.Meta); Migration.CheckHumanoid(vrm0Json["humanoid"], VRMC_vrm.Humanoid); } } From e39f93436ecacfe9989a17b530f335f1373d577b Mon Sep 17 00:00:00 2001 From: ousttrue Date: Thu, 21 Jan 2021 18:10:34 +0900 Subject: [PATCH 15/22] Migration.Check --- Assets/VRM10/Runtime/Migration/Migration.cs | 6 ++++++ Assets/VRM10/Tests/MigrationTests.cs | 3 +-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/Assets/VRM10/Runtime/Migration/Migration.cs b/Assets/VRM10/Runtime/Migration/Migration.cs index 41aad6c55a..4965304f3c 100644 --- a/Assets/VRM10/Runtime/Migration/Migration.cs +++ b/Assets/VRM10/Runtime/Migration/Migration.cs @@ -438,6 +438,12 @@ public static void CheckMeta(ListTreeNode vrm0, UniGLTF.Extensions.VR throw new NotImplementedException(); } } + + public static void Check(ListTreeNode vrm0, UniGLTF.Extensions.VRMC_vrm.VRMC_vrm vrm1) + { + Migration.CheckMeta(vrm0["meta"], vrm1.Meta); + Migration.CheckHumanoid(vrm0["humanoid"], vrm1.Humanoid); + } #endregion } } diff --git a/Assets/VRM10/Tests/MigrationTests.cs b/Assets/VRM10/Tests/MigrationTests.cs index c58ee5bb15..41fe7c9003 100644 --- a/Assets/VRM10/Tests/MigrationTests.cs +++ b/Assets/VRM10/Tests/MigrationTests.cs @@ -53,8 +53,7 @@ public void Migrate0to1() var VRMC_vrm = GetVRMC_vrm(gltf.extensions); Assert.NotNull(VRMC_vrm); - Migration.CheckMeta(vrm0Json["meta"], VRMC_vrm.Meta); - Migration.CheckHumanoid(vrm0Json["humanoid"], VRMC_vrm.Humanoid); + Migration.Check(vrm0Json, VRMC_vrm); } } } From c79d3d838cae68ef1ce4d681ebb8f5b2817bcebc Mon Sep 17 00:00:00 2001 From: ousttrue Date: Thu, 21 Jan 2021 18:20:32 +0900 Subject: [PATCH 16/22] GetExtension --- Assets/VRM10/Runtime/Migration/Migration.cs | 6 +++++ Assets/VRM10/Tests/MigrationTests.cs | 27 +++++++++++---------- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/Assets/VRM10/Runtime/Migration/Migration.cs b/Assets/VRM10/Runtime/Migration/Migration.cs index 4965304f3c..ded7b64fb9 100644 --- a/Assets/VRM10/Runtime/Migration/Migration.cs +++ b/Assets/VRM10/Runtime/Migration/Migration.cs @@ -444,6 +444,12 @@ public static void Check(ListTreeNode vrm0, UniGLTF.Extensions.VRMC_v Migration.CheckMeta(vrm0["meta"], vrm1.Meta); Migration.CheckHumanoid(vrm0["humanoid"], vrm1.Humanoid); } + + public static void Check(ListTreeNode vrm0, UniGLTF.Extensions.VRMC_springBone.VRMC_springBone vrm1) + { + var a = 0; + // Migration.CheckSpringBone(vrm0["secondaryAnimation"], vrm1.sp) + } #endregion } } diff --git a/Assets/VRM10/Tests/MigrationTests.cs b/Assets/VRM10/Tests/MigrationTests.cs index 41fe7c9003..f0a0bbd6f7 100644 --- a/Assets/VRM10/Tests/MigrationTests.cs +++ b/Assets/VRM10/Tests/MigrationTests.cs @@ -17,15 +17,22 @@ static string AliciaPath } } - UniGLTF.Extensions.VRMC_vrm.VRMC_vrm GetVRMC_vrm(UniGLTF.glTFExtension extensions) + static ListTreeNode GetVRM0(byte[] bytes) + { + var glb = UniGLTF.Glb.Parse(bytes); + var json = glb.Json.Bytes.ParseAsJson(); + return json["extensions"]["VRM"]; + } + + T GetExtension(UniGLTF.glTFExtension extensions, UniJSON.Utf8String key, Func, T> deserializer) { if (extensions is UniGLTF.glTFExtensionImport import) { foreach (var kv in import.ObjectItems()) { - if (kv.Key.GetUtf8String() == UniGLTF.Extensions.VRMC_vrm.VRMC_vrm.ExtensionNameUtf8) + if (kv.Key.GetUtf8String() == key) { - return UniGLTF.Extensions.VRMC_vrm.GltfDeserializer.Deserialize(kv.Value); + return deserializer(kv.Value); } } } @@ -33,13 +40,6 @@ UniGLTF.Extensions.VRMC_vrm.VRMC_vrm GetVRMC_vrm(UniGLTF.glTFExtension extension return default; } - static ListTreeNode GetVRM0(byte[] bytes) - { - var glb = UniGLTF.Glb.Parse(bytes); - var json = glb.Json.Bytes.ParseAsJson(); - return json["extensions"]["VRM"]; - } - [Test] public void Migrate0to1() { @@ -50,10 +50,11 @@ public void Migrate0to1() var glb = UniGLTF.Glb.Parse(vrm1); var json = glb.Json.Bytes.ParseAsJson(); var gltf = UniGLTF.GltfDeserializer.Deserialize(json); - var VRMC_vrm = GetVRMC_vrm(gltf.extensions); - Assert.NotNull(VRMC_vrm); - Migration.Check(vrm0Json, VRMC_vrm); + Migration.Check(vrm0Json, GetExtension(gltf.extensions, UniGLTF.Extensions.VRMC_vrm.VRMC_vrm.ExtensionNameUtf8, + UniGLTF.Extensions.VRMC_vrm.GltfDeserializer.Deserialize)); + Migration.Check(vrm0Json, GetExtension(gltf.extensions, UniGLTF.Extensions.VRMC_springBone.VRMC_springBone.ExtensionNameUtf8, + UniGLTF.Extensions.VRMC_springBone.GltfDeserializer.Deserialize)); } } } From 562b3a771a732498e210fca77bf13806f7726e2a Mon Sep 17 00:00:00 2001 From: ousttrue Date: Thu, 21 Jan 2021 21:51:39 +0900 Subject: [PATCH 17/22] MigrateSpringBone --- .../Runtime/Format/SpringBone/Format.g.cs | 2 + Assets/VRM10/Runtime/IO/Vrm10Storage.cs | 2 +- Assets/VRM10/Runtime/Migration/Migration.cs | 223 +++++++++++++++--- Assets/VRM10/Tests/MigrationTests.cs | 2 +- 4 files changed, 195 insertions(+), 34 deletions(-) diff --git a/Assets/VRM10/Runtime/Format/SpringBone/Format.g.cs b/Assets/VRM10/Runtime/Format/SpringBone/Format.g.cs index 2d7bfee887..4d33cc0b78 100644 --- a/Assets/VRM10/Runtime/Format/SpringBone/Format.g.cs +++ b/Assets/VRM10/Runtime/Format/SpringBone/Format.g.cs @@ -9,6 +9,8 @@ namespace UniGLTF.Extensions.VRMC_springBone public class SpringBoneJoint { + public int? Node; + // The radius of spring sphere public float? HitRadius; diff --git a/Assets/VRM10/Runtime/IO/Vrm10Storage.cs b/Assets/VRM10/Runtime/IO/Vrm10Storage.cs index eaf4f26f1b..bcd3204fdb 100644 --- a/Assets/VRM10/Runtime/IO/Vrm10Storage.cs +++ b/Assets/VRM10/Runtime/IO/Vrm10Storage.cs @@ -606,7 +606,7 @@ public Meta CreateVrmMeta(List textures) static void AssignHumanoid(List nodes, UniGLTF.Extensions.VRMC_vrm.HumanBone humanBone, VrmLib.HumanoidBones key) { - if (humanBone.Node.HasValue) + if (humanBone!=null && humanBone.Node.HasValue) { nodes[humanBone.Node.Value].HumanoidBone = key; } diff --git a/Assets/VRM10/Runtime/Migration/Migration.cs b/Assets/VRM10/Runtime/Migration/Migration.cs index ded7b64fb9..04cc8b0971 100644 --- a/Assets/VRM10/Runtime/Migration/Migration.cs +++ b/Assets/VRM10/Runtime/Migration/Migration.cs @@ -1,6 +1,6 @@ using System; using System.Collections.Generic; -using UniGLTF.Extensions.VRMC_vrm; +using System.Linq; using UniJSON; namespace UniVRM10 @@ -48,7 +48,7 @@ static bool TryGet(this UniGLTF.glTFExtensionImport extensions, string key, out // }, static UniGLTF.Extensions.VRMC_vrm.HumanBone MigrateHumanoidBone(ListTreeNode vrm0) { - return new HumanBone + return new UniGLTF.Extensions.VRMC_vrm.HumanBone { Node = vrm0["node"].GetInt32(), }; @@ -58,7 +58,7 @@ static UniGLTF.Extensions.VRMC_vrm.Humanoid MigrateHumanoid(ListTreeNode vrm0 AllowExcessivelySexualUsage = false, AllowExcessivelyViolentUsage = false, AllowRedistribution = false, - AvatarPermission = AvatarPermissionType.onlyAuthor, - CommercialUsage = CommercialUsageType.personalNonProfit, - CreditNotation = CreditNotationType.required, - Modification = ModificationType.prohibited, + AvatarPermission = UniGLTF.Extensions.VRMC_vrm.AvatarPermissionType.onlyAuthor, + CommercialUsage = UniGLTF.Extensions.VRMC_vrm.CommercialUsageType.personalNonProfit, + CreditNotation = UniGLTF.Extensions.VRMC_vrm.CreditNotationType.required, + Modification = UniGLTF.Extensions.VRMC_vrm.ModificationType.prohibited, }; foreach (var kv in vrm0.ObjectItems()) @@ -180,7 +180,7 @@ static UniGLTF.Extensions.VRMC_vrm.Meta MigrateMeta(ListTreeNode vrm0 var allowdUserType = kv.Value.GetString(); switch (allowdUserType) { - case "Everyone": meta.AvatarPermission = AvatarPermissionType.everyone; break; + case "Everyone": meta.AvatarPermission = UniGLTF.Extensions.VRMC_vrm.AvatarPermissionType.everyone; break; default: throw new NotImplementedException($"allowedUser: {allowdUserType}"); } } @@ -193,8 +193,8 @@ static UniGLTF.Extensions.VRMC_vrm.Meta MigrateMeta(ListTreeNode vrm0 var commercialUssageType = kv.Value.GetString(); switch (commercialUssageType) { - case "Allow": meta.CommercialUsage = CommercialUsageType.personalProfit; break; - default: meta.CommercialUsage = CommercialUsageType.personalNonProfit; break; + case "Allow": meta.CommercialUsage = UniGLTF.Extensions.VRMC_vrm.CommercialUsageType.personalProfit; break; + default: meta.CommercialUsage = UniGLTF.Extensions.VRMC_vrm.CommercialUsageType.personalNonProfit; break; } } break; @@ -255,37 +255,195 @@ static string GetLicenseUrl(ListTreeNode vrm0) return ""; } - public static byte[] Migrate(byte[] src) + static float[] ReverseZ(ListTreeNode xyz) { - var glb = UniGLTF.Glb.Parse(src); - var json = glb.Json.Bytes.ParseAsJson(); + return new float[]{ + xyz["x"].GetSingle(), + xyz["y"].GetSingle(), + -xyz["z"].GetSingle(), + }; + } - var gltf = UniGLTF.GltfDeserializer.Deserialize(json); - if (!(gltf.extensions is UniGLTF.glTFExtensionImport import)) + static IEnumerable EnumJoint(List nodes, UniGLTF.glTFNode node) + { + yield return node; + + if (node.children != null && node.children.Length > 0) { - throw new Exception("not extensions"); + foreach (var x in EnumJoint(nodes, nodes[node.children[0]])) + { + yield return x; + } } - if (!import.TryGet("VRM", out ListTreeNode vrm)) + } + + static UniGLTF.Extensions.VRMC_springBone.VRMC_springBone MigrateSpringBone(UniGLTF.glTF gltf, ListTreeNode sa) + { + var colliderNodes = new List(); + + foreach (var x in sa["colliderGroups"].ArrayItems()) { - throw new Exception("no vrm"); + var node = x["node"].GetInt32(); + colliderNodes.Add(node); + var gltfNode = gltf.nodes[node]; + + var collider = new UniGLTF.Extensions.VRMC_node_collider.VRMC_node_collider() + { + Shapes = new List(), + }; + + // { + // "node": 14, + // "colliders": [ + // { + // "offset": { + // "x": 0.025884293, + // "y": -0.120000005, + // "z": 0 + // }, + // "radius": 0.05 + // }, + // { + // "offset": { + // "x": -0.02588429, + // "y": -0.120000005, + // "z": 0 + // }, + // "radius": 0.05 + // }, + // { + // "offset": { + // "x": 0, + // "y": -0.0220816135, + // "z": 0 + // }, + // "radius": 0.08 + // } + // ] + // }, + foreach (var y in x["colliders"].ArrayItems()) + { + collider.Shapes.Add(new UniGLTF.Extensions.VRMC_node_collider.ColliderShape + { + Sphere = new UniGLTF.Extensions.VRMC_node_collider.ColliderShapeSphere + { + Offset = ReverseZ(y["offset"]), + Radius = y["radius"].GetSingle() + } + }); + } + + if (!(gltfNode.extensions is UniGLTF.glTFExtensionExport extensions)) + { + extensions = new UniGLTF.glTFExtensionExport(); + gltfNode.extensions = extensions; + } + + var f = new JsonFormatter(); + UniGLTF.Extensions.VRMC_node_collider.GltfSerializer.Serialize(f, collider); + extensions.Add(UniGLTF.Extensions.VRMC_node_collider.VRMC_node_collider.ExtensionName, f.GetStoreBytes()); } + var springBone = new UniGLTF.Extensions.VRMC_springBone.VRMC_springBone + { + Springs = new List(), + }; + foreach (var x in sa["boneGroups"].ArrayItems()) + { + // { + // "comment": "", + // "stiffiness": 2, + // "gravityPower": 0, + // "gravityDir": { + // "x": 0, + // "y": -1, + // "z": 0 + // }, + // "dragForce": 0.7, + // "center": -1, + // "hitRadius": 0.02, + // "bones": [ + // 97, + // 99, + // 101, + // 113, + // 114 + // ], + // "colliderGroups": [ + // 3, + // 4, + // 5 + // ] + // }, + foreach (var y in x["bones"].ArrayItems()) + { + var spring = new UniGLTF.Extensions.VRMC_springBone.Spring + { + Name = x["comment"].GetString(), + Colliders = x["colliderGroups"].ArrayItems().Select(z => colliderNodes[z.GetInt32()]).ToArray(), + Joints = new List(), + }; + + foreach (var z in EnumJoint(gltf.nodes, gltf.nodes[y.GetInt32()])) + { + spring.Joints.Add(new UniGLTF.Extensions.VRMC_springBone.SpringBoneJoint + { + Node = gltf.nodes.IndexOf(z), + DragForce = x["dragForce"].GetSingle(), + GravityDir = ReverseZ(x["gravityDir"]), + GravityPower = x["gravityPower"].GetSingle(), + HitRadius = x["hitRadius"].GetSingle(), + Stiffness = x["stiffiness"].GetSingle(), + }); + } + + springBone.Springs.Add(spring); + } + } + + return springBone; + } + + public static byte[] Migrate(byte[] src) + { + var glb = UniGLTF.Glb.Parse(src); + var json = glb.Json.Bytes.ParseAsJson(); + var gltf = UniGLTF.GltfDeserializer.Deserialize(json); + + var extensions = new UniGLTF.glTFExtensionExport(); { - var vrm1 = new VRMC_vrm(); var vrm0 = json["extensions"]["VRM"]; - // meta - vrm1.Meta = MigrateMeta(vrm0["meta"]); - // humanoid - vrm1.Humanoid = MigrateHumanoid(vrm0["humanoid"]); + { + // vrm + var vrm1 = new UniGLTF.Extensions.VRMC_vrm.VRMC_vrm(); + vrm1.Meta = MigrateMeta(vrm0["meta"]); + vrm1.Humanoid = MigrateHumanoid(vrm0["humanoid"]); + + var f = new JsonFormatter(); + UniGLTF.Extensions.VRMC_vrm.GltfSerializer.Serialize(f, vrm1); + extensions.Add(UniGLTF.Extensions.VRMC_vrm.VRMC_vrm.ExtensionName, f.GetStoreBytes()); + } + { + // springBone & collider + var vrm1 = MigrateSpringBone(gltf, json["extensions"]["VRM"]["secondaryAnimation"]); - var f = new JsonFormatter(); - GltfSerializer.Serialize(f, vrm1); - gltf.extensions = new UniGLTF.glTFExtensionExport().Add(VRMC_vrm.ExtensionName, f.GetStoreBytes()); + var f = new JsonFormatter(); + UniGLTF.Extensions.VRMC_springBone.GltfSerializer.Serialize(f, vrm1); + extensions.Add(UniGLTF.Extensions.VRMC_springBone.VRMC_springBone.ExtensionName, f.GetStoreBytes()); + } + { + // MToon + } + { + // constraint + } } ArraySegment vrm1Json = default; { + gltf.extensions = extensions; + var f = new JsonFormatter(); UniGLTF.GltfSerializer.Serialize(f, gltf); vrm1Json = f.GetStoreBytes(); @@ -384,11 +542,11 @@ static bool IsSingleList(string key, string lhs, List rhs) return lhs == rhs[0]; } - static string AvatarPermission(string key, AvatarPermissionType x) + static string AvatarPermission(string key, UniGLTF.Extensions.VRMC_vrm.AvatarPermissionType x) { switch (x) { - case AvatarPermissionType.everyone: return "Everyone"; + case UniGLTF.Extensions.VRMC_vrm.AvatarPermissionType.everyone: return "Everyone"; // case AvatarPermissionType.onlyAuthor: return "OnlyAuthor"; // case AvatarPermissionType.explicitlyLicensedPerson: return "Explicited"; } @@ -410,14 +568,15 @@ public static void CheckMeta(ListTreeNode vrm0, UniGLTF.Extensions.VR if (vrm0["commercialUssageName"].GetString() == "Allow") { - if (vrm1.CommercialUsage == CommercialUsageType.personalNonProfit) + if (vrm1.CommercialUsage == UniGLTF.Extensions.VRMC_vrm.CommercialUsageType.personalNonProfit) { throw new MigrationException("meta.commercialUssageName", $"{vrm1.CommercialUsage}"); } } else { - if (vrm1.CommercialUsage == CommercialUsageType.corporation || vrm1.CommercialUsage == CommercialUsageType.personalProfit) + if (vrm1.CommercialUsage == UniGLTF.Extensions.VRMC_vrm.CommercialUsageType.corporation + || vrm1.CommercialUsage == UniGLTF.Extensions.VRMC_vrm.CommercialUsageType.personalProfit) { throw new MigrationException("meta.commercialUssageName", $"{vrm1.CommercialUsage}"); } @@ -429,7 +588,7 @@ public static void CheckMeta(ListTreeNode vrm0, UniGLTF.Extensions.VR { case "Other": { - if (vrm1.Modification != ModificationType.prohibited) throw new MigrationException("meta.licenceName", $"{vrm1.Modification}"); + if (vrm1.Modification != UniGLTF.Extensions.VRMC_vrm.ModificationType.prohibited) throw new MigrationException("meta.licenceName", $"{vrm1.Modification}"); if (vrm1.AllowRedistribution.Value) throw new MigrationException("meta.liceneName", $"{vrm1.Modification}"); break; } @@ -445,7 +604,7 @@ public static void Check(ListTreeNode vrm0, UniGLTF.Extensions.VRMC_v Migration.CheckHumanoid(vrm0["humanoid"], vrm1.Humanoid); } - public static void Check(ListTreeNode vrm0, UniGLTF.Extensions.VRMC_springBone.VRMC_springBone vrm1) + public static void Check(ListTreeNode vrm0, UniGLTF.Extensions.VRMC_springBone.VRMC_springBone vrm1, List nodes) { var a = 0; // Migration.CheckSpringBone(vrm0["secondaryAnimation"], vrm1.sp) diff --git a/Assets/VRM10/Tests/MigrationTests.cs b/Assets/VRM10/Tests/MigrationTests.cs index f0a0bbd6f7..a465a66f38 100644 --- a/Assets/VRM10/Tests/MigrationTests.cs +++ b/Assets/VRM10/Tests/MigrationTests.cs @@ -54,7 +54,7 @@ public void Migrate0to1() Migration.Check(vrm0Json, GetExtension(gltf.extensions, UniGLTF.Extensions.VRMC_vrm.VRMC_vrm.ExtensionNameUtf8, UniGLTF.Extensions.VRMC_vrm.GltfDeserializer.Deserialize)); Migration.Check(vrm0Json, GetExtension(gltf.extensions, UniGLTF.Extensions.VRMC_springBone.VRMC_springBone.ExtensionNameUtf8, - UniGLTF.Extensions.VRMC_springBone.GltfDeserializer.Deserialize)); + UniGLTF.Extensions.VRMC_springBone.GltfDeserializer.Deserialize), gltf.nodes); } } } From 79b302ec382cc457b1a3bf3cc19575a64ab50504 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Fri, 22 Jan 2021 12:52:07 +0900 Subject: [PATCH 18/22] udpate schema --- .../Format/NodeCollider/Deserializer.g.cs | 20 +++++++++++++ .../Runtime/Format/NodeCollider/Format.g.cs | 12 ++++++++ .../Format/NodeCollider/Serializer.g.cs | 20 +++++++++++++ .../Format/SpringBone/Deserializer.g.cs | 30 +++++++++++++++++++ .../Runtime/Format/SpringBone/Format.g.cs | 26 ++++++++++++---- .../Runtime/Format/SpringBone/Serializer.g.cs | 30 +++++++++++++++++++ 6 files changed, 133 insertions(+), 5 deletions(-) diff --git a/Assets/VRM10/Runtime/Format/NodeCollider/Deserializer.g.cs b/Assets/VRM10/Runtime/Format/NodeCollider/Deserializer.g.cs index 0eba7de28a..02a1ca8056 100644 --- a/Assets/VRM10/Runtime/Format/NodeCollider/Deserializer.g.cs +++ b/Assets/VRM10/Runtime/Format/NodeCollider/Deserializer.g.cs @@ -36,6 +36,16 @@ public static VRMC_node_collider Deserialize(ListTreeNode parsed) { 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=="shapes"){ value.Shapes = Deserialize_Shapes(kv.Value); continue; @@ -63,6 +73,16 @@ public static ColliderShape Deserialize_Shapes_ITEM(ListTreeNode pars { 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=="sphere"){ value.Sphere = Deserialize_Sphere(kv.Value); continue; diff --git a/Assets/VRM10/Runtime/Format/NodeCollider/Format.g.cs b/Assets/VRM10/Runtime/Format/NodeCollider/Format.g.cs index 5512bc9abd..1f33f6cd6b 100644 --- a/Assets/VRM10/Runtime/Format/NodeCollider/Format.g.cs +++ b/Assets/VRM10/Runtime/Format/NodeCollider/Format.g.cs @@ -30,6 +30,12 @@ public class ColliderShapeCapsule public class ColliderShape { + // Dictionary object with extension-specific objects. + public glTFExtension Extensions; + + // Application-specific data. + public glTFExtension Extras; + public ColliderShapeSphere Sphere; public ColliderShapeCapsule Capsule; @@ -40,6 +46,12 @@ public class VRMC_node_collider public const string ExtensionName = "VRMC_node_collider"; public static readonly Utf8String ExtensionNameUtf8 = Utf8String.From(ExtensionName); + // Dictionary object with extension-specific objects. + public glTFExtension Extensions; + + // Application-specific data. + public glTFExtension Extras; + public List Shapes; } } diff --git a/Assets/VRM10/Runtime/Format/NodeCollider/Serializer.g.cs b/Assets/VRM10/Runtime/Format/NodeCollider/Serializer.g.cs index 298c122bde..5fc75ed36b 100644 --- a/Assets/VRM10/Runtime/Format/NodeCollider/Serializer.g.cs +++ b/Assets/VRM10/Runtime/Format/NodeCollider/Serializer.g.cs @@ -33,6 +33,16 @@ public static void Serialize(JsonFormatter f, VRMC_node_collider value) f.BeginMap(); + if(value.Extensions!=null){ + f.Key("extensions"); + value.Extensions.Serialize(f); + } + + if(value.Extras!=null){ + f.Key("extras"); + value.Extras.Serialize(f); + } + if(value.Shapes!=null&&value.Shapes.Count()>=0){ f.Key("shapes"); Serialize_Shapes(f, value.Shapes); @@ -58,6 +68,16 @@ public static void Serialize_Shapes_ITEM(JsonFormatter f, ColliderShape value) f.BeginMap(); + if(value.Extensions!=null){ + f.Key("extensions"); + value.Extensions.Serialize(f); + } + + if(value.Extras!=null){ + f.Key("extras"); + value.Extras.Serialize(f); + } + if(value.Sphere!=null){ f.Key("sphere"); Serialize_Sphere(f, value.Sphere); diff --git a/Assets/VRM10/Runtime/Format/SpringBone/Deserializer.g.cs b/Assets/VRM10/Runtime/Format/SpringBone/Deserializer.g.cs index a45cbec18f..33b72345aa 100644 --- a/Assets/VRM10/Runtime/Format/SpringBone/Deserializer.g.cs +++ b/Assets/VRM10/Runtime/Format/SpringBone/Deserializer.g.cs @@ -36,6 +36,16 @@ public static VRMC_springBone Deserialize(ListTreeNode parsed) { 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=="springs"){ value.Springs = Deserialize_Springs(kv.Value); continue; @@ -100,6 +110,21 @@ public static SpringBoneJoint Deserialize_Joints_ITEM(ListTreeNode pa { 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=="node"){ + value.Node = kv.Value.GetInt32(); + continue; + } + if(key=="hitRadius"){ value.HitRadius = kv.Value.GetSingle(); continue; @@ -125,6 +150,11 @@ public static SpringBoneJoint Deserialize_Joints_ITEM(ListTreeNode pa continue; } + if(key=="exclude"){ + value.Exclude = kv.Value.GetBoolean(); + continue; + } + } return value; } diff --git a/Assets/VRM10/Runtime/Format/SpringBone/Format.g.cs b/Assets/VRM10/Runtime/Format/SpringBone/Format.g.cs index 4d33cc0b78..8febc816d0 100644 --- a/Assets/VRM10/Runtime/Format/SpringBone/Format.g.cs +++ b/Assets/VRM10/Runtime/Format/SpringBone/Format.g.cs @@ -9,22 +9,32 @@ namespace UniGLTF.Extensions.VRMC_springBone public class SpringBoneJoint { + // Dictionary object with extension-specific objects. + public glTFExtension Extensions; + + // Application-specific data. + public glTFExtension Extras; + + // The node index. public int? Node; - - // The radius of spring sphere + + // The radius of spring sphere. public float? HitRadius; - // The force to return to the initial pose + // The force to return to the initial pose. public float? Stiffness; - // Gravitational acceleration + // Gravitational acceleration. public float? GravityPower; // The direction of gravity. A gravity other than downward direction also works. public float[] GravityDir; - // Air resistance. Deceleration force + // Air resistance. Deceleration force. public float? DragForce; + + // When enabled, this joint will skip Spring processing. + public bool? Exclude; } public class Spring @@ -44,6 +54,12 @@ public class VRMC_springBone public const string ExtensionName = "VRMC_springBone"; public static readonly Utf8String ExtensionNameUtf8 = Utf8String.From(ExtensionName); + // Dictionary object with extension-specific objects. + public glTFExtension Extensions; + + // Application-specific data. + public glTFExtension Extras; + // An array of springs. public List Springs; } diff --git a/Assets/VRM10/Runtime/Format/SpringBone/Serializer.g.cs b/Assets/VRM10/Runtime/Format/SpringBone/Serializer.g.cs index bbf867086c..8a87d1aefa 100644 --- a/Assets/VRM10/Runtime/Format/SpringBone/Serializer.g.cs +++ b/Assets/VRM10/Runtime/Format/SpringBone/Serializer.g.cs @@ -33,6 +33,16 @@ public static void Serialize(JsonFormatter f, VRMC_springBone value) f.BeginMap(); + if(value.Extensions!=null){ + f.Key("extensions"); + value.Extensions.Serialize(f); + } + + if(value.Extras!=null){ + f.Key("extras"); + value.Extras.Serialize(f); + } + if(value.Springs!=null&&value.Springs.Count()>=0){ f.Key("springs"); Serialize_Springs(f, value.Springs); @@ -93,6 +103,21 @@ public static void Serialize_Joints_ITEM(JsonFormatter f, SpringBoneJoint value) f.BeginMap(); + if(value.Extensions!=null){ + f.Key("extensions"); + value.Extensions.Serialize(f); + } + + if(value.Extras!=null){ + f.Key("extras"); + value.Extras.Serialize(f); + } + + if(value.Node.HasValue){ + f.Key("node"); + f.Value(value.Node.GetValueOrDefault()); + } + if(value.HitRadius.HasValue){ f.Key("hitRadius"); f.Value(value.HitRadius.GetValueOrDefault()); @@ -118,6 +143,11 @@ public static void Serialize_Joints_ITEM(JsonFormatter f, SpringBoneJoint value) f.Value(value.DragForce.GetValueOrDefault()); } + if(value.Exclude.HasValue){ + f.Key("exclude"); + f.Value(value.Exclude.GetValueOrDefault()); + } + f.EndMap(); } From 178c51ddec3fb027022bbfa3d451aac75a9a93ee Mon Sep 17 00:00:00 2001 From: ousttrue Date: Fri, 22 Jan 2021 15:31:14 +0900 Subject: [PATCH 19/22] =?UTF-8?q?Joint=E5=88=A5=E3=83=91=E3=83=A9=E3=83=A1?= =?UTF-8?q?=E3=83=BC=E3=82=BF=E3=83=BC=E3=82=92=E5=AE=9F=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/SpringBone/SpringBoneLogic.cs | 26 ++-- .../SpringBone/SpringBoneProcessor.cs | 111 ------------------ .../Components/SpringBone/VRM10SpringBone.cs | 61 +++++----- .../Components/SpringBone/VRM10SpringJoint.cs | 77 ++++++++++++ ...essor.cs.meta => VRM10SpringJoint.cs.meta} | 2 +- Assets/VRM10/Runtime/IO/Vrm10Storage.cs | 4 +- Assets/VRM10/Runtime/Migration/Migration.cs | 1 - .../Runtime/UnityBuilder/ComponentBuilder.cs | 3 +- .../VRMConverter/RuntimeVrmConverter.cs | 2 +- .../vrmlib/Runtime/Vrm/SpringBoneManager.cs | 5 + 10 files changed, 129 insertions(+), 163 deletions(-) delete mode 100644 Assets/VRM10/Runtime/Components/SpringBone/SpringBoneProcessor.cs create mode 100644 Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringJoint.cs rename Assets/VRM10/Runtime/Components/SpringBone/{SpringBoneProcessor.cs.meta => VRM10SpringJoint.cs.meta} (83%) diff --git a/Assets/VRM10/Runtime/Components/SpringBone/SpringBoneLogic.cs b/Assets/VRM10/Runtime/Components/SpringBone/SpringBoneLogic.cs index 6a72f1f5af..0543c0d9c1 100644 --- a/Assets/VRM10/Runtime/Components/SpringBone/SpringBoneLogic.cs +++ b/Assets/VRM10/Runtime/Components/SpringBone/SpringBoneLogic.cs @@ -36,8 +36,6 @@ public Quaternion LocalRotation } public Vector3 m_boneAxis; - public float Radius { get; set; } - public SpringBoneLogic(Transform center, Transform transform, Vector3 localChildPosition) { m_transform = transform; @@ -73,7 +71,7 @@ public struct InternalCollider public void Update(Transform center, float stiffnessForce, float dragForce, Vector3 external, - List colliders) + List colliders, float jointRadius) { var currentTail = center != null ? center.TransformPoint(m_currentTail) @@ -95,7 +93,7 @@ public void Update(Transform center, nextTail = m_transform.position + (nextTail - m_transform.position).normalized * m_length; // Collisionで移動 - nextTail = Collision(colliders, nextTail); + nextTail = Collision(colliders, nextTail, jointRadius); m_prevTail = center != null ? center.InverseTransformPoint(currentTail) @@ -117,14 +115,14 @@ protected virtual Quaternion ApplyRotation(Vector3 nextTail) nextTail - m_transform.position) * rotation; } - bool TrySphereCollision(Vector3 worldPosition, float radius, ref Vector3 nextTail) + bool TrySphereCollision(Vector3 worldPosition, float radius, ref Vector3 nextTail, float jointRadius) { - var r = Radius + radius; + var r = jointRadius + radius; if (Vector3.SqrMagnitude(nextTail - worldPosition) <= (r * r)) { // ヒット。Colliderの半径方向に押し出す var normal = (nextTail - worldPosition).normalized; - var posFromCollider = worldPosition + normal * (Radius + radius); + var posFromCollider = worldPosition + normal * (jointRadius + radius); // 長さをboneLengthに強制 nextTail = m_transform.position + (posFromCollider - m_transform.position).normalized * m_length; return true; @@ -135,7 +133,7 @@ bool TrySphereCollision(Vector3 worldPosition, float radius, ref Vector3 nextTai } } - bool TryCapsuleCollision(in InternalCollider collider, ref Vector3 nextTail) + bool TryCapsuleCollision(in InternalCollider collider, ref Vector3 nextTail, float jointRadius) { var P = collider.WorldTail - collider.WorldPosition; var Q = m_transform.position - collider.WorldPosition; @@ -143,22 +141,22 @@ bool TryCapsuleCollision(in InternalCollider collider, ref Vector3 nextTail) if (dot <= 0) { // head側半球の球判定 - return TrySphereCollision(collider.WorldPosition, collider.Radius, ref nextTail); + return TrySphereCollision(collider.WorldPosition, collider.Radius, ref nextTail, jointRadius); } var t = dot / P.magnitude; if (t >= 1.0f) { // tail側半球の球判定 - return TrySphereCollision(collider.WorldTail, collider.Radius, ref nextTail); + return TrySphereCollision(collider.WorldTail, collider.Radius, ref nextTail, jointRadius); } // head-tail上の m_transform.position との最近点 var p = collider.WorldPosition + P * t; - return TrySphereCollision(p, collider.Radius, ref nextTail); + return TrySphereCollision(p, collider.Radius, ref nextTail, jointRadius); } - protected virtual Vector3 Collision(List colliders, Vector3 nextTail) + protected virtual Vector3 Collision(List colliders, Vector3 nextTail, float jointRadius) { foreach (var collider in colliders) { @@ -166,11 +164,11 @@ protected virtual Vector3 Collision(List colliders, Vector3 ne switch (collider.ColliderTypes) { case VRM10SpringBoneColliderTypes.Sphere: - TrySphereCollision(collider.WorldPosition, collider.Radius, ref nextTail); + TrySphereCollision(collider.WorldPosition, collider.Radius, ref nextTail, jointRadius); break; case VRM10SpringBoneColliderTypes.Capsule: - TryCapsuleCollision(in collider, ref nextTail); + TryCapsuleCollision(in collider, ref nextTail, jointRadius); break; default: diff --git a/Assets/VRM10/Runtime/Components/SpringBone/SpringBoneProcessor.cs b/Assets/VRM10/Runtime/Components/SpringBone/SpringBoneProcessor.cs deleted file mode 100644 index 3d4add914e..0000000000 --- a/Assets/VRM10/Runtime/Components/SpringBone/SpringBoneProcessor.cs +++ /dev/null @@ -1,111 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; - -namespace UniVRM10 -{ - public class SpringBoneProcessor - { - List m_logics = new List(); - Dictionary m_initialLocalRotationMap; - - - public void ResetSpringBone() - { - foreach (var verlet in m_logics) - { - verlet.Head.localRotation = Quaternion.identity; - } - } - - public void SetupRecursive(Transform parent, Transform center) - { - if (parent.childCount == 0) - { - // 末端に追加のスプリングを付加する - var delta = parent.position - parent.parent.position; - var childPosition = parent.position + delta.normalized * 0.07f; - m_logics.Add(new SpringBoneLogic(center, parent, parent.worldToLocalMatrix.MultiplyPoint(childPosition))); - } - else - { - // 最初の子ボーンを尻尾としてスプリングを付加する - var firstChild = parent.GetChild(0); - var localPosition = firstChild.localPosition; - var scale = firstChild.lossyScale; - m_logics.Add(new SpringBoneLogic(center, parent, - new Vector3( - localPosition.x * scale.x, - localPosition.y * scale.y, - localPosition.z * scale.z - ))) - ; - } - - foreach (Transform child in parent) - { - SetupRecursive(child, center); - } - } - - void Setup(List RootBones, Transform m_center, bool force = false) - { - if (force || m_initialLocalRotationMap == null) - { - m_initialLocalRotationMap = new Dictionary(); - } - else - { - // restore initial rotation - foreach (var kv in m_initialLocalRotationMap) - { - kv.Key.localRotation = kv.Value; - } - m_initialLocalRotationMap.Clear(); - } - m_logics.Clear(); - - foreach (var transform in RootBones) - { - if (transform != null) - { - foreach (var x in transform.Traverse()) - { - // backup initial rotation - m_initialLocalRotationMap[x] = x.localRotation; - } - - SetupRecursive(transform, m_center); - } - } - } - - public void Update(List RootBones, List m_colliderList, - float stiffness, float m_dragForce, Vector3 external, - float m_hitRadius, Transform m_center) - { - if (m_logics == null || m_logics.Count == 0) - { - Setup(RootBones, m_center); - } - - foreach (var verlet in m_logics) - { - verlet.Radius = m_hitRadius; - verlet.Update(m_center, - stiffness, - m_dragForce, - external, - m_colliderList - ); - } - } - - public void DrawGizmos(Transform m_center, float m_hitRadius, Color m_gizmoColor) - { - foreach (var verlet in m_logics) - { - verlet.DrawGizmo(m_center, m_hitRadius, m_gizmoColor); - } - } - } -} diff --git a/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBone.cs b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBone.cs index 7365321487..561ca4f2a4 100644 --- a/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBone.cs +++ b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBone.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using UnityEngine; namespace UniVRM10 @@ -20,25 +21,6 @@ public class VRM10SpringBone [SerializeField] Color m_gizmoColor = Color.yellow; - [Serializable] - public class VRM10SpringJoint - { - [SerializeField, Range(0, 4), Header("Settings")] - public float m_stiffnessForce = 1.0f; - - [SerializeField, Range(0, 2)] - public float m_gravityPower = 0; - - [SerializeField] - public Vector3 m_gravityDir = new Vector3(0, -1.0f, 0); - - [SerializeField, Range(0, 1)] - public float m_dragForce = 0.4f; - - [SerializeField, Range(0, 0.5f), Header("Collision")] - public float m_hitRadius = 0.02f; - } - [SerializeField] public Transform m_center; @@ -48,12 +30,17 @@ public class VRM10SpringJoint [SerializeField] public List ColliderGroups = new List(); - SpringBoneProcessor m_processor = new SpringBoneProcessor(); [ContextMenu("Reset bones")] - public void ResetSpringBone() + public void ResetJoints() { - m_processor.ResetSpringBone(); + foreach (var joint in Joints) + { + if (joint != null) + { + joint.Transform.localRotation = Quaternion.identity; + } + } } List m_colliderList = new List(); @@ -101,20 +88,30 @@ public void Process() } } - // var stiffness = m_stiffnessForce * Time.deltaTime; - // var external = m_gravityDir * (m_gravityPower * Time.deltaTime); - - // m_processor.Update(RootBones, m_colliderList, - // stiffness, m_dragForce, external, - // m_hitRadius, m_center); + { + // udpate joints + VRM10SpringJoint lastJoint = Joints.FirstOrDefault(x => x != null); + foreach (var joint in Joints.Where(x => x != null).Skip(1)) + { + lastJoint.Update(m_center, Time.deltaTime, m_colliderList, joint); + lastJoint = joint; + } + lastJoint.Update(m_center, Time.deltaTime, m_colliderList, null); + } } private void OnDrawGizmos() { - // if (m_drawGizmo) - // { - // m_processor.DrawGizmos(m_center, m_hitRadius, m_gizmoColor); - // } + if (m_drawGizmo) + { + foreach (var joint in Joints) + { + if (joint != null) + { + joint.DrawGizmo(m_center, m_gizmoColor); + } + } + } } } } diff --git a/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringJoint.cs b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringJoint.cs new file mode 100644 index 0000000000..4f44cf97a3 --- /dev/null +++ b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringJoint.cs @@ -0,0 +1,77 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace UniVRM10 +{ + [Serializable] + public class VRM10SpringJoint + { + [SerializeField] + public Transform Transform; + + public VRM10SpringJoint(Transform t) + { + Transform = t; + } + + [SerializeField, Range(0, 4), Header("Settings")] + public float m_stiffnessForce = 1.0f; + + [SerializeField, Range(0, 2)] + public float m_gravityPower = 0; + + [SerializeField] + public Vector3 m_gravityDir = new Vector3(0, -1.0f, 0); + + [SerializeField, Range(0, 1)] + public float m_dragForce = 0.4f; + + [SerializeField, Range(0, 0.5f), Header("Collision")] + public float m_hitRadius = 0.02f; + + SpringBoneLogic m_logic; + + public void DrawGizmo(Transform center, Color color) + { + if (m_logic != null) + { + m_logic.DrawGizmo(center, m_hitRadius, color); + } + else + { + // TODO + } + } + + public void Update(Transform center, float deltaTime, List colliders, VRM10SpringJoint tail) + { + if (m_logic == null) + { + // Setup(joints, m_center); + // SetupRecursive(joint, m_center); + if (tail == null) + { + // 末端に追加のスプリングを付加する + var delta = Transform.position - Transform.parent.position; + var childPosition = Transform.position + delta.normalized * 0.07f; + m_logic = new SpringBoneLogic(center, Transform, Transform.worldToLocalMatrix.MultiplyPoint(childPosition)); + } + else + { + // 最初の子ボーンを尻尾としてスプリングを付加する + var localPosition = tail.Transform.localPosition; + var scale = tail.Transform.lossyScale; + m_logic = new SpringBoneLogic(center, Transform, + new Vector3( + localPosition.x * scale.x, + localPosition.y * scale.y, + localPosition.z * scale.z + )); + } + } + + m_logic.Update(center, m_stiffnessForce * deltaTime, m_dragForce, m_gravityDir * (m_gravityPower * deltaTime), colliders, m_hitRadius); + } + } +} diff --git a/Assets/VRM10/Runtime/Components/SpringBone/SpringBoneProcessor.cs.meta b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringJoint.cs.meta similarity index 83% rename from Assets/VRM10/Runtime/Components/SpringBone/SpringBoneProcessor.cs.meta rename to Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringJoint.cs.meta index 51b9ea6c26..0fab6c6f83 100644 --- a/Assets/VRM10/Runtime/Components/SpringBone/SpringBoneProcessor.cs.meta +++ b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringJoint.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: fb0714842bac26b44b774260bbef58c3 +guid: 5a7fc353e202e4f44a1025ba6e806262 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/VRM10/Runtime/IO/Vrm10Storage.cs b/Assets/VRM10/Runtime/IO/Vrm10Storage.cs index bcd3204fdb..d9eee6f4dd 100644 --- a/Assets/VRM10/Runtime/IO/Vrm10Storage.cs +++ b/Assets/VRM10/Runtime/IO/Vrm10Storage.cs @@ -606,7 +606,7 @@ public Meta CreateVrmMeta(List textures) static void AssignHumanoid(List nodes, UniGLTF.Extensions.VRMC_vrm.HumanBone humanBone, VrmLib.HumanoidBones key) { - if (humanBone!=null && humanBone.Node.HasValue) + if (humanBone != null && humanBone.Node.HasValue) { nodes[humanBone.Node.Value].HumanoidBone = key; } @@ -722,7 +722,7 @@ public SpringBoneManager CreateVrmSpringBone(List nodes) // joint foreach (var gltfJoint in gltfSpring.Joints) { - var joint = new SpringJoint(); + var joint = new SpringJoint(nodes[gltfJoint.Node.Value]); joint.HitRadius = gltfJoint.HitRadius.Value; joint.DragForce = gltfJoint.DragForce.Value; joint.GravityDir = gltfJoint.GravityDir.ToVector3(); diff --git a/Assets/VRM10/Runtime/Migration/Migration.cs b/Assets/VRM10/Runtime/Migration/Migration.cs index 04cc8b0971..720776d14e 100644 --- a/Assets/VRM10/Runtime/Migration/Migration.cs +++ b/Assets/VRM10/Runtime/Migration/Migration.cs @@ -606,7 +606,6 @@ public static void Check(ListTreeNode vrm0, UniGLTF.Extensions.VRMC_v public static void Check(ListTreeNode vrm0, UniGLTF.Extensions.VRMC_springBone.VRMC_springBone vrm1, List nodes) { - var a = 0; // Migration.CheckSpringBone(vrm0["secondaryAnimation"], vrm1.sp) } #endregion diff --git a/Assets/VRM10/Runtime/UnityBuilder/ComponentBuilder.cs b/Assets/VRM10/Runtime/UnityBuilder/ComponentBuilder.cs index 33ca9cb1b9..45ed6c4e98 100644 --- a/Assets/VRM10/Runtime/UnityBuilder/ComponentBuilder.cs +++ b/Assets/VRM10/Runtime/UnityBuilder/ComponentBuilder.cs @@ -300,7 +300,8 @@ public static void Build10(VrmLib.Model model, ModelAsset asset) // create joint for the spring foreach (var vrmJoint in vrmSpring.Joints) { - var joint = new VRM10SpringBone.VRM10SpringJoint(); + var go = asset.Map.Nodes[vrmJoint.Node]; + var joint = new VRM10SpringJoint(go.transform); joint.m_stiffnessForce = vrmJoint.Stiffness; joint.m_gravityPower = vrmJoint.GravityPower; diff --git a/Assets/VRM10/Runtime/VRMConverter/RuntimeVrmConverter.cs b/Assets/VRM10/Runtime/VRMConverter/RuntimeVrmConverter.cs index d3518c5f1f..8b1f3c94ec 100644 --- a/Assets/VRM10/Runtime/VRMConverter/RuntimeVrmConverter.cs +++ b/Assets/VRM10/Runtime/VRMConverter/RuntimeVrmConverter.cs @@ -356,7 +356,7 @@ public VrmLib.Model ToModelFrom10(GameObject root, VRM10MetaObject metaObject = foreach (var joint in springBone.Joints) { - vrmSpringBone.Joints.Add(new VrmLib.SpringJoint + vrmSpringBone.Joints.Add(new VrmLib.SpringJoint(Nodes[joint.Transform.gameObject]) { Stiffness = joint.m_stiffnessForce, GravityPower = joint.m_gravityPower, diff --git a/Assets/VRM10/vrmlib/Runtime/Vrm/SpringBoneManager.cs b/Assets/VRM10/vrmlib/Runtime/Vrm/SpringBoneManager.cs index 0edd20ec8e..270a940e70 100644 --- a/Assets/VRM10/vrmlib/Runtime/Vrm/SpringBoneManager.cs +++ b/Assets/VRM10/vrmlib/Runtime/Vrm/SpringBoneManager.cs @@ -53,6 +53,11 @@ public class SpringJoint { public readonly Node Node; + public SpringJoint(Node node) + { + Node = node; + } + public float DragForce; public Vector3 GravityDir; From 1a28a18e29c3aedf1f82f99c78aba9e649dd5f79 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Fri, 22 Jan 2021 15:34:58 +0900 Subject: [PATCH 20/22] fix comment --- .../Components/SpringBone/VRM10SpringJoint.cs | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringJoint.cs b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringJoint.cs index 4f44cf97a3..c35efd06f1 100644 --- a/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringJoint.cs +++ b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringJoint.cs @@ -48,18 +48,9 @@ public void Update(Transform center, float deltaTime, List Date: Fri, 22 Jan 2021 15:45:02 +0900 Subject: [PATCH 21/22] restore spring gizmo --- .../Components/SpringBone/VRM10SpringBone.cs | 22 +++++-------------- .../SpringBone/VRM10SpringBoneManager.cs | 19 ++++++++++++++++ .../Runtime/Components/VRM10Controller.cs | 5 +++++ 3 files changed, 30 insertions(+), 16 deletions(-) diff --git a/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBone.cs b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBone.cs index 561ca4f2a4..6b57c62c66 100644 --- a/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBone.cs +++ b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBone.cs @@ -15,21 +15,14 @@ public class VRM10SpringBone [SerializeField] public string m_comment; - [SerializeField, Header("Gizmo")] - bool m_drawGizmo = default; - - [SerializeField] - Color m_gizmoColor = Color.yellow; - - [SerializeField] - public Transform m_center; - [SerializeField] public List Joints = new List(); [SerializeField] public List ColliderGroups = new List(); + [SerializeField] + public Transform m_center; [ContextMenu("Reset bones")] public void ResetJoints() @@ -100,16 +93,13 @@ public void Process() } } - private void OnDrawGizmos() + public void DrawGizmo(Color color) { - if (m_drawGizmo) + foreach (var joint in Joints) { - foreach (var joint in Joints) + if (joint != null) { - if (joint != null) - { - joint.DrawGizmo(m_center, m_gizmoColor); - } + joint.DrawGizmo(m_center, color); } } } diff --git a/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneManager.cs b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneManager.cs index 369d7a7d09..1eea53e463 100644 --- a/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneManager.cs +++ b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneManager.cs @@ -11,9 +11,17 @@ namespace UniVRM10 [Serializable] public class VRM10SpringBoneManager { + [SerializeField, Header("Gizmo")] + bool m_drawGizmo = default; + + [SerializeField] + Color m_gizmoColor = Color.yellow; + + [SerializeField] public List Springs = new List(); + /// /// 1フレームに一回呼び出す(VRM10Controllerの仕事) /// @@ -24,5 +32,16 @@ public void Process() spring.Process(); } } + + public void DrawGizmos() + { + if (m_drawGizmo) + { + foreach (var spring in Springs) + { + spring.DrawGizmo(m_gizmoColor); + } + } + } } } diff --git a/Assets/VRM10/Runtime/Components/VRM10Controller.cs b/Assets/VRM10/Runtime/Components/VRM10Controller.cs index 1759771aee..08fc8f857b 100644 --- a/Assets/VRM10/Runtime/Components/VRM10Controller.cs +++ b/Assets/VRM10/Runtime/Components/VRM10Controller.cs @@ -168,5 +168,10 @@ private void LateUpdate() Apply(); } } + + private void OnDrawGizmos() + { + SpringBone.DrawGizmos(); + } } } From 9b45fb9f729f6ca07838e289df442bdf797b8ce6 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Fri, 22 Jan 2021 15:55:55 +0900 Subject: [PATCH 22/22] exclude checkbox --- .../Runtime/Components/SpringBone/VRM10SpringJoint.cs | 9 ++++++--- Assets/VRM10/Runtime/IO/Vrm10Storage.cs | 1 + Assets/VRM10/Runtime/UnityBuilder/ComponentBuilder.cs | 3 ++- Assets/VRM10/Runtime/VRMConverter/RuntimeVrmConverter.cs | 3 ++- Assets/VRM10/vrmlib/Runtime/Vrm/SpringBoneManager.cs | 2 ++ 5 files changed, 13 insertions(+), 5 deletions(-) diff --git a/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringJoint.cs b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringJoint.cs index c35efd06f1..88214a493d 100644 --- a/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringJoint.cs +++ b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringJoint.cs @@ -27,8 +27,11 @@ public VRM10SpringJoint(Transform t) [SerializeField, Range(0, 1)] public float m_dragForce = 0.4f; + [SerializeField] + public bool m_exclude; + [SerializeField, Range(0, 0.5f), Header("Collision")] - public float m_hitRadius = 0.02f; + public float m_jointRadius = 0.02f; SpringBoneLogic m_logic; @@ -36,7 +39,7 @@ public void DrawGizmo(Transform center, Color color) { if (m_logic != null) { - m_logic.DrawGizmo(center, m_hitRadius, color); + m_logic.DrawGizmo(center, m_jointRadius, color); } else { @@ -69,7 +72,7 @@ public void Update(Transform center, float deltaTime, List nodes) joint.GravityDir = gltfJoint.GravityDir.ToVector3(); joint.GravityPower = gltfJoint.GravityPower.Value; joint.Stiffness = gltfJoint.Stiffness.Value; + joint.Exclude = gltfJoint.Exclude.Value; springBone.Joints.Add(joint); } diff --git a/Assets/VRM10/Runtime/UnityBuilder/ComponentBuilder.cs b/Assets/VRM10/Runtime/UnityBuilder/ComponentBuilder.cs index 45ed6c4e98..6c54bbb0aa 100644 --- a/Assets/VRM10/Runtime/UnityBuilder/ComponentBuilder.cs +++ b/Assets/VRM10/Runtime/UnityBuilder/ComponentBuilder.cs @@ -307,7 +307,8 @@ public static void Build10(VrmLib.Model model, ModelAsset asset) joint.m_gravityPower = vrmJoint.GravityPower; joint.m_gravityDir = vrmJoint.GravityDir.ToUnityVector3(); joint.m_dragForce = vrmJoint.DragForce; - joint.m_hitRadius = vrmJoint.HitRadius; + joint.m_jointRadius = vrmJoint.HitRadius; + joint.m_exclude = vrmJoint.Exclude; springBone.Joints.Add(joint); } diff --git a/Assets/VRM10/Runtime/VRMConverter/RuntimeVrmConverter.cs b/Assets/VRM10/Runtime/VRMConverter/RuntimeVrmConverter.cs index 8b1f3c94ec..978572936f 100644 --- a/Assets/VRM10/Runtime/VRMConverter/RuntimeVrmConverter.cs +++ b/Assets/VRM10/Runtime/VRMConverter/RuntimeVrmConverter.cs @@ -362,7 +362,8 @@ public VrmLib.Model ToModelFrom10(GameObject root, VRM10MetaObject metaObject = GravityPower = joint.m_gravityPower, GravityDir = joint.m_gravityDir.ToNumericsVector3(), DragForce = joint.m_dragForce, - HitRadius = joint.m_hitRadius, + HitRadius = joint.m_jointRadius, + Exclude = joint.m_exclude, }); } diff --git a/Assets/VRM10/vrmlib/Runtime/Vrm/SpringBoneManager.cs b/Assets/VRM10/vrmlib/Runtime/Vrm/SpringBoneManager.cs index 270a940e70..9639a21fa2 100644 --- a/Assets/VRM10/vrmlib/Runtime/Vrm/SpringBoneManager.cs +++ b/Assets/VRM10/vrmlib/Runtime/Vrm/SpringBoneManager.cs @@ -67,6 +67,8 @@ public SpringJoint(Node node) public float HitRadius; public float Stiffness; + + public bool Exclude; } public class SpringBone