mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-08-24 19:45:37 -05:00
ExportDialogBase
This commit is contained in:
174
Assets/UniGLTF/Editor/UniGLTF/ExportDialog/ExportDialogBase.cs
Normal file
174
Assets/UniGLTF/Editor/UniGLTF/ExportDialog/ExportDialogBase.cs
Normal file
@@ -0,0 +1,174 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UniGLTF
|
||||
{
|
||||
/// <summary>
|
||||
/// ヒエラルキーをエクスポートするダイアログ。
|
||||
///
|
||||
/// * Root管理(m_state)
|
||||
/// * Validation管理(Exportボタンを押せるか否か)
|
||||
///
|
||||
/// </summary>
|
||||
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<Validator> 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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 292cdc4b7dd3b6d47a1215ad528f50c2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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<GltfExportSettings>();
|
||||
m_settingsInspector = Editor.CreateEditor(m_settings);
|
||||
}
|
||||
|
||||
protected override void Clear()
|
||||
{
|
||||
// m_settingsInspector
|
||||
UnityEditor.Editor.DestroyImmediate(m_settingsInspector);
|
||||
m_settingsInspector = null;
|
||||
}
|
||||
|
||||
protected override IEnumerable<Validator> 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<GltfExportSettings>();
|
||||
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<Validator> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user