From 65fd22f5b6bea616ea6e3a6d9e366496b6836197 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Thu, 5 Feb 2026 13:00:49 +0100 Subject: [PATCH] Add `Triangles` to `MeshAccessor` for easy index buffer access #3918 --- Source/Engine/Graphics/Models/MeshAccessor.cs | 98 +++++++++++++++++-- 1 file changed, 92 insertions(+), 6 deletions(-) diff --git a/Source/Engine/Graphics/Models/MeshAccessor.cs b/Source/Engine/Graphics/Models/MeshAccessor.cs index 228e43a8c..29aa86c18 100644 --- a/Source/Engine/Graphics/Models/MeshAccessor.cs +++ b/Source/Engine/Graphics/Models/MeshAccessor.cs @@ -265,6 +265,39 @@ namespace FlaxEngine } } + /// + /// Copies the contents of the input into the elements of this stream. + /// + /// The source . + public void Set(Span src) + { + if (IsLinear(PixelFormat.R32_UInt)) + { + src.CopyTo(MemoryMarshal.Cast(_data)); + } + else if (IsLinear(PixelFormat.R16_UInt)) + { + var count = Count; + fixed (byte* data = _data) + { + for (int i = 0; i < count; i++) + ((ushort*)data)[i] = (ushort)src[i]; + } + } + else + { + var count = Count; + fixed (byte* data = _data) + { + for (int i = 0; i < count; i++) + { + var v = new Float4(src[i]); + _sampler.Write(data + i * _stride, ref v); + } + } + } + } + /// /// Copies the contents of this stream into a destination . /// @@ -281,9 +314,7 @@ namespace FlaxEngine fixed (byte* data = _data) { for (int i = 0; i < count; i++) - { dst[i] = new Float2(_sampler.Read(data + i * _stride)); - } } } } @@ -304,9 +335,7 @@ namespace FlaxEngine fixed (byte* data = _data) { for (int i = 0; i < count; i++) - { dst[i] = new Float3(_sampler.Read(data + i * _stride)); - } } } } @@ -327,9 +356,37 @@ namespace FlaxEngine fixed (byte* data = _data) { for (int i = 0; i < count; i++) - { dst[i] = (Color)_sampler.Read(data + i * _stride); - } + } + } + } + + /// + /// Copies the contents of this stream into a destination . + /// + /// The destination . + public void CopyTo(Span dst) + { + if (IsLinear(PixelFormat.R32_UInt)) + { + _data.CopyTo(MemoryMarshal.Cast(dst)); + } + else if (IsLinear(PixelFormat.R16_UInt)) + { + var count = Count; + fixed (byte* data = _data) + { + for (int i = 0; i < count; i++) + dst[i] = ((ushort*)data)[i]; + } + } + else + { + var count = Count; + fixed (byte* data = _data) + { + for (int i = 0; i < count; i++) + dst[i] = (uint)_sampler.Read(data + i * _stride).X; } } } @@ -619,6 +676,16 @@ namespace FlaxEngine return Attribute((VertexElement.Types)((byte)VertexElement.Types.TexCoord0 + channel)); } + /// + /// Gets or sets the index buffer with triangle indices. + /// + /// Uses stream to read or write data to the index buffer. + public uint[] Triangles + { + get => GetStreamUInt(Index()); + set => SetStreamUInt(Index(), value); + } + /// /// Gets or sets the vertex positions. Null if does not exist in vertex buffers of the mesh. /// @@ -659,6 +726,25 @@ namespace FlaxEngine set => SetStreamFloat2(VertexElement.Types.TexCoord, value); } + private uint[] GetStreamUInt(Stream stream) + { + uint[] result = null; + if (stream.IsValid) + { + result = new uint[stream.Count]; + stream.CopyTo(result); + } + return result; + } + + private void SetStreamUInt(Stream stream, uint[] value) + { + if (stream.IsValid) + { + stream.Set(value); + } + } + private delegate void TransformDelegate3(ref Float3 value); private Float3[] GetStreamFloat3(VertexElement.Types attribute, TransformDelegate3 transform = null)