Skip to content

Commit

Permalink
Improved the IDtPolygonByCircleConstraint interface for better memory…
Browse files Browse the repository at this point in the history
… reuse @wrenge
  • Loading branch information
ikpil committed Dec 21, 2024
1 parent 2a26dd4 commit 3c3034d
Show file tree
Hide file tree
Showing 6 changed files with 25 additions and 22 deletions.
2 changes: 0 additions & 2 deletions src/DotRecast.Core/Buffers/RcRentedArray.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
using System;
using System.Buffers;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Threading;

namespace DotRecast.Core.Buffers
{
Expand Down
6 changes: 3 additions & 3 deletions src/DotRecast.Detour/DtNavMeshQuery.cs
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ public DtStatus FindRandomPointAroundCircle(long startRef, RcVec3f centerPos, fl

DtPoly randomPoly = null;
long randomPolyRef = 0;
float[] randomPolyVerts = null;
Span<float> randomPolyVerts = null;

while (!m_openList.IsEmpty())
{
Expand All @@ -288,8 +288,8 @@ public DtStatus FindRandomPointAroundCircle(long startRef, RcVec3f centerPos, fl
RcArrays.Copy(bestTile.data.verts, bestPoly.verts[j] * 3, polyVerts, j * 3, 3);
}

float[] constrainedVerts = constraint.Apply(polyVerts, centerPos, maxRadius);
if (constrainedVerts != null)
var ncverts = constraint.Apply(polyVerts, centerPos, maxRadius, out var constrainedVerts);
if (!constrainedVerts.IsEmpty)
{
int vertCount = constrainedVerts.Length / 3;
for (int j = 2; j < vertCount; ++j)
Expand Down
6 changes: 4 additions & 2 deletions src/DotRecast.Detour/DtNoOpDtPolygonByCircleConstraint.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System;
using DotRecast.Core.Numerics;

namespace DotRecast.Detour
Expand All @@ -10,9 +11,10 @@ private DtNoOpDtPolygonByCircleConstraint()
{
}

public float[] Apply(float[] polyVerts, RcVec3f circleCenter, float radius)
public int Apply(Span<float> polyVerts, RcVec3f circleCenter, float radius, out Span<float> constrainedVerts)
{
return polyVerts;
constrainedVerts = polyVerts;
return polyVerts.Length;
}
}
}
12 changes: 8 additions & 4 deletions src/DotRecast.Detour/DtStrictDtPolygonByCircleConstraint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public static void ScaleCircle(Span<float> src, RcVec3f center, float radius, Sp
}


public float[] Apply(float[] verts, RcVec3f center, float radius)
public int Apply(Span<float> verts, RcVec3f center, float radius, out Span<float> constrainedVerts)
{
float radiusSqr = radius * radius;
int outsideVertex = -1;
Expand All @@ -56,7 +56,8 @@ public float[] Apply(float[] verts, RcVec3f center, float radius)
if (outsideVertex == -1)
{
// polygon inside circle
return verts;
constrainedVerts = verts;
return verts.Length;
}

Span<float> qCircle = stackalloc float[UnitCircle.Length];
Expand All @@ -65,10 +66,13 @@ public float[] Apply(float[] verts, RcVec3f center, float radius)
if (intersection == null && DtUtils.PointInPolygon(center, verts, verts.Length / 3))
{
// circle inside polygon
return qCircle.ToArray();
float[] qCircleArray = qCircle.ToArray();
constrainedVerts = qCircleArray;
return qCircleArray.Length;
}

return intersection;
constrainedVerts = intersection;
return intersection?.Length ?? 0;
}
}
}
2 changes: 1 addition & 1 deletion src/DotRecast.Detour/IDtPolygonByCircleConstraint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@ namespace DotRecast.Detour
{
public interface IDtPolygonByCircleConstraint
{
float[] Apply(float[] polyVerts, RcVec3f circleCenter, float radius);
int Apply(Span<float> polyVerts, RcVec3f circleCenter, float radius, out Span<float> constrainedVerts);
}
}
19 changes: 9 additions & 10 deletions test/DotRecast.Detour.Test/PolygonByCircleConstraintTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ 3. This notice may not be removed or altered from any source distribution.

