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;
}
}
}