mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-05-11 04:54:17 -05:00
167 lines
5.4 KiB
C#
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();
|
|
}
|
|
}
|
|
} |