diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/GltfData.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/GltfData.cs index 1d4d24ac4..8494e1bb8 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/GltfData.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/GltfData.cs @@ -199,58 +199,16 @@ namespace UniGLTF return new BufferAccessor(NativeArrayManager, bytes.GetSubArray(byteOffset, bytes.Length - byteOffset), AccessorValueType.UNSIGNED_INT, AccessorVectorType.SCALAR, count); } + + default: + throw new NotImplementedException("GetIndices: unknown componenttype: " + componentType); } - throw new NotImplementedException("GetIndices: unknown componenttype: " + componentType); } - /// - /// Get indices and cast to int - /// - /// - /// - /// - IEnumerable GetIntIndicesFromAccessor(glTFAccessor accessor, out int count) + public BufferAccessor GetIndicesFromAccessor(glTFAccessor accessor) { - count = accessor.count; var view = GLTF.bufferViews[accessor.bufferView]; - switch ((glComponentType)accessor.componentType) - { - case glComponentType.UNSIGNED_BYTE: - { - return GetTypedFromAccessor(accessor, view).Select(x => (int)(x)); - } - - case glComponentType.UNSIGNED_SHORT: - { - return GetTypedFromAccessor(accessor, view).Select(x => (int)(x)); - } - - case glComponentType.UNSIGNED_INT: - { - return GetTypedFromAccessor(accessor, view).Select(x => (int)(x)); - } - } - throw new NotImplementedException("GetIndices: unknown componenttype: " + accessor.componentType); - } - - public int[] GetIndices(int accessorIndex) - { - int count; - var result = GetIntIndicesFromAccessor(GLTF.accessors[accessorIndex], out count); - var indices = new int[count]; - - // flip triangles - var it = result.GetEnumerator(); - { - for (int i = 0; i < count; i += 3) - { - it.MoveNext(); indices[i + 2] = it.Current; - it.MoveNext(); indices[i + 1] = it.Current; - it.MoveNext(); indices[i] = it.Current; - } - } - - return indices; + return GetIntIndicesFromView(view, accessor.count, accessor.byteOffset, accessor.componentType); } public NativeArray GetArrayFromAccessor(int accessorIndex) where T : struct diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshContext.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshContext.cs index 9da8d70d0..163b75e6b 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshContext.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshContext.cs @@ -6,7 +6,7 @@ using UnityEngine.Profiling; using UnityEngine.Rendering; namespace UniGLTF -{ +{ internal class MeshContext { private readonly List _vertices = new List(); @@ -23,6 +23,46 @@ namespace UniGLTF public string Name { get; } + /// + /// * flip triangle + /// * add submesh offset + /// + /// + /// + void PushIndices(BufferAccessor src, int offset) + { + switch (src.ComponentType) + { + case AccessorValueType.UNSIGNED_SHORT: + { + var indices = src.Bytes.Reinterpret(1); + for (int i = 0; i < src.Count; i += 3) + { + _indices.Add(offset + indices[i + 2]); + _indices.Add(offset + indices[i + 1]); + _indices.Add(offset + indices[i]); + } + } + break; + + case AccessorValueType.UNSIGNED_INT: + { + // たぶん int で OK + var indices = src.Bytes.Reinterpret(1); + for (int i = 0; i < src.Count; i += 3) + { + _indices.Add(offset + indices[i + 2]); + _indices.Add(offset + indices[i + 1]); + _indices.Add(offset + indices[i]); + } + } + break; + + default: + throw new NotImplementedException(); + } + } + /// /// 頂点情報をMeshに対して送る /// @@ -112,6 +152,25 @@ namespace UniGLTF return src; } + int GetIndicesCapacity(GltfData data, glTFMesh gltfMesh) + { + var count = 0; + foreach (var primitive in gltfMesh.primitives) + { + if (primitive.indices == -1) + { + var positions = data.GLTF.accessors[primitive.attributes.POSITION]; + count += positions.count; + } + else + { + var accessor = data.GLTF.accessors[primitive.indices]; + count += accessor.count; + } + } + return count; + } + /// /// 各 primitive の attribute の要素が同じでない。=> uv が有るものと無いものが混在するなど /// glTF 的にはありうる。 @@ -123,6 +182,8 @@ namespace UniGLTF /// public void ImportMeshIndependentVertexBuffer(GltfData data, glTFMesh gltfMesh, IAxisInverter inverter) { + _indices.Capacity = GetIndicesCapacity(data, gltfMesh); + foreach (var primitives in gltfMesh.primitives) { var vertexOffset = _vertices.Count; @@ -232,9 +293,9 @@ namespace UniGLTF if (indexBufferCount >= 0) { var indexOffset = _indices.Count; - var dataIndices = data.GetIndices(indexBufferCount); - _indices.AddRange(dataIndices.Select(index => index + vertexOffset)); - _subMeshes.Add(new SubMeshDescriptor(indexOffset, dataIndices.Length)); + var dataIndices = data.GetIndicesFromAccessor(data.GLTF.accessors[indexBufferCount]); + PushIndices(dataIndices, vertexOffset); + _subMeshes.Add(new SubMeshDescriptor(indexOffset, dataIndices.Count)); } else { @@ -268,6 +329,8 @@ namespace UniGLTF /// public void ImportMeshSharingVertexBuffer(GltfData data, glTFMesh gltfMesh, IAxisInverter inverter) { + _indices.Capacity = GetIndicesCapacity(data, gltfMesh); + { // 同じVertexBufferを共有しているので先頭のモノを使う var primitives = gltfMesh.primitives.First(); @@ -369,9 +432,9 @@ namespace UniGLTF else { var indexOffset = _indices.Count; - var indices = data.GetIndices(primitive.indices); - _indices.AddRange(indices); - _subMeshes.Add(new SubMeshDescriptor(indexOffset, indices.Length)); + var indices = data.GetIndicesFromAccessor(data.GLTF.accessors[primitive.indices]); + PushIndices(indices, 0); + _subMeshes.Add(new SubMeshDescriptor(indexOffset, indices.Count)); } // material diff --git a/Assets/UniGLTF/Tests/UniGLTF/MeshTests.cs b/Assets/UniGLTF/Tests/UniGLTF/MeshTests.cs index 5a8c0d48a..6fb1ecdd4 100644 --- a/Assets/UniGLTF/Tests/UniGLTF/MeshTests.cs +++ b/Assets/UniGLTF/Tests/UniGLTF/MeshTests.cs @@ -143,7 +143,7 @@ namespace UniGLTF { { - var indices = parsed.GetIndices(gltfMesh.primitives[0].indices); + var indices = parsed.GetIndicesFromAccessor(parsed.GLTF.accessors[gltfMesh.primitives[0].indices]).Bytes.Reinterpret(1); Assert.AreEqual(0, indices[0]); Assert.AreEqual(1, indices[1]); Assert.AreEqual(5, indices[2]); @@ -153,7 +153,7 @@ namespace UniGLTF } { - var indices = parsed.GetIndices(gltfMesh.primitives[1].indices); + var indices = parsed.GetIndicesFromAccessor(parsed.GLTF.accessors[gltfMesh.primitives[1].indices]).Bytes.Reinterpret(1); Assert.AreEqual(1, indices[0]); Assert.AreEqual(2, indices[1]); Assert.AreEqual(4, indices[2]); @@ -193,7 +193,7 @@ namespace UniGLTF using (var parsed = GltfData.CreateFromGltfDataForTest(data.Gltf, data.BinBytes)) { { - var indices = parsed.GetIndices(gltfMesh.primitives[0].indices); + var indices = parsed.GetIndicesFromAccessor(parsed.GLTF.accessors[gltfMesh.primitives[0].indices]).Bytes.Reinterpret(1); Assert.AreEqual(0, indices[0]); Assert.AreEqual(1, indices[1]); Assert.AreEqual(3, indices[2]); @@ -207,7 +207,7 @@ namespace UniGLTF } { - var indices = parsed.GetIndices(gltfMesh.primitives[1].indices); + var indices = parsed.GetIndicesFromAccessor(parsed.GLTF.accessors[gltfMesh.primitives[1].indices]).Bytes.Reinterpret(1); Assert.AreEqual(0, indices[0]); Assert.AreEqual(1, indices[1]); Assert.AreEqual(3, indices[2]);