From 1b6ebbdef7ee9bb99acc4be65e8e666d6f4c373a Mon Sep 17 00:00:00 2001 From: ousttrue Date: Mon, 7 Mar 2022 17:12:32 +0900 Subject: [PATCH] =?UTF-8?q?MeshUtility.SeparationProcessing=20=E3=81=AE?= =?UTF-8?q?=E4=BB=95=E6=A7=98=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * コピーしない(呼び出し側で、必要に応じてコピーする) * Assetを保存しない * Assetのリストをreturnする(呼び出し側で、必要に応じてAsset化したりDestroyする) --- .../Editor/MeshUtility/MeshProcessDialog.cs | 12 ++- .../UniGLTF/Editor/MeshUtility/MeshUtility.cs | 75 +++++++++++++------ 2 files changed, 62 insertions(+), 25 deletions(-) diff --git a/Assets/UniGLTF/Editor/MeshUtility/MeshProcessDialog.cs b/Assets/UniGLTF/Editor/MeshUtility/MeshProcessDialog.cs index 0e392b7e7..c42b5a8cd 100644 --- a/Assets/UniGLTF/Editor/MeshUtility/MeshProcessDialog.cs +++ b/Assets/UniGLTF/Editor/MeshUtility/MeshProcessDialog.cs @@ -236,7 +236,17 @@ namespace UniGLTF.MeshUtility if (go.GetComponentsInChildren().Length > 0) { - MeshUtility.SeparationProcessing(go); + // copy + var outputObject = GameObject.Instantiate(go); + outputObject.name = outputObject.name + "_mesh_separation"; + // 改変と asset の作成 + var list = MeshUtility.SeparationProcessing(outputObject); + foreach (var (src, with, without) in list) + { + // asset の永続化 + MeshUtility.SaveMesh(src, with, MeshUtility.BlendShapeLogic.WithBlendShape); + MeshUtility.SaveMesh(src, without, MeshUtility.BlendShapeLogic.WithoutBlendShape); + } return true; } else diff --git a/Assets/UniGLTF/Editor/MeshUtility/MeshUtility.cs b/Assets/UniGLTF/Editor/MeshUtility/MeshUtility.cs index 0910182e7..b8b888c62 100644 --- a/Assets/UniGLTF/Editor/MeshUtility/MeshUtility.cs +++ b/Assets/UniGLTF/Editor/MeshUtility/MeshUtility.cs @@ -20,27 +20,44 @@ namespace UniGLTF.MeshUtility #endif } - private enum BlendShapeLogic + public enum BlendShapeLogic { WithBlendShape, WithoutBlendShape, } - public static void SeparationProcessing(GameObject go) + /// + /// 対象のヒエラルキーに含まれるすべての SkinnedMeshRenderer に対して、 + /// BlendShape を含む Mesh と 含まない Mesh への分割を実施する。 + /// + /// 各 SkinnedMeshRenderer(smr) は、 + /// + /// smr - mesh(with blendshape) + /// + smr(without) - mesh(without blendshape) + /// + /// のように変化する。 + /// + /// + /// (Mesh 分割前, Mesh BlendShape有り、Mesh BlendShape無し)のリストを返す + public static List<(Mesh Src, Mesh With, Mesh Without)> SeparationProcessing(GameObject go) { - var outputObject = GameObject.Instantiate(go); - outputObject.name = outputObject.name + "_mesh_separation"; - var skinnedMeshRenderers = outputObject.GetComponentsInChildren(); + var list = new List<(Mesh Src, Mesh With, Mesh Without)>(); + var skinnedMeshRenderers = go.GetComponentsInChildren(); foreach (var skinnedMeshRenderer in skinnedMeshRenderers) { if (skinnedMeshRenderer.sharedMesh.blendShapeCount > 0) { - SeparatePolyWithBlendShape(skinnedMeshRenderer); + var (mesh, with, without) = SeparatePolyWithBlendShape(skinnedMeshRenderer); + if (mesh != null) + { + list.Add((mesh, with, without)); + } } } + return list; } - private static void SeparatePolyWithBlendShape(SkinnedMeshRenderer skinnedMeshRendererInput) + private static (Mesh mesh, Mesh With, Mesh Without) SeparatePolyWithBlendShape(SkinnedMeshRenderer skinnedMeshRendererInput) { var indicesUsedByBlendShape = new Dictionary(); var mesh = skinnedMeshRendererInput.sharedMesh; @@ -111,8 +128,13 @@ namespace UniGLTF.MeshUtility var skinnedMeshRendererWithoutBS = targetObjectForMeshWithoutBS.GetComponent(); // build meshes with/without BlendShape - BuildNewMesh(skinnedMeshRendererInput, vertexIndexWithBlendShape, submeshesWithBlendShape, BlendShapeLogic.WithBlendShape); - BuildNewMesh(skinnedMeshRendererWithoutBS, vertexIndexWithoutBlendShape, submeshesWithoutBlendShape, BlendShapeLogic.WithoutBlendShape); + var with = BuildNewMesh(skinnedMeshRendererInput, vertexIndexWithBlendShape, submeshesWithBlendShape, BlendShapeLogic.WithBlendShape); + var without = BuildNewMesh(skinnedMeshRendererWithoutBS, vertexIndexWithoutBlendShape, submeshesWithoutBlendShape, BlendShapeLogic.WithoutBlendShape); + return (mesh, with, without); + } + else + { + return default; } } @@ -158,7 +180,7 @@ namespace UniGLTF.MeshUtility } } - private static void BuildNewMesh(SkinnedMeshRenderer skinnedMeshRenderer, Dictionary newIndexLookUpDict, + private static Mesh BuildNewMesh(SkinnedMeshRenderer skinnedMeshRenderer, Dictionary newIndexLookUpDict, Dictionary subMeshes, BlendShapeLogic blendShapeLabel) { // get original mesh data @@ -233,20 +255,7 @@ namespace UniGLTF.MeshUtility skinnedMeshRenderer.sharedMaterials = materialListNew.ToArray(); skinnedMeshRenderer.sharedMesh = newMesh; - // save mesh as asset - 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) + "_" + blendShapeLabel.ToString(), ASSET_SUFFIX); - } - else - { - assetPath = string.Format("Assets/{0}{1}", Path.GetFileNameWithoutExtension(mesh.name) + "_" + blendShapeLabel.ToString(), ASSET_SUFFIX); - } - Debug.LogFormat("CreateAsset: {0}", assetPath); - AssetDatabase.CreateAsset(newMesh, assetPath); + return newMesh; } #if UNITY_EDITOR @@ -362,6 +371,24 @@ namespace UniGLTF.MeshUtility } } + public 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); + 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) + "_" + blendShapeLabel.ToString(), ASSET_SUFFIX); + } + else + { + assetPath = string.Format("Assets/{0}{1}", Path.GetFileNameWithoutExtension(mesh.name) + "_" + blendShapeLabel.ToString(), ASSET_SUFFIX); + } + Debug.LogFormat("CreateAsset: {0}", assetPath); + AssetDatabase.CreateAsset(newMesh, assetPath); + } + private static void SaveMeshData(Mesh mesh) { var assetPath = string.Format("{0}{1}", Path.GetFileNameWithoutExtension(mesh.name), ASSET_SUFFIX);