mirror of
https://github.com/AssetRipper/AssetRipper.git
synced 2025-12-11 20:15:29 +01:00
93 lines
2.3 KiB
C#
93 lines
2.3 KiB
C#
using AssetRipper.SourceGenerated.Enums;
|
|
using System.Collections;
|
|
|
|
namespace AssetRipper.SourceGenerated.Extensions;
|
|
|
|
public readonly struct TriangleEnumerable : IEnumerable<(uint, uint, uint)>
|
|
{
|
|
private readonly MeshTopology topology;
|
|
private readonly ArraySegment<uint> indexBuffer;
|
|
|
|
public TriangleEnumerable(SubMeshData subMesh, uint[] indexBuffer) : this(subMesh.Topology, GetIndexBufferSegment(subMesh, indexBuffer))
|
|
{
|
|
}
|
|
|
|
public TriangleEnumerable(MeshTopology topology, ArraySegment<uint> indexBuffer)
|
|
{
|
|
ThrowIfNotSupported(topology);
|
|
this.topology = topology;
|
|
this.indexBuffer = indexBuffer;
|
|
}
|
|
|
|
public static bool IsSupported(MeshTopology topology)
|
|
{
|
|
return topology is MeshTopology.Triangles or MeshTopology.TriangleStrip or MeshTopology.Quads;
|
|
}
|
|
|
|
public IEnumerator<(uint, uint, uint)> GetEnumerator()
|
|
{
|
|
switch (topology)
|
|
{
|
|
case MeshTopology.Triangles:
|
|
{
|
|
for (int i = 0; i < indexBuffer.Count; i += 3)
|
|
{
|
|
yield return (indexBuffer[i], indexBuffer[i + 1], indexBuffer[i + 2]);
|
|
}
|
|
}
|
|
break;
|
|
case MeshTopology.TriangleStrip:
|
|
{
|
|
// de-stripify :
|
|
for (int i = 0; i < indexBuffer.Count - 2; i++)
|
|
{
|
|
uint a = indexBuffer[i];
|
|
uint b = indexBuffer[i + 1];
|
|
uint c = indexBuffer[i + 2];
|
|
|
|
// skip degenerates
|
|
if (a == b || a == c || b == c)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// do the winding flip-flop of strips :
|
|
if ((i & 1) == 1)
|
|
{
|
|
yield return (b, a, c);
|
|
}
|
|
else
|
|
{
|
|
yield return (a, b, c);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case MeshTopology.Quads:
|
|
{
|
|
for (int q = 0; q < indexBuffer.Count; q += 4)
|
|
{
|
|
yield return (indexBuffer[q], indexBuffer[q + 1], indexBuffer[q + 2]);
|
|
yield return (indexBuffer[q], indexBuffer[q + 2], indexBuffer[q + 3]);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
private static ArraySegment<uint> GetIndexBufferSegment(SubMeshData subMesh, uint[] indexBuffer)
|
|
{
|
|
return new ArraySegment<uint>(indexBuffer, subMesh.FirstIndex, subMesh.IndexCount);
|
|
}
|
|
|
|
private static void ThrowIfNotSupported(MeshTopology topology)
|
|
{
|
|
if (!IsSupported(topology))
|
|
{
|
|
throw new ArgumentException($"Mesh topology {topology} is not supported", nameof(topology));
|
|
}
|
|
}
|
|
|
|
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
|
}
|