diff --git a/Assets/UniGLTF/Editor/MeshUtility/MeshProcessDialog.cs b/Assets/UniGLTF/Editor/MeshUtility/MeshProcessDialog.cs index 4bbe07ada..63c0c6e99 100644 --- a/Assets/UniGLTF/Editor/MeshUtility/MeshProcessDialog.cs +++ b/Assets/UniGLTF/Editor/MeshUtility/MeshProcessDialog.cs @@ -73,7 +73,10 @@ namespace UniGLTF.MeshUtility _separateByBlendShape = EditorGUILayout.Toggle(MeshProcessingMessages.MESH_SEPARATOR_BY_BLENDSHAPE.Msg(), _separateByBlendShape); if (TabMeshIntegrator.TryExecutable(_exportTarget, out string msg)) { - processed = TabMeshIntegrator.OnGUI(_exportTarget, _separateByBlendShape); + if (GUILayout.Button("Process", GUILayout.MinWidth(100))) + { + processed = TabMeshIntegrator.Execute(_exportTarget, _separateByBlendShape); + } } else { diff --git a/Assets/UniGLTF/Editor/MeshUtility/TabMeshIntegrator.cs b/Assets/UniGLTF/Editor/MeshUtility/TabMeshIntegrator.cs index c54833634..7b8d8c8cf 100644 --- a/Assets/UniGLTF/Editor/MeshUtility/TabMeshIntegrator.cs +++ b/Assets/UniGLTF/Editor/MeshUtility/TabMeshIntegrator.cs @@ -48,38 +48,56 @@ 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) + /// GameObject instance in scene or prefab + public static bool Execute(GameObject src, bool onlyBlendShapeRenderers) { var results = new List(); + + // instance or prefab => copy + var copy = GameObject.Instantiate(src); + copy.name = copy.name + "_mesh_integration"; + + // integrate if (onlyBlendShapeRenderers) { - results.Add(MeshIntegratorUtility.Integrate(root, onlyBlendShapeRenderers: MeshEnumerateOption.OnlyWithBlendShape)); - results.Add(MeshIntegratorUtility.Integrate(root, onlyBlendShapeRenderers: MeshEnumerateOption.OnlyWithoutBlendShape)); + results.Add(MeshIntegratorUtility.Integrate(copy, onlyBlendShapeRenderers: MeshEnumerateOption.OnlyWithBlendShape)); + results.Add(MeshIntegratorUtility.Integrate(copy, onlyBlendShapeRenderers: MeshEnumerateOption.OnlyWithoutBlendShape)); } else { - results.Add(MeshIntegratorUtility.Integrate(root, onlyBlendShapeRenderers: MeshEnumerateOption.All)); + results.Add(MeshIntegratorUtility.Integrate(copy, onlyBlendShapeRenderers: MeshEnumerateOption.All)); + } + + // replace + MeshIntegratorUtility.ReplaceMeshWithResults(copy, results); + + // write mesh asset. + foreach (var result in results) + { + var mesh = result.IntegratedRenderer.sharedMesh; + var assetPath = MeshIntegratorUtility.GetMeshWritePath(mesh); + Debug.LogFormat("CreateAsset: {0}", assetPath); + AssetDatabase.CreateAsset(mesh, assetPath); + } + + if (src.GetGameObjectType() == GameObjectType.AssetPrefab) + { + // write prefab. + { + var prefabPath = UnityPath.FromAsset(src); + prefabPath = prefabPath.Parent.Child($"{prefabPath.FileNameWithoutExtension}_integrated.prefab"); + Debug.LogFormat("WritePrefab: {0}", prefabPath); + PrefabUtility.SaveAsPrefabAsset(copy, prefabPath.Value); + } + + // destroy copy in scene. + GameObject.DestroyImmediate(copy); + } + else + { + // do nothing. keep copy. } - // 統合結果を適用した新しいヒエラルキーをコピーから作成する - MeshIntegratorUtility.CopyAndReplaceWithResults(root, results); return true; } } diff --git a/Assets/UniGLTF/Runtime/MeshUtility/MeshIntegratorUtility.cs b/Assets/UniGLTF/Runtime/MeshUtility/MeshIntegratorUtility.cs index f01b42dbc..5c914a144 100644 --- a/Assets/UniGLTF/Runtime/MeshUtility/MeshIntegratorUtility.cs +++ b/Assets/UniGLTF/Runtime/MeshUtility/MeshIntegratorUtility.cs @@ -165,18 +165,14 @@ namespace UniGLTF.MeshUtility } } - public static void CopyAndReplaceWithResults(GameObject root, List results) + public static void ReplaceMeshWithResults(GameObject copy, List results) { - // copy hierarchy - var outputObject = GameObject.Instantiate(root); - outputObject.name = outputObject.name + "_mesh_integration"; - - // destroy original meshes in the copied GameObject - foreach (var skinnedMesh in outputObject.GetComponentsInChildren()) + // destroy original meshes + foreach (var skinnedMesh in copy.GetComponentsInChildren()) { GameObject.DestroyImmediate(skinnedMesh); } - foreach (var normalMesh in outputObject.GetComponentsInChildren()) + foreach (var normalMesh in copy.GetComponentsInChildren()) { if (normalMesh.sharedMesh.name != MeshIntegratorUtility.INTEGRATED_MESH_NAME) { @@ -188,30 +184,24 @@ namespace UniGLTF.MeshUtility } } + // Add integrated foreach (var result in results) { - // Add integrated - result.IntegratedRenderer.transform.SetParent(outputObject.transform, false); - // save mesh data - SaveMeshData(result.IntegratedRenderer.sharedMesh); + result.IntegratedRenderer.transform.SetParent(copy.transform, false); } } - static void SaveMeshData(Mesh mesh) + public static string GetMeshWritePath(Mesh mesh) { - var assetPath = string.Format("{0}{1}", Path.GetFileNameWithoutExtension(mesh.name), ASSET_SUFFIX); - Debug.Log(assetPath); if (!string.IsNullOrEmpty((AssetDatabase.GetAssetPath(mesh)))) { var directory = Path.GetDirectoryName(AssetDatabase.GetAssetPath(mesh)).Replace("\\", "/"); - assetPath = string.Format("{0}/{1}{2}", directory, Path.GetFileNameWithoutExtension(mesh.name), ASSET_SUFFIX); + return $"{directory}/{Path.GetFileNameWithoutExtension(mesh.name)}{ASSET_SUFFIX}"; } else { - assetPath = string.Format("Assets/{0}{1}", Path.GetFileNameWithoutExtension(mesh.name), ASSET_SUFFIX); + return $"Assets/{Path.GetFileNameWithoutExtension(mesh.name)}{ASSET_SUFFIX}"; } - Debug.LogFormat("CreateAsset: {0}", assetPath); - AssetDatabase.CreateAsset(mesh, assetPath); } } } \ No newline at end of file