From ab2c5200768847b0aeca47e3803464c34e2f570e Mon Sep 17 00:00:00 2001 From: ikpil Date: Fri, 5 Jul 2024 00:15:03 +0900 Subject: [PATCH] Changed `new float[]` to `stackalloc float[]` in `DtConvexConvexIntersections.Intersect()` --- CHANGELOG.md | 1 + .../DtConvexConvexIntersections.cs | 14 +++---- .../DtStrictDtPolygonByCircleConstraint.cs | 38 +++++++++---------- 3 files changed, 23 insertions(+), 30 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9de7fcd..a83a32f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Changed stack handling from List to a fixed-size array with manual index management for optimization in `RcLayers.BuildHeightfieldLayers()` - Changed to use Span and stackalloc for improved performance and memory management in `RcLayers.BuildHeightfieldLayers()` - Changed vertCount and triCount to byte in `DtPolyDetail` +- Changed `new float[]` to `stackalloc float[]` in `DtConvexConvexIntersections.Intersect()` ### Removed - Removed RcMeshDetails.VdistSq2(float[], float[]) diff --git a/src/DotRecast.Detour/DtConvexConvexIntersections.cs b/src/DotRecast.Detour/DtConvexConvexIntersections.cs index 7537679..4e219ee 100644 --- a/src/DotRecast.Detour/DtConvexConvexIntersections.cs +++ b/src/DotRecast.Detour/DtConvexConvexIntersections.cs @@ -18,23 +18,20 @@ freely, subject to the following restrictions: */ using System; -using DotRecast.Core; using DotRecast.Core.Numerics; namespace DotRecast.Detour { - /** - * Convex-convex intersection based on "Computational Geometry in C" by Joseph O'Rourke - */ + // Convex-convex intersection based on "Computational Geometry in C" by Joseph O'Rourke public static class DtConvexConvexIntersections { private const float EPSILON = 0.0001f; - public static float[] Intersect(float[] p, float[] q) + public static float[] Intersect(Span p, Span q) { int n = p.Length / 3; int m = q.Length / 3; - float[] inters = new float[Math.Max(m, n) * 3 * 3]; + Span inters = stackalloc float[Math.Max(m, n) * 3 * 3]; int ii = 0; /* Initialize variables. */ RcVec3f a = new RcVec3f(); @@ -171,12 +168,11 @@ namespace DotRecast.Detour return null; } - float[] copied = new float[ii]; - RcArrays.Copy(inters, copied, ii); + float[] copied = inters.Slice(0, ii).ToArray(); return copied; } - private static int AddVertex(float[] inters, int ii, RcVec3f p) + private static int AddVertex(Span inters, int ii, RcVec3f p) { if (ii > 0) { diff --git a/src/DotRecast.Detour/DtStrictDtPolygonByCircleConstraint.cs b/src/DotRecast.Detour/DtStrictDtPolygonByCircleConstraint.cs index 1c78b6e..4e94b91 100644 --- a/src/DotRecast.Detour/DtStrictDtPolygonByCircleConstraint.cs +++ b/src/DotRecast.Detour/DtStrictDtPolygonByCircleConstraint.cs @@ -3,13 +3,11 @@ using DotRecast.Core.Numerics; namespace DotRecast.Detour { - /** - * Calculate the intersection between a polygon and a circle. A dodecagon is used as an approximation of the circle. - */ + // Calculate the intersection between a polygon and a circle. A dodecagon is used as an approximation of the circle. public class DtStrictDtPolygonByCircleConstraint : IDtPolygonByCircleConstraint { private const int CIRCLE_SEGMENTS = 12; - private static readonly float[] UnitCircle = MakeUnitCircle(); + private static readonly float[] UnitCircle = CreateCircle(); public static readonly IDtPolygonByCircleConstraint Shared = new DtStrictDtPolygonByCircleConstraint(); @@ -17,7 +15,7 @@ namespace DotRecast.Detour { } - private static float[] MakeUnitCircle() + public static float[] CreateCircle() { var temp = new float[CIRCLE_SEGMENTS * 3]; for (int i = 0; i < CIRCLE_SEGMENTS; i++) @@ -31,6 +29,17 @@ namespace DotRecast.Detour return temp; } + public static void ScaleCircle(Span src, RcVec3f center, float radius, Span dst) + { + for (int i = 0; i < CIRCLE_SEGMENTS; i++) + { + dst[3 * i] = src[3 * i] * radius + center.X; + dst[3 * i + 1] = center.Y; + dst[3 * i + 2] = src[3 * i + 2] * radius + center.Z; + } + } + + public float[] Apply(float[] verts, RcVec3f center, float radius) { float radiusSqr = radius * radius; @@ -50,29 +59,16 @@ namespace DotRecast.Detour return verts; } - float[] qCircle = Circle(center, radius); + Span qCircle = stackalloc float[UnitCircle.Length]; + ScaleCircle(UnitCircle, center, radius, qCircle); float[] intersection = DtConvexConvexIntersections.Intersect(verts, qCircle); if (intersection == null && DtUtils.PointInPolygon(center, verts, verts.Length / 3)) { // circle inside polygon - return qCircle; + return qCircle.ToArray(); } return intersection; } - - - private float[] Circle(RcVec3f center, float radius) - { - float[] circle = new float[12 * 3]; - for (int i = 0; i < CIRCLE_SEGMENTS * 3; i += 3) - { - circle[i] = UnitCircle[i] * radius + center.X; - circle[i + 1] = center.Y; - circle[i + 2] = UnitCircle[i + 2] * radius + center.Z; - } - - return circle; - } } } \ No newline at end of file