Changed `new float[]` to `stackalloc float[]` in `DtConvexConvexIntersections.Intersect()`

This commit is contained in:
ikpil 2024-07-05 00:15:03 +09:00
parent 4743ba68f9
commit ab2c520076
3 changed files with 23 additions and 30 deletions

View File

@ -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 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 to use Span<byte> and stackalloc for improved performance and memory management in `RcLayers.BuildHeightfieldLayers()`
- Changed vertCount and triCount to byte in `DtPolyDetail` - Changed vertCount and triCount to byte in `DtPolyDetail`
- Changed `new float[]` to `stackalloc float[]` in `DtConvexConvexIntersections.Intersect()`
### Removed ### Removed
- Removed RcMeshDetails.VdistSq2(float[], float[]) - Removed RcMeshDetails.VdistSq2(float[], float[])

View File

@ -18,23 +18,20 @@ freely, subject to the following restrictions:
*/ */
using System; using System;
using DotRecast.Core;
using DotRecast.Core.Numerics; using DotRecast.Core.Numerics;
namespace DotRecast.Detour 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 public static class DtConvexConvexIntersections
{ {
private const float EPSILON = 0.0001f; 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 n = p.Length / 3;
int m = q.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; int ii = 0;
/* Initialize variables. */ /* Initialize variables. */
RcVec3f a = new RcVec3f(); RcVec3f a = new RcVec3f();
@ -171,12 +168,11 @@ namespace DotRecast.Detour
return null; return null;
} }
float[] copied = new float[ii]; float[] copied = inters.Slice(0, ii).ToArray();
RcArrays.Copy(inters, copied, ii);
return copied; 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) if (ii > 0)
{ {

View File

@ -3,13 +3,11 @@ using DotRecast.Core.Numerics;
namespace DotRecast.Detour 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 public class DtStrictDtPolygonByCircleConstraint : IDtPolygonByCircleConstraint
{ {
private const int CIRCLE_SEGMENTS = 12; 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(); 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]; var temp = new float[CIRCLE_SEGMENTS * 3];
for (int i = 0; i < CIRCLE_SEGMENTS; i++) for (int i = 0; i < CIRCLE_SEGMENTS; i++)
@ -31,6 +29,17 @@ namespace DotRecast.Detour
return temp; 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) public float[] Apply(float[] verts, RcVec3f center, float radius)
{ {
float radiusSqr = radius * radius; float radiusSqr = radius * radius;
@ -50,29 +59,16 @@ namespace DotRecast.Detour
return verts; 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); float[] intersection = DtConvexConvexIntersections.Intersect(verts, qCircle);
if (intersection == null && DtUtils.PointInPolygon(center, verts, verts.Length / 3)) if (intersection == null && DtUtils.PointInPolygon(center, verts, verts.Length / 3))
{ {
// circle inside polygon // circle inside polygon
return qCircle; return qCircle.ToArray();
} }
return intersection; 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;
}
} }
} }