diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/BufferAccessor.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/BufferAccessor.cs new file mode 100644 index 000000000..3f3c40ff5 --- /dev/null +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/BufferAccessor.cs @@ -0,0 +1,304 @@ +using System; +using System.Collections.Generic; +using System.Numerics; +using System.Runtime.InteropServices; +using Unity.Collections; + +namespace UniGLTF +{ + public enum AccessorVectorType + { + SCALAR, + VEC2, + VEC3, + VEC4, + MAT2, + MAT3, + MAT4, + } + + public static class GltfAccessorTypeExtensions + { + public static int TypeCount(this AccessorVectorType type) + { + switch (type) + { + case AccessorVectorType.SCALAR: + return 1; + case AccessorVectorType.VEC2: + return 2; + case AccessorVectorType.VEC3: + return 3; + case AccessorVectorType.VEC4: + case AccessorVectorType.MAT2: + return 4; + case AccessorVectorType.MAT3: + return 9; + case AccessorVectorType.MAT4: + return 16; + default: + throw new NotImplementedException(); + } + } + } + + public enum AccessorValueType : int + { + BYTE = 5120, // signed ? + UNSIGNED_BYTE = 5121, + + SHORT = 5122, + UNSIGNED_SHORT = 5123, + + //INT = 5124, + UNSIGNED_INT = 5125, + + FLOAT = 5126, + } + + public static class GltfComponentTypeExtensions + { + public static int ByteSize(this AccessorValueType t) + { + switch (t) + { + case AccessorValueType.BYTE: return 1; + case AccessorValueType.UNSIGNED_BYTE: return 1; + case AccessorValueType.SHORT: return 2; + case AccessorValueType.UNSIGNED_SHORT: return 2; + case AccessorValueType.UNSIGNED_INT: return 4; + case AccessorValueType.FLOAT: return 4; + default: throw new ArgumentException(); + } + } + } + + + public class BufferAccessor + { + public INativeArrayManager ArrayManager { get; } + + public NativeArray Bytes { get; private set; } + + public AccessorValueType ComponentType { get; private set; } + + public AccessorVectorType AccessorType { get; private set; } + + public int Stride => ComponentType.ByteSize() * AccessorType.TypeCount(); + + public int Count { get; private set; } + + public int ByteLength => Stride * Count; + + public BufferAccessor(INativeArrayManager arrayManager, NativeArray bytes, AccessorValueType componentType, AccessorVectorType accessorType, int count) + { + ArrayManager = arrayManager; + Bytes = bytes; + ComponentType = componentType; + AccessorType = accessorType; + Count = count; + } + + public override string ToString() + { + return $"{Stride}stride x{Count}"; + } + + public NativeArray GetSpan(bool checkStride = true) where T : struct + { + if (checkStride && Marshal.SizeOf(typeof(T)) != Stride) + { + throw new Exception("different sizeof(T) with stride"); + } + return Bytes.Reinterpret(1); + } + + public void Assign(T[] values) where T : struct + { + if (Marshal.SizeOf(typeof(T)) != Stride) + { + throw new Exception("invalid element size"); + } + Bytes = ArrayManager.CreateNativeArray(Stride * values.Length); + Count = values.Length; + Bytes.Reinterpret(1).CopyFrom(values); + } + + public void Assign(NativeArray values) where T : struct + { + if (Marshal.SizeOf(typeof(T)) != Stride) + { + throw new Exception("invalid element size"); + } + Bytes = ArrayManager.CreateNativeArray(Marshal.SizeOf() * values.Length); + NativeArray.Copy(values, Bytes.Reinterpret(1)); + Count = values.Length; + } + + // for index buffer + public void AssignAsShort(NativeArray values) + { + if (AccessorType != AccessorVectorType.SCALAR) + { + throw new NotImplementedException(); + } + ComponentType = AccessorValueType.UNSIGNED_SHORT; + + Bytes = ArrayManager.Convert(values, (int x) => (ushort)x).Reinterpret(Marshal.SizeOf()); + Count = values.Length; + } + + // Index用 + public NativeArray GetAsIntArray() + { + if (AccessorType != AccessorVectorType.SCALAR) + { + throw new InvalidOperationException("not scalar"); + } + switch (ComponentType) + { + case AccessorValueType.UNSIGNED_SHORT: + return ArrayManager.Convert(Bytes.Reinterpret(1), (ushort x) => (int)x); + + case AccessorValueType.UNSIGNED_INT: + return Bytes.Reinterpret(1); + + default: + throw new NotImplementedException(); + } + } + + public BufferAccessor Skip(int skipFrames) + { + skipFrames = Math.Min(Count, skipFrames); + if (skipFrames == 0) + { + return this; + } + var start = Stride * skipFrames; + return new BufferAccessor(ArrayManager, Bytes.GetSubArray(start, Bytes.Length - start), ComponentType, AccessorType, Count - skipFrames); + } + + int AddViewTo(ExportingGltfData data, int bufferIndex, + int offset = 0, int count = 0) + { + var stride = Stride; + if (count == 0) + { + count = Count; + } + var slice = Bytes.GetSubArray(offset * stride, count * stride); + return data.AppendToBuffer(slice); + } + + glTFAccessor CreateGltfAccessor(int viewIndex, int count = 0, int byteOffset = 0) + { + if (count == 0) + { + count = Count; + } + return new glTFAccessor + { + bufferView = viewIndex, + byteOffset = byteOffset, + componentType = (glComponentType)ComponentType, + type = AccessorType.ToString(), + count = count, + }; + } + + int AddAccessorTo(ExportingGltfData data, int viewIndex, + Action, glTFAccessor> minMax = null, + int offset = 0, int count = 0) + { + var gltf = data.Gltf; + var accessorIndex = gltf.accessors.Count; + var accessor = CreateGltfAccessor(viewIndex, count, offset * Stride); + if (minMax != null) + { + minMax(Bytes, accessor); + } + gltf.accessors.Add(accessor); + return accessorIndex; + } + + public int AddAccessorTo(ExportingGltfData data, int bufferIndex, + // GltfBufferTargetType targetType, + bool useSparse, + Action, glTFAccessor> minMax = null, + int offset = 0, int count = 0) + { + if (ComponentType == AccessorValueType.FLOAT + && AccessorType == AccessorVectorType.VEC3 + ) + { + var values = GetSpan(); + // 巨大ポリゴンのモデル対策にValueTupleの型をushort -> uint へ + var sparseValuesWithIndex = new List>(); + for (int i = 0; i < values.Length; ++i) + { + var v = values[i]; + if (v != Vector3.Zero) + { + sparseValuesWithIndex.Add((i, v)); + } + } + + //var status = $"{sparseIndices.Count * 14}/{values.Length * 12}"; + if (useSparse + && sparseValuesWithIndex.Count > 0 // avoid empty sparse + && sparseValuesWithIndex.Count * 16 < values.Length * 12) + { + // use sparse + using (var sparseIndexBin = new NativeArray(sparseValuesWithIndex.Count * 4, Allocator.Persistent)) + using (var sparseValueBin = new NativeArray(sparseValuesWithIndex.Count * 12, Allocator.Persistent)) + { + var sparseIndexSpan = sparseIndexBin.Reinterpret(1); + var sparseValueSpan = sparseValueBin.Reinterpret(1); + + for (int i = 0; i < sparseValuesWithIndex.Count; ++i) + { + var (index, value) = sparseValuesWithIndex[i]; + sparseIndexSpan[i] = index; + sparseValueSpan[i] = value; + } + + var sparseIndexView = data.AppendToBuffer(sparseIndexBin); + var sparseValueView = data.AppendToBuffer(sparseValueBin); + + var accessorIndex = data.Gltf.accessors.Count; + var accessor = new glTFAccessor + { + componentType = (glComponentType)ComponentType, + type = AccessorType.ToString(), + count = Count, + byteOffset = -1, + sparse = new glTFSparse + { + count = sparseValuesWithIndex.Count, + indices = new glTFSparseIndices + { + componentType = (glComponentType)AccessorValueType.UNSIGNED_INT, + bufferView = sparseIndexView, + }, + values = new glTFSparseValues + { + bufferView = sparseValueView, + }, + } + }; + if (minMax != null) + { + minMax(sparseValueBin, accessor); + } + data.Gltf.accessors.Add(accessor); + return accessorIndex; + } + } + } + + var viewIndex = AddViewTo(data, bufferIndex, offset, count); + return AddAccessorTo(data, viewIndex, minMax, 0, count); + } + } +} diff --git a/Assets/VRM10/vrmlib/Runtime/BufferAccessor.cs.meta b/Assets/UniGLTF/Runtime/UniGLTF/IO/BufferAccessor.cs.meta similarity index 83% rename from Assets/VRM10/vrmlib/Runtime/BufferAccessor.cs.meta rename to Assets/UniGLTF/Runtime/UniGLTF/IO/BufferAccessor.cs.meta index 2162bb5a6..6f1ec6565 100644 --- a/Assets/VRM10/vrmlib/Runtime/BufferAccessor.cs.meta +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/BufferAccessor.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 27cdb60e5e9634743875e0655372e682 +guid: aac48ad8d56549248a1ef57ff815d151 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/GltfData.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/GltfData.cs index ff35786c3..899c6bde7 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/GltfData.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/GltfData.cs @@ -157,15 +157,16 @@ namespace UniGLTF return segment.GetSubArray(view.byteOffset, view.byteLength); } - NativeArray GetTypedFromBufferView(int count, int byteOffset, glTFBufferView view) where T : struct + NativeArray GetBytesFromBufferView(glTFBufferView view) { var segment = GetBytesFromBuffer(view.buffer); - return segment.GetSubArray(view.byteOffset + byteOffset, count * Marshal.SizeOf()).Reinterpret(1); + return segment.GetSubArray(view.byteOffset, view.byteLength); } NativeArray GetTypedFromAccessor(glTFAccessor accessor, glTFBufferView view) where T : struct { - return GetTypedFromBufferView(accessor.count, accessor.byteOffset, view); + var bytes = GetBytesFromBufferView(view); + return bytes.GetSubArray(accessor.byteOffset, bytes.Length - accessor.byteOffset).Reinterpret(1).GetSubArray(0, accessor.count); } /// @@ -176,76 +177,39 @@ namespace UniGLTF /// /// /// - IEnumerable GetIntIndicesFromView(glTFBufferView view, int count, int byteOffset, glComponentType componentType) + BufferAccessor GetIntIndicesFromView(glTFBufferView view, int count, int byteOffset, glComponentType componentType) { + var bytes = GetBytesFromBufferView(view); switch (componentType) { case glComponentType.UNSIGNED_BYTE: { - return GetTypedFromBufferView(count, byteOffset, view).Select(x => (int)(x)); + return new BufferAccessor(NativeArrayManager, bytes.GetSubArray(byteOffset, bytes.Length - byteOffset), + AccessorValueType.UNSIGNED_BYTE, AccessorVectorType.SCALAR, count); } case glComponentType.UNSIGNED_SHORT: { - return GetTypedFromBufferView(count, byteOffset, view).Select(x => (int)(x)); + return new BufferAccessor(NativeArrayManager, bytes.GetSubArray(byteOffset, bytes.Length - byteOffset), + AccessorValueType.UNSIGNED_SHORT, AccessorVectorType.SCALAR, count); } case glComponentType.UNSIGNED_INT: { - return GetTypedFromBufferView(count, byteOffset, view).Select(x => (int)(x)); + 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 GetIndicesFromAccessorIndex(int accessorIndex) { - count = accessor.count; + var accessor = GLTF.accessors[accessorIndex]; 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 @@ -263,14 +227,42 @@ namespace UniGLTF if (sparse != null && sparse.count > 0) { // override sparse values - var indices = GetIntIndicesFromView(GLTF.bufferViews[sparse.indices.bufferView], sparse.count, sparse.indices.byteOffset, sparse.indices.componentType); - var values = GetTypedFromBufferView(sparse.count, sparse.values.byteOffset, GLTF.bufferViews[sparse.values.bufferView]); + var _indices = GetIntIndicesFromView(GLTF.bufferViews[sparse.indices.bufferView], sparse.count, sparse.indices.byteOffset, sparse.indices.componentType); + var bytes = GetBytesFromBufferView(GLTF.bufferViews[sparse.values.bufferView]); + var values = bytes.GetSubArray(sparse.values.byteOffset, bytes.Length - sparse.values.byteOffset).Reinterpret(1).GetSubArray(0, sparse.count); - var it = indices.GetEnumerator(); - for (int i = 0; i < sparse.count; ++i) + switch (_indices.ComponentType) { - it.MoveNext(); - result[it.Current] = values[i]; + case AccessorValueType.UNSIGNED_BYTE: + { + var indices = _indices.Bytes; + for (int i = 0; i < sparse.count; ++i) + { + result[indices[i]] = values[i]; + } + break; + } + case AccessorValueType.UNSIGNED_SHORT: + { + var indices = _indices.Bytes.Reinterpret(1); + for (int i = 0; i < sparse.count; ++i) + { + result[indices[i]] = values[i]; + } + break; + } + case AccessorValueType.UNSIGNED_INT: + { + var indices = _indices.Bytes.Reinterpret(1); + for (int i = 0; i < sparse.count; ++i) + { + result[indices[i]] = values[i]; + } + break; + } + + default: + throw new ArgumentOutOfRangeException(); } } return result; @@ -300,14 +292,42 @@ namespace UniGLTF if (sparse != null && sparse.count > 0) { // override sparse values - var indices = GetIntIndicesFromView(GLTF.bufferViews[sparse.indices.bufferView], sparse.count, sparse.indices.byteOffset, sparse.indices.componentType); - var values = GetTypedFromBufferView(sparse.count * vertexAccessor.TypeCount, sparse.values.byteOffset, GLTF.bufferViews[sparse.values.bufferView]); + var _indices = GetIntIndicesFromView(GLTF.bufferViews[sparse.indices.bufferView], sparse.count, sparse.indices.byteOffset, sparse.indices.componentType); + var bytes = GetBytesFromBufferView(GLTF.bufferViews[sparse.values.bufferView]); + var values = bytes.GetSubArray(sparse.values.byteOffset, bytes.Length - sparse.values.byteOffset).Reinterpret(1).GetSubArray(0, sparse.count * vertexAccessor.TypeCount); - var it = indices.GetEnumerator(); - for (int i = 0; i < sparse.count; ++i) + switch (_indices.ComponentType) { - it.MoveNext(); - result[it.Current] = values[i]; + case AccessorValueType.UNSIGNED_BYTE: + { + var indices = _indices.Bytes; + for (int i = 0; i < sparse.count; ++i) + { + result[indices[i]] = values[i]; + } + break; + } + case AccessorValueType.UNSIGNED_SHORT: + { + var indices = _indices.Bytes.Reinterpret(1); + for (int i = 0; i < sparse.count; ++i) + { + result[indices[i]] = values[i]; + } + break; + } + case AccessorValueType.UNSIGNED_INT: + { + var indices = _indices.Bytes.Reinterpret(1); + for (int i = 0; i < sparse.count; ++i) + { + result[indices[i]] = values[i]; + } + break; + } + + default: + throw new ArgumentOutOfRangeException(); } } return result; diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshContext.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshContext.cs index 2a0779a08..6d29baedc 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshContext.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshContext.cs @@ -23,6 +23,58 @@ namespace UniGLTF public string Name { get; } + /// + /// * flip triangle + /// * add submesh offset + /// + /// + /// + void PushIndices(BufferAccessor src, int offset) + { + switch (src.ComponentType) + { + case AccessorValueType.UNSIGNED_BYTE: + { + var indices = src.Bytes; + 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_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 +164,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 +194,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 +305,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.GetIndicesFromAccessorIndex(indexBufferCount); + PushIndices(dataIndices, vertexOffset); + _subMeshes.Add(new SubMeshDescriptor(indexOffset, dataIndices.Count)); } else { @@ -268,6 +341,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 +444,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.GetIndicesFromAccessorIndex(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..5f7cc4f2a 100644 --- a/Assets/UniGLTF/Tests/UniGLTF/MeshTests.cs +++ b/Assets/UniGLTF/Tests/UniGLTF/MeshTests.cs @@ -134,32 +134,29 @@ namespace UniGLTF var axisInverter = Axes.X.Create(); var unityMesh = MeshExportList.Create(go); - var (gltfMesh, blendShapeIndexMap) = meshExportSettings.DivideVertexBuffer - ? MeshExporter_DividedVertexBuffer.Export(data, unityMesh, Materials, axisInverter, meshExportSettings) - : MeshExporter_SharedVertexBuffer.Export(data, unityMesh, Materials, axisInverter, meshExportSettings) - ; + var (gltfMesh, blendShapeIndexMap) = MeshExporter_SharedVertexBuffer.Export(data, unityMesh, Materials, axisInverter, meshExportSettings); using (var parsed = GltfData.CreateFromGltfDataForTest(data.Gltf, data.BinBytes)) { { - var indices = parsed.GetIndices(gltfMesh.primitives[0].indices); - Assert.AreEqual(0, indices[0]); + var indices = parsed.GetIndicesFromAccessorIndex(gltfMesh.primitives[0].indices).Bytes.Reinterpret(1); + Assert.AreEqual(5, indices[0]); Assert.AreEqual(1, indices[1]); - Assert.AreEqual(5, indices[2]); - Assert.AreEqual(5, indices[3]); + Assert.AreEqual(0, indices[2]); + Assert.AreEqual(4, indices[3]); Assert.AreEqual(1, indices[4]); - Assert.AreEqual(4, indices[5]); + Assert.AreEqual(5, indices[5]); } { - var indices = parsed.GetIndices(gltfMesh.primitives[1].indices); - Assert.AreEqual(1, indices[0]); + var indices = parsed.GetIndicesFromAccessorIndex(gltfMesh.primitives[1].indices).Bytes.Reinterpret(1); + Assert.AreEqual(4, indices[0]); Assert.AreEqual(2, indices[1]); - Assert.AreEqual(4, indices[2]); - Assert.AreEqual(4, indices[3]); + Assert.AreEqual(1, indices[2]); + Assert.AreEqual(3, indices[3]); Assert.AreEqual(2, indices[4]); - Assert.AreEqual(3, indices[5]); + Assert.AreEqual(4, indices[5]); } var positions = parsed.GetArrayFromAccessor(gltfMesh.primitives[0].attributes.POSITION); @@ -185,21 +182,19 @@ namespace UniGLTF var axisInverter = Axes.X.Create(); var unityMesh = MeshExportList.Create(go); - var (gltfMesh, blendShapeIndexMap) = meshExportSettings.DivideVertexBuffer - ? MeshExporter_DividedVertexBuffer.Export(data, unityMesh, Materials, axisInverter, meshExportSettings) - : MeshExporter_SharedVertexBuffer.Export(data, unityMesh, Materials, axisInverter, meshExportSettings) - ; + + var (gltfMesh, blendShapeIndexMap) = MeshExporter_DividedVertexBuffer.Export(data, unityMesh, Materials, axisInverter, meshExportSettings); using (var parsed = GltfData.CreateFromGltfDataForTest(data.Gltf, data.BinBytes)) { { - var indices = parsed.GetIndices(gltfMesh.primitives[0].indices); - Assert.AreEqual(0, indices[0]); + var indices = parsed.GetIndicesFromAccessorIndex(gltfMesh.primitives[0].indices).Bytes.Reinterpret(1); + Assert.AreEqual(3, indices[0]); Assert.AreEqual(1, indices[1]); - Assert.AreEqual(3, indices[2]); - Assert.AreEqual(3, indices[3]); + Assert.AreEqual(0, indices[2]); + Assert.AreEqual(2, indices[3]); Assert.AreEqual(1, indices[4]); - Assert.AreEqual(2, indices[5]); + Assert.AreEqual(3, indices[5]); } { var positions = parsed.GetArrayFromAccessor(gltfMesh.primitives[0].attributes.POSITION); @@ -207,13 +202,13 @@ namespace UniGLTF } { - var indices = parsed.GetIndices(gltfMesh.primitives[1].indices); - Assert.AreEqual(0, indices[0]); + var indices = parsed.GetIndicesFromAccessorIndex(gltfMesh.primitives[1].indices).Bytes.Reinterpret(1); + Assert.AreEqual(3, indices[0]); Assert.AreEqual(1, indices[1]); - Assert.AreEqual(3, indices[2]); - Assert.AreEqual(3, indices[3]); + Assert.AreEqual(0, indices[2]); + Assert.AreEqual(2, indices[3]); Assert.AreEqual(1, indices[4]); - Assert.AreEqual(2, indices[5]); + Assert.AreEqual(3, indices[5]); } { var positions = parsed.GetArrayFromAccessor(gltfMesh.primitives[1].attributes.POSITION); diff --git a/Assets/VRM10/Runtime/IO/BufferAccessorAdapter.cs b/Assets/VRM10/Runtime/IO/BufferAccessorAdapter.cs deleted file mode 100644 index c3ae9509c..000000000 --- a/Assets/VRM10/Runtime/IO/BufferAccessorAdapter.cs +++ /dev/null @@ -1,159 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Numerics; -using UniGLTF; -using Unity.Collections; - -namespace UniVRM10 -{ - public static class BufferAccessorAdapter - { - public static int TypeCount(this string type) - { - switch (type) - { - case "SCALAR": - return 1; - case "VEC2": - return 2; - case "VEC3": - return 3; - case "VEC4": - case "MAT2": - return 4; - case "MAT3": - return 9; - case "MAT4": - return 16; - default: - throw new NotImplementedException(); - } - } - - public static int AddViewTo(this VrmLib.BufferAccessor self, - ExportingGltfData data, int bufferIndex, - int offset = 0, int count = 0) - { - var stride = self.Stride; - if (count == 0) - { - count = self.Count; - } - var slice = self.Bytes.GetSubArray(offset * stride, count * stride); - return data.AppendToBuffer(slice); - } - - static glTFAccessor CreateGltfAccessor(this VrmLib.BufferAccessor self, - int viewIndex, int count = 0, int byteOffset = 0) - { - if (count == 0) - { - count = self.Count; - } - return new glTFAccessor - { - bufferView = viewIndex, - byteOffset = byteOffset, - componentType = (glComponentType)self.ComponentType, - type = self.AccessorType.ToString(), - count = count, - }; - } - - public static int AddAccessorTo(this VrmLib.BufferAccessor self, - ExportingGltfData data, int viewIndex, - Action, glTFAccessor> minMax = null, - int offset = 0, int count = 0) - { - var gltf = data.Gltf; - var accessorIndex = gltf.accessors.Count; - var accessor = self.CreateGltfAccessor(viewIndex, count, offset * self.Stride); - if (minMax != null) - { - minMax(self.Bytes, accessor); - } - gltf.accessors.Add(accessor); - return accessorIndex; - } - - public static int AddAccessorTo(this VrmLib.BufferAccessor self, - ExportingGltfData data, int bufferIndex, - // GltfBufferTargetType targetType, - bool useSparse, - Action, glTFAccessor> minMax = null, - int offset = 0, int count = 0) - { - if (self.ComponentType == VrmLib.AccessorValueType.FLOAT - && self.AccessorType == VrmLib.AccessorVectorType.VEC3 - ) - { - var values = self.GetSpan(); - // 巨大ポリゴンのモデル対策にValueTupleの型をushort -> uint へ - var sparseValuesWithIndex = new List>(); - for (int i = 0; i < values.Length; ++i) - { - var v = values[i]; - if (v != Vector3.Zero) - { - sparseValuesWithIndex.Add((i, v)); - } - } - - //var status = $"{sparseIndices.Count * 14}/{values.Length * 12}"; - if (useSparse - && sparseValuesWithIndex.Count > 0 // avoid empty sparse - && sparseValuesWithIndex.Count * 16 < values.Length * 12) - { - // use sparse - using (var sparseIndexBin = new NativeArray(sparseValuesWithIndex.Count * 4, Allocator.Persistent)) - using (var sparseValueBin = new NativeArray(sparseValuesWithIndex.Count * 12, Allocator.Persistent)) - { - var sparseIndexSpan = sparseIndexBin.Reinterpret(1); - var sparseValueSpan = sparseValueBin.Reinterpret(1); - - for (int i = 0; i < sparseValuesWithIndex.Count; ++i) - { - var (index, value) = sparseValuesWithIndex[i]; - sparseIndexSpan[i] = index; - sparseValueSpan[i] = value; - } - - var sparseIndexView = data.AppendToBuffer(sparseIndexBin); - var sparseValueView = data.AppendToBuffer(sparseValueBin); - - var accessorIndex = data.Gltf.accessors.Count; - var accessor = new glTFAccessor - { - componentType = (glComponentType)self.ComponentType, - type = self.AccessorType.ToString(), - count = self.Count, - byteOffset = -1, - sparse = new glTFSparse - { - count = sparseValuesWithIndex.Count, - indices = new glTFSparseIndices - { - componentType = (glComponentType)VrmLib.AccessorValueType.UNSIGNED_INT, - bufferView = sparseIndexView, - }, - values = new glTFSparseValues - { - bufferView = sparseValueView, - }, - } - }; - if (minMax != null) - { - minMax(sparseValueBin, accessor); - } - data.Gltf.accessors.Add(accessor); - return accessorIndex; - } - } - } - - var viewIndex = self.AddViewTo(data, bufferIndex, offset, count); - return self.AddAccessorTo(data, viewIndex, minMax, 0, count); - } - } -} diff --git a/Assets/VRM10/Runtime/IO/BufferAccessorAdapter.cs.meta b/Assets/VRM10/Runtime/IO/BufferAccessorAdapter.cs.meta deleted file mode 100644 index 0f617c8c4..000000000 --- a/Assets/VRM10/Runtime/IO/BufferAccessorAdapter.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 9bdd7001c32368b4da917a0384e1ef86 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/VRM10/Runtime/IO/Model/MeshImporterDivided.cs b/Assets/VRM10/Runtime/IO/Model/MeshImporterDivided.cs index bda8578c2..62943ec7b 100644 --- a/Assets/VRM10/Runtime/IO/Model/MeshImporterDivided.cs +++ b/Assets/VRM10/Runtime/IO/Model/MeshImporterDivided.cs @@ -66,32 +66,29 @@ namespace UniVRM10 foreach (var mesh in meshGroup.Meshes) { var morphTarget = mesh.MorphTargets[i]; - morphTarget.VertexBuffer.Positions.CopyToNativeSlice( - new NativeSlice( - blendShapePositions, - blendShapePositionOffset, - morphTarget.VertexBuffer.Positions.Count - ) - ); - // nullならdefault(0)のまま - morphTarget.VertexBuffer.Normals?.CopyToNativeSlice( - new NativeSlice( - blendShapeNormals, - blendShapeNormalOffset, - morphTarget.VertexBuffer.Normals.Count - ) - ); + + NativeArray.Copy( + morphTarget.VertexBuffer.Positions.Bytes.Reinterpret(1), + blendShapePositions.GetSubArray(blendShapePositionOffset, morphTarget.VertexBuffer.Positions.Count)); + + if (morphTarget.VertexBuffer.Normals != null) + { + // nullならdefault(0)のまま + NativeArray.Copy( + morphTarget.VertexBuffer.Normals.Bytes.Reinterpret(1), + blendShapeNormals.GetSubArray(blendShapeNormalOffset, morphTarget.VertexBuffer.Normals.Count)); + } blendShapePositionOffset += morphTarget.VertexBuffer.Positions.Count; blendShapeNormalOffset += morphTarget.VertexBuffer.Normals?.Count ?? morphTarget.VertexBuffer.Count; } resultMesh.AddBlendShapeFrame(meshGroup.Meshes[0].MorphTargets[i].Name, - 100.0f, - blendShapePositions.ToArray(), - blendShapeNormals.ToArray(), - null); + 100.0f, + blendShapePositions.ToArray(), + blendShapeNormals.ToArray(), + null); } } diff --git a/Assets/VRM10/Runtime/IO/Model/ModelExporter.cs b/Assets/VRM10/Runtime/IO/Model/ModelExporter.cs index 3db11857c..06eea892a 100644 --- a/Assets/VRM10/Runtime/IO/Model/ModelExporter.cs +++ b/Assets/VRM10/Runtime/IO/Model/ModelExporter.cs @@ -272,44 +272,44 @@ namespace UniVRM10 return skin; } - private static VrmLib.BufferAccessor ToBufferAccessor(INativeArrayManager arrayManager, SkinJoints[] values) + private static BufferAccessor ToBufferAccessor(INativeArrayManager arrayManager, SkinJoints[] values) { - return ToBufferAccessor(arrayManager, values, VrmLib.AccessorValueType.UNSIGNED_SHORT, VrmLib.AccessorVectorType.VEC4); + return ToBufferAccessor(arrayManager, values, AccessorValueType.UNSIGNED_SHORT, AccessorVectorType.VEC4); } - private static VrmLib.BufferAccessor ToBufferAccessor(INativeArrayManager arrayManager, Color[] colors) + private static BufferAccessor ToBufferAccessor(INativeArrayManager arrayManager, Color[] colors) { - return ToBufferAccessor(arrayManager, colors, VrmLib.AccessorValueType.FLOAT, VrmLib.AccessorVectorType.VEC4); + return ToBufferAccessor(arrayManager, colors, AccessorValueType.FLOAT, AccessorVectorType.VEC4); } - private static VrmLib.BufferAccessor ToBufferAccessor(INativeArrayManager arrayManager, Vector4[] vectors) + private static BufferAccessor ToBufferAccessor(INativeArrayManager arrayManager, Vector4[] vectors) { - return ToBufferAccessor(arrayManager, vectors, VrmLib.AccessorValueType.FLOAT, VrmLib.AccessorVectorType.VEC4); + return ToBufferAccessor(arrayManager, vectors, AccessorValueType.FLOAT, AccessorVectorType.VEC4); } - private static VrmLib.BufferAccessor ToBufferAccessor(INativeArrayManager arrayManager, Vector3[] vectors) + private static BufferAccessor ToBufferAccessor(INativeArrayManager arrayManager, Vector3[] vectors) { - return ToBufferAccessor(arrayManager, vectors, VrmLib.AccessorValueType.FLOAT, VrmLib.AccessorVectorType.VEC3); + return ToBufferAccessor(arrayManager, vectors, AccessorValueType.FLOAT, AccessorVectorType.VEC3); } - private static VrmLib.BufferAccessor ToBufferAccessor(INativeArrayManager arrayManager, Vector2[] vectors) + private static BufferAccessor ToBufferAccessor(INativeArrayManager arrayManager, Vector2[] vectors) { - return ToBufferAccessor(arrayManager, vectors, VrmLib.AccessorValueType.FLOAT, VrmLib.AccessorVectorType.VEC2); + return ToBufferAccessor(arrayManager, vectors, AccessorValueType.FLOAT, AccessorVectorType.VEC2); } - private static VrmLib.BufferAccessor ToBufferAccessor(INativeArrayManager arrayManager, int[] scalars) + private static BufferAccessor ToBufferAccessor(INativeArrayManager arrayManager, int[] scalars) { - return ToBufferAccessor(arrayManager, scalars, VrmLib.AccessorValueType.UNSIGNED_INT, VrmLib.AccessorVectorType.SCALAR); + return ToBufferAccessor(arrayManager, scalars, AccessorValueType.UNSIGNED_INT, AccessorVectorType.SCALAR); } - private static VrmLib.BufferAccessor ToBufferAccessor(INativeArrayManager arrayManager, Matrix4x4[] matrixes) + private static BufferAccessor ToBufferAccessor(INativeArrayManager arrayManager, Matrix4x4[] matrixes) { - return ToBufferAccessor(arrayManager, matrixes, VrmLib.AccessorValueType.FLOAT, VrmLib.AccessorVectorType.MAT4); + return ToBufferAccessor(arrayManager, matrixes, AccessorValueType.FLOAT, AccessorVectorType.MAT4); } - private static VrmLib.BufferAccessor ToBufferAccessor(INativeArrayManager arrayManager, T[] value, VrmLib.AccessorValueType valueType, VrmLib.AccessorVectorType vectorType) where T : struct + private static BufferAccessor ToBufferAccessor(INativeArrayManager arrayManager, T[] value, AccessorValueType valueType, AccessorVectorType vectorType) where T : struct { - return new VrmLib.BufferAccessor(arrayManager, + return new BufferAccessor(arrayManager, arrayManager.CreateNativeArray(value).Reinterpret(Marshal.SizeOf()), valueType, vectorType, diff --git a/Assets/VRM10/Runtime/Migration/MeshUpdater.cs b/Assets/VRM10/Runtime/Migration/MeshUpdater.cs index ce62da032..aeb8611f5 100644 --- a/Assets/VRM10/Runtime/Migration/MeshUpdater.cs +++ b/Assets/VRM10/Runtime/Migration/MeshUpdater.cs @@ -49,7 +49,7 @@ namespace UniVRM10 return index; } - int? AddAccessor(VrmLib.BufferAccessor buffer) where T : struct + int? AddAccessor(BufferAccessor buffer) where T : struct { if (buffer == null) { diff --git a/Assets/VRM10/vrmlib/Runtime/BufferAccessor.cs b/Assets/VRM10/vrmlib/Runtime/BufferAccessor.cs deleted file mode 100644 index 602ded4c3..000000000 --- a/Assets/VRM10/vrmlib/Runtime/BufferAccessor.cs +++ /dev/null @@ -1,360 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Numerics; -using System.Runtime.InteropServices; -using UniGLTF; -using Unity.Collections; -using Unity.Collections.LowLevel.Unsafe; - -namespace VrmLib -{ - public enum AccessorVectorType - { - SCALAR, - VEC2, - VEC3, - VEC4, - MAT2, - MAT3, - MAT4, - } - - public static class GltfAccessorTypeExtensions - { - public static int TypeCount(this AccessorVectorType type) - { - switch (type) - { - case AccessorVectorType.SCALAR: - return 1; - case AccessorVectorType.VEC2: - return 2; - case AccessorVectorType.VEC3: - return 3; - case AccessorVectorType.VEC4: - case AccessorVectorType.MAT2: - return 4; - case AccessorVectorType.MAT3: - return 9; - case AccessorVectorType.MAT4: - return 16; - default: - throw new NotImplementedException(); - } - } - } - - public enum AccessorValueType : int - { - BYTE = 5120, // signed ? - UNSIGNED_BYTE = 5121, - - SHORT = 5122, - UNSIGNED_SHORT = 5123, - - //INT = 5124, - UNSIGNED_INT = 5125, - - FLOAT = 5126, - } - - public static class GltfComponentTypeExtensions - { - public static int ByteSize(this AccessorValueType t) - { - switch (t) - { - case AccessorValueType.BYTE: return 1; - case AccessorValueType.UNSIGNED_BYTE: return 1; - case AccessorValueType.SHORT: return 2; - case AccessorValueType.UNSIGNED_SHORT: return 2; - case AccessorValueType.UNSIGNED_INT: return 4; - case AccessorValueType.FLOAT: return 4; - default: throw new ArgumentException(); - } - } - } - - - public class BufferAccessor - { - public INativeArrayManager ArrayManager { get; } - - public NativeArray Bytes; - - public AccessorValueType ComponentType; - - public AccessorVectorType AccessorType; - - public int Stride => ComponentType.ByteSize() * AccessorType.TypeCount(); - - public int Count; - - public int ByteLength => Stride * Count; - - public BufferAccessor(INativeArrayManager arrayManager, NativeArray bytes, AccessorValueType componentType, AccessorVectorType accessorType, int count) - { - ArrayManager = arrayManager; - Bytes = bytes; - ComponentType = componentType; - AccessorType = accessorType; - Count = count; - } - - public static BufferAccessor Create(INativeArrayManager arrayManager, T[] list) where T : struct - { - var t = typeof(T); - var bytes = arrayManager.CreateNativeArray(list.Length * Marshal.SizeOf(t)); - var span = bytes.Reinterpret(1); - for (int i = 0; i < list.Length; ++i) - { - span[i] = list[i]; - } - AccessorValueType componentType = default(AccessorValueType); - AccessorVectorType accessorType = default(AccessorVectorType); - if (t == typeof(Vector2)) - { - componentType = AccessorValueType.FLOAT; - accessorType = AccessorVectorType.VEC2; - } - else if (t == typeof(Vector3)) - { - componentType = AccessorValueType.FLOAT; - accessorType = AccessorVectorType.VEC3; - } - else if (t == typeof(Vector4)) - { - componentType = AccessorValueType.FLOAT; - accessorType = AccessorVectorType.VEC4; - } - else if (t == typeof(Quaternion)) - { - componentType = AccessorValueType.FLOAT; - accessorType = AccessorVectorType.VEC4; - } - else if (t == typeof(SkinJoints)) - { - componentType = AccessorValueType.UNSIGNED_SHORT; - accessorType = AccessorVectorType.VEC4; - } - else if (t == typeof(int)) - { - componentType = AccessorValueType.UNSIGNED_INT; - accessorType = AccessorVectorType.SCALAR; - } - else - { - throw new NotImplementedException(); - } - return new BufferAccessor(arrayManager, bytes, componentType, accessorType, list.Length); - } - - public override string ToString() - { - return $"{Stride}stride x{Count}"; - } - - public NativeArray GetSpan(bool checkStride = true) where T : struct - { - if (checkStride && Marshal.SizeOf(typeof(T)) != Stride) - { - throw new Exception("different sizeof(T) with stride"); - } - return Bytes.Reinterpret(1); - } - - /// - /// バッファをNativeSliceへと書き込む - /// - public unsafe void CopyToNativeSlice(NativeSlice destArray) where T : unmanaged - { - var byteArray = NativeArrayUnsafeUtility.GetUnsafePtr(Bytes); - UnsafeUtility.MemCpy((T*)destArray.GetUnsafePtr(), byteArray, Bytes.Length); - } - - public void Assign(T[] values) where T : struct - { - if (Marshal.SizeOf(typeof(T)) != Stride) - { - throw new Exception("invalid element size"); - } - Bytes = ArrayManager.CreateNativeArray(Stride * values.Length); - Count = values.Length; - Bytes.Reinterpret(1).CopyFrom(values); - } - - public void Assign(NativeArray values) where T : struct - { - if (Marshal.SizeOf(typeof(T)) != Stride) - { - throw new Exception("invalid element size"); - } - Bytes = ArrayManager.CreateNativeArray(Marshal.SizeOf() * values.Length); - NativeArray.Copy(values, Bytes.Reinterpret(1)); - Count = values.Length; - } - - // for index buffer - public void AssignAsShort(NativeArray values) - { - if (AccessorType != AccessorVectorType.SCALAR) - { - throw new NotImplementedException(); - } - ComponentType = AccessorValueType.UNSIGNED_SHORT; - - Bytes = ArrayManager.Convert(values, (int x) => (ushort)x).Reinterpret(Marshal.SizeOf()); - Count = values.Length; - } - - // Index用 - public NativeArray GetAsIntArray() - { - if (AccessorType != AccessorVectorType.SCALAR) - { - throw new InvalidOperationException("not scalar"); - } - switch (ComponentType) - { - case AccessorValueType.UNSIGNED_SHORT: - return ArrayManager.Convert(Bytes.Reinterpret(1), (ushort x) => (int)x); - - case AccessorValueType.UNSIGNED_INT: - return Bytes.Reinterpret(1); - - default: - throw new NotImplementedException(); - } - } - - public void Resize(int count) - { - if (count < Count) - { - throw new Exception(); - } - ToByteLength(Stride * count); - - Count = count; - } - - void ToByteLength(int byteLength) - { - var newBytes = ArrayManager.CreateNativeArray(byteLength); - NativeArray.Copy(Bytes, newBytes); - Bytes = newBytes; - } - - public void Extend(int count) - { - var oldLength = Bytes.Length; - ToByteLength(oldLength + Stride * count); - Count += count; - } - - // - // ArraySegment を新規に確保して置き換える - // - public void Append(BufferAccessor a, int offset = -1) - { - if (AccessorType != a.AccessorType) - { - System.Console.WriteLine(AccessorType.ToString() + "!=" + a.AccessorType.ToString()); - throw new Exception("different AccessorType"); - } - - // UNSIGNED_SHORT <-> UNSIGNED_INT の変換を許容して処理を続行 - // 統合メッシュのprimitiveのIndexBufferが65,535(ushort.MaxValue)を超える場合や、変換前にindexBuffer.ComponetTypeがushortとuint混在する場合など - if (ComponentType != a.ComponentType) - { - switch (a.ComponentType) - { - //ushort to uint - case AccessorValueType.UNSIGNED_SHORT: - { - var bytes = ArrayManager.Convert(a.Bytes.Reinterpret(1), (UInt16 x) => (UInt32)x).Reinterpret(Marshal.SizeOf()); - var accessor = new BufferAccessor(ArrayManager, bytes, AccessorValueType.UNSIGNED_INT, AccessorVectorType.SCALAR, a.Count); - a = accessor; - break; - } - - //uint to ushort (おそらく通ることはない) - case AccessorValueType.UNSIGNED_INT: - { - var bytes = ArrayManager.Convert(a.Bytes.Reinterpret(1), (UInt32 x) => (UInt16)x).Reinterpret(Marshal.SizeOf()); - var accessor = new BufferAccessor(ArrayManager, bytes, ComponentType, AccessorVectorType.SCALAR, a.Count); - a = accessor; - break; - } - - default: - throw new Exception("Cannot Convert ComponentType"); - - } - } - - // 連結した新しいバッファを確保 - var oldLength = Bytes.Length; - ToByteLength(oldLength + a.Bytes.Length); - // 後ろにコピー - NativeArray.Copy(a.Bytes, Bytes.GetSubArray(oldLength, Bytes.Length - oldLength)); - Count += a.Count; - - if (offset > 0) - { - // 後半にoffsetを足す - switch (ComponentType) - { - case AccessorValueType.UNSIGNED_SHORT: - { - var span = Bytes.GetSubArray(oldLength, Bytes.Length - oldLength).Reinterpret(1); - var ushortOffset = (ushort)offset; - for (int i = 0; i < span.Length; ++i) - { - span[i] += ushortOffset; - } - } - break; - - case AccessorValueType.UNSIGNED_INT: - { - var span = Bytes.GetSubArray(oldLength, Bytes.Length - oldLength).Reinterpret(1); - var uintOffset = (uint)offset; - for (int i = 0; i < span.Length; ++i) - { - span[i] += uintOffset; - } - } - break; - - default: - throw new NotImplementedException(); - } - } - } - - public BufferAccessor Skip(int skipFrames) - { - skipFrames = Math.Min(Count, skipFrames); - if (skipFrames == 0) - { - return this; - } - var start = Stride * skipFrames; - return new BufferAccessor(ArrayManager, Bytes.GetSubArray(start, Bytes.Length - start), ComponentType, AccessorType, Count - skipFrames); - } - - public BufferAccessor CloneWithOffset(int offsetCount) - { - var offsetSize = Stride * offsetCount; - var buffer = ArrayManager.CreateNativeArray(offsetSize + Bytes.Length); - NativeArray.Copy(Bytes, buffer.GetSubArray(offsetSize, buffer.Length - offsetSize)); - return new BufferAccessor(ArrayManager, buffer, ComponentType, AccessorType, Count + offsetCount); - } - - public void AddTo(Dictionary dict, string key) - { - dict.Add(key, this); - } - } -} diff --git a/Assets/VRM10/vrmlib/Runtime/Mesh.cs b/Assets/VRM10/vrmlib/Runtime/Mesh.cs index 0751bc610..8f6169aa2 100644 --- a/Assets/VRM10/vrmlib/Runtime/Mesh.cs +++ b/Assets/VRM10/vrmlib/Runtime/Mesh.cs @@ -62,139 +62,10 @@ namespace VrmLib public BufferAccessor IndexBuffer; - /// - /// indicesの最大値が65535未満(-1を避ける)ならばushort 型で、 - /// そうでなければ int型で IndexBufferを代入する - /// - public void AssignIndexBuffer(NativeArray indices) - { - bool isInt = false; - foreach (var i in indices) - { - if (i >= short.MaxValue) - { - isInt = true; - break; - } - } - - if (isInt) - { - if (IndexBuffer.Stride != 4) - { - IndexBuffer.ComponentType = AccessorValueType.UNSIGNED_INT; - if (IndexBuffer.AccessorType != AccessorVectorType.SCALAR) - { - throw new Exception(); - } - } - // 変換なし - IndexBuffer.Assign(indices); - } - else - { - // int to ushort - IndexBuffer.AssignAsShort(indices); - } - } - public TopologyType Topology = TopologyType.Triangles; public List Submeshes { private set; get; } = new List(); - public int SubmeshTotalDrawCount => Submeshes.Sum(x => x.DrawCount); - - public IEnumerable GetTriangles(int i) - { - var indices = IndexBuffer.GetAsIntArray(); - - var submesh = Submeshes[i]; - var submeshEnd = submesh.Offset + submesh.DrawCount; - for (int j = submesh.Offset; j < submeshEnd; j += 3) - { - var triangle = new Triangle( - indices[j], - indices[j + 1], - indices[j + 2] - ); - yield return triangle; - } - } - - public IEnumerable> Triangles - { - get - { - if (Topology != TopologyType.Triangles) - { - throw new InvalidOperationException(); - } - - var indices = IndexBuffer.GetAsIntArray(); - - for (int i = 0; i < Submeshes.Count; ++i) - { - var submesh = Submeshes[i]; - var submeshEnd = submesh.Offset + submesh.DrawCount; - for (int j = submesh.Offset; j < submeshEnd; j += 3) - { - var triangle = new Triangle( - indices[j], - indices[j + 1], - indices[j + 2] - ); - yield return (i, triangle); - } - } - } - } - - bool GetSubmeshOverlapped() where T : struct - { - var indices = IndexBuffer.GetSpan(); - var offset = 0; - var max = 0; - foreach (var x in Submeshes) - { - var submeshIndices = indices.Slice(offset, x.DrawCount); - var currentMax = 0; - foreach (var y in submeshIndices) - { - if (y < max) - { - return true; - } - currentMax = Math.Max(y, currentMax); - } - offset += x.DrawCount; - max = currentMax; - } - return false; - } - - public bool IsSubmeshOverlapped - { - get - { - if (Submeshes.Count <= 1) - { - return false; - } - - switch (IndexBuffer.ComponentType) - { - case AccessorValueType.UNSIGNED_SHORT: - return GetSubmeshOverlapped(); - - case AccessorValueType.UNSIGNED_INT: - return GetSubmeshOverlapped(); - - default: - throw new NotImplementedException(); - } - } - } - public List MorphTargets = new List(); public override string ToString() @@ -238,11 +109,6 @@ namespace VrmLib Topology = topology; } - public void RemoveUnusedSubmesh() - { - Submeshes = Submeshes.Where(x => x.DrawCount != 0).ToList(); - } - // Skin.Normalize public void ApplyRotationAndScaling(Matrix4x4 m) { diff --git a/Assets/VRM10/vrmlib/Runtime/VertexBuffer.cs b/Assets/VRM10/vrmlib/Runtime/VertexBuffer.cs index 44dbd87df..c6b74351d 100644 --- a/Assets/VRM10/vrmlib/Runtime/VertexBuffer.cs +++ b/Assets/VRM10/vrmlib/Runtime/VertexBuffer.cs @@ -2,6 +2,7 @@ using System; using System.Collections; using System.Collections.Generic; using System.Linq; +using UniGLTF; namespace VrmLib {