UniVRM/Assets/UniGLTF/Editor/MeshUtility/MeshProcessDialog.cs

167 lines
5.4 KiB
C#

using System.Linq;
using System.Reflection;
using UnityEngine;
using UnityEditor;
using UniGLTF;
using UniGLTF.M17N;
namespace UniGLTF.MeshUtility
{
public class MeshProcessDialog : EditorWindow
{
private Tabs _tab;
private GameObject _exportTarget;
private MeshProcessDialogEditor _boneMeshEraserEditor;
private SkinnedMeshRenderer _pSkinnedMesh;
private Animator _pAnimator;
private Transform _pEraseRoot;
private Vector2 _scrollPos = new Vector2(0, 0);
[SerializeField]
private SkinnedMeshRenderer _cSkinnedMesh = null;
[SerializeField]
private bool _separateByBlendShape = true;
private Animator _cAnimator = null;
private Transform _cEraseRoot = null;
[SerializeField]
private BoneMeshEraser.EraseBone[] _eraseBones;
private MethodInfo _processFunction;
GUIStyle _tabButtonStyle => "LargeButton";
GUI.ToolbarButtonSize _tabButtonSize => GUI.ToolbarButtonSize.Fixed;
public static void OpenWindow()
{
var window =
(MeshProcessDialog)EditorWindow.GetWindow(typeof(MeshProcessDialog));
window.titleContent = new GUIContent("Mesh Processing Window");
window.Show();
}
private void OnEnable()
{
if (!_boneMeshEraserEditor)
{
_boneMeshEraserEditor = (MeshProcessDialogEditor)Editor.CreateEditor(this);
}
}
static bool IsGameObjectSelected()
{
return Selection.activeObject != null && Selection.activeObject is GameObject;
}
private void OnGUI()
{
_scrollPos = EditorGUILayout.BeginScrollView(_scrollPos);
EditorGUIUtility.labelWidth = 300;
// lang
LanguageGetter.OnGuiSelectLang();
{
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField(MeshProcessingMessages.TARGET_OBJECT.Msg(), GUILayout.MaxWidth(146.0f));
_exportTarget = (GameObject)EditorGUILayout.ObjectField(_exportTarget, typeof(GameObject), true);
EditorGUILayout.EndHorizontal();
if (_exportTarget == null && IsGameObjectSelected())
{
_exportTarget = Selection.activeObject as GameObject;
}
}
// tab
_tab = TabBar.OnGUI(_tab, _tabButtonStyle, _tabButtonSize);
var processed = false;
switch (_tab)
{
case Tabs.MeshSeparator:
EditorGUILayout.HelpBox(MeshProcessingMessages.MESH_SEPARATOR.Msg(), MessageType.Info);
processed = TabMeshSeparator.OnGUI(_exportTarget);
break;
case Tabs.MeshIntegrator:
EditorGUILayout.HelpBox(MeshProcessingMessages.MESH_INTEGRATOR.Msg(), MessageType.Info);
_boneMeshEraserEditor.Tabs = _tab;
if (_boneMeshEraserEditor)
{
_boneMeshEraserEditor.OnInspectorGUI();
}
processed = TabMeshIntegrator.OnGUI(_exportTarget, _separateByBlendShape);
break;
case Tabs.BoneMeshEraser:
EditorGUILayout.HelpBox(MeshProcessingMessages.BONE_MESH_ERASER.Msg(), MessageType.Info);
_boneMeshEraserEditor.Tabs = _tab;
if (_boneMeshEraserEditor)
{
_boneMeshEraserEditor.OnInspectorGUI();
}
// any better way we can detect component change?
if (_cSkinnedMesh != _pSkinnedMesh || _cAnimator != _pAnimator || _cEraseRoot != _pEraseRoot)
{
BoneMeshEraserValidate();
}
_pSkinnedMesh = _cSkinnedMesh;
_pAnimator = _cAnimator;
_pEraseRoot = _cEraseRoot;
processed = TabBoneMeshRemover.OnGUI(_exportTarget, _cSkinnedMesh, _eraseBones);
break;
}
EditorGUILayout.EndScrollView();
if (processed)
{
Close();
GUIUtility.ExitGUI();
}
}
private void BoneMeshEraserValidate()
{
if (_cSkinnedMesh == null)
{
_eraseBones = new BoneMeshEraser.EraseBone[] { };
return;
}
if (_cEraseRoot == null)
{
if (_cAnimator != null)
{
_cEraseRoot = _cAnimator.GetBoneTransform(HumanBodyBones.Head);
//Debug.LogFormat("head: {0}", EraseRoot);
}
}
_eraseBones = _cSkinnedMesh.bones.Select(x =>
{
var eb = new BoneMeshEraser.EraseBone
{
Bone = x,
};
if (_cEraseRoot != null)
{
// 首の子孫を消去
if (eb.Bone.Ancestor().Any(y => y == _cEraseRoot))
{
//Debug.LogFormat("erase {0}", x);
eb.Erase = true;
}
}
return eb;
})
.ToArray();
}
}
}