From 042e3c9c4ce12214f07a2d04ea526810f22bfe0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A1lint=20Hodossy?= Date: Sat, 20 Jan 2024 19:06:15 +0000 Subject: [PATCH 1/2] Reuse indices in mesh parsing, remove trailing nulls in mesh writing --- unity/Editor/Importer/StlMeshParser.cs | 73 +++++++++++++++++--------- 1 file changed, 49 insertions(+), 24 deletions(-) diff --git a/unity/Editor/Importer/StlMeshParser.cs b/unity/Editor/Importer/StlMeshParser.cs index 207218dc..f1dfaa5e 100644 --- a/unity/Editor/Importer/StlMeshParser.cs +++ b/unity/Editor/Importer/StlMeshParser.cs @@ -12,11 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -using System; using System.Collections.Generic; using System.IO; using System.Linq; using UnityEngine; +using UnityEngine.Rendering; namespace Mujoco { @@ -27,6 +27,17 @@ public static class BinaryReaderExtensions { var z = reader.ReadSingle(); return new Vector3(x, y, z); } + + public static int GetOrCreateVertexIndex(Dictionary vertexIndexMap, List vertices, Listnormals, Vector3 vertex, Vector3 normal) { + if (vertexIndexMap.TryGetValue(vertex, out int existingIndex)) { + return existingIndex; + } + int newIndex = vertexIndexMap.Count; + vertexIndexMap.Add(vertex, newIndex); + vertices.Add(vertex); + normals.Add(normal); + return newIndex; + } } public static class BinaryWriterExtensions { @@ -50,7 +61,7 @@ public class StlMeshParser { // The binary STL format is described here: https://en.wikipedia.org/wiki/STL_(file_format) public static Mesh ParseBinary(byte[] stlFileContents, Vector3 scale) { var fileTypeId = System.Text.Encoding.UTF8.GetString( - stlFileContents.Take(_asciiFileTypeId.Length).ToArray()); + stlFileContents.Take(_asciiFileTypeId.Length).ToArray()); if (fileTypeId == _asciiFileTypeId) { throw new IOException("Ascii STL file format is not supported."); } @@ -59,27 +70,39 @@ public class StlMeshParser { using (var reader = new BinaryReader(stream)) { reader.ReadBytes(_headerLength); var numTriangles = reader.ReadUInt32(); - var numVertices = numTriangles * _verticesPerTriangle; - if (numVertices > _unityLimitNumVerticesPerMesh) { - throw new IndexOutOfRangeException( - "The mesh exceeds the number of vertices per mesh allowed by Unity. " + - $"({numVertices} > {_unityLimitNumVerticesPerMesh})"); - } - var triangleIndices = new List(capacity: (int)numVertices); - var vertices = new List(capacity: (int)numVertices); - var normals = new List(capacity: (int)numVertices); - for (var i = 0; i < numVertices; i += _verticesPerTriangle) { + var maxNumVertices = numTriangles * _verticesPerTriangle; + + Dictionary vertexIndexMap = new Dictionary(); + var triangleIndices = new int[(int)numTriangles * _verticesPerTriangle]; + var vertices = new List(capacity: (int)maxNumVertices); + var normals = new List(capacity: (int)maxNumVertices); + for (var i = 0; i < numTriangles; i++) { var triangleNormal = ToXZY(reader.ReadVector3()); - normals.AddRange(new[] { triangleNormal, triangleNormal, triangleNormal }); - vertices.AddRange(new[] { - ToXZY(reader.ReadVector3()), - ToXZY(reader.ReadVector3()), - ToXZY(reader.ReadVector3()) }); - triangleIndices.AddRange(new[] {i, i + 2, i + 1}); - reader.ReadInt16(); // Read the unused attribute indices field. + var verts = new[] + { + ToXZY(reader.ReadVector3()), + ToXZY(reader.ReadVector3()), + ToXZY(reader.ReadVector3()) + }; + var indices = new[] { verts[0], verts[2], verts[1] }.Select(v => + BinaryReaderExtensions.GetOrCreateVertexIndex(vertexIndexMap, + vertices, + normals, + v, + triangleNormal)).ToArray(); + for (int j = 0; j < 3; j++) { + triangleIndices[i * 3 + j] = indices[j]; + } + reader.ReadInt16(); // Read the unused attribute indices field. } var mesh = new Mesh(); + var numVertices = vertexIndexMap.Count; + + if (numVertices > _unityLimitNumVerticesPerMesh) { + mesh.indexFormat = IndexFormat.UInt32; + } + mesh.vertices = vertices.ToArray(); mesh.normals = normals.ToArray(); mesh.triangles = triangleIndices.ToArray(); @@ -88,6 +111,7 @@ public class StlMeshParser { mesh.RecalculateNormals(); mesh.RecalculateTangents(); mesh.RecalculateBounds(); + return mesh; } } @@ -118,15 +142,16 @@ public class StlMeshParser { var i2 = triangles[i + 1]; var i3 = triangles[i + 2]; var faceNormal = (normals[i1] + normals[i2] + normals[i3]).normalized; - writer.Write(ToXZY(faceNormal)); + writer.Write(faceNormal); - writer.Write(ToXZY(vertices[i1])); - writer.Write(ToXZY(vertices[i3])); - writer.Write(ToXZY(vertices[i2])); + writer.Write(vertices[i1]); + writer.Write(vertices[i2]); + writer.Write(vertices[i3]); writer.Write((short)0); } - return stream.GetBuffer(); + + return stream.ToArray(); } } } From 64b042369b1b9b4c21e74a04cc1f090ef5fdf1f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A1lint=20Hodossy?= Date: Wed, 24 Jan 2024 18:32:55 +0000 Subject: [PATCH 2/2] Readd axis swizzling to the mesh writer --- unity/Editor/Importer/StlMeshParser.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/unity/Editor/Importer/StlMeshParser.cs b/unity/Editor/Importer/StlMeshParser.cs index f1dfaa5e..ef3f2b95 100644 --- a/unity/Editor/Importer/StlMeshParser.cs +++ b/unity/Editor/Importer/StlMeshParser.cs @@ -142,11 +142,11 @@ public class StlMeshParser { var i2 = triangles[i + 1]; var i3 = triangles[i + 2]; var faceNormal = (normals[i1] + normals[i2] + normals[i3]).normalized; - writer.Write(faceNormal); + writer.Write(ToXZY(faceNormal)); - writer.Write(vertices[i1]); - writer.Write(vertices[i2]); - writer.Write(vertices[i3]); + writer.Write(ToXZY(vertices[i1])); + writer.Write(ToXZY(vertices[i3])); + writer.Write(ToXZY(vertices[i2])); writer.Write((short)0); }