From 8f088fcd709538c161dda55aeb20995f089904ee Mon Sep 17 00:00:00 2001 From: Doprez <73259914+Doprez@users.noreply.github.com> Date: Fri, 10 Nov 2023 22:28:22 -0700 Subject: [PATCH 1/2] need unsafe due to graphics stuff --- src/Stride.CommunityToolkit/Stride.CommunityToolkit.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Stride.CommunityToolkit/Stride.CommunityToolkit.csproj b/src/Stride.CommunityToolkit/Stride.CommunityToolkit.csproj index 141400a3..c28d8172 100644 --- a/src/Stride.CommunityToolkit/Stride.CommunityToolkit.csproj +++ b/src/Stride.CommunityToolkit/Stride.CommunityToolkit.csproj @@ -1,6 +1,7 @@ Stride.CommunityToolkit + true From d46ce536d74f9b973bae98fb67b118c18f04809f Mon Sep 17 00:00:00 2001 From: Doprez <73259914+Doprez@users.noreply.github.com> Date: Fri, 10 Nov 2023 22:28:38 -0700 Subject: [PATCH 2/2] added mesh data extension --- .../Extensions/ModelComponentExtensions.cs | 83 +++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/src/Stride.CommunityToolkit/Extensions/ModelComponentExtensions.cs b/src/Stride.CommunityToolkit/Extensions/ModelComponentExtensions.cs index c587f5ad..74ee0485 100644 --- a/src/Stride.CommunityToolkit/Extensions/ModelComponentExtensions.cs +++ b/src/Stride.CommunityToolkit/Extensions/ModelComponentExtensions.cs @@ -1,3 +1,6 @@ +using Stride.Games; +using Stride.Rendering; + namespace Stride.Engine; public static class ModelComponentExtensions @@ -29,4 +32,84 @@ public static Vector3 GetMeshHWL(this ModelComponent modelComponent) return new Vector3(height, width, length); } + + /// + /// Gets the ModelComponents Mesh data as vertices and indices. + /// + /// + /// + /// + public static (List verts, List indices) GetMeshVerticesAndIndices(this ModelComponent model, IGame game) + { + return GetMeshData(model.Model, game.Services, game); + } + + static unsafe (List verts, List indices) GetMeshData(Model model, IServiceRegistry services, IGame game) + { + Matrix[] nodeTransforms = null; + + int totalVerts = 0, totalIndices = 0; + foreach (var meshData in model.Meshes) + { + totalVerts += meshData.Draw.VertexBuffers[0].Count; + totalIndices += meshData.Draw.IndexBuffer.Count; + } + + var combinedVerts = new List(totalVerts); + var combinedIndices = new List(totalIndices); + + foreach (var meshData in model.Meshes) + { + var vBuffer = meshData.Draw.VertexBuffers[0].Buffer; + var iBuffer = meshData.Draw.IndexBuffer.Buffer; + byte[] verticesBytes = vBuffer.GetData(game.GraphicsContext.CommandList); ; + byte[] indicesBytes = iBuffer.GetData(game.GraphicsContext.CommandList); ; + + if ((verticesBytes?.Length ?? 0) == 0 || (indicesBytes?.Length ?? 0) == 0) + { + // returns empty lists if there is an issue + return (combinedVerts, combinedIndices); + } + + int vertMappingStart = combinedVerts.Count; + + fixed (byte* bytePtr = verticesBytes) + { + var vBindings = meshData.Draw.VertexBuffers[0]; + int count = vBindings.Count; + int stride = vBindings.Declaration.VertexStride; + for (int i = 0, vHead = vBindings.Offset; i < count; i++, vHead += stride) + { + var pos = *(Vector3*)(bytePtr + vHead); + if (nodeTransforms != null) + { + Matrix posMatrix = Matrix.Translation(pos); + Matrix.Multiply(ref posMatrix, ref nodeTransforms[meshData.NodeIndex], out var finalMatrix); + pos = finalMatrix.TranslationVector; + } + + combinedVerts.Add(pos); + } + } + + fixed (byte* bytePtr = indicesBytes) + { + if (meshData.Draw.IndexBuffer.Is32Bit) + { + foreach (int i in new Span(bytePtr + meshData.Draw.IndexBuffer.Offset, meshData.Draw.IndexBuffer.Count)) + { + combinedIndices.Add(vertMappingStart + i); + } + } + else + { + foreach (ushort i in new Span(bytePtr + meshData.Draw.IndexBuffer.Offset, meshData.Draw.IndexBuffer.Count)) + { + combinedIndices.Add(vertMappingStart + i); + } + } + } + } + return (combinedVerts, combinedIndices); + } } \ No newline at end of file