forked from mirror/DotRecast
Compare commits
No commits in common. "0b888b16fb3b144cbbecd5ae77d932e0c17ff76b" and "7de4b511350337275e4a7404893462110b695e26" have entirely different histories.
0b888b16fb
...
7de4b51135
|
@ -88,7 +88,7 @@ namespace DotRecast.Core.Collections
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
//int idx = _items.BinarySearch(item, _comparer); // don't use this! Because reference types can be reused externally.
|
//int idx = _items.BinarySearch(item, _comparer); // don't use this! Because reference types can be reused externally.
|
||||||
int idx = _items.LastIndexOf(item);
|
int idx = _items.FindLastIndex(x => item.Equals(x));
|
||||||
if (0 > idx)
|
if (0 > idx)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
|
@ -205,7 +205,7 @@ namespace DotRecast.Core.Numerics
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static float Dist2DSqr(RcVec3f p, Span<float> verts, int i)
|
public static float Dist2DSqr(RcVec3f p, float[] verts, int i)
|
||||||
{
|
{
|
||||||
float dx = verts[i] - p.X;
|
float dx = verts[i] - p.X;
|
||||||
float dz = verts[i + 2] - p.Z;
|
float dz = verts[i + 2] - p.Z;
|
||||||
|
|
|
@ -27,7 +27,7 @@ namespace DotRecast.Detour
|
||||||
{
|
{
|
||||||
private const float EPSILON = 0.0001f;
|
private const float EPSILON = 0.0001f;
|
||||||
|
|
||||||
public static Span<float> Intersect(Span<float> p, Span<float> q, Span<float> buffer)
|
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;
|
||||||
|
@ -95,7 +95,7 @@ namespace DotRecast.Detour
|
||||||
/* Special case: A & B parallel and separated. */
|
/* Special case: A & B parallel and separated. */
|
||||||
if (parallel && aHB < 0f && bHA < 0f)
|
if (parallel && aHB < 0f && bHA < 0f)
|
||||||
{
|
{
|
||||||
return Span<float>.Empty;
|
return null;
|
||||||
}
|
}
|
||||||
/* Special case: A & B collinear. */
|
/* Special case: A & B collinear. */
|
||||||
else if (parallel && MathF.Abs(aHB) < EPSILON && MathF.Abs(bHA) < EPSILON)
|
else if (parallel && MathF.Abs(aHB) < EPSILON && MathF.Abs(bHA) < EPSILON)
|
||||||
|
@ -168,9 +168,8 @@ namespace DotRecast.Detour
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Span<float> result = buffer.Slice(0, ii);
|
float[] copied = inters.Slice(0, ii).ToArray();
|
||||||
inters.Slice(0, ii).CopyTo(result);
|
return copied;
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int AddVertex(Span<float> inters, int ii, RcVec3f p)
|
private static int AddVertex(Span<float> inters, int ii, RcVec3f p)
|
||||||
|
|
|
@ -233,7 +233,6 @@ namespace DotRecast.Detour
|
||||||
IDtQueryFilter filter, IRcRand frand, IDtPolygonByCircleConstraint constraint,
|
IDtQueryFilter filter, IRcRand frand, IDtPolygonByCircleConstraint constraint,
|
||||||
out long randomRef, out RcVec3f randomPt)
|
out long randomRef, out RcVec3f randomPt)
|
||||||
{
|
{
|
||||||
const int MAX_VERT_BUFFER_SIZE = 128;
|
|
||||||
randomRef = startRef;
|
randomRef = startRef;
|
||||||
randomPt = centerPos;
|
randomPt = centerPos;
|
||||||
|
|
||||||
|
@ -267,13 +266,9 @@ namespace DotRecast.Detour
|
||||||
float radiusSqr = maxRadius * maxRadius;
|
float radiusSqr = maxRadius * maxRadius;
|
||||||
float areaSum = 0.0f;
|
float areaSum = 0.0f;
|
||||||
|
|
||||||
using RcRentedArray<float> polyVertsBuffer = RcRentedArray.Rent<float>(MAX_VERT_BUFFER_SIZE);
|
|
||||||
using RcRentedArray<float> randomPolyVertsBuffer = RcRentedArray.Rent<float>(MAX_VERT_BUFFER_SIZE);
|
|
||||||
using RcRentedArray<float> constrainedVertsBuffer = RcRentedArray.Rent<float>(MAX_VERT_BUFFER_SIZE);
|
|
||||||
|
|
||||||
DtPoly randomPoly = null;
|
DtPoly randomPoly = null;
|
||||||
long randomPolyRef = 0;
|
long randomPolyRef = 0;
|
||||||
Span<float> randomPolyVerts = Span<float>.Empty;
|
float[] randomPolyVerts = null;
|
||||||
|
|
||||||
while (!m_openList.IsEmpty())
|
while (!m_openList.IsEmpty())
|
||||||
{
|
{
|
||||||
|
@ -291,14 +286,14 @@ namespace DotRecast.Detour
|
||||||
{
|
{
|
||||||
// Calc area of the polygon.
|
// Calc area of the polygon.
|
||||||
float polyArea = 0.0f;
|
float polyArea = 0.0f;
|
||||||
Span<float> polyVerts = polyVertsBuffer.AsSpan().Slice(0, bestPoly.vertCount * 3);
|
float[] polyVerts = new float[bestPoly.vertCount * 3];
|
||||||
for (int j = 0; j < bestPoly.vertCount; ++j)
|
for (int j = 0; j < bestPoly.vertCount; ++j)
|
||||||
{
|
{
|
||||||
RcSpans.Copy(bestTile.data.verts, bestPoly.verts[j] * 3, polyVerts, j * 3, 3);
|
RcArrays.Copy(bestTile.data.verts, bestPoly.verts[j] * 3, polyVerts, j * 3, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
Span<float> constrainedVerts = constraint.Apply(polyVerts, centerPos, maxRadius, constrainedVertsBuffer.AsSpan());
|
float[] constrainedVerts = constraint.Apply(polyVerts, centerPos, maxRadius);
|
||||||
if (!constrainedVerts.IsEmpty)
|
if (constrainedVerts != null)
|
||||||
{
|
{
|
||||||
int vertCount = constrainedVerts.Length / 3;
|
int vertCount = constrainedVerts.Length / 3;
|
||||||
for (int j = 2; j < vertCount; ++j)
|
for (int j = 2; j < vertCount; ++j)
|
||||||
|
@ -316,8 +311,7 @@ namespace DotRecast.Detour
|
||||||
{
|
{
|
||||||
randomPoly = bestPoly;
|
randomPoly = bestPoly;
|
||||||
randomPolyRef = bestRef;
|
randomPolyRef = bestRef;
|
||||||
randomPolyVerts = randomPolyVertsBuffer.AsSpan().Slice(0, constrainedVerts.Length);
|
randomPolyVerts = constrainedVerts;
|
||||||
constrainedVerts.CopyTo(randomPolyVerts);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
using System;
|
|
||||||
using DotRecast.Core.Numerics;
|
using DotRecast.Core.Numerics;
|
||||||
|
|
||||||
namespace DotRecast.Detour
|
namespace DotRecast.Detour
|
||||||
|
@ -11,11 +10,9 @@ namespace DotRecast.Detour
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public Span<float> Apply(Span<float> polyVerts, RcVec3f circleCenter, float radius, Span<float> resultBuffer)
|
public float[] Apply(float[] polyVerts, RcVec3f circleCenter, float radius)
|
||||||
{
|
{
|
||||||
var result = resultBuffer.Slice(0, polyVerts.Length);
|
return polyVerts;
|
||||||
polyVerts.CopyTo(result);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -39,7 +39,8 @@ namespace DotRecast.Detour
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Span<float> Apply(Span<float> verts, RcVec3f center, float radius, Span<float> resultBuffer)
|
|
||||||
|
public float[] Apply(float[] verts, RcVec3f center, float radius)
|
||||||
{
|
{
|
||||||
float radiusSqr = radius * radius;
|
float radiusSqr = radius * radius;
|
||||||
int outsideVertex = -1;
|
int outsideVertex = -1;
|
||||||
|
@ -55,30 +56,19 @@ namespace DotRecast.Detour
|
||||||
if (outsideVertex == -1)
|
if (outsideVertex == -1)
|
||||||
{
|
{
|
||||||
// polygon inside circle
|
// polygon inside circle
|
||||||
var result = resultBuffer.Slice(0, verts.Length);
|
return verts;
|
||||||
verts.CopyTo(result);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Span<float> qCircle = stackalloc float[UnitCircle.Length];
|
Span<float> qCircle = stackalloc float[UnitCircle.Length];
|
||||||
ScaleCircle(UnitCircle, center, radius, qCircle);
|
ScaleCircle(UnitCircle, center, radius, qCircle);
|
||||||
Span<float> intersection = DtConvexConvexIntersections.Intersect(verts, qCircle, resultBuffer);
|
float[] intersection = DtConvexConvexIntersections.Intersect(verts, qCircle);
|
||||||
if (intersection.IsEmpty && DtUtils.PointInPolygon(center, verts, verts.Length / 3))
|
if (intersection == null && DtUtils.PointInPolygon(center, verts, verts.Length / 3))
|
||||||
{
|
{
|
||||||
// circle inside polygon
|
// circle inside polygon
|
||||||
var result = resultBuffer.Slice(0, qCircle.Length);
|
return qCircle.ToArray();
|
||||||
qCircle.CopyTo(result);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!intersection.IsEmpty)
|
return intersection;
|
||||||
{
|
|
||||||
var result = resultBuffer.Slice(0, intersection.Length);
|
|
||||||
// No need to copy, data is already in buffer
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Span<float>.Empty;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -24,6 +24,6 @@ namespace DotRecast.Detour
|
||||||
{
|
{
|
||||||
public interface IDtPolygonByCircleConstraint
|
public interface IDtPolygonByCircleConstraint
|
||||||
{
|
{
|
||||||
Span<float> Apply(Span<float> polyVerts, RcVec3f circleCenter, float radius, Span<float> resultBuffer);
|
float[] Apply(float[] polyVerts, RcVec3f circleCenter, float radius);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -17,7 +17,6 @@ freely, subject to the following restrictions:
|
||||||
3. This notice may not be removed or altered from any source distribution.
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
|
||||||
namespace DotRecast.Detour.Test;
|
namespace DotRecast.Detour.Test;
|
||||||
|
@ -30,10 +29,9 @@ public class ConvexConvexIntersectionTest
|
||||||
{
|
{
|
||||||
float[] p = { -4, 0, 0, -3, 0, 3, 2, 0, 3, 3, 0, -3, -2, 0, -4 };
|
float[] p = { -4, 0, 0, -3, 0, 3, 2, 0, 3, 3, 0, -3, -2, 0, -4 };
|
||||||
float[] q = { -4, 0, 0, -3, 0, 3, 2, 0, 3, 3, 0, -3, -2, 0, -4 };
|
float[] q = { -4, 0, 0, -3, 0, 3, 2, 0, 3, 3, 0, -3, -2, 0, -4 };
|
||||||
float[] buffer = new float[128];
|
float[] intersection = DtConvexConvexIntersections.Intersect(p, q);
|
||||||
Span<float> intersection = DtConvexConvexIntersections.Intersect(p, q, buffer);
|
|
||||||
Assert.That(intersection.Length, Is.EqualTo(5 * 3));
|
Assert.That(intersection.Length, Is.EqualTo(5 * 3));
|
||||||
Assert.That(intersection.ToArray(), Is.EquivalentTo(p));
|
Assert.That(intersection, Is.EqualTo(p));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -41,9 +39,8 @@ public class ConvexConvexIntersectionTest
|
||||||
{
|
{
|
||||||
float[] p = { -5, 0, -5, -5, 0, 4, 1, 0, 4, 1, 0, -5 };
|
float[] p = { -5, 0, -5, -5, 0, 4, 1, 0, 4, 1, 0, -5 };
|
||||||
float[] q = { -4, 0, 0, -3, 0, 3, 2, 0, 3, 3, 0, -3, -2, 0, -4 };
|
float[] q = { -4, 0, 0, -3, 0, 3, 2, 0, 3, 3, 0, -3, -2, 0, -4 };
|
||||||
float[] buffer = new float[128];
|
float[] intersection = DtConvexConvexIntersections.Intersect(p, q);
|
||||||
Span<float> intersection = DtConvexConvexIntersections.Intersect(p, q, buffer);
|
|
||||||
Assert.That(intersection.Length, Is.EqualTo(5 * 3));
|
Assert.That(intersection.Length, Is.EqualTo(5 * 3));
|
||||||
Assert.That(intersection.ToArray(), Is.EquivalentTo(new[] { 1, 0, 3, 1, 0, -3.4f, -2, 0, -4, -4, 0, 0, -3, 0, 3 }));
|
Assert.That(intersection, Is.EqualTo(new[] { 1, 0, 3, 1, 0, -3.4f, -2, 0, -4, -4, 0, 0, -3, 0, 3 }));
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -17,7 +17,6 @@ freely, subject to the following restrictions:
|
||||||
3. This notice may not be removed or altered from any source distribution.
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
|
||||||
using DotRecast.Core.Numerics;
|
using DotRecast.Core.Numerics;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
|
||||||
|
@ -33,12 +32,9 @@ public class PolygonByCircleConstraintTest
|
||||||
{
|
{
|
||||||
float[] polygon = { -2, 0, 2, 2, 0, 2, 2, 0, -2, -2, 0, -2 };
|
float[] polygon = { -2, 0, 2, 2, 0, 2, 2, 0, -2, -2, 0, -2 };
|
||||||
RcVec3f center = new RcVec3f(1, 0, 1);
|
RcVec3f center = new RcVec3f(1, 0, 1);
|
||||||
var radius = 6;
|
float[] constrained = _constraint.Apply(polygon, center, 6);
|
||||||
|
|
||||||
float[] buffer = new float[128];
|
Assert.That(constrained, Is.EqualTo(polygon));
|
||||||
Span<float> constrained = _constraint.Apply(polygon, center, radius, buffer);
|
|
||||||
|
|
||||||
Assert.That(constrained.ToArray(), Is.EquivalentTo(polygon));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -47,13 +43,10 @@ public class PolygonByCircleConstraintTest
|
||||||
int expectedSize = 21;
|
int expectedSize = 21;
|
||||||
float[] polygon = { -2, 0, 2, 2, 0, 2, 2, 0, -2, -2, 0, -2 };
|
float[] polygon = { -2, 0, 2, 2, 0, 2, 2, 0, -2, -2, 0, -2 };
|
||||||
RcVec3f center = new RcVec3f(2, 0, 0);
|
RcVec3f center = new RcVec3f(2, 0, 0);
|
||||||
var radius = 3;
|
|
||||||
|
|
||||||
float[] buffer = new float[128];
|
|
||||||
Span<float> constrained = _constraint.Apply(polygon, center, radius, buffer);
|
|
||||||
|
|
||||||
|
float[] constrained = _constraint.Apply(polygon, center, 3);
|
||||||
Assert.That(constrained.Length, Is.EqualTo(expectedSize));
|
Assert.That(constrained.Length, Is.EqualTo(expectedSize));
|
||||||
Assert.That(constrained.ToArray(), Is.SupersetOf(new[] { 2f, 0f, 2f, 2f, 0f, -2f }));
|
Assert.That(constrained, Is.SupersetOf(new[] { 2f, 0f, 2f, 2f, 0f, -2f }));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -62,10 +55,7 @@ public class PolygonByCircleConstraintTest
|
||||||
int expectedSize = 12 * 3;
|
int expectedSize = 12 * 3;
|
||||||
float[] polygon = { -4, 0, 0, -3, 0, 3, 2, 0, 3, 3, 0, -3, -2, 0, -4 };
|
float[] polygon = { -4, 0, 0, -3, 0, 3, 2, 0, 3, 3, 0, -3, -2, 0, -4 };
|
||||||
RcVec3f center = new RcVec3f(-1, 0, -1);
|
RcVec3f center = new RcVec3f(-1, 0, -1);
|
||||||
var radius = 2;
|
float[] constrained = _constraint.Apply(polygon, center, 2);
|
||||||
|
|
||||||
float[] buffer = new float[128];
|
|
||||||
Span<float> constrained = _constraint.Apply(polygon, center, radius, buffer);
|
|
||||||
|
|
||||||
Assert.That(constrained.Length, Is.EqualTo(expectedSize));
|
Assert.That(constrained.Length, Is.EqualTo(expectedSize));
|
||||||
|
|
||||||
|
@ -83,13 +73,10 @@ public class PolygonByCircleConstraintTest
|
||||||
int expectedSize = 9 * 3;
|
int expectedSize = 9 * 3;
|
||||||
float[] polygon = { -4, 0, 0, -3, 0, 3, 2, 0, 3, 3, 0, -3, -2, 0, -4 };
|
float[] polygon = { -4, 0, 0, -3, 0, 3, 2, 0, 3, 3, 0, -3, -2, 0, -4 };
|
||||||
RcVec3f center = new RcVec3f(-2, 0, -1);
|
RcVec3f center = new RcVec3f(-2, 0, -1);
|
||||||
var radius = 3;
|
float[] constrained = _constraint.Apply(polygon, center, 3);
|
||||||
|
|
||||||
float[] buffer = new float[128];
|
|
||||||
Span<float> constrained = _constraint.Apply(polygon, center, radius, buffer);
|
|
||||||
|
|
||||||
Assert.That(constrained.Length, Is.EqualTo(expectedSize));
|
Assert.That(constrained.Length, Is.EqualTo(expectedSize));
|
||||||
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 }));
|
Assert.That(constrained, Is.SupersetOf(new[] { -2f, 0f, -4f, -4f, 0f, 0f, -3.4641016f, 0.0f, 1.60769534f, -2.0f, 0.0f, 2.0f }));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -98,12 +85,9 @@ public class PolygonByCircleConstraintTest
|
||||||
int expectedSize = 7 * 3;
|
int expectedSize = 7 * 3;
|
||||||
float[] polygon = { -4, 0, 0, -3, 0, 3, 2, 0, 3, 3, 0, -3, -2, 0, -4 };
|
float[] polygon = { -4, 0, 0, -3, 0, 3, 2, 0, 3, 3, 0, -3, -2, 0, -4 };
|
||||||
RcVec3f center = new RcVec3f(4, 0, 0);
|
RcVec3f center = new RcVec3f(4, 0, 0);
|
||||||
var radius = 4;
|
float[] constrained = _constraint.Apply(polygon, center, 4);
|
||||||
|
|
||||||
float[] buffer = new float[128];
|
|
||||||
Span<float> constrained = _constraint.Apply(polygon, center, radius, buffer);
|
|
||||||
|
|
||||||
Assert.That(constrained.Length, Is.EqualTo(expectedSize));
|
Assert.That(constrained.Length, Is.EqualTo(expectedSize));
|
||||||
Assert.That(constrained.ToArray(), Is.SupersetOf(new[] { 1.53589869f, 0f, 3f, 2f, 0f, 3f, 3f, 0f, -3f }));
|
Assert.That(constrained, Is.SupersetOf(new[] { 1.53589869f, 0f, 3f, 2f, 0f, 3f, 3f, 0f, -3f }));
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue