refactor: cleaning up the API to .net 8 Sytem.Numerics compatibility.

This commit is contained in:
ikpil 2023-10-18 00:08:28 +09:00
parent 75d00916f3
commit 5c2dd6b757
18 changed files with 72 additions and 59 deletions

View File

@ -125,15 +125,12 @@ namespace DotRecast.Core.Numerics
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly RcVec3f Subtract(RcVec3f right)
public static RcVec3f Subtract(RcVec3f left, RcVec3f right)
{
return new RcVec3f(
X - right.X,
Y - right.Y,
Z - right.Z
);
return left - right;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly RcVec3f Add(RcVec3f v2)
{
@ -286,7 +283,11 @@ namespace DotRecast.Core.Numerics
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static RcVec3f operator -(RcVec3f left, RcVec3f right)
{
return left.Subtract(right);
return new RcVec3f(
left.X - right.X,
left.Y - right.Y,
left.Z - right.Z
);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]

View File

@ -16,5 +16,17 @@ namespace DotRecast.Core.Numerics
default: throw new IndexOutOfRangeException("vector2f index out of range");
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float Get(this RcVec3f v, int i)
{
switch (i)
{
case 0: return v.X;
case 1: return v.Y;
case 2: return v.Z;
default: throw new IndexOutOfRangeException("vector3f index out of range");
}
}
}
}

View File

