diff --git a/Assets/UniGLTF/Editor/MeshUtility/BoneMeshEraserEditor.cs b/Assets/UniGLTF/Editor/MeshUtility/BoneMeshEraserEditor.cs deleted file mode 100644 index 212e77b9b..000000000 --- a/Assets/UniGLTF/Editor/MeshUtility/BoneMeshEraserEditor.cs +++ /dev/null @@ -1,43 +0,0 @@ -using UniGLTF.M17N; -using UnityEditor; -using UnityEngine; - -namespace UniGLTF.MeshUtility -{ - /// - /// BoneMeshRemover 向けのエディタ。 - /// - /// SerializedProperty 経由で ユーザー定義 struct のフィールド - /// public List _eraseBones; - /// を EditorGUILayout.PropertyField するための細工である。 - /// - /// SerializedObject は UnityEngine.Object から作成するので、 - /// UnityEngine.Object を継承したクラスのフィールドに ユーザー定義 struct を配置する。 - /// 持ち主の SerializedObject を経由して EditorGUILayout.PropertyField してる。 - /// - [CustomEditor(typeof(MeshUtilityDialog), true)] - class BoneMeshEraserEditor : Editor - { - MeshUtilityDialog _targetDialog; - SerializedProperty _skinnedMesh; - SerializedProperty _eraseBones; - - void OnEnable() - { - _targetDialog = target as MeshUtilityDialog; - if (_targetDialog) - { - _skinnedMesh = serializedObject.FindProperty(nameof(MeshUtilityDialog._skinnedMeshRenderer)); - _eraseBones = serializedObject.FindProperty(nameof(MeshUtilityDialog._eraseBones)); - } - } - - public override void OnInspectorGUI() - { - serializedObject.Update(); - EditorGUILayout.PropertyField(_skinnedMesh); - EditorGUILayout.PropertyField(_eraseBones); - serializedObject.ApplyModifiedProperties(); - } - } -} diff --git a/Assets/VRM10/Editor/MeshUtility/MeshIntegrationTab.cs b/Assets/UniGLTF/Editor/MeshUtility/MeshIntegrationTab.cs similarity index 87% rename from Assets/VRM10/Editor/MeshUtility/MeshIntegrationTab.cs rename to Assets/UniGLTF/Editor/MeshUtility/MeshIntegrationTab.cs index fb3d5c0fb..cf90961e5 100644 --- a/Assets/VRM10/Editor/MeshUtility/MeshIntegrationTab.cs +++ b/Assets/UniGLTF/Editor/MeshUtility/MeshIntegrationTab.cs @@ -1,22 +1,21 @@ using System.Collections.Generic; -using UniGLTF.MeshUtility; using UnityEditor; using UnityEditorInternal; using UnityEngine; -namespace UniVRM10 +namespace UniGLTF.MeshUtility { - class MeshIntegrationTab + public class MeshIntegrationTab { bool _modified = false; - Vrm10MeshUtility _meshUti; + protected GltfMeshUtility _meshUti; Splitter _splitter; ReorderableList _groupList; ReorderableList _rendererList; public List _renderers = new List(); - int _selected = -1; - int Selected + protected int _selected = -1; + protected int Selected { set { @@ -34,7 +33,7 @@ namespace UniVRM10 } } - public MeshIntegrationTab(EditorWindow editor, Vrm10MeshUtility meshUtility) + public MeshIntegrationTab(EditorWindow editor, GltfMeshUtility meshUtility) { _meshUti = meshUtility; _splitter = new VerticalSplitter(editor, 200, 50); @@ -66,11 +65,10 @@ namespace UniVRM10 }; } - public void UpdateMeshIntegrationList(GameObject root) + public virtual void UpdateMeshIntegrationList(GameObject root) { _selected = -1; _meshUti.MeshIntegrationGroups.Clear(); - _meshUti.IntegrateFirstPerson(root); Selected = 0; } diff --git a/Assets/VRM10/Editor/MeshUtility/MeshIntegrationTab.cs.meta b/Assets/UniGLTF/Editor/MeshUtility/MeshIntegrationTab.cs.meta similarity index 83% rename from Assets/VRM10/Editor/MeshUtility/MeshIntegrationTab.cs.meta rename to Assets/UniGLTF/Editor/MeshUtility/MeshIntegrationTab.cs.meta index 91a743257..3ed1e2492 100644 --- a/Assets/VRM10/Editor/MeshUtility/MeshIntegrationTab.cs.meta +++ b/Assets/UniGLTF/Editor/MeshUtility/MeshIntegrationTab.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 07d031dea01a55c43b1ec68cd10bf461 +guid: 27b74253f485b4b45a8d2847ec3c2b34 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/UniGLTF/Editor/MeshUtility/MeshUtilityDialog.cs b/Assets/UniGLTF/Editor/MeshUtility/MeshUtilityDialog.cs index 17eeca36a..ba7ff48e9 100644 --- a/Assets/UniGLTF/Editor/MeshUtility/MeshUtilityDialog.cs +++ b/Assets/UniGLTF/Editor/MeshUtility/MeshUtilityDialog.cs @@ -2,34 +2,13 @@ using UnityEngine; using UnityEditor; using UniGLTF.M17N; using System.Collections.Generic; +using System.Linq; namespace UniGLTF.MeshUtility { public class MeshUtilityDialog : EditorWindow { public const string MENU_NAME = "glTF MeshUtility"; - enum MeshProcessDialogTabs - { - MeshSeparator, - MeshIntegrator, - BoneMeshEraser, - } - MeshProcessDialogTabs _tab; - - private GameObject _exportTarget; - - [SerializeField] - public bool _separateByBlendShape = true; - - [SerializeField] - public SkinnedMeshRenderer _skinnedMeshRenderer = null; - - [SerializeField] - public List _eraseBones; - - private BoneMeshEraserEditor _boneMeshEraserEditor; - private Vector2 _scrollPos = new Vector2(0, 0); - public static void OpenWindow() { var window = @@ -38,82 +17,182 @@ namespace UniGLTF.MeshUtility window.Show(); } - private void OnEnable() + protected enum Tabs { - if (!_boneMeshEraserEditor) + Freeze, + IntegrateSplit, + BoneMeshEraser, + } + protected Tabs _tab; + protected GameObject _exportTarget; + + GltfMeshUtility _meshUtil; + protected virtual GltfMeshUtility MeshUtility + { + get { - _boneMeshEraserEditor = (BoneMeshEraserEditor)Editor.CreateEditor(this); + if (_meshUtil == null) + { + _meshUtil = new GltfMeshUtility(); + } + return _meshUtil; } } + MeshIntegrationTab _integrationTab; + protected virtual MeshIntegrationTab MeshIntegration + { + get + { + if (_integrationTab == null) + { + _integrationTab = new MeshIntegrationTab(this, MeshUtility); + } + return _integrationTab; + } + } + + protected List _validations = new List(); + protected virtual void Validate() + { + _validations.Clear(); + if (_exportTarget == null) + { + _validations.Add(Validation.Error("set target GameObject")); + return; + } + } + bool IsValid => !_validations.Any(v => !v.CanExport); + Vector2 _scrollPos; + + void OnEnable() + { + } private void OnGUI() { + var modified = false; _scrollPos = EditorGUILayout.BeginScrollView(_scrollPos); EditorGUIUtility.labelWidth = 200; LanguageGetter.OnGuiSelectLang(); - _exportTarget = (GameObject)EditorGUILayout.ObjectField(MeshUtilityMessages.TARGET_OBJECT.Msg(), _exportTarget, typeof(GameObject), true); + var exportTarget = (GameObject)EditorGUILayout.ObjectField( + MeshUtilityMessages.TARGET_OBJECT.Msg(), + _exportTarget, typeof(GameObject), true); + if (exportTarget != _exportTarget) + { + _exportTarget = exportTarget; + MeshIntegration.UpdateMeshIntegrationList(_exportTarget); + modified = true; + } _tab = TabBar.OnGUI(_tab, "LargeButton", GUI.ToolbarButtonSize.Fixed); - var processed = false; + foreach (var validation in _validations) + { + validation.DrawGUI(); + } + + EditorGUILayout.HelpBox(MeshUtilityMessages.MESH_SEPARATOR.Msg(), MessageType.Info); + EditorGUILayout.HelpBox(MeshUtilityMessages.MESH_INTEGRATOR.Msg(), MessageType.Info); + switch (_tab) { - case MeshProcessDialogTabs.MeshSeparator: + case Tabs.Freeze: { - EditorGUILayout.HelpBox(MeshUtilityMessages.MESH_SEPARATOR.Msg(), MessageType.Info); - if (TabMeshSeparator.TryExecutable(_exportTarget, out string msg)) + if (MeshFreezeGui()) { - processed = TabMeshSeparator.OnGUI(_exportTarget); - } - else - { - EditorGUILayout.HelpBox(msg, MessageType.Error); + modified = true; } break; } - case MeshProcessDialogTabs.MeshIntegrator: + case Tabs.IntegrateSplit: { - EditorGUILayout.HelpBox(MeshUtilityMessages.MESH_INTEGRATOR.Msg(), MessageType.Info); - _separateByBlendShape = EditorGUILayout.Toggle(MeshUtilityMessages.MESH_SEPARATOR_BY_BLENDSHAPE.Msg(), _separateByBlendShape); - if (TabMeshIntegrator.TryExecutable(_exportTarget, out string msg)) + if (MeshIntegrateGui()) { - if (GUILayout.Button("Process", GUILayout.MinWidth(100))) - { - processed = TabMeshIntegrator.Execute(_exportTarget, _separateByBlendShape); - } - } - else - { - EditorGUILayout.HelpBox(msg, MessageType.Error); + modified = true; } break; } - case MeshProcessDialogTabs.BoneMeshEraser: + case Tabs.BoneMeshEraser: { + // TODO: FirstPerson 処理と統合する EditorGUILayout.HelpBox(MeshUtilityMessages.BONE_MESH_ERASER.Msg(), MessageType.Info); - if (_boneMeshEraserEditor) - { - _boneMeshEraserEditor.OnInspectorGUI(); - } - if (TabBoneMeshRemover.TryExecutable(_exportTarget, _skinnedMeshRenderer, out string msg)) - { - processed = TabBoneMeshRemover.OnGUI(_exportTarget, _skinnedMeshRenderer, _eraseBones); - } - else - { - EditorGUILayout.HelpBox(msg, MessageType.Error); - } + // if (_boneMeshEraserEditor) + // { + // _boneMeshEraserEditor.OnInspectorGUI(); + // } + // if (TabBoneMeshRemover.TryExecutable(_exportTarget, _skinnedMeshRenderer, out string msg)) + // { + // processed = TabBoneMeshRemover.OnGUI(_exportTarget, _skinnedMeshRenderer, _eraseBones); + // } + // else + // { + // EditorGUILayout.HelpBox(msg, MessageType.Error); + // } break; } } EditorGUILayout.EndScrollView(); - if (processed) + if (modified) { - Close(); - GUIUtility.ExitGUI(); + Validate(); } + + GUI.enabled = IsValid; + var pressed = GUILayout.Button("Process", GUILayout.MinWidth(100)); + GUI.enabled = true; + if (pressed) + { + Undo.RegisterFullObjectHierarchyUndo(exportTarget, "MeshUtility"); + foreach (var go in MeshUtility.Process(exportTarget)) + { + Undo.RegisterCreatedObjectUndo(go, "MeshUtility"); + } + _exportTarget = null; + // Show Result ? + // Close(); + // GUIUtility.ExitGUI(); + } + } + + protected bool ToggleIsModified(string label, ref bool value) + { + var newValue = EditorGUILayout.Toggle(label, value); + if (newValue == value) + { + return false; + } + value = newValue; + return true; + } + + bool MeshFreezeGui() + { + var forceUniqueName = ToggleIsModified("ForceUniqueName", ref MeshUtility.ForceUniqueName); + var blendShape = ToggleIsModified("BlendShape", ref MeshUtility.FreezeBlendShape); + var scale = ToggleIsModified("Scale", ref MeshUtility.FreezeScaling); + var rotation = ToggleIsModified("Rotation", ref MeshUtility.FreezeRotation); + return forceUniqueName || blendShape || scale || rotation; + } + + protected virtual bool MeshIntegrateGui() + { + var split = ToggleIsModified("Separate by BlendShape", ref MeshUtility.SplitByBlendShape); + var p = position; + var last = GUILayoutUtility.GetLastRect(); + var y = last.y + last.height; + var rect = new Rect + { + x = last.x, + y = y, + width = p.width, + height = p.height - y + // process button の高さ + - 30 + }; + var mod = MeshIntegration.OnGui(rect); + return split || mod; } } } \ No newline at end of file diff --git a/Assets/VRM10/Editor/MeshUtility/Splitter.cs b/Assets/UniGLTF/Editor/MeshUtility/Splitter.cs similarity index 99% rename from Assets/VRM10/Editor/MeshUtility/Splitter.cs rename to Assets/UniGLTF/Editor/MeshUtility/Splitter.cs index 743bae80c..f1fd2e221 100644 --- a/Assets/VRM10/Editor/MeshUtility/Splitter.cs +++ b/Assets/UniGLTF/Editor/MeshUtility/Splitter.cs @@ -2,7 +2,7 @@ using UnityEngine; using UnityEditor; using System; -namespace UniVRM10 +namespace UniGLTF.MeshUtility { [Serializable] public abstract class Splitter diff --git a/Assets/VRM10/Editor/MeshUtility/Splitter.cs.meta b/Assets/UniGLTF/Editor/MeshUtility/Splitter.cs.meta similarity index 83% rename from Assets/VRM10/Editor/MeshUtility/Splitter.cs.meta rename to Assets/UniGLTF/Editor/MeshUtility/Splitter.cs.meta index 57ca79cfc..4ef6a69d1 100644 --- a/Assets/VRM10/Editor/MeshUtility/Splitter.cs.meta +++ b/Assets/UniGLTF/Editor/MeshUtility/Splitter.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 385274edf555ed84a9f3706ca2a99023 +guid: dbb5f5bceb86592499a56fc18011553e MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/VRM10/Editor/MeshUtility/Vrm10MeshIntegrationTab.cs b/Assets/VRM10/Editor/MeshUtility/Vrm10MeshIntegrationTab.cs new file mode 100644 index 000000000..9a2d13fd8 --- /dev/null +++ b/Assets/VRM10/Editor/MeshUtility/Vrm10MeshIntegrationTab.cs @@ -0,0 +1,23 @@ +using UnityEditor; +using UnityEngine; + +namespace UniVRM10 +{ + class Vrm10MeshIntegrationTab : UniGLTF.MeshUtility.MeshIntegrationTab + { + Vrm10MeshUtility _vrmMeshUtil; + + public Vrm10MeshIntegrationTab(EditorWindow editor, Vrm10MeshUtility meshUtility) : base(editor, meshUtility) + { + _vrmMeshUtil = meshUtility; + } + + public override void UpdateMeshIntegrationList(GameObject root) + { + _selected = -1; + _meshUti.MeshIntegrationGroups.Clear(); + _vrmMeshUtil.IntegrateFirstPerson(root); + Selected = 0; + } + } +} \ No newline at end of file diff --git a/Assets/UniGLTF/Editor/MeshUtility/BoneMeshEraserEditor.cs.meta b/Assets/VRM10/Editor/MeshUtility/Vrm10MeshIntegrationTab.cs.meta similarity index 83% rename from Assets/UniGLTF/Editor/MeshUtility/BoneMeshEraserEditor.cs.meta rename to Assets/VRM10/Editor/MeshUtility/Vrm10MeshIntegrationTab.cs.meta index d256f2e98..078ce5177 100644 --- a/Assets/UniGLTF/Editor/MeshUtility/BoneMeshEraserEditor.cs.meta +++ b/Assets/VRM10/Editor/MeshUtility/Vrm10MeshIntegrationTab.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 2021859c0d7255643bd93c95ab3fcf3d +guid: ec2a4df10a08bab4a980b7203d341bda MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/VRM10/Editor/MeshUtility/Vrm10MeshUtilityDialog.cs b/Assets/VRM10/Editor/MeshUtility/Vrm10MeshUtilityDialog.cs index 1ac07d0b4..138421761 100644 --- a/Assets/VRM10/Editor/MeshUtility/Vrm10MeshUtilityDialog.cs +++ b/Assets/VRM10/Editor/MeshUtility/Vrm10MeshUtilityDialog.cs @@ -1,163 +1,61 @@ using UnityEngine; using UnityEditor; -using UniGLTF.M17N; -using System.Collections.Generic; -using UniGLTF.MeshUtility; using UniGLTF; -using System.Linq; namespace UniVRM10 { - public class Vrm10MeshUtilityDialog : EditorWindow + public class Vrm10MeshUtilityDialog : UniGLTF.MeshUtility.MeshUtilityDialog { - public const string MENU_NAME = "VRM 1.0 MeshUtility"; - - enum Tabs - { - Freeze, - IntegrateSplit, - } - Tabs _tab; - - public static void OpenWindow() + public new const string MENU_NAME = "VRM 1.0 MeshUtility"; + public new static void OpenWindow() { var window = (Vrm10MeshUtilityDialog)EditorWindow.GetWindow(typeof(Vrm10MeshUtilityDialog)); window.titleContent = new GUIContent(MENU_NAME); window.Show(); } - - Vrm10MeshUtility _meshUtility = new Vrm10MeshUtility(); - - List _validations = new List(); - private void Validate() + protected override void Validate() { - _validations.Clear(); - if (_exportTarget == null) - { - _validations.Add(Validation.Error("set vrm1")); - return; - } + base.Validate(); if (_exportTarget.GetComponent() == null) { _validations.Add(Validation.Error("target is not vrm1")); return; } } - bool IsValid => !_validations.Any(v => !v.CanExport); - Vector2 _scrollPos; - GameObject _exportTarget; - MeshIntegrationTab _meshIntegration; - void OnEnable() + Vrm10MeshUtility _meshUtil; + Vrm10MeshUtility Vrm10MeshUtility { - _meshIntegration = new MeshIntegrationTab(this, _meshUtility); - } - - private void OnGUI() - { - var modified = false; - _scrollPos = EditorGUILayout.BeginScrollView(_scrollPos); - EditorGUIUtility.labelWidth = 200; - LanguageGetter.OnGuiSelectLang(); - var exportTarget = (GameObject)EditorGUILayout.ObjectField( - MeshUtilityMessages.TARGET_OBJECT.Msg(), - _exportTarget, typeof(GameObject), true); - if (exportTarget != _exportTarget) + get { - _exportTarget = exportTarget; - _meshIntegration.UpdateMeshIntegrationList(_exportTarget); - modified = true; - } - _tab = TabBar.OnGUI(_tab, "LargeButton", GUI.ToolbarButtonSize.Fixed); - - foreach (var validation in _validations) - { - validation.DrawGUI(); - } - - switch (_tab) - { - case Tabs.Freeze: - { - if (MeshFreezeGui()) - { - modified = true; - } - break; - } - - case Tabs.IntegrateSplit: - { - if (MeshIntegrateGui()) - { - modified = true; - } - break; - } - } - EditorGUILayout.EndScrollView(); - - if (modified) - { - Validate(); - } - - GUI.enabled = IsValid; - var pressed = GUILayout.Button("Process", GUILayout.MinWidth(100)); - GUI.enabled = true; - if (pressed) - { - Undo.RegisterFullObjectHierarchyUndo(exportTarget, "MeshUtility"); - foreach (var go in _meshUtility.Process(exportTarget)) + if (_meshUtil == null) { - Undo.RegisterCreatedObjectUndo(go, "MeshUtility"); + _meshUtil = new Vrm10MeshUtility(); } - _exportTarget = null; - // Show Result ? - // Close(); - // GUIUtility.ExitGUI(); + return _meshUtil; + } + } + protected override UniGLTF.MeshUtility.GltfMeshUtility MeshUtility => Vrm10MeshUtility; + + Vrm10MeshIntegrationTab _integrationTab; + protected override UniGLTF.MeshUtility.MeshIntegrationTab MeshIntegration + { + get + { + if (_integrationTab == null) + { + _integrationTab = new Vrm10MeshIntegrationTab(this, Vrm10MeshUtility); + } + return _integrationTab; } } - bool ToggleIsModified(string label, ref bool value) + protected override bool MeshIntegrateGui() { - var newValue = EditorGUILayout.Toggle(label, value); - if (newValue == value) - { - return false; - } - value = newValue; - return true; - } - - bool MeshFreezeGui() - { - var forceUniqueName = ToggleIsModified("ForceUniqueName", ref _meshUtility.ForceUniqueName); - var blendShape = ToggleIsModified("BlendShape", ref _meshUtility.FreezeBlendShape); - var scale = ToggleIsModified("Scale", ref _meshUtility.FreezeScaling); - var rotation = ToggleIsModified("Rotation", ref _meshUtility.FreezeRotation); - return forceUniqueName || blendShape || scale || rotation; - } - - bool MeshIntegrateGui() - { - var firstPerson = ToggleIsModified("FirstPerson == AUTO の生成", ref _meshUtility.GenerateMeshForFirstPersonAuto); - var split = ToggleIsModified("Separate by BlendShape", ref _meshUtility.SplitByBlendShape); - var p = position; - var last = GUILayoutUtility.GetLastRect(); - var y = last.y + last.height; - var rect = new Rect - { - x = last.x, - y = y, - width = p.width, - height = p.height - y - // process button の高さ - - 30 - }; - var mod = _meshIntegration.OnGui(rect); - return firstPerson || split || mod; + var firstPerson = ToggleIsModified("FirstPerson == AUTO の生成", ref MeshUtility.GenerateMeshForFirstPersonAuto); + var mod = base.MeshIntegrateGui(); + return firstPerson || mod; } } } \ No newline at end of file