From da8793e4576ed75dbe84a93ae275f6a32ae734e3 Mon Sep 17 00:00:00 2001 From: hiroj Date: Wed, 21 Apr 2021 18:24:19 +0900 Subject: [PATCH] same mesh export --- .../Runtime/UniGLTF/IO/MeshWithRenderer.cs | 16 +++++ .../Runtime/UniGLTF/IO/gltfExporter.cs | 59 ++++++++++++++++--- 2 files changed, 68 insertions(+), 7 deletions(-) diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshWithRenderer.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshWithRenderer.cs index 1ee16c1e8..4caee6365 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshWithRenderer.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshWithRenderer.cs @@ -91,5 +91,21 @@ namespace UniGLTF yield return x; } } + + public bool IsSameMeshAndMaterials(MeshWithRenderer other) + { + return IsSameMeshAndMaterials(other.Mesh, other.Renderer.sharedMaterials); + } + + public bool IsSameMeshAndMaterials(Mesh mesh, Material[] materials) + { + if (Mesh != mesh) return false; + if (Renderer.sharedMaterials.Length != materials.Length) return false; + for (var i = 0; i < Renderer.sharedMaterials.Length; i++) + { + if (Renderer.sharedMaterials[i] != materials[i]) return false; + } + return true; + } } } diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/gltfExporter.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/gltfExporter.cs index 12631dd41..f8e42179d 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/gltfExporter.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/gltfExporter.cs @@ -134,7 +134,7 @@ namespace UniGLTF } #region Export - static glTFNode ExportNode(Transform x, List nodes, List renderers, List skins) + static glTFNode ExportNode(Transform x, List nodes, List meshWithRenderers, List skins) { var node = new glTFNode { @@ -148,22 +148,62 @@ namespace UniGLTF if (x.gameObject.activeInHierarchy) { var meshRenderer = x.GetComponent(); + if (meshRenderer != null) { - node.mesh = renderers.IndexOf(meshRenderer); + var meshFilter = x.GetComponent(); + if(meshFilter != null) + { + var mesh = meshFilter.sharedMesh; + var materials = meshRenderer.sharedMaterials; + if (TryGetSameMeshIndex(meshWithRenderers, mesh, materials, out int meshIndex)) + { + node.mesh = meshIndex; + } + else + { + // MeshとMaterialが一致するものが見つからなかった + throw new Exception("Mesh not found."); + } + } } var skinnedMeshRenderer = x.GetComponent(); if (skinnedMeshRenderer != null) { - node.mesh = renderers.IndexOf(skinnedMeshRenderer); - node.skin = skins.IndexOf(skinnedMeshRenderer); + var mesh = skinnedMeshRenderer.sharedMesh; + var materials = skinnedMeshRenderer.sharedMaterials; + if(TryGetSameMeshIndex(meshWithRenderers, mesh, materials, out int meshIndex)) + { + node.mesh = meshIndex; + node.skin = skins.IndexOf(skinnedMeshRenderer); + } + else + { + // MeshとMaterialが一致するものが見つからなかった + throw new Exception("Mesh not found."); + } } } return node; } + private static bool TryGetSameMeshIndex(List meshWithRenderers, Mesh mesh, Material[] materials, out int meshIndex) + { + for (var i = 0; i < meshWithRenderers.Count; i++) + { + if (meshWithRenderers[i].IsSameMeshAndMaterials(mesh, materials)) + { + meshIndex = i; + return true; + } + } + + meshIndex = -1; + return false; + } + public virtual void ExportExtensions(Func getTextureBytes) { @@ -189,9 +229,14 @@ namespace UniGLTF #region Meshes var unityMeshes = MeshWithRenderer.FromNodes(Nodes).Where(x => x.Mesh.vertices.Any()).ToList(); + var uniqueUnityMeshes = new List(); + foreach (var um in unityMeshes) + { + if (!uniqueUnityMeshes.Any(x => x.IsSameMeshAndMaterials(um))) uniqueUnityMeshes.Add(um); + } MeshBlendShapeIndexMap = new Dictionary>(); - foreach (var unityMesh in unityMeshes) + foreach (var unityMesh in uniqueUnityMeshes) { var (gltfMesh, blendShapeIndexMap) = MeshExporter.ExportMesh(glTF, bufferIndex, unityMesh, Materials, meshExportSettings, m_axisInverter); glTF.meshes.Add(gltfMesh); @@ -205,10 +250,10 @@ namespace UniGLTF #endregion #region Nodes and Skins - var unitySkins = unityMeshes + var unitySkins = uniqueUnityMeshes .Where(x => x.UniqueBones != null) .ToList(); - glTF.nodes = Nodes.Select(x => ExportNode(x, Nodes, unityMeshes.Select(y => y.Renderer).ToList(), unitySkins.Select(y => y.Renderer as SkinnedMeshRenderer).ToList())).ToList(); + glTF.nodes = Nodes.Select(x => ExportNode(x, Nodes, uniqueUnityMeshes, unitySkins.Select(y => y.Renderer as SkinnedMeshRenderer).ToList())).ToList(); glTF.scenes = new List { new gltfScene