@ -29,9 +29,9 @@ namespace DotRecast.Core
{
t = 0;
float v, w;
RcVec3f ab = b.Subtract(a);
RcVec3f ac = c.Subtract(a);
RcVec3f qp = sp.Subtract(sq);
RcVec3f ab = RcVec3f.Subtract(b, a);
RcVec3f ac = RcVec3f.Subtract(c, a);
RcVec3f qp = RcVec3f.Subtract(sp, sq);
// Compute triangle normal. Can be precalculated or cached if
// intersecting multiple segments against the same triangle
@ -48,7 +48,7 @@ namespace DotRecast.Core
// Compute intersection t value of pq with plane of triangle. A ray
// intersects iff 0 <= t. Segment intersects iff 0 <= t <= 1. Delay
// dividing by d until intersection has been found to pierce triangle
RcVec3f ap = sp.Subtract(a);
RcVec3f ap = RcVec3f.Subtract(sp, a);
t = RcVec3f.Dot(ap, norm);
if (t < 0.0f)
{
@ -93,18 +93,18 @@ namespace DotRecast.Core
for (int i = 0; i < 3; i++)
{
if (Math.Abs(d[i]) < EPS)
if (Math.Abs(d.Get(i)) < EPS)
{
if (sp[i] < amin[i] || sp[i] > amax[i])
if (sp.Get(i) < amin.Get(i) || sp.Get(i) > amax.Get(i))
{
return false;
}
}
else
{
float ood = 1.0f / d[i];
float t1 = (amin[i] - sp[i]) * ood;
float t2 = (amax[i] - sp[i]) * ood;
float ood = 1.0f / d.Get(i);
float t1 = (amin.Get(i) - sp.Get(i)) * ood;
float t2 = (amax.Get(i) - sp.Get(i)) * ood;
if (t1 > t2)
{

View File

@ -904,7 +904,7 @@ namespace DotRecast.Detour.Crowd
}
// Check for overlap.
RcVec3f diff = pos.Subtract(ag.npos);
RcVec3f diff = RcVec3f.Subtract(pos, ag.npos);
if (Math.Abs(diff.Y) >= (height + ag.option.height) / 2.0f)
{
continue;
@ -1077,7 +1077,7 @@ namespace DotRecast.Detour.Crowd
{
DtCrowdAgent nei = ag.neis[j].agent;
RcVec3f diff = ag.npos.Subtract(nei.npos);
RcVec3f diff = RcVec3f.Subtract(ag.npos, nei.npos);
diff.Y = 0;
float distSqr = RcVec3f.LenSqr(diff);
@ -1224,7 +1224,7 @@ namespace DotRecast.Detour.Crowd
{
DtCrowdAgent nei = ag.neis[j].agent;
long idx1 = nei.idx;
RcVec3f diff = ag.npos.Subtract(nei.npos);
RcVec3f diff = RcVec3f.Subtract(ag.npos, nei.npos);
diff.Y = 0;
float dist = RcVec3f.LenSqr(diff);

View File

@ -113,7 +113,7 @@ namespace DotRecast.Detour.Crowd
{
// Fake dynamic constraint.
float maxDelta = option.maxAcceleration * dt;
RcVec3f dv = nvel.Subtract(vel);
RcVec3f dv = RcVec3f.Subtract(nvel, vel);
float ds = dv.Length();
if (ds > maxDelta)
dv = dv.Scale(maxDelta / ds);
@ -167,8 +167,8 @@ namespace DotRecast.Detour.Crowd
var p0 = corners[ip0].pos;
var p1 = corners[ip1].pos;
var dir0 = p0.Subtract(npos);
var dir1 = p1.Subtract(npos);
var dir0 = RcVec3f.Subtract(p0, npos);
var dir1 = RcVec3f.Subtract(p1, npos);
dir0.Y = 0;
dir1.Y = 0;
@ -191,7 +191,7 @@ namespace DotRecast.Detour.Crowd
RcVec3f dir = new RcVec3f();
if (0 < corners.Count)
{
dir = corners[0].pos.Subtract(npos);
dir = RcVec3f.Subtract(corners[0].pos, npos);
dir.Y = 0;
dir.Normalize();
}

View File

@ -126,9 +126,9 @@ namespace DotRecast.Detour.Crowd
RcVec3f orig = new RcVec3f();
RcVec3f dv = new RcVec3f();
cir.dp = pb.Subtract(pa);
cir.dp = RcVec3f.Subtract(pb, pa);
cir.dp.Normalize();
dv = cir.dvel.Subtract(dvel);
dv = RcVec3f.Subtract(cir.dvel, dvel);
float a = DtUtils.TriArea2D(orig, cir.dp, dv);
if (a < 0.01f)
@ -161,7 +161,7 @@ namespace DotRecast.Detour.Crowd
tmin = 0;
tmax = 0;
RcVec3f s = c1.Subtract(c0);
RcVec3f s = RcVec3f.Subtract(c1, c0);
float r = r0 + r1;
float c = s.Dot2D(s) - r * r;
float a = v.Dot2D(v);
@ -185,8 +185,8 @@ namespace DotRecast.Detour.Crowd
private bool IsectRaySeg(RcVec3f ap, RcVec3f u, RcVec3f bp, RcVec3f bq, ref float t)
{
RcVec3f v = bq.Subtract(bp);
RcVec3f w = ap.Subtract(bp);
RcVec3f v = RcVec3f.Subtract(bq, bp);
RcVec3f w = RcVec3f.Subtract(ap, bp);
float d = RcVec3f.Perp2D(u, v);
if (Math.Abs(d) < 1e-6f)
return false;
@ -238,8 +238,8 @@ namespace DotRecast.Detour.Crowd
// RVO
RcVec3f vab = vcand.Scale(2);
vab = vab.Subtract(vel);
vab = vab.Subtract(cir.vel);
vab = RcVec3f.Subtract(vab, vel);
vab = RcVec3f.Subtract(vab, cir.vel);
// Side
side += Math.Clamp(Math.Min(cir.dp.Dot2D(vab) * 0.5f + 0.5f, cir.np.Dot2D(vab) * 2), 0.0f, 1.0f);
@ -275,7 +275,7 @@ namespace DotRecast.Detour.Crowd
if (seg.touch)
{
// Special case when the agent is very close to the segment.
RcVec3f sdir = seg.q.Subtract(seg.p);
RcVec3f sdir = RcVec3f.Subtract(seg.q, seg.p);
RcVec3f snorm = new RcVec3f();
snorm.X = -sdir.Z;
snorm.Z = sdir.X;

View File

@ -192,7 +192,7 @@ namespace DotRecast.Detour.Crowd
dist = Math.Min(dist + 0.01f, pathOptimizationRange);
// Adjust ray length.
var delta = next.Subtract(m_pos);
var delta = RcVec3f.Subtract(next, m_pos);
RcVec3f goal = RcVec3f.Mad(m_pos, delta, pathOptimizationRange / dist);
var status = navquery.Raycast(m_path[0], m_pos, goal, filter, 0, 0, out var rayHit);

View File

@ -16,7 +16,7 @@ namespace DotRecast.Detour.Extras.Jumplink
public EdgeSampler(JumpEdge edge, Trajectory trajectory)
{
this.trajectory = trajectory;
ax = edge.sq.Subtract(edge.sp);
ax = RcVec3f.Subtract(edge.sq, edge.sp);
ax.Normalize();
az.Set(ax.Z, 0, -ax.X);
az.Normalize();

View File

@ -58,8 +58,8 @@ namespace DotRecast.Detour
a1.Set(p, 3 * ((ai + n - 1) % n)); // prev a
b1.Set(q, 3 * ((bi + m - 1) % m)); // prev b
RcVec3f A = a.Subtract(a1);
RcVec3f B = b.Subtract(b1);
RcVec3f A = RcVec3f.Subtract(a, a1);
RcVec3f B = RcVec3f.Subtract(b, b1);
float cross = B.X * A.Z - A.X * B.Z; // TriArea2D({0, 0}, A, B);
float aHB = DtUtils.TriArea2D(b1, b, a);

View File

@ -28,7 +28,7 @@ namespace DotRecast.Detour
// If a point is directly over a polygon and closer than
// climb height, favor that instead of straight line nearest point.
float d = 0;
RcVec3f diff = _center.Subtract(closestPtPoly);
RcVec3f diff = RcVec3f.Subtract(_center, closestPtPoly);
if (posOverPoly)
{
d = Math.Abs(diff.Y) - tile.data.header.walkableClimb;

View File

@ -1352,7 +1352,7 @@ namespace DotRecast.Detour
nearestPt = RcVec3f.Zero;
bool overPoly = false;
RcVec3f bmin = center.Subtract(halfExtents);
RcVec3f bmin = RcVec3f.Subtract(center, halfExtents);
RcVec3f bmax = center.Add(halfExtents);
// Get nearby polygons from proximity grid.
@ -1369,7 +1369,7 @@ namespace DotRecast.Detour
// If a point is directly over a polygon and closer than
// climb height, favor that instead of straight line nearest point.
RcVec3f diff = center.Subtract(closestPtPoly);
RcVec3f diff = RcVec3f.Subtract(center, closestPtPoly);
if (posOverPoly)
{
d = Math.Abs(diff.Y) - tile.data.header.walkableClimb;

View File

@ -679,7 +679,7 @@ namespace DotRecast.Detour
}
// Find tiles the query touches.
RcVec3f bmin = center.Subtract(halfExtents);
RcVec3f bmin = RcVec3f.Subtract(center, halfExtents);
RcVec3f bmax = center.Add(halfExtents);
foreach (var t in QueryTiles(center, halfExtents))
{
@ -699,7 +699,7 @@ namespace DotRecast.Detour
return RcImmutableArray<DtMeshTile>.Empty;
}
RcVec3f bmin = center.Subtract(halfExtents);
RcVec3f bmin = RcVec3f.Subtract(center, halfExtents);
RcVec3f bmax = center.Add(halfExtents);
m_nav.CalcTileLoc(bmin, out var minx, out var miny);
m_nav.CalcTileLoc(bmax, out var maxx, out var maxy);
@ -2179,7 +2179,7 @@ namespace DotRecast.Detour
RcVec3f lastPos = RcVec3f.Zero;
curPos = startPos;
var dir = endPos.Subtract(startPos);
var dir = RcVec3f.Subtract(endPos, startPos);
DtMeshTile prevTile, tile, nextTile;
DtPoly prevPoly, poly, nextPoly;
@ -2343,8 +2343,8 @@ namespace DotRecast.Detour
curPos = RcVec3f.Mad(startPos, dir, hit.t);
var e1 = verts[segMax];
var e2 = verts[(segMax + 1) % nv];
var eDir = e2.Subtract(e1);
var diff = curPos.Subtract(e1);
var eDir = RcVec3f.Subtract(e2, e1);
var diff = RcVec3f.Subtract(curPos, e1);
float s = RcMath.Sqr(eDir.X) > RcMath.Sqr(eDir.Z) ? diff.X / eDir.X : diff.Z / eDir.Z;
curPos.Y = e1.Y + eDir.Y * s;
@ -3301,7 +3301,7 @@ namespace DotRecast.Detour
// Calc hit normal.
if (hasBestV)
{
var tangent = bestvi.Subtract(bestvj);
var tangent = RcVec3f.Subtract(bestvi, bestvj);
hitNormal.X = tangent.Z;
hitNormal.Y = 0;
hitNormal.Z = -tangent.X;

View File

@ -215,9 +215,9 @@ namespace DotRecast.Detour
const float EPS = 1e-6f;
h = 0;
RcVec3f v0 = c.Subtract(a);
RcVec3f v1 = b.Subtract(a);
RcVec3f v2 = p.Subtract(a);
RcVec3f v0 = RcVec3f.Subtract(c, a);
RcVec3f v1 = RcVec3f.Subtract(b, a);
RcVec3f v2 = RcVec3f.Subtract(p, a);
// Compute scaled barycentric coordinates
float denom = v0.X * v1.Z - v0.Z * v1.X;
@ -353,15 +353,15 @@ namespace DotRecast.Detour
segMin = -1;
segMax = -1;
var dir = p1.Subtract(p0);
var dir = RcVec3f.Subtract(p1, p0);
var p0v = p0;
for (int i = 0, j = nverts - 1; i < nverts; j = i++)
{
RcVec3f vpj = verts[j];
RcVec3f vpi = verts[i];
var edge = vpi.Subtract(vpj);
var diff = p0v.Subtract(vpj);
var edge = RcVec3f.Subtract(vpi, vpj);
var diff = RcVec3f.Subtract(p0v, vpj);
float n = RcVec3f.Perp2D(edge, diff);
float d = RcVec3f.Perp2D(dir, edge);
if (Math.Abs(d) < EPS)
@ -422,9 +422,9 @@ namespace DotRecast.Detour
s = 0;
t = 0;
RcVec3f u = aq.Subtract(ap);
RcVec3f v = bq.Subtract(bp);
RcVec3f w = ap.Subtract(bp);
RcVec3f u = RcVec3f.Subtract(aq, ap);
RcVec3f v = RcVec3f.Subtract(bq, bp);
RcVec3f w = RcVec3f.Subtract(ap, bp);
float d = RcVec3f.PerpXZ(u, v);
if (Math.Abs(d) < 1e-6f)
{

View File

@ -507,7 +507,7 @@ public class TestNavmeshSampleTool : ISampleTool
continue;
}
RcVec3f delta = s3.Subtract(s.vmin);
RcVec3f delta = RcVec3f.Subtract(s3, s.vmin);
RcVec3f p0 = RcVec3f.Mad(s.vmin, delta, 0.5f);
RcVec3f norm = new RcVec3f(delta.Z, 0, -delta.X);
norm.Normalize();

View File

@ -294,7 +294,7 @@ namespace DotRecast.Recast.Toolset.Tools
private RcVec3f CalcVel(RcVec3f pos, RcVec3f tgt, float speed)
{
RcVec3f vel = tgt.Subtract(pos);
RcVec3f vel = RcVec3f.Subtract(tgt, pos);
vel.Y = 0.0f;
vel.Normalize();
return vel.Scale(speed);

View File

@ -73,7 +73,7 @@ namespace DotRecast.Recast.Toolset.Tools
: false;
// Find movement delta.
RcVec3f delta = steerPos.Subtract(iterPos);
RcVec3f delta = RcVec3f.Subtract(steerPos, iterPos);
float len = (float)Math.Sqrt(RcVec3f.Dot(delta, delta));
// If the steer target is end of path or off-mesh link, do not move past the location.
if ((endOfPath || offMeshConnection) && len < STEP_SIZE)

View File

@ -760,12 +760,12 @@ namespace DotRecast.Recast
RcVec3f vertC = new RcVec3f(verts.AsSpan(vertIndexC * 3));
// From A to B on the x/z plane
RcVec3f prevSegmentDir = vertB.Subtract(vertA);
RcVec3f prevSegmentDir = RcVec3f.Subtract(vertB, vertA);
prevSegmentDir.Y = 0; // Squash onto x/z plane
prevSegmentDir.SafeNormalize();
// From B to C on the x/z plane
RcVec3f currSegmentDir = vertC.Subtract(vertB);
RcVec3f currSegmentDir = RcVec3f.Subtract(vertC, vertB);
currSegmentDir.Y = 0; // Squash onto x/z plane
currSegmentDir.SafeNormalize();

View File

@ -153,7 +153,7 @@ public class AbstractCrowdTest
protected RcVec3f CalcVel(RcVec3f pos, RcVec3f tgt, float speed)
{
RcVec3f vel = tgt.Subtract(pos);
RcVec3f vel = RcVec3f.Subtract(tgt, pos);
vel.Y = 0.0f;
vel.Normalize();
vel = vel.Scale(speed);