diff --git a/Assets/UniGLTF/Runtime/Extensions/ArrayExtensions.cs b/Assets/UniGLTF/Runtime/Extensions/ArrayExtensions.cs index 6547f93c8..49a709f4b 100644 --- a/Assets/UniGLTF/Runtime/Extensions/ArrayExtensions.cs +++ b/Assets/UniGLTF/Runtime/Extensions/ArrayExtensions.cs @@ -100,14 +100,6 @@ namespace UniGLTF } } - public static class ListExtensions - { - public static void Assign(this List dst, NativeArray src, Func pred) where T : struct - { - dst.Capacity = src.Length; - dst.AddRange(src.Select(pred)); - } - } public static class ArraySegmentExtensions { diff --git a/Assets/UniGLTF/Runtime/Extensions/UnityExtensions.cs b/Assets/UniGLTF/Runtime/Extensions/UnityExtensions.cs index d92808d9b..4da051b41 100644 --- a/Assets/UniGLTF/Runtime/Extensions/UnityExtensions.cs +++ b/Assets/UniGLTF/Runtime/Extensions/UnityExtensions.cs @@ -30,12 +30,31 @@ namespace UniGLTF public BlendShape(string name) { - Name = name; + Positions = new List(); + Normals = new List(); + Tangents = new List(); } - public List Positions = new List(); - public List Normals = new List(); - public List Tangents = new List(); + public BlendShape(string name, int vertexCount, bool hasPositions, bool hasNormals, bool hasTangents) + { + Name = name; + if (hasPositions) + { + Positions = new List(vertexCount); + } + if (hasNormals) + { + Normals = new List(vertexCount); + } + if (hasTangents) + { + Tangents = new List(vertexCount); + } + } + + public List Positions { get; private set; } + public List Normals { get; private set; } + public List Tangents { get; private set; } } public static class UnityExtensions diff --git a/Assets/UniGLTF/Runtime/Extensions/glTFExtensions.cs b/Assets/UniGLTF/Runtime/Extensions/glTFExtensions.cs index aeeb57da5..fce7d3dca 100644 --- a/Assets/UniGLTF/Runtime/Extensions/glTFExtensions.cs +++ b/Assets/UniGLTF/Runtime/Extensions/glTFExtensions.cs @@ -135,11 +135,22 @@ namespace UniGLTF } } + static Dictionary<(string, int, int), bool> s_cache = new Dictionary<(string, int, int), bool>(); + public static bool IsGeneratedUniGLTFAndOlder(this glTF gltf, int major, int minor) { if (gltf == null) return false; if (gltf.asset == null) return false; - return IsGeneratedUniGLTFAndOlderThan(gltf.asset.generator, major, minor); + + var key = (gltf.asset.generator, major, minor); + if (s_cache.TryGetValue(key, out bool isOlder)) + { + return isOlder; + } + + var result = IsGeneratedUniGLTFAndOlderThan(gltf.asset.generator, major, minor); + s_cache.Add(key, result); + return result; } } } diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshContext.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshContext.cs index 6d29baedc..3b5f9c050 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshContext.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshContext.cs @@ -164,23 +164,26 @@ namespace UniGLTF return src; } - int GetIndicesCapacity(GltfData data, glTFMesh gltfMesh) + (int VertexCapacity, int IndexCapacity) GetCapacity(GltfData data, glTFMesh gltfMesh) { - var count = 0; + var vertexCount = 0; + var indexCount = 0; foreach (var primitive in gltfMesh.primitives) { + var positions = data.GLTF.accessors[primitive.attributes.POSITION]; + vertexCount += positions.count; + if (primitive.indices == -1) { - var positions = data.GLTF.accessors[primitive.attributes.POSITION]; - count += positions.count; + indexCount += positions.count; } else { var accessor = data.GLTF.accessors[primitive.indices]; - count += accessor.count; + indexCount += accessor.count; } } - return count; + return (vertexCount, indexCount); } /// @@ -194,7 +197,9 @@ namespace UniGLTF /// public void ImportMeshIndependentVertexBuffer(GltfData data, glTFMesh gltfMesh, IAxisInverter inverter) { - _indices.Capacity = GetIndicesCapacity(data, gltfMesh); + (_vertices.Capacity, _indices.Capacity) = GetCapacity(data, gltfMesh); + + bool isOldVersion = data.GLTF.IsGeneratedUniGLTFAndOlder(1, 16); foreach (var primitives in gltfMesh.primitives) { @@ -220,7 +225,7 @@ namespace UniGLTF var texCoord0 = Vector2.zero; if (texCoords0 != null) { - if (data.GLTF.IsGeneratedUniGLTFAndOlder(1, 16)) + if (isOldVersion) { #pragma warning disable 0612 // backward compatibility @@ -341,7 +346,9 @@ namespace UniGLTF /// public void ImportMeshSharingVertexBuffer(GltfData data, glTFMesh gltfMesh, IAxisInverter inverter) { - _indices.Capacity = GetIndicesCapacity(data, gltfMesh); + (_vertices.Capacity, _indices.Capacity) = GetCapacity(data, gltfMesh); + + var isOldVersion = data.GLTF.IsGeneratedUniGLTFAndOlder(1, 16); { // 同じVertexBufferを共有しているので先頭のモノを使う @@ -364,7 +371,7 @@ namespace UniGLTF var texCoord0 = Vector2.zero; if (texCoords0 != null) { - if (data.GLTF.IsGeneratedUniGLTFAndOlder(1, 16)) + if (isOldVersion) { #pragma warning disable 0612 texCoord0 = texCoords0.Value[i].ReverseY(); @@ -405,29 +412,41 @@ namespace UniGLTF // blendshape if (primitives.targets != null && primitives.targets.Count > 0) { - _blendShapes.AddRange(primitives.targets.Select((x, i) => new BlendShape(i.ToString()))); for (int i = 0; i < primitives.targets.Count; ++i) { - //var name = string.Format("target{0}", i++); var primTarget = primitives.targets[i]; - var blendShape = _blendShapes[i]; + var blendShape = new BlendShape(i.ToString(), positions.Length, primTarget.POSITION != -1, primTarget.NORMAL != -1, primTarget.TANGENT != -1); + _blendShapes.Add(blendShape); if (primTarget.POSITION != -1) { - blendShape.Positions.Assign( - data.GetArrayFromAccessor(primTarget.POSITION), inverter.InvertVector3); + var morphPositions = data.GetArrayFromAccessor(primTarget.POSITION); + blendShape.Positions.Capacity = morphPositions.Length; + for (var j = 0; j < blendShape.Positions.Count; ++j) + { + blendShape.Positions.Add(inverter.InvertVector3(morphPositions[j])); + } } if (primTarget.NORMAL != -1) { - blendShape.Normals.Assign( - data.GetArrayFromAccessor(primTarget.NORMAL), inverter.InvertVector3); + var morphNormals = data.GetArrayFromAccessor(primTarget.NORMAL); + blendShape.Normals.Capacity = morphNormals.Length; + for (var j = 0; j < blendShape.Positions.Count; ++j) + { + blendShape.Normals.Add(inverter.InvertVector3(morphNormals[j])); + } + } if (primTarget.TANGENT != -1) { - blendShape.Tangents.Assign( - data.GetArrayFromAccessor(primTarget.TANGENT), inverter.InvertVector3); + var morphTangents = data.GetArrayFromAccessor(primTarget.TANGENT); + blendShape.Tangents.Capacity = morphTangents.Length; + for (var j = 0; j < blendShape.Tangents.Count; ++j) + { + blendShape.Tangents.Add(inverter.InvertVector3(morphTangents[j])); + } } } }