MMaps Updates, Needs tested.
Port From (https://github.com/TrinityCore/TrinityCore)
This commit is contained in:
@@ -66,7 +66,7 @@ namespace Framework.Constants
|
|||||||
public const uint MapLiquidMagic = 0x51494C4D; //"MLIQ";
|
public const uint MapLiquidMagic = 0x51494C4D; //"MLIQ";
|
||||||
|
|
||||||
public const uint mmapMagic = 0x4D4D4150; // 'MMAP'
|
public const uint mmapMagic = 0x4D4D4150; // 'MMAP'
|
||||||
public const int mmapVersion = 10;
|
public const int mmapVersion = 11;
|
||||||
|
|
||||||
public const string VMapMagic = "VMAP_4.A";
|
public const string VMapMagic = "VMAP_4.A";
|
||||||
public const float VMAPInvalidHeightValue = -200000.0f;
|
public const float VMAPInvalidHeightValue = -200000.0f;
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ namespace Framework.GameMath
|
|||||||
|
|
||||||
for (int i = 0; i < 3; ++i)
|
for (int i = 0; i < 3; ++i)
|
||||||
{
|
{
|
||||||
if (!float.IsInfinity(_edgeVector[i].Length()))
|
if (!float.IsFinite(_edgeVector[i].Length()))
|
||||||
{
|
{
|
||||||
finiteExtent = false;
|
finiteExtent = false;
|
||||||
// If the extent is infinite along an axis, make the center zero to avoid NaNs
|
// If the extent is infinite along an axis, make the center zero to avoid NaNs
|
||||||
@@ -95,7 +95,7 @@ namespace Framework.GameMath
|
|||||||
|
|
||||||
public bool isFinite()
|
public bool isFinite()
|
||||||
{
|
{
|
||||||
return float.IsInfinity(_volume);
|
return float.IsFinite(_volume);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -211,6 +211,8 @@ public static partial class Detour
|
|||||||
/// @param[out] h The resulting height.
|
/// @param[out] h The resulting height.
|
||||||
public static bool dtClosestHeightPointTriangle(float[] p, int pStart, float[] a, int aStart, float[] b, int bStart, float[] c, int cStart, ref float h)
|
public static bool dtClosestHeightPointTriangle(float[] p, int pStart, float[] a, int aStart, float[] b, int bStart, float[] c, int cStart, ref float h)
|
||||||
{
|
{
|
||||||
|
const float EPS = 1e-6f;
|
||||||
|
|
||||||
float[] v0 = new float[3];
|
float[] v0 = new float[3];
|
||||||
float[] v1 = new float[3];
|
float[] v1 = new float[3];
|
||||||
float[] v2 = new float[3];
|
float[] v2 = new float[3];
|
||||||
@@ -218,25 +220,24 @@ public static partial class Detour
|
|||||||
dtVsub(v1, 0, b, bStart, a, aStart);
|
dtVsub(v1, 0, b, bStart, a, aStart);
|
||||||
dtVsub(v2, 0, p, pStart, a, aStart);
|
dtVsub(v2, 0, p, pStart, a, aStart);
|
||||||
|
|
||||||
float dot00 = dtVdot2D(v0, v0);
|
// Compute scaled barycentric coordinates
|
||||||
float dot01 = dtVdot2D(v0, v1);
|
float denom = v0[0] * v1[2] - v0[2] * v1[0];
|
||||||
float dot02 = dtVdot2D(v0, v2);
|
if (MathF.Abs(denom) < EPS)
|
||||||
float dot11 = dtVdot2D(v1, v1);
|
return false;
|
||||||
float dot12 = dtVdot2D(v1, v2);
|
|
||||||
|
|
||||||
// Compute barycentric coordinates
|
float u = v1[2] * v2[0] - v1[0] * v2[2];
|
||||||
float invDenom = 1.0f / (dot00 * dot11 - dot01 * dot01);
|
float v = v0[0] * v2[2] - v0[2] * v2[0];
|
||||||
float u = (dot11 * dot02 - dot01 * dot12) * invDenom;
|
|
||||||
float v = (dot00 * dot12 - dot01 * dot02) * invDenom;
|
|
||||||
|
|
||||||
// The (sloppy) epsilon is needed to allow to get height of points which
|
if (denom < 0)
|
||||||
// are interpolated along the edges of the triangles.
|
|
||||||
const float EPS = 1e-4f;
|
|
||||||
|
|
||||||
// If point lies inside the triangle, return interpolated ycoord.
|
|
||||||
if (u >= -EPS && v >= -EPS && (u + v) <= 1 + EPS)
|
|
||||||
{
|
{
|
||||||
h = a[aStart + 1] + v0[1] * u + v1[1] * v;
|
denom = -denom;
|
||||||
|
u = -u;
|
||||||
|
v = -v;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (u >= 0.0f && v >= 0.0f && (u + v) <= denom)
|
||||||
|
{
|
||||||
|
h = a[1] + (v0[1] * u + v1[1] * v) / denom;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -779,6 +780,30 @@ public static partial class Detour
|
|||||||
float d = dtVdistSqr(p0, p0Start, p1, p1Start);
|
float d = dtVdistSqr(p0, p0Start, p1, p1Start);
|
||||||
return d < thr;
|
return d < thr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Checks that the specified vector's components are all finite.
|
||||||
|
/// @param[in] v A point. [(x, y, z)]
|
||||||
|
/// @return True if all of the point's components are finite, i.e. not NaN
|
||||||
|
/// or any of the infinities.
|
||||||
|
public static bool dtVisfinite(float[] v)
|
||||||
|
{
|
||||||
|
|
||||||
|
bool result =
|
||||||
|
float.IsFinite(v[0]) &&
|
||||||
|
float.IsFinite(v[1]) &&
|
||||||
|
float.IsFinite(v[2]);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Checks that the specified vector's 2D components are finite.
|
||||||
|
/// @param[in] v A point. [(x, y, z)]
|
||||||
|
public static bool dtVisfinite2D(float[] v)
|
||||||
|
{
|
||||||
|
bool result = float.IsFinite(v[0]) && float.IsFinite(v[2]);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/// Derives the dot product of two vectors on the xz-plane. (@p u . @p v)
|
/// Derives the dot product of two vectors on the xz-plane. (@p u . @p v)
|
||||||
/// @param[in] u A vector [(x, y, z)]
|
/// @param[in] u A vector [(x, y, z)]
|
||||||
/// @param[in] v A vector [(x, y, z)]
|
/// @param[in] v A vector [(x, y, z)]
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
/**
|
/**
|
||||||
@typedef dtPolyRef
|
@typedef dtPolyRef
|
||||||
@par
|
@par
|
||||||
@@ -725,68 +726,84 @@ public static partial class Detour
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void closestPointOnPoly(dtPolyRef polyRef, float[] pos, int posStart, float[] closest, ref bool posOverPoly)
|
void closestPointOnDetailEdges(bool onlyBoundary, dtMeshTile tile, dtPoly poly, float[] pos, float[] closest)
|
||||||
{
|
{
|
||||||
dtMeshTile tile = null;
|
uint ip = (uint)tile.polys.ToList().IndexOf(poly);
|
||||||
dtPoly poly = null;
|
dtPolyDetail pd = tile.detailMeshes[ip];
|
||||||
uint ip = 0;
|
|
||||||
getTileAndPolyByRefUnsafe(polyRef, ref tile, ref poly, ref ip);
|
float dmin = float.MaxValue;
|
||||||
|
float tmin = 0;
|
||||||
// Off-mesh connections don't have detail polygons.
|
int pmin = 0;
|
||||||
if (poly.getType() == (byte)dtPolyTypes.DT_POLYTYPE_OFFMESH_CONNECTION)
|
int pmax = 0;
|
||||||
{
|
float[] v = new float[0];
|
||||||
//const float* v0 = &tile.verts[poly.verts[0]*3];
|
|
||||||
//const float* v1 = &tile.verts[poly.verts[1]*3];
|
for (int i = 0; i < pd.triCount; i++)
|
||||||
int v0Start = poly.verts[0] * 3;
|
{
|
||||||
int v1Start = poly.verts[1] * 3;
|
int trisIndex = (int)((pd.triBase + i) * 4);
|
||||||
float d0 = dtVdist(pos, posStart, tile.verts, v0Start);
|
const int ANY_BOUNDARY_EDGE =
|
||||||
float d1 = dtVdist(pos, posStart, tile.verts, v1Start);
|
((int)dtDetailTriEdgeFlags.DT_DETAIL_EDGE_BOUNDARY << 0) |
|
||||||
float u = d0 / (d0 + d1);
|
((int)dtDetailTriEdgeFlags.DT_DETAIL_EDGE_BOUNDARY << 2) |
|
||||||
dtVlerp(closest, 0, tile.verts, v0Start, tile.verts, v1Start, u);
|
((int)dtDetailTriEdgeFlags.DT_DETAIL_EDGE_BOUNDARY << 4);
|
||||||
|
if (onlyBoundary && (tile.detailTris[trisIndex + 3] & ANY_BOUNDARY_EDGE) == 0)
|
||||||
posOverPoly = false;
|
continue;
|
||||||
return;
|
|
||||||
}
|
v = new float[3];
|
||||||
|
for (int j = 0; j < 3; ++j)
|
||||||
//uint ip = (uint)(poly - tile.polys);
|
{
|
||||||
|
if (tile.detailTris[trisIndex + j] < poly.vertCount)
|
||||||
|
v[j] = tile.verts[poly.verts[tile.detailTris[trisIndex + j]] * 3];
|
||||||
|
else
|
||||||
|
v[j] = tile.detailVerts[(pd.vertBase + (tile.detailTris[trisIndex + j] - poly.vertCount)) * 3];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int k = 0, j = 2; k < 3; j = k++)
|
||||||
|
{
|
||||||
|
if ((dtGetDetailTriEdgeFlags(tile.detailTris[trisIndex + 3], j) & (int)dtDetailTriEdgeFlags.DT_DETAIL_EDGE_BOUNDARY) == 0 &&
|
||||||
|
(onlyBoundary || tile.detailTris[trisIndex + j] < tile.detailTris[trisIndex + k]))
|
||||||
|
{
|
||||||
|
// Only looking at boundary edges and this is internal, or
|
||||||
|
// this is an inner edge that we will see again or have already seen.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
float t = 0;
|
||||||
|
float d = dtDistancePtSegSqr2D(pos, 0, v, j, v, k, ref t);
|
||||||
|
if (d < dmin)
|
||||||
|
{
|
||||||
|
dmin = d;
|
||||||
|
tmin = t;
|
||||||
|
pmin = j;
|
||||||
|
pmax = k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dtVlerp(closest, 0, v, pmin, v, pmax, tmin);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool getPolyHeight(dtMeshTile tile, dtPoly poly, float[] pos, float height)
|
||||||
|
{
|
||||||
|
// Off-mesh connections do not have detail polys and getting height
|
||||||
|
// over them does not make sense.
|
||||||
|
if (poly.getType() == (byte)dtPolyTypes.DT_POLYTYPE_OFFMESH_CONNECTION)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
uint ip = (uint)tile.polys.ToList().IndexOf(poly);
|
||||||
dtPolyDetail pd = tile.detailMeshes[ip];
|
dtPolyDetail pd = tile.detailMeshes[ip];
|
||||||
|
|
||||||
// Clamp point to be inside the polygon.
|
|
||||||
float[] verts = new float[DT_VERTS_PER_POLYGON * 3];
|
float[] verts = new float[DT_VERTS_PER_POLYGON * 3];
|
||||||
float[] edged = new float[DT_VERTS_PER_POLYGON];
|
|
||||||
float[] edget = new float[DT_VERTS_PER_POLYGON];
|
|
||||||
int nv = poly.vertCount;
|
int nv = poly.vertCount;
|
||||||
for (int i = 0; i < nv; ++i)
|
for (int i = 0; i < nv; ++i)
|
||||||
{
|
{
|
||||||
dtVcopy(verts, i * 3, tile.verts, poly.verts[i] * 3);
|
dtVcopy(verts, i * 3, tile.verts, poly.verts[i] * 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
dtVcopy(closest, 0, pos, posStart);
|
if (!dtPointInPolygon(pos, verts, nv))
|
||||||
if (!dtDistancePtPolyEdgesSqr(pos, posStart, verts, nv, edged, edget))
|
return false;
|
||||||
{
|
|
||||||
// Point is outside the polygon, dtClamp to nearest edge.
|
|
||||||
float dmin = float.MaxValue;
|
|
||||||
int imin = -1;
|
|
||||||
for (int i = 0; i < nv; ++i)
|
|
||||||
{
|
|
||||||
if (edged[i] < dmin)
|
|
||||||
{
|
|
||||||
dmin = edged[i];
|
|
||||||
imin = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//float[] va = &verts[imin*3];
|
|
||||||
//const float* vb = &verts[((imin+1)%nv)*3];
|
|
||||||
int vaStart = imin * 3;
|
|
||||||
int vbStart = ((imin + 1) % nv) * 3;
|
|
||||||
dtVlerp(closest, 0, verts, vaStart, verts, vbStart, edget[imin]);
|
|
||||||
|
|
||||||
posOverPoly = false;
|
if (height == 0)
|
||||||
}
|
return true;
|
||||||
else
|
|
||||||
{
|
|
||||||
posOverPoly = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find height at the location.
|
// Find height at the location.
|
||||||
for (int j = 0; j < pd.triCount; ++j)
|
for (int j = 0; j < pd.triCount; ++j)
|
||||||
@@ -812,12 +829,54 @@ public static partial class Detour
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
float h = .0f;
|
float h = .0f;
|
||||||
if (dtClosestHeightPointTriangle(closest, posStart, vArrays[0], vIndices[0], vArrays[1], vIndices[1], vArrays[2], vIndices[2], ref h))
|
if (dtClosestHeightPointTriangle(pos, 0, vArrays[0], vIndices[0], vArrays[1], vIndices[1], vArrays[2], vIndices[2], ref h))
|
||||||
{
|
{
|
||||||
closest[1] = h;
|
height = h;
|
||||||
break;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If all triangle checks failed above (can happen with degenerate triangles
|
||||||
|
// or larger floating point values) the point is on an edge, so just select
|
||||||
|
// closest. This should almost never happen so the extra iteration here is
|
||||||
|
// ok.
|
||||||
|
float[] closest = new float[3];
|
||||||
|
closestPointOnDetailEdges(false, tile, poly, pos, closest);
|
||||||
|
height = closest[1];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void closestPointOnPoly(dtPolyRef polyRef, float[] pos, float[] closest, ref bool posOverPoly)
|
||||||
|
{
|
||||||
|
|
||||||
|
dtMeshTile tile = new();
|
||||||
|
dtPoly poly = new();
|
||||||
|
getTileAndPolyByRefUnsafe(polyRef, ref tile, ref poly);
|
||||||
|
|
||||||
|
dtVcopy(closest, pos);
|
||||||
|
if (getPolyHeight(tile, poly, pos, closest[1]))
|
||||||
|
{
|
||||||
|
if (posOverPoly)
|
||||||
|
posOverPoly = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (posOverPoly)
|
||||||
|
posOverPoly = false;
|
||||||
|
|
||||||
|
// Off-mesh connections don't have detail polygons.
|
||||||
|
if (poly.getType() == (byte)dtPolyTypes.DT_POLYTYPE_OFFMESH_CONNECTION)
|
||||||
|
{
|
||||||
|
int v0 = poly.verts[0] * 3;
|
||||||
|
int v1 = poly.verts[1] * 3;
|
||||||
|
float t = 0;
|
||||||
|
dtDistancePtSegSqr2D(pos, 0, tile.verts, v0, tile.verts, v1, ref t);
|
||||||
|
dtVlerp(closest, 0, tile.verts, v0, tile.verts, v1, t);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Outside poly that is not an offmesh connection.
|
||||||
|
closestPointOnDetailEdges(true, tile, poly, pos, closest);
|
||||||
}
|
}
|
||||||
|
|
||||||
public dtPolyRef findNearestPolyInTile(dtMeshTile tile, float[] center, int centerStart, float[] halfExtents, float[] nearestPt)
|
public dtPolyRef findNearestPolyInTile(dtMeshTile tile, float[] center, int centerStart, float[] halfExtents, float[] nearestPt)
|
||||||
@@ -841,7 +900,7 @@ public static partial class Detour
|
|||||||
float[] diff = new float[3];
|
float[] diff = new float[3];
|
||||||
bool posOverPoly = false;
|
bool posOverPoly = false;
|
||||||
float d = 0;
|
float d = 0;
|
||||||
closestPointOnPoly(polyRef, center, centerStart, closestPtPoly, ref posOverPoly);
|
closestPointOnPoly(polyRef, center, closestPtPoly, ref posOverPoly);
|
||||||
|
|
||||||
// If a point is directly over a polygon and closer than
|
// If a point is directly over a polygon and closer than
|
||||||
// climb height, favor that instead of straight line nearest point.
|
// climb height, favor that instead of straight line nearest point.
|
||||||
@@ -996,7 +1055,7 @@ public static partial class Detour
|
|||||||
|
|
||||||
// Make sure the location is free.
|
// Make sure the location is free.
|
||||||
if (getTileAt(header.x, header.y, header.layer) != null)
|
if (getTileAt(header.x, header.y, header.layer) != null)
|
||||||
return DT_FAILURE;
|
return DT_FAILURE | DT_ALREADY_OCCUPIED;
|
||||||
|
|
||||||
// Allocate a tile.
|
// Allocate a tile.
|
||||||
dtMeshTile tile = null;
|
dtMeshTile tile = null;
|
||||||
|
|||||||
@@ -80,6 +80,11 @@ public static partial class Detour
|
|||||||
DT_RAYCAST_USE_COSTS = 0x01, ///< Raycast should calculate movement cost along the ray and fill RaycastHit::cost
|
DT_RAYCAST_USE_COSTS = 0x01, ///< Raycast should calculate movement cost along the ray and fill RaycastHit::cost
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum dtDetailTriEdgeFlags
|
||||||
|
{
|
||||||
|
DT_DETAIL_EDGE_BOUNDARY = 0x01, ///< Detail triangle edge is part of the poly boundary
|
||||||
|
};
|
||||||
|
|
||||||
/// Flags representing the type of a navigation mesh polygon.
|
/// Flags representing the type of a navigation mesh polygon.
|
||||||
public enum dtPolyTypes
|
public enum dtPolyTypes
|
||||||
{
|
{
|
||||||
@@ -616,7 +621,8 @@ public static partial class Detour
|
|||||||
/// The detail mesh's unique vertices. [(x, y, z) * dtMeshHeader::detailVertCount]
|
/// The detail mesh's unique vertices. [(x, y, z) * dtMeshHeader::detailVertCount]
|
||||||
public float[] detailVerts;
|
public float[] detailVerts;
|
||||||
|
|
||||||
/// The detail mesh's triangles. [(vertA, vertB, vertC) * dtMeshHeader::detailTriCount]
|
/// The detail mesh's triangles. [(vertA, vertB, vertC, triFlags) * dtMeshHeader::detailTriCount].
|
||||||
|
/// See dtDetailTriEdgeFlags and dtGetDetailTriEdgeFlags.
|
||||||
public byte[] detailTris;
|
public byte[] detailTris;
|
||||||
|
|
||||||
/// The tile bounding volume nodes. [Size: dtMeshHeader::bvNodeCount]
|
/// The tile bounding volume nodes. [Size: dtMeshHeader::bvNodeCount]
|
||||||
@@ -631,6 +637,15 @@ public static partial class Detour
|
|||||||
public dtMeshTile next; //< The next free tile, or the next tile in the spatial grid.
|
public dtMeshTile next; //< The next free tile, or the next tile in the spatial grid.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Get flags for edge in detail triangle.
|
||||||
|
/// @param triFlags[in] The flags for the triangle (last component of detail vertices above).
|
||||||
|
/// @param edgeIndex[in] The index of the first vertex of the edge. For instance, if 0,
|
||||||
|
/// returns flags for edge AB.
|
||||||
|
public static int dtGetDetailTriEdgeFlags(byte triFlags, int edgeIndex)
|
||||||
|
{
|
||||||
|
return (triFlags >> (edgeIndex * 2)) & 0x3;
|
||||||
|
}
|
||||||
|
|
||||||
/// Configuration parameters used to define multi-tile navigation meshes.
|
/// Configuration parameters used to define multi-tile navigation meshes.
|
||||||
/// The values are used to allocate space during the initialization of a navigation mesh.
|
/// The values are used to allocate space during the initialization of a navigation mesh.
|
||||||
// @see dtNavMesh::init()
|
// @see dtNavMesh::init()
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ using System;
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using dtPolyRef = System.UInt64;
|
using dtPolyRef = System.UInt64;
|
||||||
using dtStatus = System.UInt32;
|
using dtStatus = System.UInt32;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
// Define DT_VIRTUAL_QUERYFILTER if you wish to derive a custom filter from dtQueryFilter.
|
// Define DT_VIRTUAL_QUERYFILTER if you wish to derive a custom filter from dtQueryFilter.
|
||||||
// On certain platforms indirect or virtual function call is expensive. The default
|
// On certain platforms indirect or virtual function call is expensive. The default
|
||||||
@@ -310,6 +311,9 @@ public static partial class Detour
|
|||||||
{
|
{
|
||||||
Debug.Assert(m_nav != null);
|
Debug.Assert(m_nav != null);
|
||||||
|
|
||||||
|
if (filter == null || frand == null || randomPt == null)
|
||||||
|
return DT_FAILURE | DT_INVALID_PARAM;
|
||||||
|
|
||||||
// Randomly pick one tile. Assume that all tiles cover roughly the same area.
|
// Randomly pick one tile. Assume that all tiles cover roughly the same area.
|
||||||
dtMeshTile tile = null;
|
dtMeshTile tile = null;
|
||||||
float tsum = 0.0f;
|
float tsum = 0.0f;
|
||||||
@@ -409,14 +413,17 @@ public static partial class Detour
|
|||||||
/// @param[out] randomRef The reference id of the random location.
|
/// @param[out] randomRef The reference id of the random location.
|
||||||
/// @param[out] randomPt The random location. [(x, y, z)]
|
/// @param[out] randomPt The random location. [(x, y, z)]
|
||||||
// @returns The status flags for the query.
|
// @returns The status flags for the query.
|
||||||
public dtStatus findRandomPointAroundCircle(dtPolyRef startRef, float[] centerPos, float radius, dtQueryFilter filter, randomFloatGenerator frand, ref dtPolyRef randomRef, ref float[] randomPt)
|
public dtStatus findRandomPointAroundCircle(dtPolyRef startRef, float[] centerPos, float maxRadius, dtQueryFilter filter, randomFloatGenerator frand, ref dtPolyRef randomRef, ref float[] randomPt)
|
||||||
{
|
{
|
||||||
Debug.Assert(m_nav != null);
|
Debug.Assert(m_nav != null);
|
||||||
Debug.Assert(m_nodePool != null);
|
Debug.Assert(m_nodePool != null);
|
||||||
Debug.Assert(m_openList != null);
|
Debug.Assert(m_openList != null);
|
||||||
|
|
||||||
// Validate input
|
// Validate input
|
||||||
if (startRef == 0 || !m_nav.isValidPolyRef(startRef))
|
if (!m_nav.isValidPolyRef(startRef) ||
|
||||||
|
centerPos == null || !dtVisfinite(centerPos) ||
|
||||||
|
maxRadius < 0 || !float.IsFinite(maxRadius) ||
|
||||||
|
filter == null || frand == null || randomPt == null)
|
||||||
return DT_FAILURE | DT_INVALID_PARAM;
|
return DT_FAILURE | DT_INVALID_PARAM;
|
||||||
|
|
||||||
dtMeshTile startTile = null;
|
dtMeshTile startTile = null;
|
||||||
@@ -439,7 +446,7 @@ public static partial class Detour
|
|||||||
|
|
||||||
dtStatus status = DT_SUCCESS;
|
dtStatus status = DT_SUCCESS;
|
||||||
|
|
||||||
float radiusSqr = dtSqr(radius);
|
float radiusSqr = dtSqr(maxRadius);
|
||||||
float areaSum = 0.0f;
|
float areaSum = 0.0f;
|
||||||
|
|
||||||
dtMeshTile randomTile = null;
|
dtMeshTile randomTile = null;
|
||||||
@@ -617,104 +624,13 @@ public static partial class Detour
|
|||||||
public dtStatus closestPointOnPoly(dtPolyRef polyRef, float[] pos, float[] closest, ref bool posOverPoly)
|
public dtStatus closestPointOnPoly(dtPolyRef polyRef, float[] pos, float[] closest, ref bool posOverPoly)
|
||||||
{
|
{
|
||||||
Debug.Assert(m_nav != null);
|
Debug.Assert(m_nav != null);
|
||||||
dtMeshTile tile = null;
|
|
||||||
dtPoly poly = null;
|
if (!m_nav.isValidPolyRef(polyRef) ||
|
||||||
uint ip = 0;
|
pos == null || !dtVisfinite(pos) ||
|
||||||
if (dtStatusFailed(m_nav.getTileAndPolyByRef(polyRef, ref tile, ref poly, ref ip)))
|
closest == null)
|
||||||
return DT_FAILURE | DT_INVALID_PARAM;
|
|
||||||
if (tile == null)
|
|
||||||
return DT_FAILURE | DT_INVALID_PARAM;
|
return DT_FAILURE | DT_INVALID_PARAM;
|
||||||
|
|
||||||
// Off-mesh connections don't have detail polygons.
|
m_nav.closestPointOnPoly(polyRef, pos, closest, ref posOverPoly);
|
||||||
if (poly.getType() == (byte)dtPolyTypes.DT_POLYTYPE_OFFMESH_CONNECTION)
|
|
||||||
{
|
|
||||||
//const float* v0 = &tile.verts[poly.verts[0]*3];
|
|
||||||
//const float* v1 = &tile.verts[poly.verts[1]*3];
|
|
||||||
int v0Start = poly.verts[0] * 3;
|
|
||||||
int v1Start = poly.verts[1] * 3;
|
|
||||||
float d0 = dtVdist(pos, 0, tile.verts, v0Start);
|
|
||||||
float d1 = dtVdist(pos, 0, tile.verts, v1Start);
|
|
||||||
float u = d0 / (d0 + d1);
|
|
||||||
dtVlerp(closest, 0, tile.verts, v0Start, tile.verts, v1Start, u);
|
|
||||||
//if (posOverPoly)
|
|
||||||
posOverPoly = false;
|
|
||||||
return DT_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
//uint ip = (uint)(poly - tile.polys);
|
|
||||||
dtPolyDetail pd = tile.detailMeshes[ip];
|
|
||||||
|
|
||||||
// Clamp point to be inside the polygon.
|
|
||||||
float[] verts = new float[DT_VERTS_PER_POLYGON * 3];
|
|
||||||
float[] edged = new float[DT_VERTS_PER_POLYGON];
|
|
||||||
float[] edget = new float[DT_VERTS_PER_POLYGON];
|
|
||||||
int nv = poly.vertCount;
|
|
||||||
for (int i = 0; i < nv; ++i)
|
|
||||||
{
|
|
||||||
dtVcopy(verts, i * 3, tile.verts, poly.verts[i] * 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
dtVcopy(closest, pos);
|
|
||||||
if (!dtDistancePtPolyEdgesSqr(pos, 0, verts, nv, edged, edget))
|
|
||||||
{
|
|
||||||
// Point is outside the polygon, dtClamp to nearest edge.
|
|
||||||
float dmin = float.MaxValue;
|
|
||||||
int imin = -1;
|
|
||||||
for (int i = 0; i < nv; ++i)
|
|
||||||
{
|
|
||||||
if (edged[i] < dmin)
|
|
||||||
{
|
|
||||||
dmin = edged[i];
|
|
||||||
imin = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//const float* va = &verts[imin*3];
|
|
||||||
//const float* vb = &verts[((imin+1)%nv)*3];
|
|
||||||
int vaStart = imin * 3;
|
|
||||||
int vbStart = ((imin + 1) % nv) * 3;
|
|
||||||
dtVlerp(closest, 0, verts, vaStart, verts, vbStart, edget[imin]);
|
|
||||||
|
|
||||||
//if (posOverPoly)
|
|
||||||
posOverPoly = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//if (posOverPoly)
|
|
||||||
posOverPoly = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find height at the location.
|
|
||||||
for (int j = 0; j < pd.triCount; ++j)
|
|
||||||
{
|
|
||||||
//byte[] t = &tile.detailTris[(pd.triBase+j)*4];
|
|
||||||
//const float* v[3];
|
|
||||||
int tStart = (int)(pd.triBase + j) * 4;
|
|
||||||
int[] vStarts = new int[3];
|
|
||||||
float[][] vSrc = new float[3][];
|
|
||||||
for (int k = 0; k < 3; ++k)
|
|
||||||
{
|
|
||||||
byte tk = tile.detailTris[tStart + k];
|
|
||||||
byte vCount = poly.vertCount;
|
|
||||||
if (tk < vCount)
|
|
||||||
{
|
|
||||||
//v[k] = &tile.verts[poly.verts[tile.detailTris[tStart + k]]*3];
|
|
||||||
vStarts[k] = poly.verts[tk] * 3;
|
|
||||||
vSrc[k] = tile.verts;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//v[k] = &tile.detailVerts[(pd.vertBase+(t[k]-poly.vertCount))*3];
|
|
||||||
vStarts[k] = (int)(pd.vertBase + (tk - vCount)) * 3;
|
|
||||||
vSrc[k] = tile.detailVerts;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
float h = .0f;
|
|
||||||
if (dtClosestHeightPointTriangle(closest, 0, vSrc[0], vStarts[0], vSrc[1], vStarts[1], vSrc[2], vStarts[2], ref h))
|
|
||||||
{
|
|
||||||
closest[1] = h;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return DT_SUCCESS;
|
return DT_SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -745,6 +661,9 @@ public static partial class Detour
|
|||||||
if (dtStatusFailed(m_nav.getTileAndPolyByRef(polyRef, ref tile, ref poly)))
|
if (dtStatusFailed(m_nav.getTileAndPolyByRef(polyRef, ref tile, ref poly)))
|
||||||
return DT_FAILURE | DT_INVALID_PARAM;
|
return DT_FAILURE | DT_INVALID_PARAM;
|
||||||
|
|
||||||
|
if (pos == null || !dtVisfinite(pos) || closest == null)
|
||||||
|
return DT_FAILURE | DT_INVALID_PARAM;
|
||||||
|
|
||||||
// Collect vertices.
|
// Collect vertices.
|
||||||
float[] verts = new float[DT_VERTS_PER_POLYGON * 3];
|
float[] verts = new float[DT_VERTS_PER_POLYGON * 3];
|
||||||
float[] edged = new float[DT_VERTS_PER_POLYGON];
|
float[] edged = new float[DT_VERTS_PER_POLYGON];
|
||||||
@@ -792,10 +711,10 @@ public static partial class Detour
|
|||||||
// @returns The status flags for the query.
|
// @returns The status flags for the query.
|
||||||
// @par
|
// @par
|
||||||
///
|
///
|
||||||
/// Will return #DT_FAILURE if the provided position is outside the xz-bounds
|
/// Will return #DT_FAILURE | DT_INVALID_PARAM if the provided position is outside the xz-bounds
|
||||||
/// of the polygon.
|
/// of the polygon.
|
||||||
///
|
///
|
||||||
public dtStatus getPolyHeight(dtPolyRef polyRef, float[] pos, ref float height)
|
public dtStatus getPolyHeight(dtPolyRef polyRef, float[] pos, ref float height)
|
||||||
{
|
{
|
||||||
Debug.Assert(m_nav != null);
|
Debug.Assert(m_nav != null);
|
||||||
|
|
||||||
@@ -805,57 +724,26 @@ public static partial class Detour
|
|||||||
if (dtStatusFailed(m_nav.getTileAndPolyByRef(polyRef, ref tile, ref poly, ref ip)))
|
if (dtStatusFailed(m_nav.getTileAndPolyByRef(polyRef, ref tile, ref poly, ref ip)))
|
||||||
return DT_FAILURE | DT_INVALID_PARAM;
|
return DT_FAILURE | DT_INVALID_PARAM;
|
||||||
|
|
||||||
|
if (pos == null || !dtVisfinite2D(pos))
|
||||||
|
return DT_FAILURE | DT_INVALID_PARAM;
|
||||||
|
|
||||||
|
// We used to return success for offmesh connections, but the
|
||||||
|
// getPolyHeight in DetourNavMesh does not do this, so special
|
||||||
|
// case it here.
|
||||||
if (poly.getType() == (byte)dtPolyTypes.DT_POLYTYPE_OFFMESH_CONNECTION)
|
if (poly.getType() == (byte)dtPolyTypes.DT_POLYTYPE_OFFMESH_CONNECTION)
|
||||||
{
|
{
|
||||||
//const float* v0 = &tile.verts[poly.verts[0]*3];
|
//const float* v0 = &tile.verts[poly.verts[0]*3];
|
||||||
//const float* v1 = &tile.verts[poly.verts[1]*3];
|
//const float* v1 = &tile.verts[poly.verts[1]*3];
|
||||||
int v0Start = poly.verts[0] * 3;
|
int v0Start = poly.verts[0] * 3;
|
||||||
int v1Start = poly.verts[1] * 3;
|
int v1Start = poly.verts[1] * 3;
|
||||||
float d0 = dtVdist2D(pos, 0, tile.verts, v0Start);
|
float t = 0;
|
||||||
float d1 = dtVdist2D(pos, 0, tile.verts, v1Start);
|
dtDistancePtSegSqr2D(pos, 0, tile.verts, v0Start, tile.verts, v1Start, ref t);
|
||||||
float u = d0 / (d0 + d1);
|
|
||||||
//if (height)
|
//if (height)
|
||||||
height = tile.verts[v0Start + 1] + (tile.verts[v1Start + 1] - tile.verts[v0Start + 1]) * u;
|
height = tile.verts[v0Start + 1] + (tile.verts[v1Start + 1] - tile.verts[v0Start + 1]) * t;
|
||||||
return DT_SUCCESS;
|
return DT_SUCCESS;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
//const uint ip = (uint)(poly - tile.polys);
|
|
||||||
dtPolyDetail pd = tile.detailMeshes[ip];
|
|
||||||
for (int j = 0; j < pd.triCount; ++j)
|
|
||||||
{
|
|
||||||
//byte[] t = tile.detailTris[(pd.triBase+j)*4] ;
|
|
||||||
//float* v[3];
|
|
||||||
int tStart = (int)(pd.triBase + j) * 4;
|
|
||||||
int[] vStarts = new int[3];
|
|
||||||
float[][] vSrc = new float[3][];
|
|
||||||
|
|
||||||
for (int k = 0; k < 3; ++k)
|
return m_nav.getPolyHeight(tile, poly, pos, height) ? DT_SUCCESS : DT_FAILURE | DT_INVALID_PARAM;
|
||||||
{
|
|
||||||
if (tile.detailTris[tStart + k] < poly.vertCount)
|
|
||||||
{
|
|
||||||
//v[k] = &tile.verts[poly.verts[tile.detailTris[tStart + k]]*3];
|
|
||||||
vStarts[k] = poly.verts[tile.detailTris[tStart + k]] * 3;
|
|
||||||
vSrc[k] = tile.verts;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//v[k] = &tile.detailVerts[(pd.vertBase+(tile.detailTris[tStart + k]-poly.vertCount))*3];
|
|
||||||
vStarts[k] = (int)(pd.vertBase + (tile.detailTris[tStart + k] - poly.vertCount)) * 3;
|
|
||||||
vSrc[k] = tile.detailVerts;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
float h = .0f;
|
|
||||||
if (dtClosestHeightPointTriangle(pos, 0, vSrc[0], vStarts[0], vSrc[1], vStarts[1], vSrc[2], vStarts[2], ref h))
|
|
||||||
{
|
|
||||||
//if (height)
|
|
||||||
height = h;
|
|
||||||
return DT_SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return DT_FAILURE | DT_INVALID_PARAM;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// @}
|
// @}
|
||||||
@@ -884,6 +772,8 @@ public static partial class Detour
|
|||||||
|
|
||||||
nearestRef = 0;
|
nearestRef = 0;
|
||||||
|
|
||||||
|
// queryPolygons below will check rest of params
|
||||||
|
|
||||||
dtFindNearestPolyQuery query = new(this, center);
|
dtFindNearestPolyQuery query = new(this, center);
|
||||||
|
|
||||||
dtStatus status = queryPolygons(center, halfExtents, filter, query);
|
dtStatus status = queryPolygons(center, halfExtents, filter, query);
|
||||||
@@ -1049,6 +939,13 @@ public static partial class Detour
|
|||||||
{
|
{
|
||||||
Debug.Assert(m_nav != null);
|
Debug.Assert(m_nav != null);
|
||||||
|
|
||||||
|
if (center == null || !dtVisfinite(center) ||
|
||||||
|
halfExtents == null || !dtVisfinite(halfExtents) ||
|
||||||
|
filter == null || query == null)
|
||||||
|
{
|
||||||
|
return DT_FAILURE | DT_INVALID_PARAM;
|
||||||
|
}
|
||||||
|
|
||||||
float[] bmin = new float[3];
|
float[] bmin = new float[3];
|
||||||
float[] bmax = new float[3];
|
float[] bmax = new float[3];
|
||||||
dtVsub(bmin, center, halfExtents);
|
dtVsub(bmin, center, halfExtents);
|
||||||
@@ -1106,12 +1003,11 @@ public static partial class Detour
|
|||||||
|
|
||||||
pathCount = 0;
|
pathCount = 0;
|
||||||
|
|
||||||
if (maxPath <= 0)
|
|
||||||
return DT_FAILURE | DT_INVALID_PARAM;
|
|
||||||
|
|
||||||
// Validate input
|
// Validate input
|
||||||
if (!m_nav.isValidPolyRef(startRef) || !m_nav.isValidPolyRef(endRef) ||
|
if (!m_nav.isValidPolyRef(startRef) || !m_nav.isValidPolyRef(endRef) ||
|
||||||
startPos == null || endPos == null || filter == null || maxPath <= 0 || path == null)
|
startPos == null || !dtVisfinite(startPos) ||
|
||||||
|
endPos == null || !dtVisfinite(endPos) ||
|
||||||
|
filter == null || path == null || maxPath <= 0)
|
||||||
return DT_FAILURE | DT_INVALID_PARAM;
|
return DT_FAILURE | DT_INVALID_PARAM;
|
||||||
|
|
||||||
if (startRef == endRef)
|
if (startRef == endRef)
|
||||||
@@ -1372,11 +1268,10 @@ public static partial class Detour
|
|||||||
m_query.options = options;
|
m_query.options = options;
|
||||||
m_query.raycastLimitSqr = float.MaxValue;
|
m_query.raycastLimitSqr = float.MaxValue;
|
||||||
|
|
||||||
if (startRef == 0 || endRef == 0)
|
|
||||||
return DT_FAILURE | DT_INVALID_PARAM;
|
|
||||||
|
|
||||||
// Validate input
|
// Validate input
|
||||||
if (!m_nav.isValidPolyRef(startRef) || !m_nav.isValidPolyRef(endRef))
|
if (!m_nav.isValidPolyRef(startRef) || !m_nav.isValidPolyRef(endRef) ||
|
||||||
|
startPos == null || !dtVisfinite(startPos) ||
|
||||||
|
endPos == null || !dtVisfinite(endPos) || filter == null)
|
||||||
return DT_FAILURE | DT_INVALID_PARAM;
|
return DT_FAILURE | DT_INVALID_PARAM;
|
||||||
|
|
||||||
// trade quality with performance?
|
// trade quality with performance?
|
||||||
@@ -1646,6 +1541,9 @@ public static partial class Detour
|
|||||||
{
|
{
|
||||||
pathCount = 0;
|
pathCount = 0;
|
||||||
|
|
||||||
|
if (path == null || maxPath <= 0)
|
||||||
|
return DT_FAILURE | DT_INVALID_PARAM;
|
||||||
|
|
||||||
if (dtStatusFailed(m_query.status))
|
if (dtStatusFailed(m_query.status))
|
||||||
{
|
{
|
||||||
// Reset query.
|
// Reset query.
|
||||||
@@ -1747,10 +1645,8 @@ public static partial class Detour
|
|||||||
{
|
{
|
||||||
pathCount = 0;
|
pathCount = 0;
|
||||||
|
|
||||||
if (existingSize == 0)
|
if (existing == null || existingSize <= 0 || path == null || maxPath <= 0)
|
||||||
{
|
return DT_FAILURE | DT_INVALID_PARAM;
|
||||||
return DT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dtStatusFailed(m_query.status))
|
if (dtStatusFailed(m_query.status))
|
||||||
{
|
{
|
||||||
@@ -1971,10 +1867,10 @@ public static partial class Detour
|
|||||||
|
|
||||||
straightPathCount = 0;
|
straightPathCount = 0;
|
||||||
|
|
||||||
if (maxStraightPath == 0)
|
if (startPos == null || !dtVisfinite(startPos) ||
|
||||||
return DT_FAILURE | DT_INVALID_PARAM;
|
endPos == null || !dtVisfinite(endPos) ||
|
||||||
|
path == null || pathSize <= 0 || path[0] == 0 ||
|
||||||
if (path[0] == 0)
|
maxStraightPath <= 0)
|
||||||
return DT_FAILURE | DT_INVALID_PARAM;
|
return DT_FAILURE | DT_INVALID_PARAM;
|
||||||
|
|
||||||
dtStatus stat = 0;
|
dtStatus stat = 0;
|
||||||
@@ -2225,9 +2121,11 @@ public static partial class Detour
|
|||||||
visitedCount = 0;
|
visitedCount = 0;
|
||||||
|
|
||||||
// Validate input
|
// Validate input
|
||||||
if (startRef == 0)
|
if (!m_nav.isValidPolyRef(startRef) ||
|
||||||
return DT_FAILURE | DT_INVALID_PARAM;
|
startPos == null || !dtVisfinite(startPos) ||
|
||||||
if (!m_nav.isValidPolyRef(startRef))
|
endPos == null || !dtVisfinite(endPos) ||
|
||||||
|
filter == null || resultPos == null || visited == null ||
|
||||||
|
maxVisitedSize <= 0)
|
||||||
return DT_FAILURE | DT_INVALID_PARAM;
|
return DT_FAILURE | DT_INVALID_PARAM;
|
||||||
|
|
||||||
dtStatus status = DT_SUCCESS;
|
dtStatus status = DT_SUCCESS;
|
||||||
@@ -2578,7 +2476,6 @@ public static partial class Detour
|
|||||||
///
|
///
|
||||||
public dtStatus raycast(dtPolyRef startRef, float[] startPos, float[] endPos, dtQueryFilter filter, ref float t, float[] hitNormal, dtPolyRef[] path, ref uint pathCount, int maxPath)
|
public dtStatus raycast(dtPolyRef startRef, float[] startPos, float[] endPos, dtQueryFilter filter, ref float t, float[] hitNormal, dtPolyRef[] path, ref uint pathCount, int maxPath)
|
||||||
{
|
{
|
||||||
|
|
||||||
dtRaycastHit hit = new();
|
dtRaycastHit hit = new();
|
||||||
hit.path = path;
|
hit.path = path;
|
||||||
hit.maxPath = maxPath;
|
hit.maxPath = maxPath;
|
||||||
@@ -2647,15 +2544,19 @@ public static partial class Detour
|
|||||||
{
|
{
|
||||||
Debug.Assert(m_nav != null);
|
Debug.Assert(m_nav != null);
|
||||||
|
|
||||||
|
if (hit == null)
|
||||||
|
return DT_FAILURE | DT_INVALID_PARAM;
|
||||||
|
|
||||||
hit.t = 0;
|
hit.t = 0;
|
||||||
hit.pathCount = 0;
|
hit.pathCount = 0;
|
||||||
hit.pathCost = 0;
|
hit.pathCost = 0;
|
||||||
|
|
||||||
// Validate input
|
// Validate input
|
||||||
if (startRef == 0 || !m_nav.isValidPolyRef(startRef))
|
if (!m_nav.isValidPolyRef(startRef) ||
|
||||||
return DT_FAILURE | DT_INVALID_PARAM;
|
startPos == null || !dtVisfinite(startPos) ||
|
||||||
|
endPos == null || !dtVisfinite(endPos) ||
|
||||||
if (prevRef != 0 && !m_nav.isValidPolyRef(prevRef))
|
filter == null ||
|
||||||
|
(prevRef != 0 && !m_nav.isValidPolyRef(prevRef)))
|
||||||
return DT_FAILURE | DT_INVALID_PARAM;
|
return DT_FAILURE | DT_INVALID_PARAM;
|
||||||
|
|
||||||
float[] dir = new float[3];
|
float[] dir = new float[3];
|
||||||
@@ -2925,7 +2826,10 @@ public static partial class Detour
|
|||||||
resultCount = 0;
|
resultCount = 0;
|
||||||
|
|
||||||
// Validate input
|
// Validate input
|
||||||
if (startRef == 0 || !m_nav.isValidPolyRef(startRef))
|
if (!m_nav.isValidPolyRef(startRef) ||
|
||||||
|
centerPos == null || !dtVisfinite(centerPos) ||
|
||||||
|
radius < 0 || !float.IsFinite(radius) ||
|
||||||
|
filter == null || maxResult < 0)
|
||||||
return DT_FAILURE | DT_INVALID_PARAM;
|
return DT_FAILURE | DT_INVALID_PARAM;
|
||||||
|
|
||||||
m_nodePool.clear();
|
m_nodePool.clear();
|
||||||
@@ -3113,6 +3017,11 @@ public static partial class Detour
|
|||||||
|
|
||||||
resultCount = 0;
|
resultCount = 0;
|
||||||
|
|
||||||
|
if (!m_nav.isValidPolyRef(startRef) ||
|
||||||
|
verts == null || nverts < 3 ||
|
||||||
|
filter == null || maxResult < 0)
|
||||||
|
return DT_FAILURE | DT_INVALID_PARAM;
|
||||||
|
|
||||||
// Validate input
|
// Validate input
|
||||||
if (startRef == 0 || !m_nav.isValidPolyRef(startRef))
|
if (startRef == 0 || !m_nav.isValidPolyRef(startRef))
|
||||||
return DT_FAILURE | DT_INVALID_PARAM;
|
return DT_FAILURE | DT_INVALID_PARAM;
|
||||||
@@ -3305,8 +3214,10 @@ public static partial class Detour
|
|||||||
|
|
||||||
resultCount = 0;
|
resultCount = 0;
|
||||||
|
|
||||||
// Validate input
|
if (!m_nav.isValidPolyRef(startRef) ||
|
||||||
if (startRef == 0 || !m_nav.isValidPolyRef(startRef))
|
centerPos == null || !dtVisfinite(centerPos) ||
|
||||||
|
radius < 0 || !float.IsFinite(radius) ||
|
||||||
|
filter == null || maxResult < 0)
|
||||||
return DT_FAILURE | DT_INVALID_PARAM;
|
return DT_FAILURE | DT_INVALID_PARAM;
|
||||||
|
|
||||||
const int MAX_STACK = 48;
|
const int MAX_STACK = 48;
|
||||||
@@ -3543,6 +3454,9 @@ public static partial class Detour
|
|||||||
if (dtStatusFailed(m_nav.getTileAndPolyByRef(polyRef, ref tile, ref poly)))
|
if (dtStatusFailed(m_nav.getTileAndPolyByRef(polyRef, ref tile, ref poly)))
|
||||||
return DT_FAILURE | DT_INVALID_PARAM;
|
return DT_FAILURE | DT_INVALID_PARAM;
|
||||||
|
|
||||||
|
if (filter == null || segmentVerts == null || maxSegments < 0)
|
||||||
|
return DT_FAILURE | DT_INVALID_PARAM;
|
||||||
|
|
||||||
int n = 0;
|
int n = 0;
|
||||||
const int MAX_INTERVAL = 16;
|
const int MAX_INTERVAL = 16;
|
||||||
dtSegInterval[] ints = new dtSegInterval[MAX_INTERVAL];
|
dtSegInterval[] ints = new dtSegInterval[MAX_INTERVAL];
|
||||||
@@ -3705,7 +3619,10 @@ public static partial class Detour
|
|||||||
Debug.Assert(m_openList != null);
|
Debug.Assert(m_openList != null);
|
||||||
|
|
||||||
// Validate input
|
// Validate input
|
||||||
if (startRef == 0 || !m_nav.isValidPolyRef(startRef))
|
if (!m_nav.isValidPolyRef(startRef) ||
|
||||||
|
centerPos == null || !dtVisfinite(centerPos) ||
|
||||||
|
maxRadius < 0 || !float.IsFinite(maxRadius) ||
|
||||||
|
filter == null || hitPos == null || hitNormal == null)
|
||||||
return DT_FAILURE | DT_INVALID_PARAM;
|
return DT_FAILURE | DT_INVALID_PARAM;
|
||||||
|
|
||||||
m_nodePool.clear();
|
m_nodePool.clear();
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ public static partial class Detour
|
|||||||
public const uint DT_BUFFER_TOO_SMALL = 1 << 4; // Result buffer for the query was too small to store all results.
|
public const uint DT_BUFFER_TOO_SMALL = 1 << 4; // Result buffer for the query was too small to store all results.
|
||||||
public const uint DT_OUT_OF_NODES = 1 << 5; // Query ran out of nodes during search.
|
public const uint DT_OUT_OF_NODES = 1 << 5; // Query ran out of nodes during search.
|
||||||
public const uint DT_PARTIAL_RESULT = 1 << 6; // Query did not reach the end location, returning best guess.
|
public const uint DT_PARTIAL_RESULT = 1 << 6; // Query did not reach the end location, returning best guess.
|
||||||
|
public const uint DT_ALREADY_OCCUPIED = 1 << 7; // A tile has already been assigned to the given x,y coordinate
|
||||||
|
|
||||||
// Returns true of status is success.
|
// Returns true of status is success.
|
||||||
public static bool dtStatusSucceed(dtStatus status)
|
public static bool dtStatusSucceed(dtStatus status)
|
||||||
|
|||||||
@@ -239,28 +239,28 @@ namespace Game.DataStorage
|
|||||||
|
|
||||||
orbitInfo.StartDelay = circularMovementInfos.Read<uint>(1);
|
orbitInfo.StartDelay = circularMovementInfos.Read<uint>(1);
|
||||||
orbitInfo.Radius = circularMovementInfos.Read<float>(2);
|
orbitInfo.Radius = circularMovementInfos.Read<float>(2);
|
||||||
if (!float.IsInfinity(orbitInfo.Radius))
|
if (!float.IsFinite(orbitInfo.Radius))
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.Sql, $"Table `areatrigger_create_properties_orbit` has listed areatrigger (AreaTriggerCreatePropertiesId: {areaTriggerCreatePropertiesId}) with invalid Radius ({orbitInfo.Radius}), set to 0!");
|
Log.outError(LogFilter.Sql, $"Table `areatrigger_create_properties_orbit` has listed areatrigger (AreaTriggerCreatePropertiesId: {areaTriggerCreatePropertiesId}) with invalid Radius ({orbitInfo.Radius}), set to 0!");
|
||||||
orbitInfo.Radius = 0.0f;
|
orbitInfo.Radius = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
orbitInfo.BlendFromRadius = circularMovementInfos.Read<float>(3);
|
orbitInfo.BlendFromRadius = circularMovementInfos.Read<float>(3);
|
||||||
if (!float.IsInfinity(orbitInfo.BlendFromRadius))
|
if (!float.IsFinite(orbitInfo.BlendFromRadius))
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.Sql, $"Table `areatrigger_create_properties_orbit` has listed areatrigger (AreaTriggerCreatePropertiesId: {areaTriggerCreatePropertiesId}) with invalid BlendFromRadius ({orbitInfo.BlendFromRadius}), set to 0!");
|
Log.outError(LogFilter.Sql, $"Table `areatrigger_create_properties_orbit` has listed areatrigger (AreaTriggerCreatePropertiesId: {areaTriggerCreatePropertiesId}) with invalid BlendFromRadius ({orbitInfo.BlendFromRadius}), set to 0!");
|
||||||
orbitInfo.BlendFromRadius = 0.0f;
|
orbitInfo.BlendFromRadius = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
orbitInfo.InitialAngle = circularMovementInfos.Read<float>(4);
|
orbitInfo.InitialAngle = circularMovementInfos.Read<float>(4);
|
||||||
if (!float.IsInfinity(orbitInfo.InitialAngle))
|
if (!float.IsFinite(orbitInfo.InitialAngle))
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.Sql, $"Table `areatrigger_create_properties_orbit` has listed areatrigger (AreaTriggerCreatePropertiesId: {areaTriggerCreatePropertiesId}) with invalid InitialAngle ({orbitInfo.InitialAngle}), set to 0!");
|
Log.outError(LogFilter.Sql, $"Table `areatrigger_create_properties_orbit` has listed areatrigger (AreaTriggerCreatePropertiesId: {areaTriggerCreatePropertiesId}) with invalid InitialAngle ({orbitInfo.InitialAngle}), set to 0!");
|
||||||
orbitInfo.InitialAngle = 0.0f;
|
orbitInfo.InitialAngle = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
orbitInfo.ZOffset = circularMovementInfos.Read<float>(5);
|
orbitInfo.ZOffset = circularMovementInfos.Read<float>(5);
|
||||||
if (!float.IsInfinity(orbitInfo.ZOffset))
|
if (!float.IsFinite(orbitInfo.ZOffset))
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.Sql, $"Table `spell_areatrigger_circular` has listed areatrigger (MiscId: {areaTriggerCreatePropertiesId}) with invalid ZOffset ({orbitInfo.ZOffset}), set to 0!");
|
Log.outError(LogFilter.Sql, $"Table `spell_areatrigger_circular` has listed areatrigger (MiscId: {areaTriggerCreatePropertiesId}) with invalid ZOffset ({orbitInfo.ZOffset}), set to 0!");
|
||||||
orbitInfo.ZOffset = 0.0f;
|
orbitInfo.ZOffset = 0.0f;
|
||||||
|
|||||||
@@ -3377,7 +3377,7 @@ namespace Game.Entities
|
|||||||
stmt.AddValue(0, GetGUID().GetCounter());
|
stmt.AddValue(0, GetGUID().GetCounter());
|
||||||
characterTransaction.Append(stmt);
|
characterTransaction.Append(stmt);
|
||||||
|
|
||||||
static float finiteAlways(float f) { return !float.IsInfinity(f) ? f : 0.0f; };
|
static float finiteAlways(float f) { return !float.IsFinite(f) ? f : 0.0f; };
|
||||||
|
|
||||||
if (create)
|
if (create)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ namespace Game.Maps
|
|||||||
{
|
{
|
||||||
public static bool IsValidMapCoord(float c)
|
public static bool IsValidMapCoord(float c)
|
||||||
{
|
{
|
||||||
return !float.IsInfinity(c) && (Math.Abs(c) <= (MapConst.MapHalfSize - 0.5f));
|
return !float.IsFinite(c) && (Math.Abs(c) <= (MapConst.MapHalfSize - 0.5f));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool IsValidMapCoord(float x, float y)
|
public static bool IsValidMapCoord(float x, float y)
|
||||||
@@ -40,7 +40,7 @@ namespace Game.Maps
|
|||||||
|
|
||||||
public static bool IsValidMapCoord(float x, float y, float z, float o)
|
public static bool IsValidMapCoord(float x, float y, float z, float o)
|
||||||
{
|
{
|
||||||
return IsValidMapCoord(x, y, z) && !float.IsInfinity(o);
|
return IsValidMapCoord(x, y, z) && float.IsFinite(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool IsValidMapCoord(uint mapid, float x, float y)
|
public static bool IsValidMapCoord(uint mapid, float x, float y)
|
||||||
|
|||||||
@@ -703,10 +703,14 @@ namespace Game.Movement
|
|||||||
ulong[] visited = new ulong[MAX_VISIT_POLY];
|
ulong[] visited = new ulong[MAX_VISIT_POLY];
|
||||||
|
|
||||||
int nvisited = 0;
|
int nvisited = 0;
|
||||||
_navMeshQuery.moveAlongSurface(polys[0], iterPos, moveTgt, _filter, result, visited, ref nvisited, MAX_VISIT_POLY);
|
if (Detour.dtStatusFailed(_navMeshQuery.moveAlongSurface(polys[0], iterPos, moveTgt, _filter, result, visited, ref nvisited, MAX_VISIT_POLY)))
|
||||||
|
return Detour.DT_FAILURE;
|
||||||
|
|
||||||
npolys = FixupCorridor(polys, npolys, 74, visited, nvisited);
|
npolys = FixupCorridor(polys, npolys, 74, visited, nvisited);
|
||||||
|
|
||||||
_navMeshQuery.getPolyHeight(polys[0], result, ref result[1]);
|
if (Detour.dtStatusFailed(_navMeshQuery.getPolyHeight(polys[0], result, ref result[1])))
|
||||||
|
return Detour.DT_FAILURE;
|
||||||
|
|
||||||
result[1] += 0.5f;
|
result[1] += 0.5f;
|
||||||
Detour.dtVcopy(iterPos, result);
|
Detour.dtVcopy(iterPos, result);
|
||||||
|
|
||||||
@@ -752,7 +756,9 @@ namespace Game.Movement
|
|||||||
}
|
}
|
||||||
// Move position at the other side of the off-mesh link.
|
// Move position at the other side of the off-mesh link.
|
||||||
Detour.dtVcopy(iterPos, connectionEndPos);
|
Detour.dtVcopy(iterPos, connectionEndPos);
|
||||||
_navMeshQuery.getPolyHeight(polys[0], iterPos, ref iterPos[1]);
|
if (Detour.dtStatusFailed(_navMeshQuery.getPolyHeight(polys[0], iterPos, ref iterPos[1])))
|
||||||
|
return Detour.DT_FAILURE;
|
||||||
|
|
||||||
iterPos[1] += 0.5f;
|
iterPos[1] += 0.5f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user