From 7d5d323ead3889559cc1c648fba5acb366a08fb9 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Mon, 19 Apr 2021 19:29:05 +0900 Subject: [PATCH] ExportDialogBase --- .../UniGLTF/ExportDialog/ExportDialogBase.cs | 174 +++++++++++++++ .../ExportDialog/ExportDialogBase.cs.meta | 11 + .../UniGLTF/ExportDialog/GltfExportWindow.cs | 210 ++++-------------- 3 files changed, 234 insertions(+), 161 deletions(-) create mode 100644 Assets/UniGLTF/Editor/UniGLTF/ExportDialog/ExportDialogBase.cs create mode 100644 Assets/UniGLTF/Editor/UniGLTF/ExportDialog/ExportDialogBase.cs.meta diff --git a/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/ExportDialogBase.cs b/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/ExportDialogBase.cs new file mode 100644 index 000000000..d5c2044ed --- /dev/null +++ b/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/ExportDialogBase.cs @@ -0,0 +1,174 @@ +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using UnityEditor; +using UnityEngine; + +namespace UniGLTF +{ + /// + /// ヒエラルキーをエクスポートするダイアログ。 + /// + /// * Root管理(m_state) + /// * Validation管理(Exportボタンを押せるか否か) + /// + /// + public abstract class ExportDialogBase : EditorWindow + { + ExporterDialogState m_state; + protected ExporterDialogState State => m_state; + + protected virtual void OnEnable() + { + Undo.willFlushUndoRecord += Repaint; + Selection.selectionChanged += Repaint; + + m_state = new ExporterDialogState(); + m_state.ExportRootChanged += (root) => + { + Repaint(); + }; + m_state.ExportRoot = Selection.activeObject as GameObject; + + Initialize(); + } + + protected abstract void Initialize(); + + void OnDisable() + { + Clear(); + + m_state.Dispose(); + + Selection.selectionChanged -= Repaint; + Undo.willFlushUndoRecord -= Repaint; + } + + protected abstract void Clear(); + + // + // scroll + // + public delegate Vector2 BeginVerticalScrollViewFunc(Vector2 scrollPosition, bool alwaysShowVertical, GUIStyle verticalScrollbar, GUIStyle background, params GUILayoutOption[] options); + static BeginVerticalScrollViewFunc s_func; + static BeginVerticalScrollViewFunc BeginVerticalScrollView + { + get + { + if (s_func == null) + { + var methods = typeof(EditorGUILayout).GetMethods(BindingFlags.Static | BindingFlags.NonPublic).Where(x => x.Name == "BeginVerticalScrollView").ToArray(); + var method = methods.First(x => x.GetParameters()[1].ParameterType == typeof(bool)); + s_func = (BeginVerticalScrollViewFunc)method.CreateDelegate(typeof(BeginVerticalScrollViewFunc)); + } + return s_func; + } + } + private Vector2 m_ScrollPosition; + + // + // validation + // + protected abstract IEnumerable ValidatorFactory(); + + void OnGUI() + { + var modified = false; + if (BeginGUI()) + { + modified = DoGUI(); + } + EndGUI(); + + if (modified) + { + State.Invalidate(); + } + } + + protected abstract bool DoGUI(); + + bool BeginGUI() + { + // ArgumentException: Getting control 1's position in a group with only 1 controls when doing repaint Aborting + // Validation により GUI の表示項目が変わる場合があるので、 + // EventType.Layout と EventType.Repaint 間で内容が変わらないようしている。 + if (Event.current.type == EventType.Layout) + { + State.Validate(ValidatorFactory()); + } + + EditorGUIUtility.labelWidth = 150; + + // lang + Getter.OnGuiSelectLang(); + + EditorGUILayout.LabelField("ExportRoot"); + { + State.ExportRoot = (GameObject)EditorGUILayout.ObjectField(State.ExportRoot, typeof(GameObject), true); + } + + // Render contents using Generic Inspector GUI + m_ScrollPosition = BeginVerticalScrollView(m_ScrollPosition, false, GUI.skin.verticalScrollbar, "OL Box"); + GUIUtility.GetControlID(645789, FocusType.Passive); + + // validation + foreach (var v in State.Validations) + { + v.DrawGUI(); + if (v.ErrorLevel == ErrorLevels.Critical) + { + // Export UI を表示しない + return false; + } + } + return true; + } + + protected abstract string SaveTitle { get; } + protected abstract string SaveName { get; } + protected abstract string[] SaveExtensions { get; } + + void EndGUI() + { + EditorGUILayout.EndScrollView(); + + // + // export button + // + // Create and Other Buttons + { + // errors + GUILayout.BeginVertical(); + // GUILayout.FlexibleSpace(); + + { + GUILayout.BeginHorizontal(); + GUILayout.FlexibleSpace(); + GUI.enabled = State.Validations.All(x => x.CanExport); + + if (GUILayout.Button("Export", GUILayout.MinWidth(100))) + { + var path = SaveFileDialog.GetPath(SaveTitle, SaveName, SaveExtensions); + if (!string.IsNullOrEmpty(path)) + { + ExportPath(path); + // close + Close(); + GUIUtility.ExitGUI(); + } + } + GUI.enabled = true; + + GUILayout.EndHorizontal(); + } + GUILayout.EndVertical(); + } + + GUILayout.Space(8); + } + + protected abstract void ExportPath(string path); + } +} diff --git a/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/ExportDialogBase.cs.meta b/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/ExportDialogBase.cs.meta new file mode 100644 index 000000000..079c45185 --- /dev/null +++ b/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/ExportDialogBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 292cdc4b7dd3b6d47a1215ad528f50c2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/GltfExportWindow.cs b/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/GltfExportWindow.cs index 471470e26..734810433 100644 --- a/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/GltfExportWindow.cs +++ b/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/GltfExportWindow.cs @@ -1,7 +1,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using System.Reflection; using UniGLTF.Animation; using UnityEditor; using UnityEngine; @@ -9,7 +8,7 @@ using VRMShaders; namespace UniGLTF { - public class GltfExportWindow : EditorWindow + public class GltfExportWindow : ExportDialogBase { const string MENU_KEY = UniGLTFVersion.MENU + "/Export " + UniGLTFVersion.UNIGLTF_VERSION; @@ -22,6 +21,46 @@ namespace UniGLTF } private static void Export(GameObject go, string path, MeshExportSettings settings, Axises inverseAxis) + { + } + + GltfExportSettings m_settings; + Editor m_settingsInspector; + + protected override void Initialize() + { + m_settings = ScriptableObject.CreateInstance(); + m_settingsInspector = Editor.CreateEditor(m_settings); + } + + protected override void Clear() + { + // m_settingsInspector + UnityEditor.Editor.DestroyImmediate(m_settingsInspector); + m_settingsInspector = null; + } + + protected override IEnumerable ValidatorFactory() + { + yield return HierarchyValidator.ValidateRoot; + yield return AnimationValidator.Validate; + if (!State.ExportRoot) + { + yield break; + } + } + protected override bool DoGUI() + { + m_settings.Root = State.ExportRoot; + m_settingsInspector.OnInspectorGUI(); + return true; + } + + protected override string SaveTitle => "Save gltf"; + protected override string SaveName => $"{State.ExportRoot.name}.glb"; + protected override string[] SaveExtensions => new string[] { "glb", "gltf" }; + + protected override void ExportPath(string path) { var ext = Path.GetExtension(path).ToLower(); var isGlb = false; @@ -33,9 +72,15 @@ namespace UniGLTF } var gltf = new glTF(); - using (var exporter = new gltfExporter(gltf, inverseAxis)) + using (var exporter = new gltfExporter(gltf, m_settings.InverseAxis)) { - exporter.Prepare(go); + exporter.Prepare(State.ExportRoot); + var settings = new MeshExportSettings + { + ExportOnlyBlendShapePosition = m_settings.DropNormal, + UseSparseAccessorForMorphTarget = m_settings.Sparse, + DivideVertexBuffer = m_settings.DivideVertexBuffer, + }; exporter.Export(settings, AssetTextureUtil.IsTextureEditorAsset, AssetTextureUtil.GetTextureBytesWithMime); } @@ -64,164 +109,7 @@ namespace UniGLTF AssetDatabase.ImportAsset(path.ToUnityRelativePath()); AssetDatabase.Refresh(); } - } - ExporterDialogState m_state; - GltfExportSettings m_settings; - Editor m_settingsInspector; - - void OnEnable() - { - // Debug.Log("OnEnable"); - Undo.willFlushUndoRecord += Repaint; - Selection.selectionChanged += Repaint; - - m_settings = ScriptableObject.CreateInstance(); - m_settingsInspector = Editor.CreateEditor(m_settings); - - m_state = new ExporterDialogState(); - m_state.ExportRootChanged += (root) => - { - Repaint(); - }; - m_state.ExportRoot = Selection.activeObject as GameObject; - } - - void OnDisable() - { - m_state.Dispose(); - - // Debug.Log("OnDisable"); - Selection.selectionChanged -= Repaint; - Undo.willFlushUndoRecord -= Repaint; - - // m_settingsInspector - UnityEditor.Editor.DestroyImmediate(m_settingsInspector); - m_settingsInspector = null; - // m_settings - ScriptableObject.DestroyImmediate(m_settings); - m_settings = null; - } - - public delegate Vector2 BeginVerticalScrollViewFunc(Vector2 scrollPosition, bool alwaysShowVertical, GUIStyle verticalScrollbar, GUIStyle background, params GUILayoutOption[] options); - static BeginVerticalScrollViewFunc s_func; - static BeginVerticalScrollViewFunc BeginVerticalScrollView - { - get - { - if (s_func == null) - { - var methods = typeof(EditorGUILayout).GetMethods(BindingFlags.Static | BindingFlags.NonPublic).Where(x => x.Name == "BeginVerticalScrollView").ToArray(); - var method = methods.First(x => x.GetParameters()[1].ParameterType == typeof(bool)); - s_func = (BeginVerticalScrollViewFunc)method.CreateDelegate(typeof(BeginVerticalScrollViewFunc)); - } - return s_func; - } - } - private Vector2 m_ScrollPosition; - - IEnumerable ValidatorFactory() - { - yield return HierarchyValidator.ValidateRoot; - yield return AnimationValidator.Validate; - if (!m_state.ExportRoot) - { - yield break; - } - } - - private void OnGUI() - { - // ArgumentException: Getting control 1's position in a group with only 1 controls when doing repaint Aborting - // Validation により GUI の表示項目が変わる場合があるので、 - // EventType.Layout と EventType.Repaint 間で内容が変わらないようしている。 - if (Event.current.type == EventType.Layout) - { - m_state.Validate(ValidatorFactory()); - } - - EditorGUIUtility.labelWidth = 150; - - // lang - Getter.OnGuiSelectLang(); - - EditorGUILayout.LabelField("ExportRoot"); - { - m_state.ExportRoot = (GameObject)EditorGUILayout.ObjectField(m_state.ExportRoot, typeof(GameObject), true); - } - - // Render contents using Generic Inspector GUI - m_ScrollPosition = BeginVerticalScrollView(m_ScrollPosition, false, GUI.skin.verticalScrollbar, "OL Box"); - GUIUtility.GetControlID(645789, FocusType.Passive); - - bool modified = ScrollArea(); - - EditorGUILayout.EndScrollView(); - - // Create and Other Buttons - { - // errors - GUILayout.BeginVertical(); - // GUILayout.FlexibleSpace(); - - { - GUILayout.BeginHorizontal(); - GUILayout.FlexibleSpace(); - GUI.enabled = m_state.Validations.All(x => x.CanExport); - - if (GUILayout.Button("Export", GUILayout.MinWidth(100))) - { - var path = SaveFileDialog.GetPath("Save gltf", $"{m_state.ExportRoot.name}.glb", "glb", "gltf"); - if (!string.IsNullOrEmpty(path)) - { - // export - Export(m_state.ExportRoot, path, new MeshExportSettings - { - ExportOnlyBlendShapePosition = m_settings.DropNormal, - UseSparseAccessorForMorphTarget = m_settings.Sparse, - DivideVertexBuffer = m_settings.DivideVertexBuffer, - }, m_settings.InverseAxis); - // close - Close(); - GUIUtility.ExitGUI(); - } - } - GUI.enabled = true; - - GUILayout.EndHorizontal(); - } - GUILayout.EndVertical(); - } - - GUILayout.Space(8); - - if (modified) - { - m_state.Invalidate(); - } - } - - bool ScrollArea() - { - // - // Validation - // - foreach (var v in m_state.Validations) - { - v.DrawGUI(); - if (v.ErrorLevel == ErrorLevels.Critical) - { - // Export UI を表示しない - return false; - } - } - - // - // GUI - // - m_settings.Root = m_state.ExportRoot; - m_settingsInspector.OnInspectorGUI(); - return true; } } }