From 3e14b73cb4d5ad849edf8878d638fdef2ac97345 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Mon, 11 Jul 2022 18:08:52 +0900 Subject: [PATCH] fix MESH_PRIMITIVE_POSITION_ACCESSOR_WITHOUT_BOUNDS --- Assets/VRM10/Runtime/Migration/MeshUpdater.cs | 77 +++++++++++++------ 1 file changed, 54 insertions(+), 23 deletions(-) diff --git a/Assets/VRM10/Runtime/Migration/MeshUpdater.cs b/Assets/VRM10/Runtime/Migration/MeshUpdater.cs index c205ea9e9..97158b313 100644 --- a/Assets/VRM10/Runtime/Migration/MeshUpdater.cs +++ b/Assets/VRM10/Runtime/Migration/MeshUpdater.cs @@ -46,16 +46,38 @@ namespace UniVRM10 var bufferView = _buffer.Extend(bytes, target); var index = _bufferViews.Count; _bufferViews.Add(bufferView); + + // padding for 4byte alignment var mod = bytes.Length % 4; if (mod != 0) { - // padding for 4byte alignment _buffer.Extend(new ArraySegment(new byte[4 - mod])); } + return index; } - int AddAccessor(NativeArray span, glBufferTarget target) where T : struct + static (float[], float[]) GetMinMax(NativeArray v) + { + var minX = float.PositiveInfinity; + var minY = float.PositiveInfinity; + var minZ = float.PositiveInfinity; + var maxX = float.NegativeInfinity; + var maxY = float.NegativeInfinity; + var maxZ = float.NegativeInfinity; + for (int i = 1; i < v.Length; ++i) + { + if (v[i].x < minX) minX = v[i].x; + if (v[i].y < minY) minY = v[i].y; + if (v[i].z < minZ) minZ = v[i].z; + if (v[i].x > maxX) maxX = v[i].x; + if (v[i].y > maxY) maxY = v[i].y; + if (v[i].z > maxZ) maxZ = v[i].z; + } + return (new float[] { minX, minY, minZ }, new float[] { maxX, maxY, maxZ }); + } + + int AddAccessor(NativeArray span, glBufferTarget target, bool minMaxBounds) where T : struct { var bufferViewIndex = AddBuffer(span.Reinterpret(Marshal.SizeOf()), target); var accessor = new glTFAccessor @@ -66,18 +88,27 @@ namespace UniVRM10 componentType = glTFExtensions.GetComponentType(), type = glTFExtensions.GetAccessorType(), }; + if (minMaxBounds) + { + if (span is NativeArray positions) + { + var (min, max) = GetMinMax(positions); + accessor.min = min; + accessor.max = max; + } + } var index = _accessors.Count; _accessors.Add(accessor); return index; } - int? AddAccessor(BufferAccessor buffer, glBufferTarget target) where T : struct + int? AddAccessor(BufferAccessor buffer, glBufferTarget target, bool minMaxBounds) where T : struct { if (buffer == null) { return default; } - return AddAccessor(buffer.GetSpan(), target); + return AddAccessor(buffer.GetSpan(), target, minMaxBounds); } struct MorphAccessor @@ -136,7 +167,7 @@ namespace UniVRM10 if (skinIndex == -1) { skinIndex = gltf.skins.Count; - gltfSkin.inverseBindMatrices = AddAccessor(node.MeshGroup.Skin.InverseMatrices.GetSpan(), default); + gltfSkin.inverseBindMatrices = AddAccessor(node.MeshGroup.Skin.InverseMatrices.GetSpan(), default, false); gltf.skins.Add(gltfSkin); } else @@ -222,20 +253,20 @@ namespace UniVRM10 default: throw new NotImplementedException(); } - var position = AddAccessor(mesh.VertexBuffer.Positions, glBufferTarget.ARRAY_BUFFER); - var normal = AddAccessor(mesh.VertexBuffer.Normals, glBufferTarget.ARRAY_BUFFER); - var uv = AddAccessor(mesh.VertexBuffer.TexCoords, glBufferTarget.ARRAY_BUFFER); - var weights = AddAccessor(mesh.VertexBuffer.Weights, glBufferTarget.ARRAY_BUFFER); - var joints = AddAccessor(mesh.VertexBuffer.Joints, glBufferTarget.ARRAY_BUFFER); - var color = AddAccessor(mesh.VertexBuffer.Colors, glBufferTarget.ARRAY_BUFFER); + var position = AddAccessor(mesh.VertexBuffer.Positions, glBufferTarget.ARRAY_BUFFER, true); + var normal = AddAccessor(mesh.VertexBuffer.Normals, glBufferTarget.ARRAY_BUFFER, false); + var uv = AddAccessor(mesh.VertexBuffer.TexCoords, glBufferTarget.ARRAY_BUFFER, false); + var weights = AddAccessor(mesh.VertexBuffer.Weights, glBufferTarget.ARRAY_BUFFER, false); + var joints = AddAccessor(mesh.VertexBuffer.Joints, glBufferTarget.ARRAY_BUFFER, false); + var color = AddAccessor(mesh.VertexBuffer.Colors, glBufferTarget.ARRAY_BUFFER, false); var morphTargets = new MorphAccessor[] { }; if (mesh.MorphTargets != null) { morphTargets = mesh.MorphTargets.Select(x => new MorphAccessor { - Position = AddAccessor(x.VertexBuffer.Positions, glBufferTarget.ARRAY_BUFFER), - Normal = AddAccessor(x.VertexBuffer.Normals, glBufferTarget.ARRAY_BUFFER), + Position = AddAccessor(x.VertexBuffer.Positions, glBufferTarget.ARRAY_BUFFER, true), + Normal = AddAccessor(x.VertexBuffer.Normals, glBufferTarget.ARRAY_BUFFER, false), }).ToArray(); } @@ -243,7 +274,7 @@ namespace UniVRM10 foreach (var (gltfPrim, submesh) in Enumerable.Zip(gltfMesh.primitives, mesh.Submeshes, (l, r) => (l, r))) { var subIndices = indices.GetSubArray(submesh.Offset, submesh.DrawCount); - gltfPrim.indices = AddAccessor(subIndices, glBufferTarget.ELEMENT_ARRAY_BUFFER); + gltfPrim.indices = AddAccessor(subIndices, glBufferTarget.ELEMENT_ARRAY_BUFFER, false); gltfPrim.attributes.POSITION = position.Value; gltfPrim.attributes.NORMAL = normal.GetValueOrDefault(-1); // たぶん、ありえる gltfPrim.attributes.TANGENT = -1; @@ -306,24 +337,24 @@ namespace UniVRM10 throw new NotImplementedException(); } - var position = AddAccessor(mesh.VertexBuffer.Positions, glBufferTarget.ARRAY_BUFFER); - var normal = AddAccessor(mesh.VertexBuffer.Normals, glBufferTarget.ARRAY_BUFFER); - var uv = AddAccessor(mesh.VertexBuffer.TexCoords, glBufferTarget.ARRAY_BUFFER); - var weights = AddAccessor(mesh.VertexBuffer.Weights, glBufferTarget.ARRAY_BUFFER); - var joints = AddAccessor(mesh.VertexBuffer.Joints, glBufferTarget.ARRAY_BUFFER); - var color = AddAccessor(mesh.VertexBuffer.Colors, glBufferTarget.ARRAY_BUFFER); + var position = AddAccessor(mesh.VertexBuffer.Positions, glBufferTarget.ARRAY_BUFFER, true); + var normal = AddAccessor(mesh.VertexBuffer.Normals, glBufferTarget.ARRAY_BUFFER, false); + var uv = AddAccessor(mesh.VertexBuffer.TexCoords, glBufferTarget.ARRAY_BUFFER, false); + var weights = AddAccessor(mesh.VertexBuffer.Weights, glBufferTarget.ARRAY_BUFFER, false); + var joints = AddAccessor(mesh.VertexBuffer.Joints, glBufferTarget.ARRAY_BUFFER, false); + var color = AddAccessor(mesh.VertexBuffer.Colors, glBufferTarget.ARRAY_BUFFER, false); var morphTargets = new MorphAccessor[] { }; if (mesh.MorphTargets != null) { morphTargets = mesh.MorphTargets.Select(x => new MorphAccessor { - Position = AddAccessor(x.VertexBuffer.Positions, glBufferTarget.ARRAY_BUFFER), - Normal = AddAccessor(x.VertexBuffer.Normals, glBufferTarget.ARRAY_BUFFER), + Position = AddAccessor(x.VertexBuffer.Positions, glBufferTarget.ARRAY_BUFFER, true), + Normal = AddAccessor(x.VertexBuffer.Normals, glBufferTarget.ARRAY_BUFFER, false), }).ToArray(); } - gltfPrim.indices = AddAccessor(indices, glBufferTarget.ELEMENT_ARRAY_BUFFER); + gltfPrim.indices = AddAccessor(indices, glBufferTarget.ELEMENT_ARRAY_BUFFER, false); gltfPrim.attributes.POSITION = position.Value; gltfPrim.attributes.NORMAL = normal.GetValueOrDefault(-1); // たぶん、ありえる gltfPrim.attributes.TANGENT = -1;