forked from mirror/DotRecast
remove warn
This commit is contained in:
parent
75aaaefbc3
commit
1ed0d41218
|
@ -17,8 +17,6 @@ freely, subject to the following restrictions:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using DotRecast.Core;
|
|
||||||
using static DotRecast.Core.RcMath;
|
|
||||||
|
|
||||||
namespace DotRecast.Core
|
namespace DotRecast.Core
|
||||||
{
|
{
|
||||||
|
@ -78,16 +76,16 @@ namespace DotRecast.Core
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float[] IntersectSegmentAABB(Vector3f sp, Vector3f sq, Vector3f amin, Vector3f amax)
|
public static bool IsectSegAABB(Vector3f sp, Vector3f sq, Vector3f amin, Vector3f amax, out float tmin, out float tmax)
|
||||||
{
|
{
|
||||||
float EPS = 1e-6f;
|
const float EPS = 1e-6f;
|
||||||
|
|
||||||
Vector3f d = new Vector3f();
|
Vector3f d = new Vector3f();
|
||||||
d.x = sq.x - sp.x;
|
d.x = sq.x - sp.x;
|
||||||
d.y = sq.y - sp.y;
|
d.y = sq.y - sp.y;
|
||||||
d.z = sq.z - sp.z;
|
d.z = sq.z - sp.z;
|
||||||
float tmin = 0.0f;
|
tmin = 0.0f;
|
||||||
float tmax = 1.0f;
|
tmax = float.MaxValue;
|
||||||
|
|
||||||
for (int i = 0; i < 3; i++)
|
for (int i = 0; i < 3; i++)
|
||||||
{
|
{
|
||||||
|
@ -95,7 +93,7 @@ namespace DotRecast.Core
|
||||||
{
|
{
|
||||||
if (sp[i] < amin[i] || sp[i] > amax[i])
|
if (sp[i] < amin[i] || sp[i] > amax[i])
|
||||||
{
|
{
|
||||||
return null;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -103,11 +101,10 @@ namespace DotRecast.Core
|
||||||
float ood = 1.0f / d[i];
|
float ood = 1.0f / d[i];
|
||||||
float t1 = (amin[i] - sp[i]) * ood;
|
float t1 = (amin[i] - sp[i]) * ood;
|
||||||
float t2 = (amax[i] - sp[i]) * ood;
|
float t2 = (amax[i] - sp[i]) * ood;
|
||||||
|
|
||||||
if (t1 > t2)
|
if (t1 > t2)
|
||||||
{
|
{
|
||||||
float tmp = t1;
|
(t1, t2) = (t2, t1);
|
||||||
t1 = t2;
|
|
||||||
t2 = tmp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (t1 > tmin)
|
if (t1 > tmin)
|
||||||
|
@ -122,12 +119,12 @@ namespace DotRecast.Core
|
||||||
|
|
||||||
if (tmin > tmax)
|
if (tmin > tmax)
|
||||||
{
|
{
|
||||||
return null;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new float[] { tmin, tmax };
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -24,31 +24,11 @@ namespace DotRecast.Core
|
||||||
{
|
{
|
||||||
public static class RcMath
|
public static class RcMath
|
||||||
{
|
{
|
||||||
public const float EPS = 1e-4f;
|
|
||||||
private static readonly float EQUAL_THRESHOLD = Sqr(1.0f / 16384.0f);
|
|
||||||
|
|
||||||
public static float Sqr(float f)
|
public static float Sqr(float f)
|
||||||
{
|
{
|
||||||
return f * f;
|
return f * f;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float GetPathLen(float[] path, int npath)
|
|
||||||
{
|
|
||||||
float totd = 0;
|
|
||||||
for (int i = 0; i < npath - 1; ++i)
|
|
||||||
{
|
|
||||||
totd += (float)Math.Sqrt(Vector3f.DistSqr(path, i * 3, (i + 1) * 3));
|
|
||||||
}
|
|
||||||
|
|
||||||
return totd;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static float Step(float threshold, float v)
|
|
||||||
{
|
|
||||||
return v < threshold ? 0.0f : 1.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static float Clamp(float v, float min, float max)
|
public static float Clamp(float v, float min, float max)
|
||||||
{
|
{
|
||||||
return Math.Max(Math.Min(v, max), min);
|
return Math.Max(Math.Min(v, max), min);
|
||||||
|
@ -58,431 +38,5 @@ namespace DotRecast.Core
|
||||||
{
|
{
|
||||||
return Math.Max(Math.Min(v, max), min);
|
return Math.Max(Math.Min(v, max), min);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float Lerp(float f, float g, float u)
|
|
||||||
{
|
|
||||||
return u * g + (1f - u) * f;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Performs a 'sloppy' colocation check of the specified points.
|
|
||||||
/// @param[in] p0 A point. [(x, y, z)]
|
|
||||||
/// @param[in] p1 A point. [(x, y, z)]
|
|
||||||
/// @return True if the points are considered to be at the same location.
|
|
||||||
///
|
|
||||||
/// Basically, this function will return true if the specified points are
|
|
||||||
/// close enough to eachother to be considered colocated.
|
|
||||||
public static bool VEqual(Vector3f p0, Vector3f p1)
|
|
||||||
{
|
|
||||||
return VEqual(p0, p1, EQUAL_THRESHOLD);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool VEqual(Vector3f p0, Vector3f p1, float thresholdSqr)
|
|
||||||
{
|
|
||||||
float d = Vector3f.DistSqr(p0, p1);
|
|
||||||
return d < thresholdSqr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// @}
|
|
||||||
/// @name Computational geometry helper functions.
|
|
||||||
/// @{
|
|
||||||
/// Derives the signed xz-plane area of the triangle ABC, or the
|
|
||||||
/// relationship of line AB to point C.
|
|
||||||
/// @param[in] a Vertex A. [(x, y, z)]
|
|
||||||
/// @param[in] b Vertex B. [(x, y, z)]
|
|
||||||
/// @param[in] c Vertex C. [(x, y, z)]
|
|
||||||
/// @return The signed xz-plane area of the triangle.
|
|
||||||
public static float TriArea2D(float[] verts, int a, int b, int c)
|
|
||||||
{
|
|
||||||
float abx = verts[b] - verts[a];
|
|
||||||
float abz = verts[b + 2] - verts[a + 2];
|
|
||||||
float acx = verts[c] - verts[a];
|
|
||||||
float acz = verts[c + 2] - verts[a + 2];
|
|
||||||
return acx * abz - abx * acz;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static float TriArea2D(Vector3f a, Vector3f b, Vector3f c)
|
|
||||||
{
|
|
||||||
float abx = b.x - a.x;
|
|
||||||
float abz = b.z - a.z;
|
|
||||||
float acx = c.x - a.x;
|
|
||||||
float acz = c.z - a.z;
|
|
||||||
return acx * abz - abx * acz;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Determines if two axis-aligned bounding boxes overlap.
|
|
||||||
/// @param[in] amin Minimum bounds of box A. [(x, y, z)]
|
|
||||||
/// @param[in] amax Maximum bounds of box A. [(x, y, z)]
|
|
||||||
/// @param[in] bmin Minimum bounds of box B. [(x, y, z)]
|
|
||||||
/// @param[in] bmax Maximum bounds of box B. [(x, y, z)]
|
|
||||||
/// @return True if the two AABB's overlap.
|
|
||||||
/// @see dtOverlapBounds
|
|
||||||
public static bool OverlapQuantBounds(int[] amin, int[] amax, int[] bmin, int[] bmax)
|
|
||||||
{
|
|
||||||
bool overlap = true;
|
|
||||||
overlap = (amin[0] > bmax[0] || amax[0] < bmin[0]) ? false : overlap;
|
|
||||||
overlap = (amin[1] > bmax[1] || amax[1] < bmin[1]) ? false : overlap;
|
|
||||||
overlap = (amin[2] > bmax[2] || amax[2] < bmin[2]) ? false : overlap;
|
|
||||||
return overlap;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Determines if two axis-aligned bounding boxes overlap.
|
|
||||||
/// @param[in] amin Minimum bounds of box A. [(x, y, z)]
|
|
||||||
/// @param[in] amax Maximum bounds of box A. [(x, y, z)]
|
|
||||||
/// @param[in] bmin Minimum bounds of box B. [(x, y, z)]
|
|
||||||
/// @param[in] bmax Maximum bounds of box B. [(x, y, z)]
|
|
||||||
/// @return True if the two AABB's overlap.
|
|
||||||
/// @see dtOverlapQuantBounds
|
|
||||||
public static bool OverlapBounds(Vector3f amin, Vector3f amax, Vector3f bmin, Vector3f bmax)
|
|
||||||
{
|
|
||||||
bool overlap = true;
|
|
||||||
overlap = (amin.x > bmax.x || amax.x < bmin.x) ? false : overlap;
|
|
||||||
overlap = (amin.y > bmax.y || amax.y < bmin.y) ? false : overlap;
|
|
||||||
overlap = (amin.z > bmax.z || amax.z < bmin.z) ? false : overlap;
|
|
||||||
return overlap;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static float DistancePtSegSqr2D(Vector3f pt, float[] verts, int p, int q, out float t)
|
|
||||||
{
|
|
||||||
var vp = Vector3f.Of(verts, p);
|
|
||||||
var vq = Vector3f.Of(verts, q);
|
|
||||||
return DistancePtSegSqr2D(pt, vp, vq, out t);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static float DistancePtSegSqr2D(Vector3f pt, Vector3f p, Vector3f q, out float t)
|
|
||||||
{
|
|
||||||
float pqx = q.x - p.x;
|
|
||||||
float pqz = q.z - p.z;
|
|
||||||
float dx = pt.x - p.x;
|
|
||||||
float dz = pt.z - p.z;
|
|
||||||
float d = pqx * pqx + pqz * pqz;
|
|
||||||
t = pqx * dx + pqz * dz;
|
|
||||||
if (d > 0)
|
|
||||||
{
|
|
||||||
t /= d;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (t < 0)
|
|
||||||
{
|
|
||||||
t = 0;
|
|
||||||
}
|
|
||||||
else if (t > 1)
|
|
||||||
{
|
|
||||||
t = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
dx = p.x + t * pqx - pt.x;
|
|
||||||
dz = p.z + t * pqz - pt.z;
|
|
||||||
return dx * dx + dz * dz;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static float? ClosestHeightPointTriangle(Vector3f p, Vector3f a, Vector3f b, Vector3f c)
|
|
||||||
{
|
|
||||||
Vector3f v0 = c.Subtract(a);
|
|
||||||
Vector3f v1 = b.Subtract(a);
|
|
||||||
Vector3f v2 = p.Subtract(a);
|
|
||||||
|
|
||||||
// Compute scaled barycentric coordinates
|
|
||||||
float denom = v0.x * v1.z - v0.z * v1.x;
|
|
||||||
if (Math.Abs(denom) < EPS)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
float u = v1.z * v2.x - v1.x * v2.z;
|
|
||||||
float v = v0.x * v2.z - v0.z * v2.x;
|
|
||||||
|
|
||||||
if (denom < 0)
|
|
||||||
{
|
|
||||||
denom = -denom;
|
|
||||||
u = -u;
|
|
||||||
v = -v;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If point lies inside the triangle, return interpolated ycoord.
|
|
||||||
if (u >= 0.0f && v >= 0.0f && (u + v) <= denom)
|
|
||||||
{
|
|
||||||
float h = a.y + (v0.y * u + v1.y * v) / denom;
|
|
||||||
return h;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @par
|
|
||||||
///
|
|
||||||
/// All points are projected onto the xz-plane, so the y-values are ignored.
|
|
||||||
public static bool PointInPolygon(Vector3f pt, float[] verts, int nverts)
|
|
||||||
{
|
|
||||||
// TODO: Replace pnpoly with triArea2D tests?
|
|
||||||
int i, j;
|
|
||||||
bool c = false;
|
|
||||||
for (i = 0, j = nverts - 1; i < nverts; j = i++)
|
|
||||||
{
|
|
||||||
int vi = i * 3;
|
|
||||||
int vj = j * 3;
|
|
||||||
if (((verts[vi + 2] > pt.z) != (verts[vj + 2] > pt.z)) && (pt.x < (verts[vj + 0] - verts[vi + 0])
|
|
||||||
* (pt.z - verts[vi + 2]) / (verts[vj + 2] - verts[vi + 2]) + verts[vi + 0]))
|
|
||||||
{
|
|
||||||
c = !c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool DistancePtPolyEdgesSqr(Vector3f pt, float[] verts, int nverts, float[] ed, float[] et)
|
|
||||||
{
|
|
||||||
// TODO: Replace pnpoly with triArea2D tests?
|
|
||||||
int i, j;
|
|
||||||
bool c = false;
|
|
||||||
for (i = 0, j = nverts - 1; i < nverts; j = i++)
|
|
||||||
{
|
|
||||||
int vi = i * 3;
|
|
||||||
int vj = j * 3;
|
|
||||||
if (((verts[vi + 2] > pt.z) != (verts[vj + 2] > pt.z)) &&
|
|
||||||
(pt.x < (verts[vj + 0] - verts[vi + 0]) * (pt.z - verts[vi + 2]) / (verts[vj + 2] - verts[vi + 2]) + verts[vi + 0]))
|
|
||||||
{
|
|
||||||
c = !c;
|
|
||||||
}
|
|
||||||
|
|
||||||
ed[j] = DistancePtSegSqr2D(pt, verts, vj, vi, out et[j]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Vector2f ProjectPoly(Vector3f axis, float[] poly, int npoly)
|
|
||||||
{
|
|
||||||
float rmin, rmax;
|
|
||||||
rmin = rmax = axis.Dot2D(poly, 0);
|
|
||||||
for (int i = 1; i < npoly; ++i)
|
|
||||||
{
|
|
||||||
float d = axis.Dot2D(poly, i * 3);
|
|
||||||
rmin = Math.Min(rmin, d);
|
|
||||||
rmax = Math.Max(rmax, d);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Vector2f
|
|
||||||
{
|
|
||||||
x = rmin,
|
|
||||||
y = rmax,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool OverlapRange(float amin, float amax, float bmin, float bmax, float eps)
|
|
||||||
{
|
|
||||||
return ((amin + eps) > bmax || (amax - eps) < bmin) ? false : true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const float eps = 1e-4f;
|
|
||||||
|
|
||||||
/// @par
|
|
||||||
///
|
|
||||||
/// All vertices are projected onto the xz-plane, so the y-values are ignored.
|
|
||||||
public static bool OverlapPolyPoly2D(float[] polya, int npolya, float[] polyb, int npolyb)
|
|
||||||
{
|
|
||||||
for (int i = 0, j = npolya - 1; i < npolya; j = i++)
|
|
||||||
{
|
|
||||||
int va = j * 3;
|
|
||||||
int vb = i * 3;
|
|
||||||
|
|
||||||
Vector3f n = Vector3f.Of(polya[vb + 2] - polya[va + 2], 0, -(polya[vb + 0] - polya[va + 0]));
|
|
||||||
|
|
||||||
Vector2f aminmax = ProjectPoly(n, polya, npolya);
|
|
||||||
Vector2f bminmax = ProjectPoly(n, polyb, npolyb);
|
|
||||||
if (!OverlapRange(aminmax.x, aminmax.y, bminmax.x, bminmax.y, eps))
|
|
||||||
{
|
|
||||||
// Found separating axis
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0, j = npolyb - 1; i < npolyb; j = i++)
|
|
||||||
{
|
|
||||||
int va = j * 3;
|
|
||||||
int vb = i * 3;
|
|
||||||
|
|
||||||
Vector3f n = Vector3f.Of(polyb[vb + 2] - polyb[va + 2], 0, -(polyb[vb + 0] - polyb[va + 0]));
|
|
||||||
|
|
||||||
Vector2f aminmax = ProjectPoly(n, polya, npolya);
|
|
||||||
Vector2f bminmax = ProjectPoly(n, polyb, npolyb);
|
|
||||||
if (!OverlapRange(aminmax.x, aminmax.y, bminmax.x, bminmax.y, eps))
|
|
||||||
{
|
|
||||||
// Found separating axis
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns a random point in a convex polygon.
|
|
||||||
// Adapted from Graphics Gems article.
|
|
||||||
public static Vector3f RandomPointInConvexPoly(float[] pts, int npts, float[] areas, float s, float t)
|
|
||||||
{
|
|
||||||
// Calc triangle araes
|
|
||||||
float areasum = 0.0f;
|
|
||||||
for (int i = 2; i < npts; i++)
|
|
||||||
{
|
|
||||||
areas[i] = TriArea2D(pts, 0, (i - 1) * 3, i * 3);
|
|
||||||
areasum += Math.Max(0.001f, areas[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find sub triangle weighted by area.
|
|
||||||
float thr = s * areasum;
|
|
||||||
float acc = 0.0f;
|
|
||||||
float u = 1.0f;
|
|
||||||
int tri = npts - 1;
|
|
||||||
for (int i = 2; i < npts; i++)
|
|
||||||
{
|
|
||||||
float dacc = areas[i];
|
|
||||||
if (thr >= acc && thr < (acc + dacc))
|
|
||||||
{
|
|
||||||
u = (thr - acc) / dacc;
|
|
||||||
tri = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
acc += dacc;
|
|
||||||
}
|
|
||||||
|
|
||||||
float v = (float)Math.Sqrt(t);
|
|
||||||
|
|
||||||
float a = 1 - v;
|
|
||||||
float b = (1 - u) * v;
|
|
||||||
float c = u * v;
|
|
||||||
int pa = 0;
|
|
||||||
int pb = (tri - 1) * 3;
|
|
||||||
int pc = tri * 3;
|
|
||||||
|
|
||||||
return new Vector3f()
|
|
||||||
{
|
|
||||||
x = a * pts[pa] + b * pts[pb] + c * pts[pc],
|
|
||||||
y = a * pts[pa + 1] + b * pts[pb + 1] + c * pts[pc + 1],
|
|
||||||
z = a * pts[pa + 2] + b * pts[pb + 2] + c * pts[pc + 2]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int NextPow2(int v)
|
|
||||||
{
|
|
||||||
v--;
|
|
||||||
v |= v >> 1;
|
|
||||||
v |= v >> 2;
|
|
||||||
v |= v >> 4;
|
|
||||||
v |= v >> 8;
|
|
||||||
v |= v >> 16;
|
|
||||||
v++;
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int Ilog2(int v)
|
|
||||||
{
|
|
||||||
int r;
|
|
||||||
int shift;
|
|
||||||
r = (v > 0xffff ? 1 : 0) << 4;
|
|
||||||
v >>= r;
|
|
||||||
shift = (v > 0xff ? 1 : 0) << 3;
|
|
||||||
v >>= shift;
|
|
||||||
r |= shift;
|
|
||||||
shift = (v > 0xf ? 1 : 0) << 2;
|
|
||||||
v >>= shift;
|
|
||||||
r |= shift;
|
|
||||||
shift = (v > 0x3 ? 1 : 0) << 1;
|
|
||||||
v >>= shift;
|
|
||||||
r |= shift;
|
|
||||||
r |= (v >> 1);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static IntersectResult IntersectSegmentPoly2D(Vector3f p0, Vector3f p1, float[] verts, int nverts)
|
|
||||||
{
|
|
||||||
IntersectResult result = new IntersectResult();
|
|
||||||
float EPS = 0.000001f;
|
|
||||||
var dir = p1.Subtract(p0);
|
|
||||||
|
|
||||||
var p0v = p0;
|
|
||||||
for (int i = 0, j = nverts - 1; i < nverts; j = i++)
|
|
||||||
{
|
|
||||||
Vector3f vpj = Vector3f.Of(verts, j * 3);
|
|
||||||
Vector3f vpi = Vector3f.Of(verts, i * 3);
|
|
||||||
var edge = vpi.Subtract(vpj);
|
|
||||||
var diff = p0v.Subtract(vpj);
|
|
||||||
float n = Vector3f.Perp2D(edge, diff);
|
|
||||||
float d = Vector3f.Perp2D(dir, edge);
|
|
||||||
if (Math.Abs(d) < EPS)
|
|
||||||
{
|
|
||||||
// S is nearly parallel to this edge
|
|
||||||
if (n < 0)
|
|
||||||
{
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
float t = n / d;
|
|
||||||
if (d < 0)
|
|
||||||
{
|
|
||||||
// segment S is entering across this edge
|
|
||||||
if (t > result.tmin)
|
|
||||||
{
|
|
||||||
result.tmin = t;
|
|
||||||
result.segMin = j;
|
|
||||||
// S enters after leaving polygon
|
|
||||||
if (result.tmin > result.tmax)
|
|
||||||
{
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// segment S is leaving across this edge
|
|
||||||
if (t < result.tmax)
|
|
||||||
{
|
|
||||||
result.tmax = t;
|
|
||||||
result.segMax = j;
|
|
||||||
// S leaves before entering polygon
|
|
||||||
if (result.tmax < result.tmin)
|
|
||||||
{
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
result.intersects = true;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int OppositeTile(int side)
|
|
||||||
{
|
|
||||||
return (side + 4) & 0x7;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static bool IntersectSegSeg2D(Vector3f ap, Vector3f aq, Vector3f bp, Vector3f bq, out float s, out float t)
|
|
||||||
{
|
|
||||||
s = 0;
|
|
||||||
t = 0;
|
|
||||||
|
|
||||||
Vector3f u = aq.Subtract(ap);
|
|
||||||
Vector3f v = bq.Subtract(bp);
|
|
||||||
Vector3f w = ap.Subtract(bp);
|
|
||||||
float d = Vector3f.PerpXZ(u, v);
|
|
||||||
if (Math.Abs(d) < 1e-6f)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
s = Vector3f.PerpXZ(v, w) / d;
|
|
||||||
t = Vector3f.PerpXZ(u, w) / d;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1161,7 +1161,7 @@ namespace DotRecast.Detour.Crowd
|
||||||
Vector3f[] s = ag.boundary.GetSegment(j);
|
Vector3f[] s = ag.boundary.GetSegment(j);
|
||||||
Vector3f s3 = s[1];
|
Vector3f s3 = s[1];
|
||||||
//Array.Copy(s, 3, s3, 0, 3);
|
//Array.Copy(s, 3, s3, 0, 3);
|
||||||
if (TriArea2D(ag.npos, s[0], s3) < 0.0f)
|
if (DetourCommon.TriArea2D(ag.npos, s[0], s3) < 0.0f)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,7 +120,7 @@ namespace DotRecast.Detour.Crowd
|
||||||
var s3 = Vector3f.Of(s[3], s[4], s[5]);
|
var s3 = Vector3f.Of(s[3], s[4], s[5]);
|
||||||
|
|
||||||
// Skip too distant segments.
|
// Skip too distant segments.
|
||||||
var distSqr = DistancePtSegSqr2D(pos, s0, s3, out var tseg);
|
var distSqr = DetourCommon.DistancePtSegSqr2D(pos, s0, s3, out var tseg);
|
||||||
if (distSqr > Sqr(collisionQueryRange))
|
if (distSqr > Sqr(collisionQueryRange))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -131,7 +131,7 @@ namespace DotRecast.Detour.Crowd
|
||||||
cir.dp.Normalize();
|
cir.dp.Normalize();
|
||||||
dv = cir.dvel.Subtract(dvel);
|
dv = cir.dvel.Subtract(dvel);
|
||||||
|
|
||||||
float a = TriArea2D(orig, cir.dp, dv);
|
float a = DetourCommon.TriArea2D(orig, cir.dp, dv);
|
||||||
if (a < 0.01f)
|
if (a < 0.01f)
|
||||||
{
|
{
|
||||||
cir.np.x = -cir.dp.z;
|
cir.np.x = -cir.dp.z;
|
||||||
|
@ -150,7 +150,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 = DistancePtSegSqr2D(pos, seg.p, seg.q, out var t);
|
var distSqr = DetourCommon.DistancePtSegSqr2D(pos, seg.p, seg.q, out var t);
|
||||||
seg.touch = distSqr < Sqr(r);
|
seg.touch = distSqr < Sqr(r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ namespace DotRecast.Detour.Crowd
|
||||||
int iterCount = config.maxFindPathIterations;
|
int iterCount = config.maxFindPathIterations;
|
||||||
while (iterCount > 0)
|
while (iterCount > 0)
|
||||||
{
|
{
|
||||||
PathQuery? q = queue.First?.Value;
|
PathQuery q = queue.First?.Value;
|
||||||
if (q == null)
|
if (q == null)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -74,7 +74,7 @@ namespace DotRecast.Detour.TileCache
|
||||||
/// Encodes a tile id.
|
/// Encodes a tile id.
|
||||||
private long EncodeTileId(int salt, int it)
|
private long EncodeTileId(int salt, int it)
|
||||||
{
|
{
|
||||||
return ((long)salt << m_tileBits) | it;
|
return ((long)salt << m_tileBits) | (long)it;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Decodes a tile salt.
|
/// Decodes a tile salt.
|
||||||
|
@ -94,7 +94,7 @@ namespace DotRecast.Detour.TileCache
|
||||||
/// Encodes an obstacle id.
|
/// Encodes an obstacle id.
|
||||||
private long EncodeObstacleId(int salt, int it)
|
private long EncodeObstacleId(int salt, int it)
|
||||||
{
|
{
|
||||||
return ((long)salt << 16) | it;
|
return ((long)salt << 16) | (long)it;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Decodes an obstacle salt.
|
/// Decodes an obstacle salt.
|
||||||
|
@ -120,7 +120,7 @@ namespace DotRecast.Detour.TileCache
|
||||||
m_tcomp = tcomp;
|
m_tcomp = tcomp;
|
||||||
m_tmproc = tmprocs;
|
m_tmproc = tmprocs;
|
||||||
|
|
||||||
m_tileLutSize = NextPow2(m_params.maxTiles / 4);
|
m_tileLutSize = DetourCommon.NextPow2(m_params.maxTiles / 4);
|
||||||
if (m_tileLutSize == 0)
|
if (m_tileLutSize == 0)
|
||||||
{
|
{
|
||||||
m_tileLutSize = 1;
|
m_tileLutSize = 1;
|
||||||
|
@ -136,7 +136,7 @@ namespace DotRecast.Detour.TileCache
|
||||||
m_nextFreeTile = m_tiles[i];
|
m_nextFreeTile = m_tiles[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
m_tileBits = Ilog2(NextPow2(m_params.maxTiles));
|
m_tileBits = DetourCommon.Ilog2(DetourCommon.NextPow2(m_params.maxTiles));
|
||||||
m_saltBits = Math.Min(31, 32 - m_tileBits);
|
m_saltBits = Math.Min(31, 32 - m_tileBits);
|
||||||
if (m_saltBits < 10)
|
if (m_saltBits < 10)
|
||||||
{
|
{
|
||||||
|
@ -458,7 +458,7 @@ namespace DotRecast.Detour.TileCache
|
||||||
Vector3f tbmin = new Vector3f();
|
Vector3f tbmin = new Vector3f();
|
||||||
Vector3f tbmax = new Vector3f();
|
Vector3f tbmax = new Vector3f();
|
||||||
CalcTightTileBounds(tile.header, ref tbmin, ref tbmax);
|
CalcTightTileBounds(tile.header, ref tbmin, ref tbmax);
|
||||||
if (OverlapBounds(bmin, bmax, tbmin, tbmax))
|
if (DetourCommon.OverlapBounds(bmin, bmax, tbmin, tbmax))
|
||||||
{
|
{
|
||||||
results.Add(i);
|
results.Add(i);
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,8 +63,8 @@ namespace DotRecast.Detour
|
||||||
Vector3f B = b.Subtract(b1);
|
Vector3f B = b.Subtract(b1);
|
||||||
|
|
||||||
float cross = B.x * A.z - A.x * B.z; // TriArea2D({0, 0}, A, B);
|
float cross = B.x * A.z - A.x * B.z; // TriArea2D({0, 0}, A, B);
|
||||||
float aHB = TriArea2D(b1, b, a);
|
float aHB = DetourCommon.TriArea2D(b1, b, a);
|
||||||
float bHA = TriArea2D(a1, a, b);
|
float bHA = DetourCommon.TriArea2D(a1, a, b);
|
||||||
if (Math.Abs(cross) < EPSILON)
|
if (Math.Abs(cross) < EPSILON)
|
||||||
{
|
{
|
||||||
cross = 0f;
|
cross = 0f;
|
||||||
|
@ -235,7 +235,7 @@ namespace DotRecast.Detour
|
||||||
|
|
||||||
private static Intersection SegSegInt(Vector3f a, Vector3f b, Vector3f c, Vector3f d, ref Vector3f p, ref Vector3f q)
|
private static Intersection SegSegInt(Vector3f a, Vector3f b, Vector3f c, Vector3f d, ref Vector3f p, ref Vector3f q)
|
||||||
{
|
{
|
||||||
if (IntersectSegSeg2D(a, b, c, d, out var s, out var t))
|
if (DetourCommon.IntersectSegSeg2D(a, b, c, d, out var s, out var t))
|
||||||
{
|
{
|
||||||
if (s >= 0.0f && s <= 1.0f && t >= 0.0f && t <= 1.0f)
|
if (s >= 0.0f && s <= 1.0f && t >= 0.0f && t <= 1.0f)
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,10 +3,41 @@ using DotRecast.Core;
|
||||||
|
|
||||||
namespace DotRecast.Detour
|
namespace DotRecast.Detour
|
||||||
{
|
{
|
||||||
public static class DtCommon
|
public static class DetourCommon
|
||||||
{
|
{
|
||||||
private static readonly float EQUAL_THRESHOLD = RcMath.Sqr(1.0f / 16384.0f);
|
private static readonly float EQUAL_THRESHOLD = RcMath.Sqr(1.0f / 16384.0f);
|
||||||
|
|
||||||
|
public static int NextPow2(int v)
|
||||||
|
{
|
||||||
|
v--;
|
||||||
|
v |= v >> 1;
|
||||||
|
v |= v >> 2;
|
||||||
|
v |= v >> 4;
|
||||||
|
v |= v >> 8;
|
||||||
|
v |= v >> 16;
|
||||||
|
v++;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int Ilog2(int v)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
int shift;
|
||||||
|
r = (v > 0xffff ? 1 : 0) << 4;
|
||||||
|
v >>= r;
|
||||||
|
shift = (v > 0xff ? 1 : 0) << 3;
|
||||||
|
v >>= shift;
|
||||||
|
r |= shift;
|
||||||
|
shift = (v > 0xf ? 1 : 0) << 2;
|
||||||
|
v >>= shift;
|
||||||
|
r |= shift;
|
||||||
|
shift = (v > 0x3 ? 1 : 0) << 1;
|
||||||
|
v >>= shift;
|
||||||
|
r |= shift;
|
||||||
|
r |= (v >> 1);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
/// Performs a 'sloppy' colocation check of the specified points.
|
/// Performs a 'sloppy' colocation check of the specified points.
|
||||||
/// @param[in] p0 A point. [(x, y, z)]
|
/// @param[in] p0 A point. [(x, y, z)]
|
||||||
/// @param[in] p1 A point. [(x, y, z)]
|
/// @param[in] p1 A point. [(x, y, z)]
|
||||||
|
@ -311,7 +342,7 @@ namespace DotRecast.Detour
|
||||||
public static IntersectResult IntersectSegmentPoly2D(Vector3f p0, Vector3f p1, float[] verts, int nverts)
|
public static IntersectResult IntersectSegmentPoly2D(Vector3f p0, Vector3f p1, float[] verts, int nverts)
|
||||||
{
|
{
|
||||||
IntersectResult result = new IntersectResult();
|
IntersectResult result = new IntersectResult();
|
||||||
float EPS = 0.000001f;
|
const float EPS = 0.000001f;
|
||||||
var dir = p1.Subtract(p0);
|
var dir = p1.Subtract(p0);
|
||||||
|
|
||||||
var p0v = p0;
|
var p0v = p0;
|
||||||
|
|
|
@ -140,8 +140,8 @@ namespace DotRecast.Detour.Io
|
||||||
|
|
||||||
private long Convert32BitRef(int refs, NavMeshParams option)
|
private long Convert32BitRef(int refs, NavMeshParams option)
|
||||||
{
|
{
|
||||||
int m_tileBits = Ilog2(NextPow2(option.maxTiles));
|
int m_tileBits = DetourCommon.Ilog2(DetourCommon.NextPow2(option.maxTiles));
|
||||||
int m_polyBits = Ilog2(NextPow2(option.maxPolys));
|
int m_polyBits = DetourCommon.Ilog2(DetourCommon.NextPow2(option.maxPolys));
|
||||||
// Only allow 31 salt bits, since the salt mask is calculated using 32bit uint and it will overflow.
|
// Only allow 31 salt bits, since the salt mask is calculated using 32bit uint and it will overflow.
|
||||||
int m_saltBits = Math.Min(31, 32 - m_tileBits - m_polyBits);
|
int m_saltBits = Math.Min(31, 32 - m_tileBits - m_polyBits);
|
||||||
int saltMask = (1 << m_saltBits) - 1;
|
int saltMask = (1 << m_saltBits) - 1;
|
||||||
|
|
|
@ -728,7 +728,7 @@ namespace DotRecast.Detour
|
||||||
{
|
{
|
||||||
// Internal edge
|
// Internal edge
|
||||||
int idx = (bestPoly.neis[j] - 1);
|
int idx = (bestPoly.neis[j] - 1);
|
||||||
long refs = m_nav.GetPolyRefBase(bestTile) | idx;
|
long refs = m_nav.GetPolyRefBase(bestTile) | (long)idx;
|
||||||
if (filter.PassFilter(refs, bestTile, bestTile.data.polys[idx]))
|
if (filter.PassFilter(refs, bestTile, bestTile.data.polys[idx]))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
|
@ -738,7 +738,7 @@ namespace DotRecast.Detour
|
||||||
// Calc distance to the edge.
|
// Calc distance to the edge.
|
||||||
int vj = bestPoly.verts[j] * 3;
|
int vj = bestPoly.verts[j] * 3;
|
||||||
int vi = bestPoly.verts[i] * 3;
|
int vi = bestPoly.verts[i] * 3;
|
||||||
var distSqr = DistancePtSegSqr2D(centerPos, bestTile.data.verts, vj, vi, out var tseg);
|
var distSqr = DetourCommon.DistancePtSegSqr2D(centerPos, bestTile.data.verts, vj, vi, out var tseg);
|
||||||
// Edge is too far, skip.
|
// Edge is too far, skip.
|
||||||
if (distSqr > radiusSqr)
|
if (distSqr > radiusSqr)
|
||||||
{
|
{
|
||||||
|
@ -781,7 +781,7 @@ namespace DotRecast.Detour
|
||||||
// Calc distance to the edge.
|
// Calc distance to the edge.
|
||||||
int va = bestPoly.verts[link.edge] * 3;
|
int va = bestPoly.verts[link.edge] * 3;
|
||||||
int vb = bestPoly.verts[(link.edge + 1) % bestPoly.vertCount] * 3;
|
int vb = bestPoly.verts[(link.edge + 1) % bestPoly.vertCount] * 3;
|
||||||
var distSqr = DistancePtSegSqr2D(centerPos, bestTile.data.verts, va, vb, out var tseg);
|
var distSqr = DetourCommon.DistancePtSegSqr2D(centerPos, bestTile.data.verts, va, vb, out var tseg);
|
||||||
// If the circle is not touching the next polygon, skip it.
|
// If the circle is not touching the next polygon, skip it.
|
||||||
if (distSqr > radiusSqr)
|
if (distSqr > radiusSqr)
|
||||||
{
|
{
|
||||||
|
|
|
@ -116,21 +116,17 @@ namespace DotRecast.Detour
|
||||||
return EncodePolyId(tile.salt, it, 0);
|
return EncodePolyId(tile.salt, it, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// @{
|
||||||
* Derives a standard polygon reference.
|
/// @name Encoding and Decoding
|
||||||
*
|
/// These functions are generally meant for internal use only.
|
||||||
* @note This function is generally meant for internal use only.
|
/// Derives a standard polygon reference.
|
||||||
* @param salt
|
/// @note This function is generally meant for internal use only.
|
||||||
* The tile's salt value.
|
/// @param[in] salt The tile's salt value.
|
||||||
* @param it
|
/// @param[in] it The index of the tile.
|
||||||
* The index of the tile.
|
/// @param[in] ip The index of the polygon within the tile.
|
||||||
* @param ip
|
|
||||||
* The index of the polygon within the tile.
|
|
||||||
* @return encoded polygon reference
|
|
||||||
*/
|
|
||||||
public static long EncodePolyId(int salt, int it, int ip)
|
public static long EncodePolyId(int salt, int it, int ip)
|
||||||
{
|
{
|
||||||
return (((long)salt) << (DT_POLY_BITS + DT_TILE_BITS)) | ((long)it << DT_POLY_BITS) | ip;
|
return (((long)salt) << (DT_POLY_BITS + DT_TILE_BITS)) | ((long)it << DT_POLY_BITS) | (long)ip;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Decodes a standard polygon reference.
|
/// Decodes a standard polygon reference.
|
||||||
|
@ -299,7 +295,7 @@ namespace DotRecast.Detour
|
||||||
// Init tiles
|
// Init tiles
|
||||||
m_maxTiles = option.maxTiles;
|
m_maxTiles = option.maxTiles;
|
||||||
m_maxVertPerPoly = maxVertsPerPoly;
|
m_maxVertPerPoly = maxVertsPerPoly;
|
||||||
m_tileLutMask = Math.Max(1, NextPow2(option.maxTiles)) - 1;
|
m_tileLutMask = Math.Max(1, DetourCommon.NextPow2(option.maxTiles)) - 1;
|
||||||
m_tiles = new MeshTile[m_maxTiles];
|
m_tiles = new MeshTile[m_maxTiles];
|
||||||
for (int i = 0; i < m_maxTiles; i++)
|
for (int i = 0; i < m_maxTiles; i++)
|
||||||
{
|
{
|
||||||
|
@ -356,12 +352,12 @@ namespace DotRecast.Detour
|
||||||
while (nodeIndex < end)
|
while (nodeIndex < end)
|
||||||
{
|
{
|
||||||
BVNode node = tile.data.bvTree[nodeIndex];
|
BVNode node = tile.data.bvTree[nodeIndex];
|
||||||
bool overlap = OverlapQuantBounds(bmin, bmax, node.bmin, node.bmax);
|
bool overlap = DetourCommon.OverlapQuantBounds(bmin, bmax, node.bmin, node.bmax);
|
||||||
bool isLeafNode = node.i >= 0;
|
bool isLeafNode = node.i >= 0;
|
||||||
|
|
||||||
if (isLeafNode && overlap)
|
if (isLeafNode && overlap)
|
||||||
{
|
{
|
||||||
polys.Add(@base | node.i);
|
polys.Add(@base | (long)node.i);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (overlap || isLeafNode)
|
if (overlap || isLeafNode)
|
||||||
|
@ -402,9 +398,9 @@ namespace DotRecast.Detour
|
||||||
bmax.Max(tile.data.verts, v);
|
bmax.Max(tile.data.verts, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (OverlapBounds(qmin, qmax, bmin, bmax))
|
if (DetourCommon.OverlapBounds(qmin, qmax, bmin, bmax))
|
||||||
{
|
{
|
||||||
polys.Add(@base | i);
|
polys.Add(@base | (long)i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -539,9 +535,9 @@ namespace DotRecast.Detour
|
||||||
for (int j = 0; j < neis.Count; ++j)
|
for (int j = 0; j < neis.Count; ++j)
|
||||||
{
|
{
|
||||||
ConnectExtLinks(tile, neis[j], i);
|
ConnectExtLinks(tile, neis[j], i);
|
||||||
ConnectExtLinks(neis[j], tile, OppositeTile(i));
|
ConnectExtLinks(neis[j], tile, DetourCommon.OppositeTile(i));
|
||||||
ConnectExtOffMeshLinks(tile, neis[j], i);
|
ConnectExtOffMeshLinks(tile, neis[j], i);
|
||||||
ConnectExtOffMeshLinks(neis[j], tile, OppositeTile(i));
|
ConnectExtOffMeshLinks(neis[j], tile, DetourCommon.OppositeTile(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -657,7 +653,7 @@ namespace DotRecast.Detour
|
||||||
|
|
||||||
int idx = AllocLink(tile);
|
int idx = AllocLink(tile);
|
||||||
Link link = tile.links[idx];
|
Link link = tile.links[idx];
|
||||||
link.refs = @base | (poly.neis[j] - 1);
|
link.refs = @base | (long)(poly.neis[j] - 1);
|
||||||
link.edge = j;
|
link.edge = j;
|
||||||
link.side = 0xff;
|
link.side = 0xff;
|
||||||
link.bmin = link.bmax = 0;
|
link.bmin = link.bmax = 0;
|
||||||
|
@ -743,7 +739,7 @@ namespace DotRecast.Detour
|
||||||
// Create new links
|
// Create new links
|
||||||
int va = poly.verts[j] * 3;
|
int va = poly.verts[j] * 3;
|
||||||
int vb = poly.verts[(j + 1) % nv] * 3;
|
int vb = poly.verts[(j + 1) % nv] * 3;
|
||||||
IList<Tuple<long, float, float>> connectedPolys = FindConnectingPolys(tile.data.verts, va, vb, target, OppositeTile(dir));
|
IList<Tuple<long, float, float>> connectedPolys = FindConnectingPolys(tile.data.verts, va, vb, target, DetourCommon.OppositeTile(dir));
|
||||||
foreach (Tuple<long, float, float> connectedPoly in connectedPolys)
|
foreach (Tuple<long, float, float> connectedPoly in connectedPolys)
|
||||||
{
|
{
|
||||||
int idx = AllocLink(tile);
|
int idx = AllocLink(tile);
|
||||||
|
@ -802,7 +798,7 @@ namespace DotRecast.Detour
|
||||||
|
|
||||||
// Connect off-mesh links.
|
// Connect off-mesh links.
|
||||||
// We are interested on links which land from target tile to this tile.
|
// We are interested on links which land from target tile to this tile.
|
||||||
int oppositeSide = (side == -1) ? 0xff : OppositeTile(side);
|
int oppositeSide = (side == -1) ? 0xff : DetourCommon.OppositeTile(side);
|
||||||
|
|
||||||
for (int i = 0; i < target.data.header.offMeshConCount; ++i)
|
for (int i = 0; i < target.data.header.offMeshConCount; ++i)
|
||||||
{
|
{
|
||||||
|
@ -871,7 +867,7 @@ namespace DotRecast.Detour
|
||||||
int landPolyIdx = DecodePolyIdPoly(refs);
|
int landPolyIdx = DecodePolyIdPoly(refs);
|
||||||
Poly landPoly = tile.data.polys[landPolyIdx];
|
Poly landPoly = tile.data.polys[landPolyIdx];
|
||||||
link = tile.links[tidx];
|
link = tile.links[tidx];
|
||||||
link.refs = GetPolyRefBase(target) | (targetCon.poly);
|
link.refs = GetPolyRefBase(target) | (long)targetCon.poly;
|
||||||
link.edge = 0xff;
|
link.edge = 0xff;
|
||||||
link.side = (side == -1 ? 0xff : side);
|
link.side = (side == -1 ? 0xff : side);
|
||||||
link.bmin = link.bmax = 0;
|
link.bmin = link.bmax = 0;
|
||||||
|
@ -931,7 +927,7 @@ namespace DotRecast.Detour
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add return value.
|
// Add return value.
|
||||||
long refs = @base | i;
|
long refs = @base | (long)i;
|
||||||
float tmin = Math.Max(amin.x, bmin.x);
|
float tmin = Math.Max(amin.x, bmin.x);
|
||||||
float tmax = Math.Min(amax.x, bmax.x);
|
float tmax = Math.Min(amax.x, bmax.x);
|
||||||
result.Add(Tuple.Create(refs, tmin, tmax));
|
result.Add(Tuple.Create(refs, tmin, tmax));
|
||||||
|
@ -1099,7 +1095,7 @@ namespace DotRecast.Detour
|
||||||
int landPolyIdx = DecodePolyIdPoly(refs);
|
int landPolyIdx = DecodePolyIdPoly(refs);
|
||||||
Poly landPoly = tile.data.polys[landPolyIdx];
|
Poly landPoly = tile.data.polys[landPolyIdx];
|
||||||
link = tile.links[tidx];
|
link = tile.links[tidx];
|
||||||
link.refs = @base | (con.poly);
|
link.refs = @base | (long)con.poly;
|
||||||
link.edge = 0xff;
|
link.edge = 0xff;
|
||||||
link.side = 0xff;
|
link.side = 0xff;
|
||||||
link.bmin = link.bmax = 0;
|
link.bmin = link.bmax = 0;
|
||||||
|
@ -1173,7 +1169,7 @@ namespace DotRecast.Detour
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var d = DistancePtSegSqr2D(pos, v[j], v[k], out var t);
|
var d = DetourCommon.DistancePtSegSqr2D(pos, v[j], v[k], out var t);
|
||||||
if (d < dmin)
|
if (d < dmin)
|
||||||
{
|
{
|
||||||
dmin = d;
|
dmin = d;
|
||||||
|
@ -1197,7 +1193,7 @@ namespace DotRecast.Detour
|
||||||
v[1].y = tile.data.verts[poly.verts[k] * 3 + 1];
|
v[1].y = tile.data.verts[poly.verts[k] * 3 + 1];
|
||||||
v[1].z = tile.data.verts[poly.verts[k] * 3 + 2];
|
v[1].z = tile.data.verts[poly.verts[k] * 3 + 2];
|
||||||
|
|
||||||
var d = DistancePtSegSqr2D(pos, v[0], v[1], out var t);
|
var d = DetourCommon.DistancePtSegSqr2D(pos, v[0], v[1], out var t);
|
||||||
if (d < dmin)
|
if (d < dmin)
|
||||||
{
|
{
|
||||||
dmin = d;
|
dmin = d;
|
||||||
|
@ -1229,7 +1225,7 @@ namespace DotRecast.Detour
|
||||||
Array.Copy(tile.data.verts, poly.verts[i] * 3, verts, i * 3, 3);
|
Array.Copy(tile.data.verts, poly.verts[i] * 3, verts, i * 3, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!PointInPolygon(pos, verts, nv))
|
if (!DetourCommon.PointInPolygon(pos, verts, nv))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -1266,7 +1262,7 @@ namespace DotRecast.Detour
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float? h = ClosestHeightPointTriangle(pos, v[0], v[1], v[2]);
|
float? h = DetourCommon.ClosestHeightPointTriangle(pos, v[0], v[1], v[2]);
|
||||||
if (null != h)
|
if (null != h)
|
||||||
{
|
{
|
||||||
return h;
|
return h;
|
||||||
|
@ -1288,7 +1284,7 @@ namespace DotRecast.Detour
|
||||||
v[k + 1].z = tile.data.verts[poly.verts[j + k] * 3 + 2];
|
v[k + 1].z = tile.data.verts[poly.verts[j + k] * 3 + 2];
|
||||||
}
|
}
|
||||||
|
|
||||||
float? h = ClosestHeightPointTriangle(pos, v[0], v[1], v[2]);
|
float? h = DetourCommon.ClosestHeightPointTriangle(pos, v[0], v[1], v[2]);
|
||||||
if (null != h)
|
if (null != h)
|
||||||
{
|
{
|
||||||
return h;
|
return h;
|
||||||
|
@ -1325,7 +1321,7 @@ namespace DotRecast.Detour
|
||||||
var v0 = new Vector3f { x = tile.data.verts[i], y = tile.data.verts[i + 1], z = tile.data.verts[i + 2] };
|
var v0 = new Vector3f { x = tile.data.verts[i], y = tile.data.verts[i + 1], z = tile.data.verts[i + 2] };
|
||||||
i = poly.verts[1] * 3;
|
i = poly.verts[1] * 3;
|
||||||
var v1 = new Vector3f { x = tile.data.verts[i], y = tile.data.verts[i + 1], z = tile.data.verts[i + 2] };
|
var v1 = new Vector3f { x = tile.data.verts[i], y = tile.data.verts[i + 1], z = tile.data.verts[i + 2] };
|
||||||
var distSqr = DistancePtSegSqr2D(pos, v0, v1, out var t);
|
var distSqr = DetourCommon.DistancePtSegSqr2D(pos, v0, v1, out var t);
|
||||||
return new ClosestPointOnPolyResult(false, Vector3f.Lerp(v0, v1, t));
|
return new ClosestPointOnPolyResult(false, Vector3f.Lerp(v0, v1, t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -131,7 +131,7 @@ namespace DotRecast.Detour
|
||||||
}
|
}
|
||||||
|
|
||||||
// Must pass filter
|
// Must pass filter
|
||||||
long refs = @base | i;
|
long refs = @base | (long)i;
|
||||||
if (!filter.PassFilter(refs, tile, p))
|
if (!filter.PassFilter(refs, tile, p))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
|
@ -144,7 +144,7 @@ namespace DotRecast.Detour
|
||||||
int va = p.verts[0] * 3;
|
int va = p.verts[0] * 3;
|
||||||
int vb = p.verts[j - 1] * 3;
|
int vb = p.verts[j - 1] * 3;
|
||||||
int vc = p.verts[j] * 3;
|
int vc = p.verts[j] * 3;
|
||||||
polyArea += TriArea2D(tile.data.verts, va, vb, vc);
|
polyArea += DetourCommon.TriArea2D(tile.data.verts, va, vb, vc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Choose random polygon weighted by area, using reservoi sampling.
|
// Choose random polygon weighted by area, using reservoi sampling.
|
||||||
|
@ -174,7 +174,7 @@ namespace DotRecast.Detour
|
||||||
float s = frand.Next();
|
float s = frand.Next();
|
||||||
float t = frand.Next();
|
float t = frand.Next();
|
||||||
|
|
||||||
var pt = RandomPointInConvexPoly(verts, poly.vertCount, areas, s, t);
|
var pt = DetourCommon.RandomPointInConvexPoly(verts, poly.vertCount, areas, s, t);
|
||||||
ClosestPointOnPolyResult closest = ClosestPointOnPoly(polyRef, pt).result;
|
ClosestPointOnPolyResult closest = ClosestPointOnPoly(polyRef, pt).result;
|
||||||
return Results.Success(new FindRandomPointResult(polyRef, closest.GetClosest()));
|
return Results.Success(new FindRandomPointResult(polyRef, closest.GetClosest()));
|
||||||
}
|
}
|
||||||
|
@ -291,7 +291,7 @@ namespace DotRecast.Detour
|
||||||
int va = 0;
|
int va = 0;
|
||||||
int vb = (j - 1) * 3;
|
int vb = (j - 1) * 3;
|
||||||
int vc = j * 3;
|
int vc = j * 3;
|
||||||
polyArea += TriArea2D(constrainedVerts, va, vb, vc);
|
polyArea += DetourCommon.TriArea2D(constrainedVerts, va, vb, vc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Choose random polygon weighted by area, using reservoi sampling.
|
// Choose random polygon weighted by area, using reservoi sampling.
|
||||||
|
@ -346,7 +346,7 @@ namespace DotRecast.Detour
|
||||||
var vb = portalpoints.result.right;
|
var vb = portalpoints.result.right;
|
||||||
|
|
||||||
// If the circle is not touching the next polygon, skip it.
|
// If the circle is not touching the next polygon, skip it.
|
||||||
var distSqr = DistancePtSegSqr2D(centerPos, va, vb, out var tesg);
|
var distSqr = DetourCommon.DistancePtSegSqr2D(centerPos, va, vb, out var tesg);
|
||||||
if (distSqr > radiusSqr)
|
if (distSqr > radiusSqr)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
|
@ -400,7 +400,7 @@ namespace DotRecast.Detour
|
||||||
float t = frand.Next();
|
float t = frand.Next();
|
||||||
|
|
||||||
float[] areas = new float[randomPolyVerts.Length / 3];
|
float[] areas = new float[randomPolyVerts.Length / 3];
|
||||||
Vector3f pt = RandomPointInConvexPoly(randomPolyVerts, randomPolyVerts.Length / 3, areas, s, t);
|
Vector3f pt = DetourCommon.RandomPointInConvexPoly(randomPolyVerts, randomPolyVerts.Length / 3, areas, s, t);
|
||||||
ClosestPointOnPolyResult closest = ClosestPointOnPoly(randomPolyRef, pt).result;
|
ClosestPointOnPolyResult closest = ClosestPointOnPoly(randomPolyRef, pt).result;
|
||||||
return Results.Success(new FindRandomPointResult(randomPolyRef, closest.GetClosest()));
|
return Results.Success(new FindRandomPointResult(randomPolyRef, closest.GetClosest()));
|
||||||
}
|
}
|
||||||
|
@ -478,7 +478,7 @@ namespace DotRecast.Detour
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3f closest;
|
Vector3f closest;
|
||||||
if (DistancePtPolyEdgesSqr(pos, verts, nv, edged, edget))
|
if (DetourCommon.DistancePtPolyEdgesSqr(pos, verts, nv, edged, edget))
|
||||||
{
|
{
|
||||||
closest = pos;
|
closest = pos;
|
||||||
}
|
}
|
||||||
|
@ -539,7 +539,7 @@ namespace DotRecast.Detour
|
||||||
var v0 = new Vector3f { x = tile.data.verts[i], y = tile.data.verts[i + 1], z = tile.data.verts[i + 2] };
|
var v0 = new Vector3f { x = tile.data.verts[i], y = tile.data.verts[i + 1], z = tile.data.verts[i + 2] };
|
||||||
i = poly.verts[1] * 3;
|
i = poly.verts[1] * 3;
|
||||||
var v1 = new Vector3f { x = tile.data.verts[i], y = tile.data.verts[i + 1], z = tile.data.verts[i + 2] };
|
var v1 = new Vector3f { x = tile.data.verts[i], y = tile.data.verts[i + 1], z = tile.data.verts[i + 2] };
|
||||||
var distSqr = DistancePtSegSqr2D(pos, v0, v1, out var tseg);
|
var distSqr = DetourCommon.DistancePtSegSqr2D(pos, v0, v1, out var tseg);
|
||||||
return Results.Success(v0.y + (v1.y - v0.y) * tseg);
|
return Results.Success(v0.y + (v1.y - v0.y) * tseg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -605,12 +605,12 @@ namespace DotRecast.Detour
|
||||||
while (nodeIndex < end)
|
while (nodeIndex < end)
|
||||||
{
|
{
|
||||||
BVNode node = tile.data.bvTree[nodeIndex];
|
BVNode node = tile.data.bvTree[nodeIndex];
|
||||||
bool overlap = OverlapQuantBounds(bmin, bmax, node.bmin, node.bmax);
|
bool overlap = DetourCommon.OverlapQuantBounds(bmin, bmax, node.bmin, node.bmax);
|
||||||
bool isLeafNode = node.i >= 0;
|
bool isLeafNode = node.i >= 0;
|
||||||
|
|
||||||
if (isLeafNode && overlap)
|
if (isLeafNode && overlap)
|
||||||
{
|
{
|
||||||
long refs = @base | node.i;
|
long refs = @base | (long)node.i;
|
||||||
if (filter.PassFilter(refs, tile, tile.data.polys[node.i]))
|
if (filter.PassFilter(refs, tile, tile.data.polys[node.i]))
|
||||||
{
|
{
|
||||||
query.Process(tile, tile.data.polys[node.i], refs);
|
query.Process(tile, tile.data.polys[node.i], refs);
|
||||||
|
@ -642,7 +642,7 @@ namespace DotRecast.Detour
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
long refs = @base | i;
|
long refs = @base | (long)i;
|
||||||
if (!filter.PassFilter(refs, tile, p))
|
if (!filter.PassFilter(refs, tile, p))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
|
@ -659,7 +659,7 @@ namespace DotRecast.Detour
|
||||||
bmax.Max(tile.data.verts, v);
|
bmax.Max(tile.data.verts, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (OverlapBounds(qmin, qmax, bmin, bmax))
|
if (DetourCommon.OverlapBounds(qmin, qmax, bmin, bmax))
|
||||||
{
|
{
|
||||||
query.Process(tile, p, refs);
|
query.Process(tile, p, refs);
|
||||||
}
|
}
|
||||||
|
@ -712,7 +712,7 @@ namespace DotRecast.Detour
|
||||||
Vector3f bmax = center.Add(halfExtents);
|
Vector3f bmax = center.Add(halfExtents);
|
||||||
m_nav.CalcTileLoc(bmin, out var minx, out var miny);
|
m_nav.CalcTileLoc(bmin, out var minx, out var miny);
|
||||||
m_nav.CalcTileLoc(bmax, out var maxx, out var maxy);
|
m_nav.CalcTileLoc(bmax, out var maxx, out var maxy);
|
||||||
|
|
||||||
List<MeshTile> tiles = new List<MeshTile>();
|
List<MeshTile> tiles = new List<MeshTile>();
|
||||||
for (int y = miny; y <= maxy; ++y)
|
for (int y = miny; y <= maxy; ++y)
|
||||||
{
|
{
|
||||||
|
@ -1424,7 +1424,7 @@ namespace DotRecast.Detour
|
||||||
protected Status AppendVertex(Vector3f pos, int flags, long refs, List<StraightPathItem> straightPath,
|
protected Status AppendVertex(Vector3f pos, int flags, long refs, List<StraightPathItem> straightPath,
|
||||||
int maxStraightPath)
|
int maxStraightPath)
|
||||||
{
|
{
|
||||||
if (straightPath.Count > 0 && VEqual(straightPath[straightPath.Count - 1].pos, pos))
|
if (straightPath.Count > 0 && DetourCommon.VEqual(straightPath[straightPath.Count - 1].pos, pos))
|
||||||
{
|
{
|
||||||
// The vertices are equal, update flags and poly.
|
// The vertices are equal, update flags and poly.
|
||||||
straightPath[straightPath.Count - 1].flags = flags;
|
straightPath[straightPath.Count - 1].flags = flags;
|
||||||
|
@ -1496,7 +1496,7 @@ namespace DotRecast.Detour
|
||||||
}
|
}
|
||||||
|
|
||||||
// Append intersection
|
// Append intersection
|
||||||
if (IntersectSegSeg2D(startPos, endPos, left, right, out var _, out var t))
|
if (DetourCommon.IntersectSegSeg2D(startPos, endPos, left, right, out var _, out var t))
|
||||||
{
|
{
|
||||||
var pt = Vector3f.Lerp(left, right, t);
|
var pt = Vector3f.Lerp(left, right, t);
|
||||||
stat = AppendVertex(pt, 0, path[i + 1], straightPath, maxStraightPath);
|
stat = AppendVertex(pt, 0, path[i + 1], straightPath, maxStraightPath);
|
||||||
|
@ -1620,7 +1620,7 @@ namespace DotRecast.Detour
|
||||||
// If starting really close the portal, advance.
|
// If starting really close the portal, advance.
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
{
|
{
|
||||||
var distSqr = DistancePtSegSqr2D(portalApex, left, right, out var t);
|
var distSqr = DetourCommon.DistancePtSegSqr2D(portalApex, left, right, out var t);
|
||||||
if (distSqr < Sqr(0.001f))
|
if (distSqr < Sqr(0.001f))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
|
@ -1636,9 +1636,9 @@ namespace DotRecast.Detour
|
||||||
}
|
}
|
||||||
|
|
||||||
// Right vertex.
|
// Right vertex.
|
||||||
if (TriArea2D(portalApex, portalRight, right) <= 0.0f)
|
if (DetourCommon.TriArea2D(portalApex, portalRight, right) <= 0.0f)
|
||||||
{
|
{
|
||||||
if (VEqual(portalApex, portalRight) || TriArea2D(portalApex, portalLeft, right) > 0.0f)
|
if (DetourCommon.VEqual(portalApex, portalRight) || DetourCommon.TriArea2D(portalApex, portalLeft, right) > 0.0f)
|
||||||
{
|
{
|
||||||
portalRight = right;
|
portalRight = right;
|
||||||
rightPolyRef = (i + 1 < path.Count) ? path[i + 1] : 0;
|
rightPolyRef = (i + 1 < path.Count) ? path[i + 1] : 0;
|
||||||
|
@ -1693,9 +1693,9 @@ namespace DotRecast.Detour
|
||||||
}
|
}
|
||||||
|
|
||||||
// Left vertex.
|
// Left vertex.
|
||||||
if (TriArea2D(portalApex, portalLeft, left) >= 0.0f)
|
if (DetourCommon.TriArea2D(portalApex, portalLeft, left) >= 0.0f)
|
||||||
{
|
{
|
||||||
if (VEqual(portalApex, portalLeft) || TriArea2D(portalApex, portalRight, left) < 0.0f)
|
if (DetourCommon.VEqual(portalApex, portalLeft) || DetourCommon.TriArea2D(portalApex, portalRight, left) < 0.0f)
|
||||||
{
|
{
|
||||||
portalLeft = left;
|
portalLeft = left;
|
||||||
leftPolyRef = (i + 1 < path.Count) ? path[i + 1] : 0;
|
leftPolyRef = (i + 1 < path.Count) ? path[i + 1] : 0;
|
||||||
|
@ -1845,7 +1845,7 @@ namespace DotRecast.Detour
|
||||||
}
|
}
|
||||||
|
|
||||||
// If target is inside the poly, stop search.
|
// If target is inside the poly, stop search.
|
||||||
if (PointInPolygon(endPos, verts, nverts))
|
if (DetourCommon.PointInPolygon(endPos, verts, nverts))
|
||||||
{
|
{
|
||||||
bestNode = curNode;
|
bestNode = curNode;
|
||||||
bestPos = endPos;
|
bestPos = endPos;
|
||||||
|
@ -1887,7 +1887,7 @@ namespace DotRecast.Detour
|
||||||
else if (curPoly.neis[j] != 0)
|
else if (curPoly.neis[j] != 0)
|
||||||
{
|
{
|
||||||
int idx = curPoly.neis[j] - 1;
|
int idx = curPoly.neis[j] - 1;
|
||||||
long refs = m_nav.GetPolyRefBase(curTile) | idx;
|
long refs = m_nav.GetPolyRefBase(curTile) | (long)idx;
|
||||||
if (filter.PassFilter(refs, curTile, curTile.data.polys[idx]))
|
if (filter.PassFilter(refs, curTile, curTile.data.polys[idx]))
|
||||||
{
|
{
|
||||||
// Internal edge, encode id.
|
// Internal edge, encode id.
|
||||||
|
@ -1900,7 +1900,7 @@ namespace DotRecast.Detour
|
||||||
// Wall edge, calc distance.
|
// Wall edge, calc distance.
|
||||||
int vj = j * 3;
|
int vj = j * 3;
|
||||||
int vi = i * 3;
|
int vi = i * 3;
|
||||||
var distSqr = DistancePtSegSqr2D(endPos, verts, vj, vi, out var tseg);
|
var distSqr = DetourCommon.DistancePtSegSqr2D(endPos, verts, vj, vi, out var tseg);
|
||||||
if (distSqr < bestDist)
|
if (distSqr < bestDist)
|
||||||
{
|
{
|
||||||
// Update nearest distance.
|
// Update nearest distance.
|
||||||
|
@ -1924,7 +1924,7 @@ namespace DotRecast.Detour
|
||||||
// TODO: Maybe should use GetPortalPoints(), but this one is way faster.
|
// TODO: Maybe should use GetPortalPoints(), but this one is way faster.
|
||||||
int vj = j * 3;
|
int vj = j * 3;
|
||||||
int vi = i * 3;
|
int vi = i * 3;
|
||||||
var distSqr = DistancePtSegSqr2D(searchPos, verts, vj, vi, out var _);
|
var distSqr = DetourCommon.DistancePtSegSqr2D(searchPos, verts, vj, vi, out var _);
|
||||||
if (distSqr > searchRadSqr)
|
if (distSqr > searchRadSqr)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
|
@ -2118,7 +2118,7 @@ namespace DotRecast.Detour
|
||||||
Vector3f left = ppoints.result.left;
|
Vector3f left = ppoints.result.left;
|
||||||
Vector3f right = ppoints.result.right;
|
Vector3f right = ppoints.result.right;
|
||||||
float t = 0.5f;
|
float t = 0.5f;
|
||||||
if (IntersectSegSeg2D(fromPos, toPos, left, right, out var _, out var t2))
|
if (DetourCommon.IntersectSegSeg2D(fromPos, toPos, left, right, out var _, out var t2))
|
||||||
{
|
{
|
||||||
t = Clamp(t2, 0.1f, 0.9f);
|
t = Clamp(t2, 0.1f, 0.9f);
|
||||||
}
|
}
|
||||||
|
@ -2230,7 +2230,7 @@ namespace DotRecast.Detour
|
||||||
nv++;
|
nv++;
|
||||||
}
|
}
|
||||||
|
|
||||||
IntersectResult iresult = IntersectSegmentPoly2D(startPos, endPos, verts, nv);
|
IntersectResult iresult = DetourCommon.IntersectSegmentPoly2D(startPos, endPos, verts, nv);
|
||||||
if (!iresult.intersects)
|
if (!iresult.intersects)
|
||||||
{
|
{
|
||||||
// Could not hit the polygon, keep the old t and report hit.
|
// Could not hit the polygon, keep the old t and report hit.
|
||||||
|
@ -2543,7 +2543,7 @@ namespace DotRecast.Detour
|
||||||
var vb = pp.result.right;
|
var vb = pp.result.right;
|
||||||
|
|
||||||
// If the circle is not touching the next polygon, skip it.
|
// If the circle is not touching the next polygon, skip it.
|
||||||
var distSqr = DistancePtSegSqr2D(centerPos, va, vb, out var _);
|
var distSqr = DetourCommon.DistancePtSegSqr2D(centerPos, va, vb, out var _);
|
||||||
if (distSqr > radiusSqr)
|
if (distSqr > radiusSqr)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
|
@ -2730,7 +2730,7 @@ namespace DotRecast.Detour
|
||||||
var vb = pp.result.right;
|
var vb = pp.result.right;
|
||||||
|
|
||||||
// If the poly is not touching the edge to the next polygon, skip the connection it.
|
// If the poly is not touching the edge to the next polygon, skip the connection it.
|
||||||
IntersectResult ir = IntersectSegmentPoly2D(va, vb, verts, nverts);
|
IntersectResult ir = DetourCommon.IntersectSegmentPoly2D(va, vb, verts, nverts);
|
||||||
if (!ir.intersects)
|
if (!ir.intersects)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
|
@ -2906,7 +2906,7 @@ namespace DotRecast.Detour
|
||||||
var vb = pp.result.right;
|
var vb = pp.result.right;
|
||||||
|
|
||||||
// If the circle is not touching the next polygon, skip it.
|
// If the circle is not touching the next polygon, skip it.
|
||||||
var distSqr = DistancePtSegSqr2D(centerPos, va, vb, out var _);
|
var distSqr = DetourCommon.DistancePtSegSqr2D(centerPos, va, vb, out var _);
|
||||||
if (distSqr > radiusSqr)
|
if (distSqr > radiusSqr)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
|
@ -2959,7 +2959,7 @@ namespace DotRecast.Detour
|
||||||
Array.Copy(pastTile.data.verts, pastPoly.verts[k] * 3, pb, k * 3, 3);
|
Array.Copy(pastTile.data.verts, pastPoly.verts[k] * 3, pb, k * 3, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (OverlapPolyPoly2D(pa, npa, pb, npb))
|
if (DetourCommon.OverlapPolyPoly2D(pa, npa, pb, npb))
|
||||||
{
|
{
|
||||||
overlap = true;
|
overlap = true;
|
||||||
break;
|
break;
|
||||||
|
@ -3071,7 +3071,7 @@ namespace DotRecast.Detour
|
||||||
if (poly.neis[j] != 0)
|
if (poly.neis[j] != 0)
|
||||||
{
|
{
|
||||||
int idx = (poly.neis[j] - 1);
|
int idx = (poly.neis[j] - 1);
|
||||||
neiRef = m_nav.GetPolyRefBase(tile) | idx;
|
neiRef = m_nav.GetPolyRefBase(tile) | (long)idx;
|
||||||
if (!filter.PassFilter(neiRef, tile, tile.data.polys[idx]))
|
if (!filter.PassFilter(neiRef, tile, tile.data.polys[idx]))
|
||||||
{
|
{
|
||||||
neiRef = 0;
|
neiRef = 0;
|
||||||
|
@ -3239,7 +3239,7 @@ namespace DotRecast.Detour
|
||||||
{
|
{
|
||||||
// Internal edge
|
// Internal edge
|
||||||
int idx = (bestPoly.neis[j] - 1);
|
int idx = (bestPoly.neis[j] - 1);
|
||||||
long refs = m_nav.GetPolyRefBase(bestTile) | idx;
|
long refs = m_nav.GetPolyRefBase(bestTile) | (long)idx;
|
||||||
if (filter.PassFilter(refs, bestTile, bestTile.data.polys[idx]))
|
if (filter.PassFilter(refs, bestTile, bestTile.data.polys[idx]))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
|
@ -3249,7 +3249,7 @@ namespace DotRecast.Detour
|
||||||
// Calc distance to the edge.
|
// Calc distance to the edge.
|
||||||
int vj = bestPoly.verts[j] * 3;
|
int vj = bestPoly.verts[j] * 3;
|
||||||
int vi = bestPoly.verts[i] * 3;
|
int vi = bestPoly.verts[i] * 3;
|
||||||
var distSqr = DistancePtSegSqr2D(centerPos, bestTile.data.verts, vj, vi, out var tseg);
|
var distSqr = DetourCommon.DistancePtSegSqr2D(centerPos, bestTile.data.verts, vj, vi, out var tseg);
|
||||||
|
|
||||||
// Edge is too far, skip.
|
// Edge is too far, skip.
|
||||||
if (distSqr > radiusSqr)
|
if (distSqr > radiusSqr)
|
||||||
|
@ -3293,7 +3293,7 @@ namespace DotRecast.Detour
|
||||||
// Calc distance to the edge.
|
// Calc distance to the edge.
|
||||||
int va = bestPoly.verts[link.edge] * 3;
|
int va = bestPoly.verts[link.edge] * 3;
|
||||||
int vb = bestPoly.verts[(link.edge + 1) % bestPoly.vertCount] * 3;
|
int vb = bestPoly.verts[(link.edge + 1) % bestPoly.vertCount] * 3;
|
||||||
var distSqr = DistancePtSegSqr2D(centerPos, bestTile.data.verts, va, vb, out var tseg);
|
var distSqr = DetourCommon.DistancePtSegSqr2D(centerPos, bestTile.data.verts, va, vb, out var tseg);
|
||||||
// If the circle is not touching the next polygon, skip it.
|
// If the circle is not touching the next polygon, skip it.
|
||||||
if (distSqr > radiusSqr)
|
if (distSqr > radiusSqr)
|
||||||
{
|
{
|
||||||
|
|
|
@ -34,7 +34,7 @@ namespace DotRecast.Detour
|
||||||
|
|
||||||
float[] qCircle = Circle(center, radius);
|
float[] qCircle = Circle(center, radius);
|
||||||
float[] intersection = ConvexConvexIntersection.Intersect(verts, qCircle);
|
float[] intersection = ConvexConvexIntersection.Intersect(verts, qCircle);
|
||||||
if (intersection == null && PointInPolygon(center, verts, verts.Length / 3))
|
if (intersection == null && DetourCommon.PointInPolygon(center, verts, verts.Length / 3))
|
||||||
{
|
{
|
||||||
// circle inside polygon
|
// circle inside polygon
|
||||||
return qCircle;
|
return qCircle;
|
||||||
|
|
|
@ -100,7 +100,7 @@ public class TileNavMeshBuilder : AbstractNavMeshBuilder
|
||||||
Recast.CalcGridSize(geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax(), cellSize, out var gw, out var gh);
|
Recast.CalcGridSize(geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax(), cellSize, out var gw, out var gh);
|
||||||
int tw = (gw + tileSize - 1) / tileSize;
|
int tw = (gw + tileSize - 1) / tileSize;
|
||||||
int th = (gh + tileSize - 1) / tileSize;
|
int th = (gh + tileSize - 1) / tileSize;
|
||||||
int tileBits = Math.Min(Ilog2(NextPow2(tw * th)), 14);
|
int tileBits = Math.Min(DetourCommon.Ilog2(DetourCommon.NextPow2(tw * th)), 14);
|
||||||
return tileBits;
|
return tileBits;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -394,7 +394,7 @@ public class DebugDraw
|
||||||
|
|
||||||
void AppendArrowHead(Vector3f p, Vector3f q, float s, int col)
|
void AppendArrowHead(Vector3f p, Vector3f q, float s, int col)
|
||||||
{
|
{
|
||||||
float eps = 0.001f;
|
const float eps = 0.001f;
|
||||||
if (VdistSqr(p, q) < eps * eps)
|
if (VdistSqr(p, q) < eps * eps)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -291,8 +291,7 @@ public class NavMeshRenderer
|
||||||
debugDraw.Begin(DebugDrawPrimitives.POINTS, 3.0f);
|
debugDraw.Begin(DebugDrawPrimitives.POINTS, 3.0f);
|
||||||
foreach (ConvexVolume vol in geom.ConvexVolumes())
|
foreach (ConvexVolume vol in geom.ConvexVolumes())
|
||||||
{
|
{
|
||||||
int col = DebugDraw
|
int col = DebugDraw.DuDarkenCol(DebugDraw.DuTransCol(DebugDraw.AreaToCol(vol.areaMod.GetMaskedValue()), 220));
|
||||||
.DuDarkenCol(DebugDraw.DuTransCol(DebugDraw.AreaToCol(vol.areaMod.GetMaskedValue()), 220));
|
|
||||||
for (int j = 0; j < vol.verts.Length; j += 3)
|
for (int j = 0; j < vol.verts.Length; j += 3)
|
||||||
{
|
{
|
||||||
debugDraw.Vertex(vol.verts[j + 0], vol.verts[j + 1] + 0.1f, vol.verts[j + 2], col);
|
debugDraw.Vertex(vol.verts[j + 0], vol.verts[j + 1] + 0.1f, vol.verts[j + 2], col);
|
||||||
|
|
|
@ -132,7 +132,7 @@ public class RecastDebugDraw : DebugDraw
|
||||||
}
|
}
|
||||||
|
|
||||||
int col;
|
int col;
|
||||||
if (query != null && query.IsInClosedList(@base | i))
|
if (query != null && query.IsInClosedList(@base | (long)i))
|
||||||
{
|
{
|
||||||
col = DuRGBA(255, 196, 0, 64);
|
col = DuRGBA(255, 196, 0, 64);
|
||||||
}
|
}
|
||||||
|
@ -179,7 +179,7 @@ public class RecastDebugDraw : DebugDraw
|
||||||
}
|
}
|
||||||
|
|
||||||
int col, col2;
|
int col, col2;
|
||||||
if (query != null && query.IsInClosedList(@base | i))
|
if (query != null && query.IsInClosedList(@base | (long)i))
|
||||||
{
|
{
|
||||||
col = DuRGBA(255, 196, 0, 220);
|
col = DuRGBA(255, 196, 0, 220);
|
||||||
}
|
}
|
||||||
|
@ -1269,7 +1269,7 @@ public class RecastDebugDraw : DebugDraw
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
DebugDrawNavMeshPoly(mesh, @base | j, col);
|
DebugDrawNavMeshPoly(mesh, @base | (long)j, col);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,8 +77,8 @@ public class DemoInputGeomProvider : IInputGeomProvider
|
||||||
Vector3f.Copy(ref bmax, vertices, 0);
|
Vector3f.Copy(ref bmax, vertices, 0);
|
||||||
for (int i = 1; i < vertices.Length / 3; i++)
|
for (int i = 1; i < vertices.Length / 3; i++)
|
||||||
{
|
{
|
||||||
bmin.Min(vertices, i * 3);
|
bmin.Min(vertices, i * 3);
|
||||||
bmax.Max(vertices, i * 3);
|
bmax.Max(vertices, i * 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
_mesh = new TriMesh(vertices, faces);
|
_mesh = new TriMesh(vertices, faces);
|
||||||
|
@ -152,15 +152,13 @@ public class DemoInputGeomProvider : IInputGeomProvider
|
||||||
public float? RaycastMesh(Vector3f src, Vector3f dst)
|
public float? RaycastMesh(Vector3f src, Vector3f dst)
|
||||||
{
|
{
|
||||||
// Prune hit ray.
|
// Prune hit ray.
|
||||||
float[] btminmax = Intersections.IntersectSegmentAABB(src, dst, bmin, bmax);
|
if (!Intersections.IsectSegAABB(src, dst, bmin, bmax, out var btmin, out var btmax))
|
||||||
if (null == btminmax)
|
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
float btmin = btminmax[0];
|
float[] p = new float[2];
|
||||||
float btmax = btminmax[1];
|
float[] q = new float[2];
|
||||||
float[] p = new float[2], q = new float[2];
|
|
||||||
p[0] = src.x + (dst.x - src.x) * btmin;
|
p[0] = src.x + (dst.x - src.x) * btmin;
|
||||||
p[1] = src.z + (dst.z - src.z) * btmin;
|
p[1] = src.z + (dst.z - src.z) * btmin;
|
||||||
q[0] = src.x + (dst.x - src.x) * btmax;
|
q[0] = src.x + (dst.x - src.x) * btmax;
|
||||||
|
@ -185,12 +183,12 @@ public class DemoInputGeomProvider : IInputGeomProvider
|
||||||
vertices[tris[j] * 3 + 2]
|
vertices[tris[j] * 3 + 2]
|
||||||
);
|
);
|
||||||
Vector3f v2 = Vector3f.Of(
|
Vector3f v2 = Vector3f.Of(
|
||||||
vertices[tris[j + 1] * 3],
|
vertices[tris[j + 1] * 3],
|
||||||
vertices[tris[j + 1] * 3 + 1],
|
vertices[tris[j + 1] * 3 + 1],
|
||||||
vertices[tris[j + 1] * 3 + 2]
|
vertices[tris[j + 1] * 3 + 2]
|
||||||
);
|
);
|
||||||
Vector3f v3 = Vector3f.Of(
|
Vector3f v3 = Vector3f.Of(
|
||||||
vertices[tris[j + 2] * 3],
|
vertices[tris[j + 2] * 3],
|
||||||
vertices[tris[j + 2] * 3 + 1],
|
vertices[tris[j + 2] * 3 + 1],
|
||||||
vertices[tris[j + 2] * 3 + 2]
|
vertices[tris[j + 2] * 3 + 2]
|
||||||
);
|
);
|
||||||
|
@ -225,4 +223,4 @@ public class DemoInputGeomProvider : IInputGeomProvider
|
||||||
{
|
{
|
||||||
_convexVolumes.Clear();
|
_convexVolumes.Clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -236,10 +236,8 @@ public class CrowdTool : Tool
|
||||||
Vector3f bmin = new Vector3f();
|
Vector3f bmin = new Vector3f();
|
||||||
Vector3f bmax = new Vector3f();
|
Vector3f bmax = new Vector3f();
|
||||||
GetAgentBounds(ag, ref bmin, ref bmax);
|
GetAgentBounds(ag, ref bmin, ref bmax);
|
||||||
float[] isect = Intersections.IntersectSegmentAABB(s, p, bmin, bmax);
|
if (Intersections.IsectSegAABB(s, p, bmin, bmax, out var tmin, out var tmax))
|
||||||
if (null != isect)
|
|
||||||
{
|
{
|
||||||
float tmin = isect[0];
|
|
||||||
if (tmin > 0 && tmin < tsel)
|
if (tmin > 0 && tmin < tsel)
|
||||||
{
|
{
|
||||||
isel = ag;
|
isel = ag;
|
||||||
|
@ -486,7 +484,7 @@ public class CrowdTool : Tool
|
||||||
Vector3f[] s = ag.boundary.GetSegment(j);
|
Vector3f[] s = ag.boundary.GetSegment(j);
|
||||||
Vector3f s0 = s[0];
|
Vector3f s0 = s[0];
|
||||||
Vector3f s3 = s[1];
|
Vector3f s3 = s[1];
|
||||||
if (TriArea2D(pos, s0, s3) < 0.0f)
|
if (DetourCommon.TriArea2D(pos, s0, s3) < 0.0f)
|
||||||
col = DuDarkenCol(col);
|
col = DuDarkenCol(col);
|
||||||
|
|
||||||
dd.AppendArrow(s[0].x, s[0].y + 0.2f, s[0].z, s[1].x, s[1].z + 0.2f, s[1].z, 0.0f, 0.3f, col);
|
dd.AppendArrow(s[0].x, s[0].y + 0.2f, s[0].z, s[1].x, s[1].z + 0.2f, s[1].z, 0.0f, 0.3f, col);
|
||||||
|
|
|
@ -850,7 +850,7 @@ public class TestNavmeshTool : Tool
|
||||||
var v0 = Vector3f.Of(s[0], s[1], s[2]);
|
var v0 = Vector3f.Of(s[0], s[1], s[2]);
|
||||||
var s3 = Vector3f.Of(s[3], s[4], s[5]);
|
var s3 = Vector3f.Of(s[3], s[4], s[5]);
|
||||||
// Skip too distant segments.
|
// Skip too distant segments.
|
||||||
var distSqr = DistancePtSegSqr2D(m_spos, v0, s3, out var tseg);
|
var distSqr = DetourCommon.DistancePtSegSqr2D(m_spos, v0, s3, out var tseg);
|
||||||
if (distSqr > RcMath.Sqr(m_neighbourhoodRadius))
|
if (distSqr > RcMath.Sqr(m_neighbourhoodRadius))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
|
@ -871,7 +871,7 @@ public class TestNavmeshTool : Tool
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int col = DuRGBA(192, 32, 16, 192);
|
int col = DuRGBA(192, 32, 16, 192);
|
||||||
if (TriArea2D(m_spos, s.vmin, s3) < 0.0f)
|
if (DetourCommon.TriArea2D(m_spos, s.vmin, s3) < 0.0f)
|
||||||
{
|
{
|
||||||
col = DuRGBA(96, 32, 16, 192);
|
col = DuRGBA(96, 32, 16, 192);
|
||||||
}
|
}
|
||||||
|
|
|
@ -156,7 +156,7 @@ namespace DotRecast.Recast
|
||||||
|
|
||||||
private static bool CircumCircle(float[] verts, int p1, int p2, int p3, ref Vector3f c, RcAtomicFloat r)
|
private static bool CircumCircle(float[] verts, int p1, int p2, int p3, ref Vector3f c, RcAtomicFloat r)
|
||||||
{
|
{
|
||||||
float EPS = 1e-6f;
|
const float EPS = 1e-6f;
|
||||||
// Calculate the circle relative to p1, to avoid some precision issues.
|
// Calculate the circle relative to p1, to avoid some precision issues.
|
||||||
Vector3f v1 = new Vector3f();
|
Vector3f v1 = new Vector3f();
|
||||||
Vector3f v2 = new Vector3f();
|
Vector3f v2 = new Vector3f();
|
||||||
|
@ -204,7 +204,7 @@ namespace DotRecast.Recast
|
||||||
float v = (dot00 * dot12 - dot01 * dot02) * invDenom;
|
float v = (dot00 * dot12 - dot01 * dot02) * invDenom;
|
||||||
|
|
||||||
// If point lies inside the triangle, return interpolated y-coord.
|
// If point lies inside the triangle, return interpolated y-coord.
|
||||||
float EPS = 1e-4f;
|
const float EPS = 1e-4f;
|
||||||
if (u >= -EPS && v >= -EPS && (u + v) <= 1 + EPS)
|
if (u >= -EPS && v >= -EPS && (u + v) <= 1 + EPS)
|
||||||
{
|
{
|
||||||
float y = verts[a + 1] + v0.y * u + v1.y * v;
|
float y = verts[a + 1] + v0.y * u + v1.y * v;
|
||||||
|
@ -512,7 +512,7 @@ namespace DotRecast.Recast
|
||||||
|
|
||||||
static int CompleteFacet(Telemetry ctx, float[] pts, int npts, List<int> edges, int maxEdges, int nfaces, int e)
|
static int CompleteFacet(Telemetry ctx, float[] pts, int npts, List<int> edges, int maxEdges, int nfaces, int e)
|
||||||
{
|
{
|
||||||
float EPS = 1e-5f;
|
const float EPS = 1e-5f;
|
||||||
|
|
||||||
int edge = e * 4;
|
int edge = e * 4;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue