fix MESH_PRIMITIVE_POSITION_ACCESSOR_WITHOUT_BOUNDS

This commit is contained in:
ousttrue
2022-07-11 18:08:52 +09:00
parent 71ca64b10d
commit 3e14b73cb4

View File

@@ -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<byte>(new byte[4 - mod]));
}
return index;
}
int AddAccessor<T>(NativeArray<T> span, glBufferTarget target) where T : struct
static (float[], float[]) GetMinMax(NativeArray<Vector3> 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<T>(NativeArray<T> span, glBufferTarget target, bool minMaxBounds) where T : struct
{
var bufferViewIndex = AddBuffer(span.Reinterpret<byte>(Marshal.SizeOf<T>()), target);
var accessor = new glTFAccessor
@@ -66,18 +88,27 @@ namespace UniVRM10
componentType = glTFExtensions.GetComponentType<T>(),
type = glTFExtensions.GetAccessorType<T>(),
};
if (minMaxBounds)
{
if (span is NativeArray<Vector3> positions)
{
var (min, max) = GetMinMax(positions);
accessor.min = min;
accessor.max = max;
}
}
var index = _accessors.Count;
_accessors.Add(accessor);
return index;
}
int? AddAccessor<T>(BufferAccessor buffer, glBufferTarget target) where T : struct
int? AddAccessor<T>(BufferAccessor buffer, glBufferTarget target, bool minMaxBounds) where T : struct
{
if (buffer == null)
{
return default;
}
return AddAccessor(buffer.GetSpan<T>(), target);
return AddAccessor(buffer.GetSpan<T>(), 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<Matrix4x4>(), default);
gltfSkin.inverseBindMatrices = AddAccessor(node.MeshGroup.Skin.InverseMatrices.GetSpan<Matrix4x4>(), default, false);
gltf.skins.Add(gltfSkin);
}
else
@@ -222,20 +253,20 @@ namespace UniVRM10
default:
throw new NotImplementedException();
}
var position = AddAccessor<Vector3>(mesh.VertexBuffer.Positions, glBufferTarget.ARRAY_BUFFER);
var normal = AddAccessor<Vector3>(mesh.VertexBuffer.Normals, glBufferTarget.ARRAY_BUFFER);
var uv = AddAccessor<Vector2>(mesh.VertexBuffer.TexCoords, glBufferTarget.ARRAY_BUFFER);
var weights = AddAccessor<Vector4>(mesh.VertexBuffer.Weights, glBufferTarget.ARRAY_BUFFER);
var joints = AddAccessor<UShort4>(mesh.VertexBuffer.Joints, glBufferTarget.ARRAY_BUFFER);
var color = AddAccessor<Vector4>(mesh.VertexBuffer.Colors, glBufferTarget.ARRAY_BUFFER);
var position = AddAccessor<Vector3>(mesh.VertexBuffer.Positions, glBufferTarget.ARRAY_BUFFER, true);
var normal = AddAccessor<Vector3>(mesh.VertexBuffer.Normals, glBufferTarget.ARRAY_BUFFER, false);
var uv = AddAccessor<Vector2>(mesh.VertexBuffer.TexCoords, glBufferTarget.ARRAY_BUFFER, false);
var weights = AddAccessor<Vector4>(mesh.VertexBuffer.Weights, glBufferTarget.ARRAY_BUFFER, false);
var joints = AddAccessor<UShort4>(mesh.VertexBuffer.Joints, glBufferTarget.ARRAY_BUFFER, false);
var color = AddAccessor<Vector4>(mesh.VertexBuffer.Colors, glBufferTarget.ARRAY_BUFFER, false);
var morphTargets = new MorphAccessor[] { };
if (mesh.MorphTargets != null)
{
morphTargets = mesh.MorphTargets.Select(x => new MorphAccessor
{
Position = AddAccessor<Vector3>(x.VertexBuffer.Positions, glBufferTarget.ARRAY_BUFFER),
Normal = AddAccessor<Vector3>(x.VertexBuffer.Normals, glBufferTarget.ARRAY_BUFFER),
Position = AddAccessor<Vector3>(x.VertexBuffer.Positions, glBufferTarget.ARRAY_BUFFER, true),
Normal = AddAccessor<Vector3>(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<Vector3>(mesh.VertexBuffer.Positions, glBufferTarget.ARRAY_BUFFER);
var normal = AddAccessor<Vector3>(mesh.VertexBuffer.Normals, glBufferTarget.ARRAY_BUFFER);
var uv = AddAccessor<Vector2>(mesh.VertexBuffer.TexCoords, glBufferTarget.ARRAY_BUFFER);
var weights = AddAccessor<Vector4>(mesh.VertexBuffer.Weights, glBufferTarget.ARRAY_BUFFER);
var joints = AddAccessor<UShort4>(mesh.VertexBuffer.Joints, glBufferTarget.ARRAY_BUFFER);
var color = AddAccessor<Vector4>(mesh.VertexBuffer.Colors, glBufferTarget.ARRAY_BUFFER);
var position = AddAccessor<Vector3>(mesh.VertexBuffer.Positions, glBufferTarget.ARRAY_BUFFER, true);
var normal = AddAccessor<Vector3>(mesh.VertexBuffer.Normals, glBufferTarget.ARRAY_BUFFER, false);
var uv = AddAccessor<Vector2>(mesh.VertexBuffer.TexCoords, glBufferTarget.ARRAY_BUFFER, false);
var weights = AddAccessor<Vector4>(mesh.VertexBuffer.Weights, glBufferTarget.ARRAY_BUFFER, false);
var joints = AddAccessor<UShort4>(mesh.VertexBuffer.Joints, glBufferTarget.ARRAY_BUFFER, false);
var color = AddAccessor<Vector4>(mesh.VertexBuffer.Colors, glBufferTarget.ARRAY_BUFFER, false);
var morphTargets = new MorphAccessor[] { };
if (mesh.MorphTargets != null)
{
morphTargets = mesh.MorphTargets.Select(x => new MorphAccessor
{
Position = AddAccessor<Vector3>(x.VertexBuffer.Positions, glBufferTarget.ARRAY_BUFFER),
Normal = AddAccessor<Vector3>(x.VertexBuffer.Normals, glBufferTarget.ARRAY_BUFFER),
Position = AddAccessor<Vector3>(x.VertexBuffer.Positions, glBufferTarget.ARRAY_BUFFER, true),
Normal = AddAccessor<Vector3>(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;