diff --git a/CHANGELOG.md b/CHANGELOG.md index 92bb78a..b25300a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Changed - Changed data structure of 'neis' from List to byte[] for optimized memory usage and improved access speed in `DtLayerMonotoneRegion` +- Changed new RcVec3f[3] to stackalloc RcVec3f[3] in DtNavMesh.GetPolyHeight() to reduce heap allocation ### Removed - Nothing diff --git a/src/DotRecast.Detour/DtNavMesh.cs b/src/DotRecast.Detour/DtNavMesh.cs index 0960267..d31cbac 100644 --- a/src/DotRecast.Detour/DtNavMesh.cs +++ b/src/DotRecast.Detour/DtNavMesh.cs @@ -66,7 +66,7 @@ namespace DotRecast.Detour m_tiles = new DtMeshTile[m_maxTiles]; m_posLookup = new DtMeshTile[m_tileLutSize]; m_nextFree = null; - for (int i = m_maxTiles-1; i >= 0; --i) + for (int i = m_maxTiles - 1; i >= 0; --i) { m_tiles[i] = new DtMeshTile(i); m_tiles[i].salt = 1; @@ -1045,6 +1045,7 @@ namespace DotRecast.Detour RcVec3f pmin = new RcVec3f(); RcVec3f pmax = new RcVec3f(); + Span tempV = stackalloc RcVec3f[3]; if (tile.data.detailMeshes != null) { ref DtPolyDetail pd = ref tile.data.detailMeshes[ip]; @@ -1057,7 +1058,7 @@ namespace DotRecast.Detour continue; } - RcVec3f[] v = new RcVec3f[3]; + Span v = tempV; for (int j = 0; j < 3; ++j) { if (tris[ti + j] < poly.vertCount) @@ -1105,7 +1106,7 @@ namespace DotRecast.Detour } else { - RcVec3f[] v = new RcVec3f[2]; + Span v = tempV.Slice(0, 2); for (int j = 0; j < poly.vertCount; ++j) { int k = (j + 1) % poly.vertCount; @@ -1156,13 +1157,14 @@ namespace DotRecast.Detour } // Find height at the location. + Span tempV = stackalloc RcVec3f[3]; if (tile.data.detailMeshes != null) { ref DtPolyDetail pd = ref tile.data.detailMeshes[ip]; for (int j = 0; j < pd.triCount; ++j) { int t = (pd.triBase + j) * 4; - RcVec3f[] v = new RcVec3f[3]; + Span v = tempV; for (int k = 0; k < 3; ++k) { if (tile.data.detailTris[t + k] < poly.vertCount) @@ -1196,7 +1198,7 @@ namespace DotRecast.Detour } else { - RcVec3f[] v = new RcVec3f[3]; + Span v = tempV; v[0].X = tile.data.verts[poly.verts[0] * 3]; v[0].Y = tile.data.verts[poly.verts[0] * 3 + 1]; v[0].Z = tile.data.verts[poly.verts[0] * 3 + 2]; diff --git a/src/DotRecast.Detour/DtNavMeshRaycast.cs b/src/DotRecast.Detour/DtNavMeshRaycast.cs index 5d31955..e0d60b1 100644 --- a/src/DotRecast.Detour/DtNavMeshRaycast.cs +++ b/src/DotRecast.Detour/DtNavMeshRaycast.cs @@ -17,6 +17,7 @@ freely, subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ +using System; using DotRecast.Core; using DotRecast.Core.Numerics; @@ -48,6 +49,7 @@ namespace DotRecast.Detour private static bool Raycast(DtMeshTile tile, RcVec3f sp, RcVec3f sq, out float hitTime) { hitTime = 0.0f; + Span tempVerts = stackalloc RcVec3f[3]; for (int i = 0; i < tile.data.header.polyCount; ++i) { DtPoly p = tile.data.polys[i]; @@ -58,7 +60,7 @@ namespace DotRecast.Detour ref DtPolyDetail pd = ref tile.data.detailMeshes[i]; - RcVec3f[] verts = new RcVec3f[3]; + Span verts = tempVerts; for (int j = 0; j < pd.triCount; ++j) { int t = (pd.triBase + j) * 4; diff --git a/src/DotRecast.Recast.Toolset/Gizmos/RcCapsuleGizmo.cs b/src/DotRecast.Recast.Toolset/Gizmos/RcCapsuleGizmo.cs index 90a10a7..1e86135 100644 --- a/src/DotRecast.Recast.Toolset/Gizmos/RcCapsuleGizmo.cs +++ b/src/DotRecast.Recast.Toolset/Gizmos/RcCapsuleGizmo.cs @@ -19,7 +19,7 @@ namespace DotRecast.Recast.Toolset.Gizmos 0.5f * (start.Z + end.Z) }; RcVec3f axis = new RcVec3f(end.X - start.X, end.Y - start.Y, end.Z - start.Z); - RcVec3f[] normals = new RcVec3f[3]; + Span normals = stackalloc RcVec3f[3]; normals[1] = new RcVec3f(end.X - start.X, end.Y - start.Y, end.Z - start.Z); normals[1] = RcVec3f.Normalize(normals[1]); normals[0] = GetSideVector(axis); diff --git a/src/DotRecast.Recast.Toolset/Gizmos/RcCylinderGizmo.cs b/src/DotRecast.Recast.Toolset/Gizmos/RcCylinderGizmo.cs index 2183bbf..841e7f4 100644 --- a/src/DotRecast.Recast.Toolset/Gizmos/RcCylinderGizmo.cs +++ b/src/DotRecast.Recast.Toolset/Gizmos/RcCylinderGizmo.cs @@ -19,7 +19,7 @@ namespace DotRecast.Recast.Toolset.Gizmos 0.5f * (start.Z + end.Z) ); RcVec3f axis = new RcVec3f(end.X - start.X, end.Y - start.Y, end.Z - start.Z); - RcVec3f[] normals = new RcVec3f[3]; + Span normals = stackalloc RcVec3f[3]; normals[1] = new RcVec3f(end.X - start.X, end.Y - start.Y, end.Z - start.Z); normals[1] = RcVec3f.Normalize(normals[1]); normals[0] = GetSideVector(axis); diff --git a/src/DotRecast.Recast.Toolset/Tools/RcTestNavMeshTool.cs b/src/DotRecast.Recast.Toolset/Tools/RcTestNavMeshTool.cs index 37702d0..2375bf6 100644 --- a/src/DotRecast.Recast.Toolset/Tools/RcTestNavMeshTool.cs +++ b/src/DotRecast.Recast.Toolset/Tools/RcTestNavMeshTool.cs @@ -380,7 +380,7 @@ namespace DotRecast.Recast.Toolset.Tools float nx = (epos.Z - spos.Z) * 0.25f; float nz = -(epos.X - spos.X) * 0.25f; - var tempQueryPoly = new RcVec3f[4]; + RcVec3f[] tempQueryPoly = new RcVec3f[4]; tempQueryPoly[0].X = spos.X + nx * 1.2f; tempQueryPoly[0].Y = spos.Y + agentHeight / 2; tempQueryPoly[0].Z = spos.Z + nz * 1.2f; diff --git a/src/DotRecast.Recast/RcPolyMeshRaycast.cs b/src/DotRecast.Recast/RcPolyMeshRaycast.cs index 279538e..f872a92 100644 --- a/src/DotRecast.Recast/RcPolyMeshRaycast.cs +++ b/src/DotRecast.Recast/RcPolyMeshRaycast.cs @@ -17,6 +17,7 @@ freely, subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ +using System; using System.Collections.Generic; using DotRecast.Core; using DotRecast.Core.Numerics; @@ -45,6 +46,7 @@ namespace DotRecast.Recast private static bool Raycast(RcPolyMesh poly, RcPolyMeshDetail meshDetail, RcVec3f sp, RcVec3f sq, out float hitTime) { hitTime = 0; + Span tempVs = stackalloc RcVec3f[3]; if (meshDetail != null) { for (int i = 0; i < meshDetail.nmeshes; ++i) @@ -57,7 +59,7 @@ namespace DotRecast.Recast int tris = btris * 4; for (int j = 0; j < ntris; ++j) { - RcVec3f[] vs = new RcVec3f[3]; + Span vs = tempVs; for (int k = 0; k < 3; ++k) { vs[k].X = meshDetail.verts[verts + meshDetail.tris[tris + j * 4 + k] * 3];