GltfData.GetIndices の責務を MeshContext に移動

* triangle flip
* concat submesh indices
This commit is contained in:
ousttrue 2022-02-15 18:27:36 +09:00
parent dac2a5e19e
commit fb09c3fa6d
3 changed files with 79 additions and 58 deletions

View File

@ -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);
}
/// <summary>
/// Get indices and cast to int
/// </summary>
/// <param name="accessor"></param>
/// <param name="count"></param>
/// <returns></returns>
IEnumerable<int> 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<Byte>(accessor, view).Select(x => (int)(x));
}
case glComponentType.UNSIGNED_SHORT:
{
return GetTypedFromAccessor<UInt16>(accessor, view).Select(x => (int)(x));
}
case glComponentType.UNSIGNED_INT:
{
return GetTypedFromAccessor<UInt32>(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<T> GetArrayFromAccessor<T>(int accessorIndex) where T : struct

View File

@ -6,7 +6,7 @@ using UnityEngine.Profiling;
using UnityEngine.Rendering;
namespace UniGLTF
{
{
internal class MeshContext
{
private readonly List<MeshVertex> _vertices = new List<MeshVertex>();
@ -23,6 +23,46 @@ namespace UniGLTF
public string Name { get; }
/// <summary>
/// * flip triangle
/// * add submesh offset
/// </summary>
/// <param name="src"></param>
/// <param name="offset"></param>
void PushIndices(BufferAccessor src, int offset)
{
switch (src.ComponentType)
{
case AccessorValueType.UNSIGNED_SHORT:
{
var indices = src.Bytes.Reinterpret<ushort>(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<int>(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();
}
}
/// <summary>
/// 頂点情報をMeshに対して送る
/// </summary>
@ -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;
}
/// <summary>
/// 各 primitive の attribute の要素が同じでない。=> uv が有るものと無いものが混在するなど
/// glTF 的にはありうる。
@ -123,6 +182,8 @@ namespace UniGLTF
/// <returns></returns>
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
/// <returns></returns>
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

View File

@ -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<int>(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<int>(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<int>(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<int>(1);
Assert.AreEqual(0, indices[0]);
Assert.AreEqual(1, indices[1]);
Assert.AreEqual(3, indices[2]);