namespace DotRecast.Detour.Test;


public class PolygonByCircleConstraintTest
{
private readonly IDtPolygonByCircleConstraint _constraint = DtStrictDtPolygonByCircleConstraint.Shared;
Expand All @@ -32,9 +31,9 @@ public void ShouldHandlePolygonFullyInsideCircle()
{
float[] polygon = { -2, 0, 2, 2, 0, 2, 2, 0, -2, -2, 0, -2 };
RcVec3f center = new RcVec3f(1, 0, 1);
float[] constrained = _constraint.Apply(polygon, center, 6);

Assert.That(constrained, Is.EqualTo(polygon));
_constraint.Apply(polygon, center, 6, out var constrained);
Assert.That(constrained.ToArray(), Is.EqualTo(polygon));
}

[Test]
Expand All @@ -44,9 +43,9 @@ public void ShouldHandleVerticalSegment()
float[] polygon = { -2, 0, 2, 2, 0, 2, 2, 0, -2, -2, 0, -2 };
RcVec3f center = new RcVec3f(2, 0, 0);

float[] constrained = _constraint.Apply(polygon, center, 3);
_constraint.Apply(polygon, center, 3, out var constrained);
Assert.That(constrained.Length, Is.EqualTo(expectedSize));
Assert.That(constrained, Is.SupersetOf(new[] { 2f, 0f, 2f, 2f, 0f, -2f }));
Assert.That(constrained.ToArray(), Is.SupersetOf(new[] { 2f, 0f, 2f, 2f, 0f, -2f }));
}

[Test]
Expand All @@ -55,7 +54,7 @@ public void ShouldHandleCircleFullyInsidePolygon()
int expectedSize = 12 * 3;
float[] polygon = { -4, 0, 0, -3, 0, 3, 2, 0, 3, 3, 0, -3, -2, 0, -4 };
RcVec3f center = new RcVec3f(-1, 0, -1);
float[] constrained = _constraint.Apply(polygon, center, 2);
_constraint.Apply(polygon, center, 2, out var constrained);

Assert.That(constrained.Length, Is.EqualTo(expectedSize));

Expand All @@ -73,10 +72,10 @@ public void ShouldHandleCircleInsidePolygon()
int expectedSize = 9 * 3;
float[] polygon = { -4, 0, 0, -3, 0, 3, 2, 0, 3, 3, 0, -3, -2, 0, -4 };
RcVec3f center = new RcVec3f(-2, 0, -1);
float[] constrained = _constraint.Apply(polygon, center, 3);
_constraint.Apply(polygon, center, 3, out var constrained);

Assert.That(constrained.Length, Is.EqualTo(expectedSize));
Assert.That(constrained, Is.SupersetOf(new[] { -2f, 0f, -4f, -4f, 0f, 0f, -3.4641016f, 0.0f, 1.60769534f, -2.0f, 0.0f, 2.0f }));
Assert.That(constrained.ToArray(), Is.SupersetOf(new[] { -2f, 0f, -4f, -4f, 0f, 0f, -3.4641016f, 0.0f, 1.60769534f, -2.0f, 0.0f, 2.0f }));
}

[Test]
Expand All @@ -85,9 +84,9 @@ public void ShouldHandleCircleOutsidePolygon()
int expectedSize = 7 * 3;
float[] polygon = { -4, 0, 0, -3, 0, 3, 2, 0, 3, 3, 0, -3, -2, 0, -4 };
RcVec3f center = new RcVec3f(4, 0, 0);
float[] constrained = _constraint.Apply(polygon, center, 4);
_constraint.Apply(polygon, center, 4, out var constrained);

Assert.That(constrained.Length, Is.EqualTo(expectedSize));
Assert.That(constrained, Is.SupersetOf(new[] { 1.53589869f, 0f, 3f, 2f, 0f, 3f, 3f, 0f, -3f }));
Assert.That(constrained.ToArray(), Is.SupersetOf(new[] { 1.53589869f, 0f, 3f, 2f, 0f, 3f, 3f, 0f, -3f }));
}
}

0 comments on commit 3c3034d

Please sign in to comment.