Skip to content

Commit

Permalink
Changed new float[] to stackalloc float[] in `DtConvexConvexInter…
Browse files Browse the repository at this point in the history
…sections.Intersect()`
  • Loading branch information
ikpil committed Jul 4, 2024
1 parent 4743ba6 commit ab2c520
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 30 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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<byte> 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[])
Expand Down
14 changes: 5 additions & 9 deletions src/DotRecast.Detour/DtConvexConvexIntersections.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,20 @@ 3. This notice may not be removed or altered from any source distribution.
*/

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<float> p, Span<float> q)
{
int n = p.Length / 3;
int m = q.Length / 3;
float[] inters = new float[Math.Max(m, n) * 3 * 3];
Span<float> inters = stackalloc float[Math.Max(m, n) * 3 * 3];
int ii = 0;
/* Initialize variables. */
RcVec3f a = new RcVec3f();
Expand Down Expand Up @@ -171,12 +168,11 @@ public static float[] Intersect(float[] p, float[] q)
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<float> inters, int ii, RcVec3f p)
{
if (ii > 0)
{
Expand Down
38 changes: 17 additions & 21 deletions src/DotRecast.Detour/DtStrictDtPolygonByCircleConstraint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,19 @@

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();

private DtStrictDtPolygonByCircleConstraint()
{
}

private static float[] MakeUnitCircle()
public static float[] CreateCircle()
{
var temp = new float[CIRCLE_SEGMENTS * 3];
for (int i = 0; i < CIRCLE_SEGMENTS; i++)
Expand All @@ -31,6 +29,17 @@ private static float[] MakeUnitCircle()
return temp;
}

public static void ScaleCircle(Span<float> src, RcVec3f center, float radius, Span<float> 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;
Expand All @@ -50,29 +59,16 @@ public float[] Apply(float[] verts, RcVec3f center, float radius)
return verts;
}

float[] qCircle = Circle(center, radius);
Span<float> 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;
}
}
}

0 comments on commit ab2c520

Please sign in to comment.