Skip to content

Commit

Permalink
Merge pull request #899 from hiroj/fix_same_mesh_export
Browse files Browse the repository at this point in the history
同一のMeshとMaterialを参照しているNodeをExportする場合に、重複をチェックして同じMeshIndexを参照するように変更
  • Loading branch information
ousttrue authored Apr 21, 2021
2 parents baaf950 + da8793e commit af50e8e
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 7 deletions.
16 changes: 16 additions & 0 deletions Assets/UniGLTF/Runtime/UniGLTF/IO/MeshWithRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,5 +91,21 @@ public static IEnumerable<MeshWithRenderer> FromNodes(IEnumerable<Transform> nod
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;
}
}
}
59 changes: 52 additions & 7 deletions Assets/UniGLTF/Runtime/UniGLTF/IO/gltfExporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ public void Dispose()
}

#region Export
static glTFNode ExportNode(Transform x, List<Transform> nodes, List<Renderer> renderers, List<SkinnedMeshRenderer> skins)
static glTFNode ExportNode(Transform x, List<Transform> nodes, List<MeshWithRenderer> meshWithRenderers, List<SkinnedMeshRenderer> skins)
{
var node = new glTFNode
{
Expand All @@ -148,22 +148,62 @@ static glTFNode ExportNode(Transform x, List<Transform> nodes, List<Renderer> re
if (x.gameObject.activeInHierarchy)
{
var meshRenderer = x.GetComponent<MeshRenderer>();

if (meshRenderer != null)
{
node.mesh = renderers.IndexOf(meshRenderer);
var meshFilter = x.GetComponent<MeshFilter>();
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<SkinnedMeshRenderer>();
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<MeshWithRenderer> 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<Texture2D, (byte[], string)> getTextureBytes)
{

Expand All @@ -189,9 +229,14 @@ public virtual void Export(MeshExportSettings meshExportSettings, Func<Texture,

#region Meshes
var unityMeshes = MeshWithRenderer.FromNodes(Nodes).Where(x => x.Mesh.vertices.Any()).ToList();
var uniqueUnityMeshes = new List<MeshWithRenderer>();
foreach (var um in unityMeshes)
{
if (!uniqueUnityMeshes.Any(x => x.IsSameMeshAndMaterials(um))) uniqueUnityMeshes.Add(um);
}

MeshBlendShapeIndexMap = new Dictionary<Mesh, Dictionary<int, int>>();
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);
Expand All @@ -205,10 +250,10 @@ public virtual void Export(MeshExportSettings meshExportSettings, Func<Texture,
#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<gltfScene>
{
new gltfScene
Expand Down

0 comments on commit af50e8e

Please sign in to comment.