forked from bit/DotRecastNetSim
refactor: RcVec3f.Mad, IsFinite, Lerp
This commit is contained in:
parent
18a195404f
commit
9a62fbf9f4
|
@ -263,62 +263,6 @@ namespace DotRecast.Core.Numerics
|
|||
(vector1.Z * vector2.Z);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static float PerpXZ(RcVec3f a, RcVec3f b)
|
||||
{
|
||||
return (a.X * b.Z) - (a.Z * b.X);
|
||||
}
|
||||
|
||||
/// Performs a scaled vector addition. (@p v1 + (@p v2 * @p s))
|
||||
/// @param[out] dest The result vector. [(x, y, z)]
|
||||
/// @param[in] v1 The base vector. [(x, y, z)]
|
||||
/// @param[in] v2 The vector to scale and add to @p v1. [(x, y, z)]
|
||||
/// @param[in] s The amount to scale @p v2 by before adding to @p v1.
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static RcVec3f Mad(RcVec3f v1, RcVec3f v2, float s)
|
||||
{
|
||||
return new RcVec3f()
|
||||
{
|
||||
X = v1.X + (v2.X * s),
|
||||
Y = v1.Y + (v2.Y * s),
|
||||
Z = v1.Z + (v2.Z * s),
|
||||
};
|
||||
}
|
||||
|
||||
/// Performs a linear interpolation between two vectors. (@p v1 toward @p
|
||||
/// v2)
|
||||
/// @param[out] dest The result vector. [(x, y, x)]
|
||||
/// @param[in] v1 The starting vector.
|
||||
/// @param[in] v2 The destination vector.
|
||||
/// @param[in] t The interpolation factor. [Limits: 0 <= value <= 1.0]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static RcVec3f Lerp(float[] verts, int v1, int v2, float t)
|
||||
{
|
||||
return new RcVec3f(
|
||||
verts[v1 + 0] + (verts[v2 + 0] - verts[v1 + 0]) * t,
|
||||
verts[v1 + 1] + (verts[v2 + 1] - verts[v1 + 1]) * t,
|
||||
verts[v1 + 2] + (verts[v2 + 2] - verts[v1 + 2]) * t
|
||||
);
|
||||
}
|
||||
|
||||
/// Checks that the specified vector's components are all finite.
|
||||
/// @param[in] v A point. [(x, y, z)]
|
||||
/// @return True if all of the point's components are finite, i.e. not NaN
|
||||
/// or any of the infinities.
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool IsFinite(RcVec3f v)
|
||||
{
|
||||
return float.IsFinite(v.X) && float.IsFinite(v.Y) && float.IsFinite(v.Z);
|
||||
}
|
||||
|
||||
/// Checks that the specified vector's 2D components are finite.
|
||||
/// @param[in] v A point. [(x, y, z)]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool IsFinite2D(RcVec3f v)
|
||||
{
|
||||
return float.IsFinite(v.X) && float.IsFinite(v.Z);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public readonly void CopyTo(float[] array)
|
||||
{
|
||||
|
|
|
@ -219,5 +219,61 @@ namespace DotRecast.Core.Numerics
|
|||
{
|
||||
return u.Z * v.X - u.X * v.Z;
|
||||
}
|
||||
|
||||
/// Checks that the specified vector's components are all finite.
|
||||
/// @param[in] v A point. [(x, y, z)]
|
||||
/// @return True if all of the point's components are finite, i.e. not NaN
|
||||
/// or any of the infinities.
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool IsFinite(RcVec3f v)
|
||||
{
|
||||
return float.IsFinite(v.X) && float.IsFinite(v.Y) && float.IsFinite(v.Z);
|
||||
}
|
||||
|
||||
/// Checks that the specified vector's 2D components are finite.
|
||||
/// @param[in] v A point. [(x, y, z)]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool IsFinite2D(RcVec3f v)
|
||||
{
|
||||
return float.IsFinite(v.X) && float.IsFinite(v.Z);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static float PerpXZ(RcVec3f a, RcVec3f b)
|
||||
{
|
||||
return (a.X * b.Z) - (a.Z * b.X);
|
||||
}
|
||||
|
||||
/// Performs a linear interpolation between two vectors. (@p v1 toward @p
|
||||
/// v2)
|
||||
/// @param[out] dest The result vector. [(x, y, x)]
|
||||
/// @param[in] v1 The starting vector.
|
||||
/// @param[in] v2 The destination vector.
|
||||
/// @param[in] t The interpolation factor. [Limits: 0 <= value <= 1.0]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static RcVec3f Lerp(float[] verts, int v1, int v2, float t)
|
||||
{
|
||||
return new RcVec3f(
|
||||
verts[v1 + 0] + (verts[v2 + 0] - verts[v1 + 0]) * t,
|
||||
verts[v1 + 1] + (verts[v2 + 1] - verts[v1 + 1]) * t,
|
||||
verts[v1 + 2] + (verts[v2 + 2] - verts[v1 + 2]) * t
|
||||
);
|
||||
}
|
||||
|
||||
/// Performs a scaled vector addition. (@p v1 + (@p v2 * @p s))
|
||||
/// @param[out] dest The result vector. [(x, y, z)]
|
||||
/// @param[in] v1 The base vector. [(x, y, z)]
|
||||
/// @param[in] v2 The vector to scale and add to @p v1. [(x, y, z)]
|
||||
/// @param[in] s The amount to scale @p v2 by before adding to @p v1.
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static RcVec3f Mad(RcVec3f v1, RcVec3f v2, float s)
|
||||
{
|
||||
return new RcVec3f()
|
||||
{
|
||||
X = v1.X + (v2.X * s),
|
||||
Y = v1.Y + (v2.Y * s),
|
||||
Z = v1.Z + (v2.Z * s),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1094,14 +1094,14 @@ namespace DotRecast.Detour.Crowd
|
|||
float dist = MathF.Sqrt(distSqr);
|
||||
float weight = separationWeight * (1.0f - RcMath.Sqr(dist * invSeparationDist));
|
||||
|
||||
disp = RcVec3f.Mad(disp, diff, weight / dist);
|
||||
disp = RcVecUtils.Mad(disp, diff, weight / dist);
|
||||
w += 1.0f;
|
||||
}
|
||||
|
||||
if (w > 0.0001f)
|
||||
{
|
||||
// Adjust desired velocity.
|
||||
dvel = RcVec3f.Mad(dvel, disp, 1.0f / w);
|
||||
dvel = RcVecUtils.Mad(dvel, disp, 1.0f / w);
|
||||
// Clamp desired velocity to desired speed.
|
||||
float speedSqr = dvel.LengthSquared();
|
||||
float desiredSqr = RcMath.Sqr(ag.desiredSpeed);
|
||||
|
@ -1254,7 +1254,7 @@ namespace DotRecast.Detour.Crowd
|
|||
pen = (1.0f / dist) * (pen * 0.5f) * _config.collisionResolveFactor;
|
||||
}
|
||||
|
||||
ag.disp = RcVec3f.Mad(ag.disp, diff, pen);
|
||||
ag.disp = RcVecUtils.Mad(ag.disp, diff, pen);
|
||||
|
||||
w += 1.0f;
|
||||
}
|
||||
|
|
|
@ -121,7 +121,7 @@ namespace DotRecast.Detour.Crowd
|
|||
|
||||
// Integrate
|
||||
if (vel.Length() > 0.0001f)
|
||||
npos = RcVec3f.Mad(npos, vel, dt);
|
||||
npos = RcVecUtils.Mad(npos, vel, dt);
|
||||
else
|
||||
vel = RcVec3f.Zero;
|
||||
}
|
||||
|
|
|
@ -193,7 +193,7 @@ namespace DotRecast.Detour.Crowd
|
|||
|
||||
// Adjust ray length.
|
||||
var delta = RcVec3f.Subtract(next, m_pos);
|
||||
RcVec3f goal = RcVec3f.Mad(m_pos, delta, pathOptimizationRange / dist);
|
||||
RcVec3f goal = RcVecUtils.Mad(m_pos, delta, pathOptimizationRange / dist);
|
||||
|
||||
var status = navquery.Raycast(m_path[0], m_pos, goal, filter, 0, 0, out var rayHit);
|
||||
if (status.Succeeded())
|
||||
|
|
|
@ -205,7 +205,7 @@ namespace DotRecast.Detour
|
|||
randomPt = centerPos;
|
||||
|
||||
// Validate input
|
||||
if (!m_nav.IsValidPolyRef(startRef) || !RcVec3f.IsFinite(centerPos) || maxRadius < 0
|
||||
if (!m_nav.IsValidPolyRef(startRef) || !RcVecUtils.IsFinite(centerPos) || maxRadius < 0
|
||||
|| !float.IsFinite(maxRadius) || null == filter || null == frand)
|
||||
{
|
||||
return DtStatus.DT_FAILURE | DtStatus.DT_INVALID_PARAM;
|
||||
|
@ -406,7 +406,7 @@ namespace DotRecast.Detour
|
|||
closest = pos;
|
||||
posOverPoly = false;
|
||||
|
||||
if (!m_nav.IsValidPolyRef(refs) || !RcVec3f.IsFinite(pos))
|
||||
if (!m_nav.IsValidPolyRef(refs) || !RcVecUtils.IsFinite(pos))
|
||||
{
|
||||
return DtStatus.DT_FAILURE | DtStatus.DT_INVALID_PARAM;
|
||||
}
|
||||
|
@ -441,7 +441,7 @@ namespace DotRecast.Detour
|
|||
return DtStatus.DT_FAILURE | DtStatus.DT_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (tile == null || !RcVec3f.IsFinite(pos))
|
||||
if (tile == null || !RcVecUtils.IsFinite(pos))
|
||||
{
|
||||
return DtStatus.DT_FAILURE | DtStatus.DT_INVALID_PARAM;
|
||||
}
|
||||
|
@ -476,7 +476,7 @@ namespace DotRecast.Detour
|
|||
|
||||
int va = imin * 3;
|
||||
int vb = ((imin + 1) % nv) * 3;
|
||||
closest = RcVec3f.Lerp(verts, va, vb, edget[imin]);
|
||||
closest = RcVecUtils.Lerp(verts, va, vb, edget[imin]);
|
||||
}
|
||||
|
||||
return DtStatus.DT_SUCCSESS;
|
||||
|
@ -502,7 +502,7 @@ namespace DotRecast.Detour
|
|||
return DtStatus.DT_FAILURE | DtStatus.DT_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (!RcVec3f.IsFinite2D(pos))
|
||||
if (!RcVecUtils.IsFinite2D(pos))
|
||||
{
|
||||
return DtStatus.DT_FAILURE | DtStatus.DT_INVALID_PARAM;
|
||||
}
|
||||
|
@ -673,7 +673,7 @@ namespace DotRecast.Detour
|
|||
*/
|
||||
public DtStatus QueryPolygons(RcVec3f center, RcVec3f halfExtents, IDtQueryFilter filter, IDtPolyQuery query)
|
||||
{
|
||||
if (!RcVec3f.IsFinite(center) || !RcVec3f.IsFinite(halfExtents) || null == filter)
|
||||
if (!RcVecUtils.IsFinite(center) || !RcVecUtils.IsFinite(halfExtents) || null == filter)
|
||||
{
|
||||
return DtStatus.DT_INVALID_PARAM;
|
||||
}
|
||||
|
@ -694,7 +694,7 @@ namespace DotRecast.Detour
|
|||
*/
|
||||
public IList<DtMeshTile> QueryTiles(RcVec3f center, RcVec3f halfExtents)
|
||||
{
|
||||
if (!RcVec3f.IsFinite(center) || !RcVec3f.IsFinite(halfExtents))
|
||||
if (!RcVecUtils.IsFinite(center) || !RcVecUtils.IsFinite(halfExtents))
|
||||
{
|
||||
return RcImmutableArray<DtMeshTile>.Empty;
|
||||
}
|
||||
|
@ -744,7 +744,7 @@ namespace DotRecast.Detour
|
|||
path.Clear();
|
||||
|
||||
// Validate input
|
||||
if (!m_nav.IsValidPolyRef(startRef) || !m_nav.IsValidPolyRef(endRef) || !RcVec3f.IsFinite(startPos) || !RcVec3f.IsFinite(endPos) || null == filter)
|
||||
if (!m_nav.IsValidPolyRef(startRef) || !m_nav.IsValidPolyRef(endRef) || !RcVecUtils.IsFinite(startPos) || !RcVecUtils.IsFinite(endPos) || null == filter)
|
||||
{
|
||||
return DtStatus.DT_FAILURE | DtStatus.DT_INVALID_PARAM;
|
||||
}
|
||||
|
@ -1020,7 +1020,7 @@ namespace DotRecast.Detour
|
|||
m_query.raycastLimitSqr = RcMath.Sqr(raycastLimit);
|
||||
|
||||
// Validate input
|
||||
if (!m_nav.IsValidPolyRef(startRef) || !m_nav.IsValidPolyRef(endRef) || !RcVec3f.IsFinite(startPos) || !RcVec3f.IsFinite(endPos) || null == filter)
|
||||
if (!m_nav.IsValidPolyRef(startRef) || !m_nav.IsValidPolyRef(endRef) || !RcVecUtils.IsFinite(startPos) || !RcVecUtils.IsFinite(endPos) || null == filter)
|
||||
{
|
||||
return DtStatus.DT_INVALID_PARAM;
|
||||
}
|
||||
|
@ -1514,7 +1514,7 @@ namespace DotRecast.Detour
|
|||
ref List<DtStraightPath> straightPath,
|
||||
int maxStraightPath, int options)
|
||||
{
|
||||
if (!RcVec3f.IsFinite(startPos) || !RcVec3f.IsFinite(endPos) || null == straightPath
|
||||
if (!RcVecUtils.IsFinite(startPos) || !RcVecUtils.IsFinite(endPos) || null == straightPath
|
||||
|| null == path || 0 == path.Count || path[0] == 0 || maxStraightPath <= 0)
|
||||
{
|
||||
return DtStatus.DT_FAILURE | DtStatus.DT_INVALID_PARAM;
|
||||
|
@ -1779,8 +1779,8 @@ namespace DotRecast.Detour
|
|||
visited.Clear();
|
||||
|
||||
// Validate input
|
||||
if (!m_nav.IsValidPolyRef(startRef) || !RcVec3f.IsFinite(startPos)
|
||||
|| !RcVec3f.IsFinite(endPos) || null == filter)
|
||||
if (!m_nav.IsValidPolyRef(startRef) || !RcVecUtils.IsFinite(startPos)
|
||||
|| !RcVecUtils.IsFinite(endPos) || null == filter)
|
||||
{
|
||||
return DtStatus.DT_FAILURE | DtStatus.DT_INVALID_PARAM;
|
||||
}
|
||||
|
@ -1883,7 +1883,7 @@ namespace DotRecast.Detour
|
|||
if (distSqr < bestDist)
|
||||
{
|
||||
// Update nearest distance.
|
||||
bestPos = RcVec3f.Lerp(verts, vj, vi, tseg);
|
||||
bestPos = RcVecUtils.Lerp(verts, vj, vi, tseg);
|
||||
bestDist = distSqr;
|
||||
bestNode = curNode;
|
||||
}
|
||||
|
@ -2062,8 +2062,8 @@ namespace DotRecast.Detour
|
|||
float s = 1.0f / 255.0f;
|
||||
float tmin = link.bmin * s;
|
||||
float tmax = link.bmax * s;
|
||||
left = RcVec3f.Lerp(fromTile.data.verts, v0 * 3, v1 * 3, tmin);
|
||||
right = RcVec3f.Lerp(fromTile.data.verts, v0 * 3, v1 * 3, tmax);
|
||||
left = RcVecUtils.Lerp(fromTile.data.verts, v0 * 3, v1 * 3, tmin);
|
||||
right = RcVecUtils.Lerp(fromTile.data.verts, v0 * 3, v1 * 3, tmax);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2165,7 +2165,7 @@ namespace DotRecast.Detour
|
|||
hit = null;
|
||||
|
||||
// Validate input
|
||||
if (!m_nav.IsValidPolyRef(startRef) || !RcVec3f.IsFinite(startPos) || !RcVec3f.IsFinite(endPos)
|
||||
if (!m_nav.IsValidPolyRef(startRef) || !RcVecUtils.IsFinite(startPos) || !RcVecUtils.IsFinite(endPos)
|
||||
|| null == filter || (prevRef != 0 && !m_nav.IsValidPolyRef(prevRef)))
|
||||
{
|
||||
return DtStatus.DT_FAILURE | DtStatus.DT_INVALID_PARAM;
|
||||
|
@ -2340,7 +2340,7 @@ namespace DotRecast.Detour
|
|||
// compute the intersection point at the furthest end of the polygon
|
||||
// and correct the height (since the raycast moves in 2d)
|
||||
lastPos = curPos;
|
||||
curPos = RcVec3f.Mad(startPos, dir, hit.t);
|
||||
curPos = RcVecUtils.Mad(startPos, dir, hit.t);
|
||||
var e1 = verts[segMax];
|
||||
var e2 = verts[(segMax + 1) % nv];
|
||||
var eDir = RcVec3f.Subtract(e2, e1);
|
||||
|
@ -2434,7 +2434,7 @@ namespace DotRecast.Detour
|
|||
}
|
||||
|
||||
// Validate input
|
||||
if (!m_nav.IsValidPolyRef(startRef) || !RcVec3f.IsFinite(centerPos) || radius < 0
|
||||
if (!m_nav.IsValidPolyRef(startRef) || !RcVecUtils.IsFinite(centerPos) || radius < 0
|
||||
|| !float.IsFinite(radius) || null == filter)
|
||||
{
|
||||
return DtStatus.DT_FAILURE | DtStatus.DT_INVALID_PARAM;
|
||||
|
@ -2777,7 +2777,7 @@ namespace DotRecast.Detour
|
|||
ref List<long> resultRef, ref List<long> resultParent)
|
||||
{
|
||||
// Validate input
|
||||
if (!m_nav.IsValidPolyRef(startRef) || !RcVec3f.IsFinite(centerPos) || radius < 0
|
||||
if (!m_nav.IsValidPolyRef(startRef) || !RcVecUtils.IsFinite(centerPos) || radius < 0
|
||||
|| !float.IsFinite(radius) || null == filter
|
||||
|| null == resultRef || null == resultParent)
|
||||
{
|
||||
|
@ -3055,8 +3055,8 @@ namespace DotRecast.Detour
|
|||
float tmin = ints[k].tmin / 255.0f;
|
||||
float tmax = ints[k].tmax / 255.0f;
|
||||
var seg = new RcSegmentVert();
|
||||
seg.vmin = RcVec3f.Lerp(tile.data.verts, vj, vi, tmin);
|
||||
seg.vmax = RcVec3f.Lerp(tile.data.verts, vj, vi, tmax);
|
||||
seg.vmin = RcVecUtils.Lerp(tile.data.verts, vj, vi, tmin);
|
||||
seg.vmax = RcVecUtils.Lerp(tile.data.verts, vj, vi, tmax);
|
||||
segmentVerts.Add(seg);
|
||||
segmentRefs.Add(ints[k].refs);
|
||||
}
|
||||
|
@ -3069,8 +3069,8 @@ namespace DotRecast.Detour
|
|||
float tmin = imin / 255.0f;
|
||||
float tmax = imax / 255.0f;
|
||||
var seg = new RcSegmentVert();
|
||||
seg.vmin = RcVec3f.Lerp(tile.data.verts, vj, vi, tmin);
|
||||
seg.vmax = RcVec3f.Lerp(tile.data.verts, vj, vi, tmax);
|
||||
seg.vmin = RcVecUtils.Lerp(tile.data.verts, vj, vi, tmin);
|
||||
seg.vmax = RcVecUtils.Lerp(tile.data.verts, vj, vi, tmax);
|
||||
segmentVerts.Add(seg);
|
||||
segmentRefs.Add(0L);
|
||||
}
|
||||
|
@ -3109,7 +3109,7 @@ namespace DotRecast.Detour
|
|||
hitNormal = RcVec3f.Zero;
|
||||
|
||||
// Validate input
|
||||
if (!m_nav.IsValidPolyRef(startRef) || !RcVec3f.IsFinite(centerPos) || maxRadius < 0
|
||||
if (!m_nav.IsValidPolyRef(startRef) || !RcVecUtils.IsFinite(centerPos) || maxRadius < 0
|
||||
|| !float.IsFinite(maxRadius) || null == filter)
|
||||
{
|
||||
return DtStatus.DT_FAILURE | DtStatus.DT_INVALID_PARAM;
|
||||
|
|
|
@ -425,14 +425,14 @@ namespace DotRecast.Detour
|
|||
RcVec3f u = RcVec3f.Subtract(aq, ap);
|
||||
RcVec3f v = RcVec3f.Subtract(bq, bp);
|
||||
RcVec3f w = RcVec3f.Subtract(ap, bp);
|
||||
float d = RcVec3f.PerpXZ(u, v);
|
||||
float d = RcVecUtils.PerpXZ(u, v);
|
||||
if (MathF.Abs(d) < 1e-6f)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
s = RcVec3f.PerpXZ(v, w) / d;
|
||||
t = RcVec3f.PerpXZ(u, w) / d;
|
||||
s = RcVecUtils.PerpXZ(v, w) / d;
|
||||
t = RcVecUtils.PerpXZ(u, w) / d;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -508,10 +508,10 @@ public class TestNavmeshSampleTool : ISampleTool
|
|||
}
|
||||
|
||||
RcVec3f delta = RcVec3f.Subtract(s3, s.vmin);
|
||||
RcVec3f p0 = RcVec3f.Mad(s.vmin, delta, 0.5f);
|
||||
RcVec3f p0 = RcVecUtils.Mad(s.vmin, delta, 0.5f);
|
||||
RcVec3f norm = new RcVec3f(delta.Z, 0, -delta.X);
|
||||
norm = RcVec3f.Normalize(norm);
|
||||
RcVec3f p1 = RcVec3f.Mad(p0, norm, agentRadius * 0.5f);
|
||||
RcVec3f p1 = RcVecUtils.Mad(p0, norm, agentRadius * 0.5f);
|
||||
// Skip backfacing segments.
|
||||
if (segmentRefs[j] != 0)
|
||||
{
|
||||
|
|
|
@ -85,7 +85,7 @@ namespace DotRecast.Recast.Toolset.Tools
|
|||
len = STEP_SIZE / len;
|
||||
}
|
||||
|
||||
RcVec3f moveTgt = RcVec3f.Mad(iterPos, delta, len);
|
||||
RcVec3f moveTgt = RcVecUtils.Mad(iterPos, delta, len);
|
||||
|
||||
// Move
|
||||
navQuery.MoveAlongSurface(polys[0], iterPos, moveTgt, filter, out var result, ref visited);
|
||||
|
|
|
@ -172,13 +172,6 @@ public class Vector3Tests
|
|||
// IsFinite
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Repeat(100000)]
|
||||
public void TestVectorPerp2D()
|
||||
{
|
||||
// Perp2D
|
||||
}
|
||||
|
||||
// [Test]
|
||||
// [Repeat(100000)]
|
||||
// public void TestVectorLerp()
|
||||
|
|
Loading…
Reference in New Issue