refactor: math

This commit is contained in:
ikpil 2023-09-23 07:30:47 +09:00
parent 07074105a4
commit a46aa0eaee
25 changed files with 168 additions and 166 deletions

View File

@ -21,7 +21,6 @@ freely, subject to the following restrictions:
using System; using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using DotRecast.Core; using DotRecast.Core;
using DotRecast.Detour.Crowd.Tracking; using DotRecast.Detour.Crowd.Tracking;
@ -29,7 +28,7 @@ using DotRecast.Detour.Crowd.Tracking;
namespace DotRecast.Detour.Crowd namespace DotRecast.Detour.Crowd
{ {
using static DotRecast.Core.RcMath;
/** /**
* Members in this module implement local steering and dynamic avoidance features. * Members in this module implement local steering and dynamic avoidance features.
@ -881,7 +880,7 @@ namespace DotRecast.Detour.Crowd
// Update the collision boundary after certain distance has been passed or // Update the collision boundary after certain distance has been passed or
// if it has become invalid. // if it has become invalid.
float updateThr = ag.option.collisionQueryRange * 0.25f; float updateThr = ag.option.collisionQueryRange * 0.25f;
if (RcVec3f.Dist2DSqr(ag.npos, ag.boundary.GetCenter()) > Sqr(updateThr) if (RcVec3f.Dist2DSqr(ag.npos, ag.boundary.GetCenter()) > RcMath.Sqr(updateThr)
|| !ag.boundary.IsValid(_navQuery, _filters[ag.option.queryFilterType])) || !ag.boundary.IsValid(_navQuery, _filters[ag.option.queryFilterType]))
{ {
ag.boundary.Update(ag.corridor.GetFirstPoly(), ag.npos, ag.option.collisionQueryRange, _navQuery, ag.boundary.Update(ag.corridor.GetFirstPoly(), ag.npos, ag.option.collisionQueryRange, _navQuery,
@ -916,7 +915,7 @@ namespace DotRecast.Detour.Crowd
diff.y = 0; diff.y = 0;
float distSqr = RcVec3f.LenSqr(diff); float distSqr = RcVec3f.LenSqr(diff);
if (distSqr > Sqr(range)) if (distSqr > RcMath.Sqr(range))
{ {
continue; continue;
} }
@ -1090,13 +1089,13 @@ namespace DotRecast.Detour.Crowd
continue; continue;
} }
if (distSqr > Sqr(separationDist)) if (distSqr > RcMath.Sqr(separationDist))
{ {
continue; continue;
} }
float dist = (float)Math.Sqrt(distSqr); float dist = (float)Math.Sqrt(distSqr);
float weight = separationWeight * (1.0f - Sqr(dist * invSeparationDist)); float weight = separationWeight * (1.0f - RcMath.Sqr(dist * invSeparationDist));
disp = RcVec3f.Mad(disp, diff, weight / dist); disp = RcVec3f.Mad(disp, diff, weight / dist);
w += 1.0f; w += 1.0f;
@ -1108,7 +1107,7 @@ namespace DotRecast.Detour.Crowd
dvel = RcVec3f.Mad(dvel, disp, 1.0f / w); dvel = RcVec3f.Mad(dvel, disp, 1.0f / w);
// Clamp desired velocity to desired speed. // Clamp desired velocity to desired speed.
float speedSqr = RcVec3f.LenSqr(dvel); float speedSqr = RcVec3f.LenSqr(dvel);
float desiredSqr = Sqr(ag.desiredSpeed); float desiredSqr = RcMath.Sqr(ag.desiredSpeed);
if (speedSqr > desiredSqr) if (speedSqr > desiredSqr)
{ {
dvel = dvel.Scale(desiredSqr / speedSqr); dvel = dvel.Scale(desiredSqr / speedSqr);
@ -1232,7 +1231,7 @@ namespace DotRecast.Detour.Crowd
diff.y = 0; diff.y = 0;
float dist = RcVec3f.LenSqr(diff); float dist = RcVec3f.LenSqr(diff);
if (dist > Sqr(ag.option.radius + nei.option.radius)) if (dist > RcMath.Sqr(ag.option.radius + nei.option.radius))
{ {
continue; continue;
} }
@ -1352,7 +1351,7 @@ namespace DotRecast.Detour.Crowd
private float Tween(float t, float t0, float t1) private float Tween(float t, float t0, float t1)
{ {
return Clamp((t - t0) / (t1 - t0), 0.0f, 1.0f); return RcMath.Clamp((t - t0) / (t1 - t0), 0.0f, 1.0f);
} }
} }
} }

View File

@ -25,7 +25,7 @@ using DotRecast.Core;
namespace DotRecast.Detour.Crowd namespace DotRecast.Detour.Crowd
{ {
using static RcMath;
public class DtLocalBoundary public class DtLocalBoundary
{ {
@ -123,7 +123,7 @@ namespace DotRecast.Detour.Crowd
// Skip too distant segments. // Skip too distant segments.
var distSqr = DtUtils.DistancePtSegSqr2D(pos, s0, s3, out var tseg); var distSqr = DtUtils.DistancePtSegSqr2D(pos, s0, s3, out var tseg);
if (distSqr > Sqr(collisionQueryRange)) if (distSqr > RcMath.Sqr(collisionQueryRange))
{ {
continue; continue;
} }

View File

@ -24,7 +24,7 @@ using DotRecast.Detour.Crowd.Tracking;
namespace DotRecast.Detour.Crowd namespace DotRecast.Detour.Crowd
{ {
using static RcMath;
public class DtObstacleAvoidanceQuery public class DtObstacleAvoidanceQuery
{ {
@ -151,7 +151,7 @@ namespace DotRecast.Detour.Crowd
// Precalc if the agent is really close to the segment. // Precalc if the agent is really close to the segment.
float r = 0.01f; float r = 0.01f;
var distSqr = DtUtils.DistancePtSegSqr2D(pos, seg.p, seg.q, out var t); var distSqr = DtUtils.DistancePtSegSqr2D(pos, seg.p, seg.q, out var t);
seg.touch = distSqr < Sqr(r); seg.touch = distSqr < RcMath.Sqr(r);
} }
} }
@ -243,7 +243,7 @@ namespace DotRecast.Detour.Crowd
vab = vab.Subtract(cir.vel); vab = vab.Subtract(cir.vel);
// Side // Side
side += Clamp(Math.Min(cir.dp.Dot2D(vab) * 0.5f + 0.5f, cir.np.Dot2D(vab) * 2), 0.0f, 1.0f); side += RcMath.Clamp(Math.Min(cir.dp.Dot2D(vab) * 0.5f + 0.5f, cir.np.Dot2D(vab) * 2), 0.0f, 1.0f);
nside++; nside++;
if (!SweepCircleCircle(pos, rad, vab, cir.p, cir.rad, out var htmin, out var htmax)) if (!SweepCircleCircle(pos, rad, vab, cir.p, cir.rad, out var htmin, out var htmax))
@ -346,7 +346,7 @@ namespace DotRecast.Detour.Crowd
for (int x = 0; x < m_params.gridSize; ++x) for (int x = 0; x < m_params.gridSize; ++x)
{ {
RcVec3f vcand = RcVec3f.Of(cvx + x * cs - half, 0f, cvz + y * cs - half); RcVec3f vcand = RcVec3f.Of(cvx + x * cs - half, 0f, cvz + y * cs - half);
if (Sqr(vcand.x) + Sqr(vcand.z) > Sqr(vmax + cs / 2)) if (RcMath.Sqr(vcand.x) + RcMath.Sqr(vcand.z) > RcMath.Sqr(vmax + cs / 2))
continue; continue;
float penalty = ProcessSample(vcand, cs, pos, rad, vel, dvel, minPenalty, debug); float penalty = ProcessSample(vcand, cs, pos, rad, vel, dvel, minPenalty, debug);
@ -410,8 +410,8 @@ namespace DotRecast.Detour.Crowd
int nrings = m_params.adaptiveRings; int nrings = m_params.adaptiveRings;
int depth = m_params.adaptiveDepth; int depth = m_params.adaptiveDepth;
int nd = Clamp(ndivs, 1, DT_MAX_PATTERN_DIVS); int nd = RcMath.Clamp(ndivs, 1, DT_MAX_PATTERN_DIVS);
int nr = Clamp(nrings, 1, DT_MAX_PATTERN_RINGS); int nr = RcMath.Clamp(nrings, 1, DT_MAX_PATTERN_RINGS);
float da = (1.0f / nd) * DT_PI * 2; float da = (1.0f / nd) * DT_PI * 2;
float ca = (float)Math.Cos(da); float ca = (float)Math.Cos(da);
float sa = (float)Math.Sin(da); float sa = (float)Math.Sin(da);
@ -476,7 +476,7 @@ namespace DotRecast.Detour.Crowd
for (int i = 0; i < npat; ++i) for (int i = 0; i < npat; ++i)
{ {
RcVec3f vcand = RcVec3f.Of(res.x + pat[i * 2 + 0] * cr, 0f, res.z + pat[i * 2 + 1] * cr); RcVec3f vcand = RcVec3f.Of(res.x + pat[i * 2 + 0] * cr, 0f, res.z + pat[i * 2 + 1] * cr);
if (Sqr(vcand.x) + Sqr(vcand.z) > Sqr(vmax + 0.001f)) if (RcMath.Sqr(vcand.x) + RcMath.Sqr(vcand.z) > RcMath.Sqr(vmax + 0.001f))
continue; continue;
float penalty = ProcessSample(vcand, cr / 10, pos, rad, vel, dvel, minPenalty, debug); float penalty = ProcessSample(vcand, cr / 10, pos, rad, vel, dvel, minPenalty, debug);

View File

@ -25,45 +25,45 @@ using DotRecast.Core;
namespace DotRecast.Detour.Crowd namespace DotRecast.Detour.Crowd
{ {
using static DotRecast.Core.RcMath;
/** /**
* Represents a dynamic polygon corridor used to plan agent movement. * Represents a dynamic polygon corridor used to plan agent movement.
* *
* The corridor is loaded with a path, usually obtained from a #NavMeshQuery::FindPath() query. The corridor is then * The corridor is loaded with a path, usually obtained from a #NavMeshQuery::FindPath() query. The corridor is then
* used to plan local movement, with the corridor automatically updating as needed to deal with inaccurate agent * used to plan local movement, with the corridor automatically updating as needed to deal with inaccurate agent
* locomotion. * locomotion.
* *
* Example of a common use case: * Example of a common use case:
* *
* -# Construct the corridor object and call -# Obtain a path from a #dtNavMeshQuery object. -# Use #Reset() to set the * -# Construct the corridor object and call -# Obtain a path from a #dtNavMeshQuery object. -# Use #Reset() to set the
* agent's current position. (At the beginning of the path.) -# Use #SetCorridor() to load the path and target. -# Use * agent's current position. (At the beginning of the path.) -# Use #SetCorridor() to load the path and target. -# Use
* #FindCorners() to plan movement. (This handles dynamic path straightening.) -# Use #MovePosition() to feed agent * #FindCorners() to plan movement. (This handles dynamic path straightening.) -# Use #MovePosition() to feed agent
* movement back into the corridor. (The corridor will automatically adjust as needed.) -# If the target is moving, use * movement back into the corridor. (The corridor will automatically adjust as needed.) -# If the target is moving, use
* #MoveTargetPosition() to update the end of the corridor. (The corridor will automatically adjust as needed.) -# * #MoveTargetPosition() to update the end of the corridor. (The corridor will automatically adjust as needed.) -#
* Repeat the previous 3 steps to continue to move the agent. * Repeat the previous 3 steps to continue to move the agent.
* *
* The corridor position and target are always constrained to the navigation mesh. * The corridor position and target are always constrained to the navigation mesh.
* *
* One of the difficulties in maintaining a path is that floating point errors, locomotion inaccuracies, and/or local * One of the difficulties in maintaining a path is that floating point errors, locomotion inaccuracies, and/or local
* steering can result in the agent crossing the boundary of the path corridor, temporarily invalidating the path. This * steering can result in the agent crossing the boundary of the path corridor, temporarily invalidating the path. This
* class uses local mesh queries to detect and update the corridor as needed to handle these types of issues. * class uses local mesh queries to detect and update the corridor as needed to handle these types of issues.
* *
* The fact that local mesh queries are used to move the position and target locations results in two beahviors that * The fact that local mesh queries are used to move the position and target locations results in two beahviors that
* need to be considered: * need to be considered:
* *
* Every time a move function is used there is a chance that the path will become non-optimial. Basically, the further * Every time a move function is used there is a chance that the path will become non-optimial. Basically, the further
* the target is moved from its original location, and the further the position is moved outside the original corridor, * the target is moved from its original location, and the further the position is moved outside the original corridor,
* the more likely the path will become non-optimal. This issue can be addressed by periodically running the * the more likely the path will become non-optimal. This issue can be addressed by periodically running the
* #OptimizePathTopology() and #OptimizePathVisibility() methods. * #OptimizePathTopology() and #OptimizePathVisibility() methods.
* *
* All local mesh queries have distance limitations. (Review the #dtNavMeshQuery methods for details.) So the most * All local mesh queries have distance limitations. (Review the #dtNavMeshQuery methods for details.) So the most
* accurate use case is to move the position and target in small increments. If a large increment is used, then the * accurate use case is to move the position and target in small increments. If a large increment is used, then the
* corridor may not be able to accurately find the new location. Because of this limiation, if a position is moved in a * corridor may not be able to accurately find the new location. Because of this limiation, if a position is moved in a
* large increment, then compare the desired and resulting polygon references. If the two do not match, then path * large increment, then compare the desired and resulting polygon references. If the two do not match, then path
* replanning may be needed. E.g. If you move the target, check #GetLastPoly() to see if it is the expected polygon. * replanning may be needed. E.g. If you move the target, check #GetLastPoly() to see if it is the expected polygon.
* *
*/ */
public class DtPathCorridor public class DtPathCorridor
{ {
private RcVec3f m_pos = new RcVec3f(); private RcVec3f m_pos = new RcVec3f();
@ -95,7 +95,7 @@ namespace DotRecast.Detour.Crowd
m_target = pos; m_target = pos;
} }
private static readonly float MIN_TARGET_DIST = Sqr(0.01f); private static readonly float MIN_TARGET_DIST = RcMath.Sqr(0.01f);
/** /**
* Finds the corners in the corridor from the position toward the target. (The straightened path.) * Finds the corners in the corridor from the position toward the target. (The straightened path.)

View File

@ -23,7 +23,7 @@ using DotRecast.Core;
namespace DotRecast.Detour.Crowd.Tracking namespace DotRecast.Detour.Crowd.Tracking
{ {
using static RcMath;
public class DtObstacleAvoidanceDebugData public class DtObstacleAvoidanceDebugData
{ {
@ -68,7 +68,7 @@ namespace DotRecast.Detour.Crowd.Tracking
float penRange = maxPen - minPen; float penRange = maxPen - minPen;
float s = penRange > 0.001f ? (1.0f / penRange) : 1; float s = penRange > 0.001f ? (1.0f / penRange) : 1;
for (int i = 0; i < n; ++i) for (int i = 0; i < n; ++i)
arr[i] = Clamp((arr[i] - minPen) * s, 0.0f, 1.0f); arr[i] = RcMath.Clamp((arr[i] - minPen) * s, 0.0f, 1.0f);
} }
public void NormalizeSamples() public void NormalizeSamples()

View File

@ -18,7 +18,7 @@ freely, subject to the following restrictions:
*/ */
using DotRecast.Core; using DotRecast.Core;
using static DotRecast.Core.RcMath;
namespace DotRecast.Detour.Extras namespace DotRecast.Detour.Extras
{ {
@ -50,12 +50,12 @@ namespace DotRecast.Detour.Extras
bmax.Max(data.verts, data.polys[i].verts[j] * 3); bmax.Max(data.verts, data.polys[i].verts[j] * 3);
} }
it.bmin[0] = Clamp((int)((bmin.x - data.header.bmin.x) * quantFactor), 0, 0x7fffffff); it.bmin[0] = RcMath.Clamp((int)((bmin.x - data.header.bmin.x) * quantFactor), 0, 0x7fffffff);
it.bmin[1] = Clamp((int)((bmin.y - data.header.bmin.y) * quantFactor), 0, 0x7fffffff); it.bmin[1] = RcMath.Clamp((int)((bmin.y - data.header.bmin.y) * quantFactor), 0, 0x7fffffff);
it.bmin[2] = Clamp((int)((bmin.z - data.header.bmin.z) * quantFactor), 0, 0x7fffffff); it.bmin[2] = RcMath.Clamp((int)((bmin.z - data.header.bmin.z) * quantFactor), 0, 0x7fffffff);
it.bmax[0] = Clamp((int)((bmax.x - data.header.bmin.x) * quantFactor), 0, 0x7fffffff); it.bmax[0] = RcMath.Clamp((int)((bmax.x - data.header.bmin.x) * quantFactor), 0, 0x7fffffff);
it.bmax[1] = Clamp((int)((bmax.y - data.header.bmin.y) * quantFactor), 0, 0x7fffffff); it.bmax[1] = RcMath.Clamp((int)((bmax.y - data.header.bmin.y) * quantFactor), 0, 0x7fffffff);
it.bmax[2] = Clamp((int)((bmax.z - data.header.bmin.z) * quantFactor), 0, 0x7fffffff); it.bmax[2] = RcMath.Clamp((int)((bmax.z - data.header.bmin.z) * quantFactor), 0, 0x7fffffff);
} }
return DtNavMeshBuilder.Subdivide(items, data.header.polyCount, 0, data.header.polyCount, 0, nodes); return DtNavMeshBuilder.Subdivide(items, data.header.polyCount, 0, data.header.polyCount, 0, nodes);

