mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-05-16 07:34:05 -05:00
disable process button if not validated
This commit is contained in:
parent
5fd2a743a1
commit
41a7aeda65
|
|
@ -8,7 +8,7 @@ namespace UniGLTF.MeshUtility
|
|||
public class MeshProcessDialog : EditorWindow
|
||||
{
|
||||
const string TITLE = "Mesh Processing Window";
|
||||
public MeshProcessDialogTabs Tab;
|
||||
MeshProcessDialogTabs _tab;
|
||||
|
||||
private GameObject _exportTarget;
|
||||
|
||||
|
|
@ -42,40 +42,28 @@ namespace UniGLTF.MeshUtility
|
|||
}
|
||||
}
|
||||
|
||||
static bool IsGameObjectSelected()
|
||||
{
|
||||
return Selection.activeObject != null && Selection.activeObject is GameObject;
|
||||
}
|
||||
|
||||
private void OnGUI()
|
||||
{
|
||||
_scrollPos = EditorGUILayout.BeginScrollView(_scrollPos);
|
||||
EditorGUIUtility.labelWidth = 300;
|
||||
// lang
|
||||
EditorGUIUtility.labelWidth = 200;
|
||||
LanguageGetter.OnGuiSelectLang();
|
||||
_exportTarget = (GameObject)EditorGUILayout.ObjectField(MeshProcessingMessages.TARGET_OBJECT.Msg(), _exportTarget, typeof(GameObject), true);
|
||||
_tab = TabBar.OnGUI(_tab, "LargeButton", GUI.ToolbarButtonSize.Fixed);
|
||||
|
||||
{
|
||||
// _exportTarget
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField(MeshProcessingMessages.TARGET_OBJECT.Msg(), GUILayout.MaxWidth(146.0f));
|
||||
_exportTarget = (GameObject)EditorGUILayout.ObjectField(_exportTarget, typeof(GameObject), true);
|
||||
EditorGUILayout.EndHorizontal();
|
||||
// auto select ?
|
||||
if (_exportTarget == null && IsGameObjectSelected())
|
||||
{
|
||||
_exportTarget = Selection.activeObject as GameObject;
|
||||
}
|
||||
}
|
||||
|
||||
// tab
|
||||
Tab = TabBar.OnGUI(Tab, "LargeButton", GUI.ToolbarButtonSize.Fixed);
|
||||
var processed = false;
|
||||
switch (Tab)
|
||||
switch (_tab)
|
||||
{
|
||||
case MeshProcessDialogTabs.MeshSeparator:
|
||||
{
|
||||
EditorGUILayout.HelpBox(MeshProcessingMessages.MESH_SEPARATOR.Msg(), MessageType.Info);
|
||||
processed = TabMeshSeparator.OnGUI(_exportTarget);
|
||||
if (TabMeshSeparator.TryExecutable(_exportTarget, out string msg))
|
||||
{
|
||||
processed = TabMeshSeparator.OnGUI(_exportTarget);
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.HelpBox(msg, MessageType.Error);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -83,7 +71,14 @@ namespace UniGLTF.MeshUtility
|
|||
{
|
||||
EditorGUILayout.HelpBox(MeshProcessingMessages.MESH_INTEGRATOR.Msg(), MessageType.Info);
|
||||
_separateByBlendShape = EditorGUILayout.Toggle(MeshProcessingMessages.MESH_SEPARATOR_BY_BLENDSHAPE.Msg(), _separateByBlendShape);
|
||||
processed = TabMeshIntegrator.OnGUI(_exportTarget, _separateByBlendShape);
|
||||
if (TabMeshIntegrator.TryExecutable(_exportTarget, out string msg))
|
||||
{
|
||||
processed = TabMeshIntegrator.OnGUI(_exportTarget, _separateByBlendShape);
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.HelpBox(msg, MessageType.Error);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -95,7 +90,14 @@ namespace UniGLTF.MeshUtility
|
|||
_boneMeshEraserEditor.OnInspectorGUI();
|
||||
}
|
||||
_boneMeshRemoverValidator.Validate(_skinnedMeshRenderer, _eraseBones);
|
||||
processed = TabBoneMeshRemover.OnGUI(_exportTarget, _skinnedMeshRenderer, _eraseBones);
|
||||
if (TabBoneMeshRemover.TryExecutable(_exportTarget, _skinnedMeshRenderer, out string msg))
|
||||
{
|
||||
processed = TabBoneMeshRemover.OnGUI(_exportTarget, _skinnedMeshRenderer, _eraseBones);
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.HelpBox(msg, MessageType.Error);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -80,8 +80,8 @@ namespace UniGLTF.MeshUtility
|
|||
[LangMsg(Languages.en, "Skinned/Static mesh is not contained")]
|
||||
NO_MESH,
|
||||
|
||||
[LangMsg(Languages.ja, "ターゲットオブジェクトはVRMモデルです。`VRM0-> MeshIntegrator`を使ってください")]
|
||||
[LangMsg(Languages.en, "Target object is VRM model, use `VRM0 -> MeshIntegrator` instead")]
|
||||
[LangMsg(Languages.ja, "BlendShapeClipが不整合を起こすので、`VRM0-> MeshIntegrator`を使ってください")]
|
||||
[LangMsg(Languages.en, "Because BlendShapeClip causes inconsistency , use `VRM0 -> MeshIntegrator` instead")]
|
||||
VRM_DETECTED,
|
||||
}
|
||||
}
|
||||
|
|
@ -13,6 +13,24 @@ namespace UniGLTF.MeshUtility
|
|||
const string BONE_MESH_ERASER_NAME = "BoneMeshEraser";
|
||||
const string ASSET_SUFFIX = ".mesh.asset";
|
||||
|
||||
public static bool TryExecutable(GameObject root, SkinnedMeshRenderer smr, out string msg)
|
||||
{
|
||||
if (root == null)
|
||||
{
|
||||
msg = MeshProcessingMessages.NO_GAMEOBJECT_SELECTED.Msg();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (smr == null)
|
||||
{
|
||||
msg = MeshProcessingMessages.SELECT_SKINNED_MESH.Msg();
|
||||
return false;
|
||||
}
|
||||
|
||||
msg = "";
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool OnGUI(GameObject root, SkinnedMeshRenderer smr, List<BoneMeshEraser.EraseBone> eraseBones)
|
||||
{
|
||||
var _isInvokeSuccess = false;
|
||||
|
|
@ -32,18 +50,6 @@ namespace UniGLTF.MeshUtility
|
|||
|
||||
private static bool Execute(GameObject root, SkinnedMeshRenderer smr, List<BoneMeshEraser.EraseBone> eraseBones)
|
||||
{
|
||||
if (root == null)
|
||||
{
|
||||
EditorUtility.DisplayDialog("Failed", MeshProcessingMessages.NO_GAMEOBJECT_SELECTED.Msg(), "ok");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (smr == null)
|
||||
{
|
||||
EditorUtility.DisplayDialog("Failed", MeshProcessingMessages.SELECT_SKINNED_MESH.Msg(), "ok");
|
||||
return false;
|
||||
}
|
||||
|
||||
var bones = smr.bones;
|
||||
|
||||
var meshNode = new GameObject(BONE_MESH_ERASER_NAME);
|
||||
|
|
|
|||
|
|
@ -7,21 +7,29 @@ namespace UniGLTF.MeshUtility
|
|||
{
|
||||
public static class TabMeshIntegrator
|
||||
{
|
||||
public static bool OnGUI(GameObject root, bool onlyBlendShapeRenderers)
|
||||
public static bool TryExecutable(GameObject root, out string msg)
|
||||
{
|
||||
var _isInvokeSuccess = false;
|
||||
GUILayout.BeginVertical();
|
||||
// check
|
||||
if (root == null)
|
||||
{
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
if (GUILayout.Button("Process", GUILayout.MinWidth(100)))
|
||||
{
|
||||
_isInvokeSuccess = TabMeshIntegrator.Execute(root, onlyBlendShapeRenderers);
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
msg = MeshProcessingMessages.NO_GAMEOBJECT_SELECTED.Msg();
|
||||
return false;
|
||||
}
|
||||
GUILayout.EndVertical();
|
||||
return _isInvokeSuccess;
|
||||
|
||||
if (HasVrm(root))
|
||||
{
|
||||
msg = MeshProcessingMessages.VRM_DETECTED.Msg();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (root.GetComponentsInChildren<SkinnedMeshRenderer>().Length == 0 && root.GetComponentsInChildren<MeshFilter>().Length == 0)
|
||||
{
|
||||
msg = MeshProcessingMessages.NO_MESH.Msg();
|
||||
return false;
|
||||
}
|
||||
|
||||
msg = "";
|
||||
return true;
|
||||
}
|
||||
|
||||
const string VRM_META = "VRMMeta";
|
||||
|
|
@ -40,28 +48,25 @@ namespace UniGLTF.MeshUtility
|
|||
return false;
|
||||
}
|
||||
|
||||
public static bool OnGUI(GameObject root, bool onlyBlendShapeRenderers)
|
||||
{
|
||||
var _isInvokeSuccess = false;
|
||||
GUILayout.BeginVertical();
|
||||
{
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
if (GUILayout.Button("Process", GUILayout.MinWidth(100)))
|
||||
{
|
||||
_isInvokeSuccess = TabMeshIntegrator.Execute(root, onlyBlendShapeRenderers);
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
GUILayout.EndVertical();
|
||||
return _isInvokeSuccess;
|
||||
}
|
||||
|
||||
static bool Execute(GameObject root, bool onlyBlendShapeRenderers)
|
||||
{
|
||||
// check
|
||||
if (root == null)
|
||||
{
|
||||
EditorUtility.DisplayDialog("Failed", MeshProcessingMessages.NO_GAMEOBJECT_SELECTED.Msg(), "ok");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (HasVrm(root))
|
||||
{
|
||||
EditorUtility.DisplayDialog("Failed", MeshProcessingMessages.VRM_DETECTED.Msg(), "ok");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (root.GetComponentsInChildren<SkinnedMeshRenderer>().Length == 0 && root.GetComponentsInChildren<MeshFilter>().Length == 0)
|
||||
{
|
||||
EditorUtility.DisplayDialog("Failed", MeshProcessingMessages.NO_MESH.Msg(), "ok");
|
||||
return false;
|
||||
}
|
||||
|
||||
// execute
|
||||
var results = new List<MeshIntegrationResult>();
|
||||
if (onlyBlendShapeRenderers)
|
||||
{
|
||||
|
|
@ -75,7 +80,6 @@ namespace UniGLTF.MeshUtility
|
|||
|
||||
// 統合結果を適用した新しいヒエラルキーをコピーから作成する
|
||||
MeshIntegratorUtility.CopyAndReplaceWithResults(root, results);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,15 +12,32 @@ namespace UniGLTF.MeshUtility
|
|||
/// </summary>
|
||||
public static class TabMeshSeparator
|
||||
{
|
||||
private static readonly Vector3 ZERO_MOVEMENT = Vector3.zero;
|
||||
const string ASSET_SUFFIX = ".mesh.asset";
|
||||
private const string ASSET_SUFFIX = ".mesh.asset";
|
||||
|
||||
enum BlendShapeLogic
|
||||
private enum BlendShapeLogic
|
||||
{
|
||||
WithBlendShape,
|
||||
WithoutBlendShape,
|
||||
}
|
||||
|
||||
public static bool TryExecutable(GameObject root, out string msg)
|
||||
{
|
||||
if (root == null)
|
||||
{
|
||||
msg = MeshProcessingMessages.NO_GAMEOBJECT_SELECTED.Msg();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (root.GetComponentsInChildren<SkinnedMeshRenderer>().Length == 0)
|
||||
{
|
||||
msg = MeshProcessingMessages.NO_SKINNED_MESH.Msg();
|
||||
return false;
|
||||
}
|
||||
|
||||
msg = "";
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool OnGUI(GameObject root)
|
||||
{
|
||||
var _isInvokeSuccess = false;
|
||||
|
|
@ -38,36 +55,25 @@ namespace UniGLTF.MeshUtility
|
|||
return _isInvokeSuccess;
|
||||
}
|
||||
|
||||
static bool Execute(GameObject root)
|
||||
private static bool Execute(GameObject root)
|
||||
{
|
||||
if (root == null)
|
||||
{
|
||||
EditorUtility.DisplayDialog("Failed", MeshProcessingMessages.NO_GAMEOBJECT_SELECTED.Msg(), "ok");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (root.GetComponentsInChildren<SkinnedMeshRenderer>().Length == 0)
|
||||
{
|
||||
EditorUtility.DisplayDialog("Failed", MeshProcessingMessages.NO_SKINNED_MESH.Msg(), "ok");
|
||||
return false;
|
||||
}
|
||||
|
||||
// copy
|
||||
var outputObject = GameObject.Instantiate(root);
|
||||
outputObject.name = outputObject.name + "_mesh_separation";
|
||||
|
||||
// 改変と asset の作成
|
||||
var list = SeparationProcessing(outputObject);
|
||||
|
||||
// asset の永続化
|
||||
foreach (var (src, with, without) in list)
|
||||
{
|
||||
// asset の永続化
|
||||
SaveMesh(src, with, BlendShapeLogic.WithBlendShape);
|
||||
SaveMesh(src, without, BlendShapeLogic.WithoutBlendShape);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void SaveMesh(Mesh mesh, Mesh newMesh, BlendShapeLogic blendShapeLabel)
|
||||
private static void SaveMesh(Mesh mesh, Mesh newMesh, BlendShapeLogic blendShapeLabel)
|
||||
{
|
||||
// save mesh as asset
|
||||
var assetPath = string.Format("{0}{1}", Path.GetFileNameWithoutExtension(mesh.name), ASSET_SUFFIX);
|
||||
|
|
@ -98,7 +104,7 @@ namespace UniGLTF.MeshUtility
|
|||
/// </summary>
|
||||
/// <param name="go"></param>
|
||||
/// <return>(Mesh 分割前, Mesh BlendShape有り、Mesh BlendShape無し)のリストを返す</return>
|
||||
public static List<(Mesh Src, Mesh With, Mesh Without)> SeparationProcessing(GameObject go)
|
||||
private static List<(Mesh Src, Mesh With, Mesh Without)> SeparationProcessing(GameObject go)
|
||||
{
|
||||
var list = new List<(Mesh Src, Mesh With, Mesh Without)>();
|
||||
var skinnedMeshRenderers = go.GetComponentsInChildren<SkinnedMeshRenderer>();
|
||||
|
|
@ -131,7 +137,7 @@ namespace UniGLTF.MeshUtility
|
|||
|
||||
for (int j = 0; j < deltaVertices.Length; j++)
|
||||
{
|
||||
if (!deltaVertices[j].Equals(ZERO_MOVEMENT))
|
||||
if (!deltaVertices[j].Equals(Vector3.zero))
|
||||
{
|
||||
if (!indicesUsedByBlendShape.Values.Contains(j))
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user