Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

backport v0.67 #899 #901

Merged
merged 1 commit into from
Apr 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -85,5 +85,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;
}
}
}
61 changes: 53 additions & 8 deletions Assets/UniGLTF/Runtime/UniGLTF/IO/gltfExporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,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 @@ -257,22 +257,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 Export(MeshExportSettings meshExportSettings)
{
var bytesBuffer = new ArrayByteBuffer(new byte[50 * 1024 * 1024]);
Expand Down Expand Up @@ -300,10 +340,15 @@ public virtual void Export(MeshExportSettings meshExportSettings)

#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 (mesh, gltfMesh, blendShapeIndexMap) in MeshExporter.ExportMeshes(
glTF, bufferIndex, unityMeshes, Materials, meshExportSettings))
glTF, bufferIndex, uniqueUnityMeshes, Materials, meshExportSettings))
{
glTF.meshes.Add(gltfMesh);
if (!MeshBlendShapeIndexMap.ContainsKey(mesh))
Expand All @@ -312,14 +357,14 @@ public virtual void Export(MeshExportSettings meshExportSettings)
MeshBlendShapeIndexMap.Add(mesh, blendShapeIndexMap);
}
}
Meshes = unityMeshes.Select(x => x.Mesh).ToList();
Meshes = uniqueUnityMeshes.Select(x => x.Mesh).ToList();
#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