View File

@ -1,6 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using DotRecast.Core; using DotRecast.Core;
using static DotRecast.Core.RcMath;
namespace DotRecast.Detour.Extras.Jumplink namespace DotRecast.Detour.Extras.Jumplink
{ {

View File

@ -1,7 +1,7 @@
using System; using System;
using DotRecast.Core; using DotRecast.Core;
using DotRecast.Recast; using DotRecast.Recast;
using static DotRecast.Core.RcMath;
namespace DotRecast.Detour.Extras.Jumplink namespace DotRecast.Detour.Extras.Jumplink
{ {

View File

@ -24,7 +24,7 @@ using System.IO;
using DotRecast.Core; using DotRecast.Core;
using DotRecast.Detour.TileCache.Io; using DotRecast.Detour.TileCache.Io;
using DotRecast.Detour.TileCache.Io.Compress; using DotRecast.Detour.TileCache.Io.Compress;
using static DotRecast.Core.RcMath;
namespace DotRecast.Detour.TileCache namespace DotRecast.Detour.TileCache
{ {
@ -1810,7 +1810,7 @@ namespace DotRecast.Detour.TileCache
bmax.x = pos.x + radius; bmax.x = pos.x + radius;
bmax.y = pos.y + height; bmax.y = pos.y + height;
bmax.z = pos.z + radius; bmax.z = pos.z + radius;
float r2 = Sqr(radius / cs + 0.5f); float r2 = RcMath.Sqr(radius / cs + 0.5f);
int w = layer.header.width; int w = layer.header.width;
int h = layer.header.height; int h = layer.header.height;

View File

@ -18,7 +18,7 @@ freely, subject to the following restrictions:
*/ */
using DotRecast.Core; using DotRecast.Core;
using static DotRecast.Core.RcMath;
namespace DotRecast.Detour namespace DotRecast.Detour
{ {

View File

@ -24,7 +24,7 @@ using DotRecast.Core;
namespace DotRecast.Detour namespace DotRecast.Detour
{ {
using static RcMath;
public class DtNavMesh public class DtNavMesh
{ {
@ -346,12 +346,12 @@ namespace DotRecast.Detour
int[] bmin = new int[3]; int[] bmin = new int[3];
int[] bmax = new int[3]; int[] bmax = new int[3];
// dtClamp query box to world box. // dtClamp query box to world box.
float minx = Clamp(qmin.x, tbmin.x, tbmax.x) - tbmin.x; float minx = RcMath.Clamp(qmin.x, tbmin.x, tbmax.x) - tbmin.x;
float miny = Clamp(qmin.y, tbmin.y, tbmax.y) - tbmin.y; float miny = RcMath.Clamp(qmin.y, tbmin.y, tbmax.y) - tbmin.y;
float minz = Clamp(qmin.z, tbmin.z, tbmax.z) - tbmin.z; float minz = RcMath.Clamp(qmin.z, tbmin.z, tbmax.z) - tbmin.z;
float maxx = Clamp(qmax.x, tbmin.x, tbmax.x) - tbmin.x; float maxx = RcMath.Clamp(qmax.x, tbmin.x, tbmax.x) - tbmin.x;
float maxy = Clamp(qmax.y, tbmin.y, tbmax.y) - tbmin.y; float maxy = RcMath.Clamp(qmax.y, tbmin.y, tbmax.y) - tbmin.y;
float maxz = Clamp(qmax.z, tbmin.z, tbmax.z) - tbmin.z; float maxz = RcMath.Clamp(qmax.z, tbmin.z, tbmax.z) - tbmin.z;
// Quantize // Quantize
bmin[0] = (int)(qfac * minx) & 0x7ffffffe; bmin[0] = (int)(qfac * minx) & 0x7ffffffe;
bmin[1] = (int)(qfac * miny) & 0x7ffffffe; bmin[1] = (int)(qfac * miny) & 0x7ffffffe;
@ -781,8 +781,8 @@ namespace DotRecast.Detour
tmax = temp; tmax = temp;
} }
link.bmin = (int)Math.Round(Clamp(tmin, 0.0f, 1.0f) * 255.0f); link.bmin = (int)Math.Round(RcMath.Clamp(tmin, 0.0f, 1.0f) * 255.0f);
link.bmax = (int)Math.Round(Clamp(tmax, 0.0f, 1.0f) * 255.0f); link.bmax = (int)Math.Round(RcMath.Clamp(tmax, 0.0f, 1.0f) * 255.0f);
} }
else if (dir == 2 || dir == 6) else if (dir == 2 || dir == 6)
{ {
@ -797,8 +797,8 @@ namespace DotRecast.Detour
tmax = temp; tmax = temp;
} }
link.bmin = (int)Math.Round(Clamp(tmin, 0.0f, 1.0f) * 255.0f); link.bmin = (int)Math.Round(RcMath.Clamp(tmin, 0.0f, 1.0f) * 255.0f);
link.bmax = (int)Math.Round(Clamp(tmax, 0.0f, 1.0f) * 255.0f); link.bmax = (int)Math.Round(RcMath.Clamp(tmax, 0.0f, 1.0f) * 255.0f);
} }
} }
} }
@ -853,7 +853,7 @@ namespace DotRecast.Detour
// findNearestPoly may return too optimistic results, further check // findNearestPoly may return too optimistic results, further check
// to make sure. // to make sure.
if (Sqr(nearestPt.x - p.x) + Sqr(nearestPt.z - p.z) > Sqr(targetCon.rad)) if (RcMath.Sqr(nearestPt.x - p.x) + RcMath.Sqr(nearestPt.z - p.z) > RcMath.Sqr(targetCon.rad))
{ {
continue; continue;
} }
@ -1083,7 +1083,7 @@ namespace DotRecast.Detour
float[] p = con.pos; // First vertex float[] p = con.pos; // First vertex
// findNearestPoly may return too optimistic results, further check // findNearestPoly may return too optimistic results, further check
// to make sure. // to make sure.
if (Sqr(nearestPt.x - p[0]) + Sqr(nearestPt.z - p[2]) > Sqr(con.rad)) if (RcMath.Sqr(nearestPt.x - p[0]) + RcMath.Sqr(nearestPt.z - p[2]) > RcMath.Sqr(con.rad))
{ {
continue; continue;
} }

View File

@ -23,7 +23,7 @@ using DotRecast.Core;
namespace DotRecast.Detour namespace DotRecast.Detour
{ {
using static DotRecast.Core.RcMath;
public static class DtNavMeshBuilder public static class DtNavMeshBuilder
{ {
@ -171,13 +171,13 @@ namespace DotRecast.Detour
} }
// BV-tree uses cs for all dimensions // BV-tree uses cs for all dimensions
it.bmin[0] = Clamp((int)((bmin.x - option.bmin.x) * quantFactor), 0, int.MaxValue); it.bmin[0] = RcMath.Clamp((int)((bmin.x - option.bmin.x) * quantFactor), 0, int.MaxValue);
it.bmin[1] = Clamp((int)((bmin.y - option.bmin.y) * quantFactor), 0, int.MaxValue); it.bmin[1] = RcMath.Clamp((int)((bmin.y - option.bmin.y) * quantFactor), 0, int.MaxValue);
it.bmin[2] = Clamp((int)((bmin.z - option.bmin.z) * quantFactor), 0, int.MaxValue); it.bmin[2] = RcMath.Clamp((int)((bmin.z - option.bmin.z) * quantFactor), 0, int.MaxValue);
it.bmax[0] = Clamp((int)((bmax.x - option.bmin.x) * quantFactor), 0, int.MaxValue); it.bmax[0] = RcMath.Clamp((int)((bmax.x - option.bmin.x) * quantFactor), 0, int.MaxValue);
it.bmax[1] = Clamp((int)((bmax.y - option.bmin.y) * quantFactor), 0, int.MaxValue); it.bmax[1] = RcMath.Clamp((int)((bmax.y - option.bmin.y) * quantFactor), 0, int.MaxValue);
it.bmax[2] = Clamp((int)((bmax.z - option.bmin.z) * quantFactor), 0, int.MaxValue); it.bmax[2] = RcMath.Clamp((int)((bmax.z - option.bmin.z) * quantFactor), 0, int.MaxValue);
} }
else else
{ {

View File

@ -24,7 +24,7 @@ using DotRecast.Core;
namespace DotRecast.Detour namespace DotRecast.Detour
{ {
using static RcMath;
using static DtNode; using static DtNode;
public class DtNavMeshQuery public class DtNavMeshQuery
@ -603,12 +603,12 @@ namespace DotRecast.Detour
int[] bmin = new int[3]; int[] bmin = new int[3];
int[] bmax = new int[3]; int[] bmax = new int[3];
// dtClamp query box to world box. // dtClamp query box to world box.
float minx = Clamp(qmin.x, tbmin.x, tbmax.x) - tbmin.x; float minx = RcMath.Clamp(qmin.x, tbmin.x, tbmax.x) - tbmin.x;
float miny = Clamp(qmin.y, tbmin.y, tbmax.y) - tbmin.y; float miny = RcMath.Clamp(qmin.y, tbmin.y, tbmax.y) - tbmin.y;
float minz = Clamp(qmin.z, tbmin.z, tbmax.z) - tbmin.z; float minz = RcMath.Clamp(qmin.z, tbmin.z, tbmax.z) - tbmin.z;
float maxx = Clamp(qmax.x, tbmin.x, tbmax.x) - tbmin.x; float maxx = RcMath.Clamp(qmax.x, tbmin.x, tbmax.x) - tbmin.x;
float maxy = Clamp(qmax.y, tbmin.y, tbmax.y) - tbmin.y; float maxy = RcMath.Clamp(qmax.y, tbmin.y, tbmax.y) - tbmin.y;
float maxz = Clamp(qmax.z, tbmin.z, tbmax.z) - tbmin.z; float maxz = RcMath.Clamp(qmax.z, tbmin.z, tbmax.z) - tbmin.z;
// Quantize // Quantize
bmin[0] = (int)(qfac * minx) & 0x7ffffffe; bmin[0] = (int)(qfac * minx) & 0x7ffffffe;
bmin[1] = (int)(qfac * miny) & 0x7ffffffe; bmin[1] = (int)(qfac * miny) & 0x7ffffffe;
@ -780,7 +780,7 @@ namespace DotRecast.Detour
var raycastLimit = fpo.raycastLimit; var raycastLimit = fpo.raycastLimit;
var options = fpo.options; var options = fpo.options;
float raycastLimitSqr = Sqr(raycastLimit); float raycastLimitSqr = RcMath.Sqr(raycastLimit);
// trade quality with performance? // trade quality with performance?
if ((options & DT_FINDPATH_ANY_ANGLE) != 0 && raycastLimit < 0f) if ((options & DT_FINDPATH_ANY_ANGLE) != 0 && raycastLimit < 0f)
@ -789,7 +789,7 @@ namespace DotRecast.Detour
// so it is enough to compute it from the first tile. // so it is enough to compute it from the first tile.
DtMeshTile tile = m_nav.GetTileByRef(startRef); DtMeshTile tile = m_nav.GetTileByRef(startRef);
float agentRadius = tile.data.header.walkableRadius; float agentRadius = tile.data.header.walkableRadius;
raycastLimitSqr = Sqr(agentRadius * DtNavMesh.DT_RAY_CAST_LIMIT_PROPORTIONS); raycastLimitSqr = RcMath.Sqr(agentRadius * DtNavMesh.DT_RAY_CAST_LIMIT_PROPORTIONS);
} }
if (startRef == endRef) if (startRef == endRef)
@ -1044,7 +1044,7 @@ namespace DotRecast.Detour
m_query.filter = filter; m_query.filter = filter;
m_query.options = options; m_query.options = options;
m_query.heuristic = heuristic; m_query.heuristic = heuristic;
m_query.raycastLimitSqr = Sqr(raycastLimit); m_query.raycastLimitSqr = RcMath.Sqr(raycastLimit);
// Validate input // 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) || !RcVec3f.IsFinite(startPos) || !RcVec3f.IsFinite(endPos) || null == filter)
@ -1059,7 +1059,7 @@ namespace DotRecast.Detour
// so it is enough to compute it from the first tile. // so it is enough to compute it from the first tile.
DtMeshTile tile = m_nav.GetTileByRef(startRef); DtMeshTile tile = m_nav.GetTileByRef(startRef);
float agentRadius = tile.data.header.walkableRadius; float agentRadius = tile.data.header.walkableRadius;
m_query.raycastLimitSqr = Sqr(agentRadius * DtNavMesh.DT_RAY_CAST_LIMIT_PROPORTIONS); m_query.raycastLimitSqr = RcMath.Sqr(agentRadius * DtNavMesh.DT_RAY_CAST_LIMIT_PROPORTIONS);
} }
if (startRef == endRef) if (startRef == endRef)
@ -1622,7 +1622,7 @@ namespace DotRecast.Detour
if (i == 0) if (i == 0)
{ {
var distSqr = DtUtils.DistancePtSegSqr2D(portalApex, left, right, out var t); var distSqr = DtUtils.DistancePtSegSqr2D(portalApex, left, right, out var t);
if (distSqr < Sqr(0.001f)) if (distSqr < RcMath.Sqr(0.001f))
{ {
continue; continue;
} }
@ -1829,7 +1829,7 @@ namespace DotRecast.Detour
// Search constraints // Search constraints
var searchPos = RcVec3f.Lerp(startPos, endPos, 0.5f); var searchPos = RcVec3f.Lerp(startPos, endPos, 0.5f);
float searchRadSqr = Sqr(RcVec3f.Distance(startPos, endPos) / 2.0f + 0.001f); float searchRadSqr = RcMath.Sqr(RcVec3f.Distance(startPos, endPos) / 2.0f + 0.001f);
float[] verts = new float[m_nav.GetMaxVertsPerPoly() * 3]; float[] verts = new float[m_nav.GetMaxVertsPerPoly() * 3];
@ -2125,7 +2125,7 @@ namespace DotRecast.Detour
float t = 0.5f; float t = 0.5f;
if (DtUtils.IntersectSegSeg2D(fromPos, toPos, left, right, out var _, out var t2)) if (DtUtils.IntersectSegSeg2D(fromPos, toPos, left, right, out var _, out var t2))
{ {
t = Clamp(t2, 0.1f, 0.9f); t = RcMath.Clamp(t2, 0.1f, 0.9f);
} }
pt = RcVec3f.Lerp(left, right, t); pt = RcVec3f.Lerp(left, right, t);
@ -2371,7 +2371,7 @@ namespace DotRecast.Detour
var e2 = verts[(segMax + 1) % nv]; var e2 = verts[(segMax + 1) % nv];
var eDir = e2.Subtract(e1); var eDir = e2.Subtract(e1);
var diff = curPos.Subtract(e1); var diff = curPos.Subtract(e1);
float s = Sqr(eDir.x) > Sqr(eDir.z) ? diff.x / eDir.x : diff.z / eDir.z; 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; curPos.y = e1.y + eDir.y * s;
hit.pathCost += filter.GetCost(lastPos, curPos, prevRef, prevTile, prevPoly, curRef, tile, poly, hit.pathCost += filter.GetCost(lastPos, curPos, prevRef, prevTile, prevPoly, curRef, tile, poly,
@ -2481,7 +2481,7 @@ namespace DotRecast.Detour
startNode.flags = DtNode.DT_NODE_OPEN; startNode.flags = DtNode.DT_NODE_OPEN;
m_openList.Push(startNode); m_openList.Push(startNode);
float radiusSqr = Sqr(radius); float radiusSqr = RcMath.Sqr(radius);
while (!m_openList.IsEmpty()) while (!m_openList.IsEmpty())
{ {
@ -2828,7 +2828,7 @@ namespace DotRecast.Detour
resultRef.Add(startNode.id); resultRef.Add(startNode.id);
resultParent.Add(0L); resultParent.Add(0L);
float radiusSqr = Sqr(radius); float radiusSqr = RcMath.Sqr(radius);
float[] pa = new float[m_nav.GetMaxVertsPerPoly() * 3]; float[] pa = new float[m_nav.GetMaxVertsPerPoly() * 3];
float[] pb = new float[m_nav.GetMaxVertsPerPoly() * 3]; float[] pb = new float[m_nav.GetMaxVertsPerPoly() * 3];
@ -3156,7 +3156,7 @@ namespace DotRecast.Detour
startNode.flags = DtNode.DT_NODE_OPEN; startNode.flags = DtNode.DT_NODE_OPEN;
m_openList.Push(startNode); m_openList.Push(startNode);
float radiusSqr = Sqr(maxRadius); float radiusSqr = RcMath.Sqr(maxRadius);
var hasBestV = false; var hasBestV = false;
var bestvj = RcVec3f.Zero; var bestvj = RcVec3f.Zero;

View File

@ -43,7 +43,7 @@ using DotRecast.Recast.Toolset.Geom;
using DotRecast.Recast.Demo.Tools; using DotRecast.Recast.Demo.Tools;
using DotRecast.Recast.Demo.UI; using DotRecast.Recast.Demo.UI;
using DotRecast.Recast.Toolset; using DotRecast.Recast.Toolset;
using static DotRecast.Core.RcMath;
using MouseButton = Silk.NET.Input.MouseButton; using MouseButton = Silk.NET.Input.MouseButton;
using Window = Silk.NET.Windowing.Window; using Window = Silk.NET.Windowing.Window;
@ -433,13 +433,13 @@ public class RecastDemo : IRecastDemoChannel
_modState |= 0 < tempMoveAccel ? (int)KeyModState.Shift : (int)KeyModState.None; _modState |= 0 < tempMoveAccel ? (int)KeyModState.Shift : (int)KeyModState.None;
//Logger.Information($"{_modState}"); //Logger.Information($"{_modState}");
_moveFront = Clamp(_moveFront + tempMoveFront * dt * 4.0f, 0, 2.0f); _moveFront = RcMath.Clamp(_moveFront + tempMoveFront * dt * 4.0f, 0, 2.0f);
_moveLeft = Clamp(_moveLeft + tempMoveLeft * dt * 4.0f, 0, 2.0f); _moveLeft = RcMath.Clamp(_moveLeft + tempMoveLeft * dt * 4.0f, 0, 2.0f);
_moveBack = Clamp(_moveBack + tempMoveBack * dt * 4.0f, 0, 2.0f); _moveBack = RcMath.Clamp(_moveBack + tempMoveBack * dt * 4.0f, 0, 2.0f);
_moveRight = Clamp(_moveRight + tempMoveRight * dt * 4.0f, 0, 2.0f); _moveRight = RcMath.Clamp(_moveRight + tempMoveRight * dt * 4.0f, 0, 2.0f);
_moveUp = Clamp(_moveUp + tempMoveUp * dt * 4.0f, 0, 2.0f); _moveUp = RcMath.Clamp(_moveUp + tempMoveUp * dt * 4.0f, 0, 2.0f);
_moveDown = Clamp(_moveDown + tempMoveDown * dt * 4.0f, 0, 2.0f); _moveDown = RcMath.Clamp(_moveDown + tempMoveDown * dt * 4.0f, 0, 2.0f);
_moveAccel = Clamp(_moveAccel + tempMoveAccel * dt * 4.0f, 0, 2.0f); _moveAccel = RcMath.Clamp(_moveAccel + tempMoveAccel * dt * 4.0f, 0, 2.0f);
} }
} }
@ -490,7 +490,7 @@ public class RecastDemo : IRecastDemoChannel
// Update sample simulation. // Update sample simulation.
float SIM_RATE = 20; float SIM_RATE = 20;
float DELTA_TIME = 1.0f / SIM_RATE; float DELTA_TIME = 1.0f / SIM_RATE;
timeAcc = Clamp((float)(timeAcc + dt), -1.0f, 1.0f); timeAcc = RcMath.Clamp((float)(timeAcc + dt), -1.0f, 1.0f);
int simIter = 0; int simIter = 0;
while (timeAcc > DELTA_TIME) while (timeAcc > DELTA_TIME)
{ {
@ -574,7 +574,7 @@ public class RecastDemo : IRecastDemoChannel
RcVec3f bmin = bminN; RcVec3f bmin = bminN;
RcVec3f bmax = bmaxN; RcVec3f bmax = bmaxN;
camr = (float)(Math.Sqrt(Sqr(bmax.x - bmin.x) + Sqr(bmax.y - bmin.y) + Sqr(bmax.z - bmin.z)) / 2); camr = (float)(Math.Sqrt(RcMath.Sqr(bmax.x - bmin.x) + RcMath.Sqr(bmax.y - bmin.y) + RcMath.Sqr(bmax.z - bmin.z)) / 2);
cameraPos.x = (bmax.x + bmin.x) / 2 + camr; cameraPos.x = (bmax.x + bmin.x) / 2 + camr;
cameraPos.y = (bmax.y + bmin.y) / 2 + camr; cameraPos.y = (bmax.y + bmin.y) / 2 + camr;
cameraPos.z = (bmax.z + bmin.z) / 2 + camr; cameraPos.z = (bmax.z + bmin.z) / 2 + camr;

View File

@ -1,7 +1,7 @@
using DotRecast.Core; using DotRecast.Core;
using DotRecast.Recast.Demo.Draw; using DotRecast.Recast.Demo.Draw;
using DotRecast.Recast.Toolset.Gizmos; using DotRecast.Recast.Toolset.Gizmos;
using static DotRecast.Core.RcMath;
namespace DotRecast.Recast.Demo.Tools; namespace DotRecast.Recast.Demo.Tools;
@ -50,7 +50,7 @@ public static class GizmoRenderer
normal.y = e0.z * e1.x - e0.x * e1.z; normal.y = e0.z * e1.x - e0.x * e1.z;
normal.z = e0.x * e1.y - e0.y * e1.x; normal.z = e0.x * e1.y - e0.y * e1.x;
RcVec3f.Normalize(ref normal); RcVec3f.Normalize(ref normal);
float c = Clamp(0.57735026f * (normal.x + normal.y + normal.z), -1, 1); float c = RcMath.Clamp(0.57735026f * (normal.x + normal.y + normal.z), -1, 1);
int col = DebugDraw.DuLerpCol( int col = DebugDraw.DuLerpCol(
DebugDraw.DuRGBA(32, 32, 0, 160), DebugDraw.DuRGBA(32, 32, 0, 160),
DebugDraw.DuRGBA(220, 220, 0, 160), DebugDraw.DuRGBA(220, 220, 0, 160),
@ -139,7 +139,7 @@ public static class GizmoRenderer
for (int j = 0; j < 3; j++) for (int j = 0; j < 3; j++)
{ {
int v = sphere.triangles[i + j] * 3; int v = sphere.triangles[i + j] * 3;
float c = Clamp(0.57735026f * (sphere.vertices[v] + sphere.vertices[v + 1] + sphere.vertices[v + 2]), -1, 1); float c = RcMath.Clamp(0.57735026f * (sphere.vertices[v] + sphere.vertices[v + 1] + sphere.vertices[v + 2]), -1, 1);
int col = DebugDraw.DuLerpCol(DebugDraw.DuRGBA(32, 32, 0, 160), DebugDraw.DuRGBA(220, 220, 0, 160), (int)(127 * (1 + c))); int col = DebugDraw.DuLerpCol(DebugDraw.DuRGBA(32, 32, 0, 160), DebugDraw.DuRGBA(220, 220, 0, 160), (int)(127 * (1 + c)));
debugDraw.Vertex( debugDraw.Vertex(

View File

@ -1,5 +1,5 @@
using DotRecast.Core; using DotRecast.Core;
using static DotRecast.Core.RcMath;
using static DotRecast.Recast.Toolset.Gizmos.RcGizmoHelper; using static DotRecast.Recast.Toolset.Gizmos.RcGizmoHelper;
namespace DotRecast.Recast.Toolset.Gizmos namespace DotRecast.Recast.Toolset.Gizmos
@ -48,7 +48,7 @@ namespace DotRecast.Recast.Toolset.Gizmos
v.y = vertices[i + 1] - center[1]; v.y = vertices[i + 1] - center[1];
v.z = vertices[i + 2] - center[2]; v.z = vertices[i + 2] - center[2];
RcVec3f.Normalize(ref v); RcVec3f.Normalize(ref v);
gradient[i / 3] = Clamp(0.57735026f * (v.x + v.y + v.z), -1, 1); gradient[i / 3] = RcMath.Clamp(0.57735026f * (v.x + v.y + v.z), -1, 1);
} }
} }

View File

@ -1,5 +1,5 @@
using DotRecast.Core; using DotRecast.Core;
using static DotRecast.Core.RcMath;
using static DotRecast.Recast.Toolset.Gizmos.RcGizmoHelper; using static DotRecast.Recast.Toolset.Gizmos.RcGizmoHelper;
@ -53,7 +53,7 @@ namespace DotRecast.Recast.Toolset.Gizmos
v.y = vertices[i + 1] - center.y; v.y = vertices[i + 1] - center.y;
v.z = vertices[i + 2] - center.z; v.z = vertices[i + 2] - center.z;
RcVec3f.Normalize(ref v); RcVec3f.Normalize(ref v);
gradient[i / 3] = Clamp(0.57735026f * (v.x + v.y + v.z), -1, 1); gradient[i / 3] = RcMath.Clamp(0.57735026f * (v.x + v.y + v.z), -1, 1);
} }
} }
} }

View File

@ -19,7 +19,7 @@ freely, subject to the following restrictions:
using System; using System;
using DotRecast.Core; using DotRecast.Core;
using static DotRecast.Core.RcMath;
using static DotRecast.Recast.RcConstants; using static DotRecast.Recast.RcConstants;
@ -27,6 +27,7 @@ namespace DotRecast.Recast
{ {
using static RcCommons; using static RcCommons;
public static class RcCompacts public static class RcCompacts
{ {
private const int MAX_LAYERS = RC_NOT_CONNECTED - 1; private const int MAX_LAYERS = RC_NOT_CONNECTED - 1;
@ -92,8 +93,8 @@ namespace DotRecast.Recast
{ {
int bot = s.smax; int bot = s.smax;
int top = s.next != null ? (int)s.next.smin : MAX_HEIGHT; int top = s.next != null ? (int)s.next.smin : MAX_HEIGHT;
chf.spans[idx].y = Clamp(bot, 0, MAX_HEIGHT); chf.spans[idx].y = RcMath.Clamp(bot, 0, MAX_HEIGHT);
chf.spans[idx].h = Clamp(top - bot, 0, MAX_HEIGHT); chf.spans[idx].h = RcMath.Clamp(top - bot, 0, MAX_HEIGHT);
chf.areas[idx] = s.area; chf.areas[idx] = s.area;
idx++; idx++;
tmpCount++; tmpCount++;

View File

@ -19,12 +19,13 @@ freely, subject to the following restrictions:
using System; using System;
using DotRecast.Core; using DotRecast.Core;
using static DotRecast.Core.RcMath;
using static DotRecast.Recast.RcConstants; using static DotRecast.Recast.RcConstants;
namespace DotRecast.Recast namespace DotRecast.Recast
{ {
public static class RcFilledVolumeRasterization public static class RcFilledVolumeRasterization
{ {
private const float EPSILON = 0.00001f; private const float EPSILON = 0.00001f;
@ -221,8 +222,8 @@ namespace DotRecast.Recast
int smax = (int)Math.Ceiling((h[1] - hf.bmin.y) * ich); int smax = (int)Math.Ceiling((h[1] - hf.bmin.y) * ich);
if (smin != smax) if (smin != smax)
{ {
int ismin = Clamp(smin, 0, SPAN_MAX_HEIGHT); int ismin = RcMath.Clamp(smin, 0, SPAN_MAX_HEIGHT);
int ismax = Clamp(smax, ismin + 1, SPAN_MAX_HEIGHT); int ismax = RcMath.Clamp(smax, ismin + 1, SPAN_MAX_HEIGHT);
RcRasterizations.AddSpan(hf, x, z, ismin, ismax, area, flagMergeThr); RcRasterizations.AddSpan(hf, x, z, ismin, ismax, area, flagMergeThr);
} }
} }
@ -281,12 +282,12 @@ namespace DotRecast.Recast
{ {
float[] s = MergeIntersections( float[] s = MergeIntersections(
RayCylinderIntersection(RcVec3f.Of( RayCylinderIntersection(RcVec3f.Of(
Clamp(start.x, rectangle[0], rectangle[2]), rectangle[4], RcMath.Clamp(start.x, rectangle[0], rectangle[2]), rectangle[4],
Clamp(start.z, rectangle[1], rectangle[3]) RcMath.Clamp(start.z, rectangle[1], rectangle[3])
), start, axis, radiusSqr), ), start, axis, radiusSqr),
RayCylinderIntersection(RcVec3f.Of( RayCylinderIntersection(RcVec3f.Of(
Clamp(end.x, rectangle[0], rectangle[2]), rectangle[4], RcMath.Clamp(end.x, rectangle[0], rectangle[2]), rectangle[4],
Clamp(end.z, rectangle[1], rectangle[3]) RcMath.Clamp(end.z, rectangle[1], rectangle[3])
), start, axis, radiusSqr)); ), start, axis, radiusSqr));
float axisLen2dSqr = axis.x * axis.x + axis.z * axis.z; float axisLen2dSqr = axis.x * axis.x + axis.z * axis.z;
if (axisLen2dSqr > EPSILON) if (axisLen2dSqr > EPSILON)
@ -397,7 +398,7 @@ namespace DotRecast.Recast
{ {
// 2d intersection of plane and segment // 2d intersection of plane and segment
float t = (x - start.x) / direction.x; float t = (x - start.x) / direction.x;
float z = Clamp(start.z + t * direction.z, rectangle[1], rectangle[3]); float z = RcMath.Clamp(start.z + t * direction.z, rectangle[1], rectangle[3]);
return RcVec3f.Of(x, rectangle[4], z); return RcVec3f.Of(x, rectangle[4], z);
} }
@ -410,7 +411,7 @@ namespace DotRecast.Recast
{ {
// 2d intersection of plane and segment // 2d intersection of plane and segment
float t = (z - start.z) / direction.z; float t = (z - start.z) / direction.z;
float x = Clamp(start.x + t * direction.x, rectangle[0], rectangle[2]); float x = RcMath.Clamp(start.x + t * direction.x, rectangle[0], rectangle[2]);
return RcVec3f.Of(x, rectangle[4], z); return RcVec3f.Of(x, rectangle[4], z);
} }

View File

@ -21,12 +21,13 @@ freely, subject to the following restrictions:
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using DotRecast.Core; using DotRecast.Core;
using static DotRecast.Core.RcMath;
using static DotRecast.Recast.RcConstants; using static DotRecast.Recast.RcConstants;
namespace DotRecast.Recast namespace DotRecast.Recast
{ {
using static RcCommons; using static RcCommons;
public static class RcMeshDetails public static class RcMeshDetails
{ {
@ -351,8 +352,8 @@ namespace DotRecast.Recast
{ {
int ix = (int)Math.Floor(fx * ics + 0.01f); int ix = (int)Math.Floor(fx * ics + 0.01f);
int iz = (int)Math.Floor(fz * ics + 0.01f); int iz = (int)Math.Floor(fz * ics + 0.01f);
ix = Clamp(ix - hp.xmin, 0, hp.width - 1); ix = RcMath.Clamp(ix - hp.xmin, 0, hp.width - 1);
iz = Clamp(iz - hp.ymin, 0, hp.height - 1); iz = RcMath.Clamp(iz - hp.ymin, 0, hp.height - 1);
int h = hp.data[ix + iz * hp.width]; int h = hp.data[ix + iz * hp.width];
if (h == RC_UNSET_HEIGHT) if (h == RC_UNSET_HEIGHT)
{ {

View File

@ -20,26 +20,27 @@ freely, subject to the following restrictions:
using System; using System;
using DotRecast.Core; using DotRecast.Core;
using static DotRecast.Core.RcMath;
using static DotRecast.Recast.RcConstants; using static DotRecast.Recast.RcConstants;
namespace DotRecast.Recast namespace DotRecast.Recast
{ {
public static class RcRasterizations public static class RcRasterizations
{ {
/** /**
* Check whether two bounding boxes overlap * Check whether two bounding boxes overlap
* *
* @param amin * @param amin
* Min axis extents of bounding box A * Min axis extents of bounding box A
* @param amax * @param amax
* Max axis extents of bounding box A * Max axis extents of bounding box A
* @param bmin * @param bmin
* Min axis extents of bounding box B * Min axis extents of bounding box B
* @param bmax * @param bmax
* Max axis extents of bounding box B * Max axis extents of bounding box B
* @returns true if the two bounding boxes overlap. False otherwise * @returns true if the two bounding boxes overlap. False otherwise
*/ */
private static bool OverlapBounds(float[] amin, float[] amax, float[] bmin, float[] bmax) private static bool OverlapBounds(float[] amin, float[] amax, float[] bmin, float[] bmax)
{ {
bool overlap = true; bool overlap = true;
@ -229,9 +230,9 @@ namespace DotRecast.Recast
/// @param[in] inverseCellHeight 1 / cellHeight /// @param[in] inverseCellHeight 1 / cellHeight
/// @param[in] flagMergeThreshold The threshold in which area flags will be merged /// @param[in] flagMergeThreshold The threshold in which area flags will be merged
/// @returns true if the operation completes successfully. false if there was an error adding spans to the heightfield. /// @returns true if the operation completes successfully. false if there was an error adding spans to the heightfield.
private static void RasterizeTri(float[] verts, int v0, int v1, int v2, int area, RcHeightfield heightfield, private static void RasterizeTri(float[] verts, int v0, int v1, int v2, int area, RcHeightfield heightfield,
RcVec3f heightfieldBBMin, RcVec3f heightfieldBBMax, RcVec3f heightfieldBBMin, RcVec3f heightfieldBBMax,
float cellSize, float inverseCellSize, float inverseCellHeight, float cellSize, float inverseCellSize, float inverseCellHeight,
int flagMergeThreshold) int flagMergeThreshold)
{ {
RcVec3f tmin = new RcVec3f(); RcVec3f tmin = new RcVec3f();
@ -257,8 +258,8 @@ namespace DotRecast.Recast
int w = heightfield.width; int w = heightfield.width;
int h = heightfield.height; int h = heightfield.height;
// use -1 rather than 0 to cut the polygon properly at the start of the tile // use -1 rather than 0 to cut the polygon properly at the start of the tile
z0 = Clamp(z0, -1, h - 1); z0 = RcMath.Clamp(z0, -1, h - 1);
z1 = Clamp(z1, 0, h - 1); z1 = RcMath.Clamp(z1, 0, h - 1);
// Clip the triangle into all grid cells it touches. // Clip the triangle into all grid cells it touches.
float[] buf = new float[7 * 3 * 4]; float[] buf = new float[7 * 3 * 4];
@ -303,8 +304,8 @@ namespace DotRecast.Recast
continue; continue;
} }
x0 = Clamp(x0, -1, w - 1); x0 = RcMath.Clamp(x0, -1, w - 1);
x1 = Clamp(x1, 0, w - 1); x1 = RcMath.Clamp(x1, 0, w - 1);
int nv, nv2 = nvRow; int nv, nv2 = nvRow;
for (int x = x0; x <= x1; ++x) for (int x = x0; x <= x1; ++x)
@ -345,8 +346,8 @@ namespace DotRecast.Recast
spanMax = by; spanMax = by;
// Snap the span to the heightfield height grid. // Snap the span to the heightfield height grid.
int spanMinCellIndex = Clamp((int)Math.Floor(spanMin * inverseCellHeight), 0, SPAN_MAX_HEIGHT); int spanMinCellIndex = RcMath.Clamp((int)Math.Floor(spanMin * inverseCellHeight), 0, SPAN_MAX_HEIGHT);
int spanMaxCellIndex = Clamp((int)Math.Ceiling(spanMax * inverseCellHeight), spanMinCellIndex + 1, SPAN_MAX_HEIGHT); int spanMaxCellIndex = RcMath.Clamp((int)Math.Ceiling(spanMax * inverseCellHeight), spanMinCellIndex + 1, SPAN_MAX_HEIGHT);
AddSpan(heightfield, x, z, spanMinCellIndex, spanMaxCellIndex, area, flagMergeThreshold); AddSpan(heightfield, x, z, spanMinCellIndex, spanMaxCellIndex, area, flagMergeThreshold);
} }

View File

@ -26,7 +26,7 @@ using NUnit.Framework;
namespace DotRecast.Detour.Crowd.Test; namespace DotRecast.Detour.Crowd.Test;
using static DotRecast.Core.RcMath;
[Parallelizable] [Parallelizable]
public class AbstractCrowdTest public class AbstractCrowdTest

View File

@ -23,7 +23,7 @@ using DotRecast.Detour.Io;
using DotRecast.Recast; using DotRecast.Recast;
using DotRecast.Recast.Geom; using DotRecast.Recast.Geom;
using NUnit.Framework; using NUnit.Framework;
using static DotRecast.Core.RcMath;
namespace DotRecast.Detour.Test.Io; namespace DotRecast.Detour.Test.Io;

View File

@ -21,7 +21,7 @@ using System.Diagnostics;
using DotRecast.Core; using DotRecast.Core;
using NUnit.Framework; using NUnit.Framework;
using static DotRecast.Core.RcMath;
namespace DotRecast.Detour.Test; namespace DotRecast.Detour.Test;

View File

@ -24,7 +24,7 @@ using DotRecast.Detour.TileCache.Test.Io;
using DotRecast.Recast; using DotRecast.Recast;
using DotRecast.Recast.Geom; using DotRecast.Recast.Geom;
using NUnit.Framework; using NUnit.Framework;
using static DotRecast.Core.RcMath;
namespace DotRecast.Detour.TileCache.Test; namespace DotRecast.Detour.TileCache.Test;