MMaps Updates, Needs tested.

Port From (https://github.com/TrinityCore/TrinityCore)
This commit is contained in:
hondacrx
2021-12-02 14:50:55 -05:00
parent 30265c0716
commit f5695f0cf2
11 changed files with 279 additions and 257 deletions
+1 -1
View File
@@ -66,7 +66,7 @@ namespace Framework.Constants
public const uint MapLiquidMagic = 0x51494C4D; //"MLIQ";
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 float VMAPInvalidHeightValue = -200000.0f;
+2 -2
View File
@@ -37,7 +37,7 @@ namespace Framework.GameMath
for (int i = 0; i < 3; ++i)
{
if (!float.IsInfinity(_edgeVector[i].Length()))
if (!float.IsFinite(_edgeVector[i].Length()))
{
finiteExtent = false;
// 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()
{
return float.IsInfinity(_volume);
return float.IsFinite(_volume);
}
}
}
@@ -211,6 +211,8 @@ public static partial class Detour
/// @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)
{
const float EPS = 1e-6f;
float[] v0 = new float[3];
float[] v1 = 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(v2, 0, p, pStart, a, aStart);
float dot00 = dtVdot2D(v0, v0);
float dot01 = dtVdot2D(v0, v1);
float dot02 = dtVdot2D(v0, v2);
float dot11 = dtVdot2D(v1, v1);
float dot12 = dtVdot2D(v1, v2);
// Compute scaled barycentric coordinates
float denom = v0[0] * v1[2] - v0[2] * v1[0];
if (MathF.Abs(denom) < EPS)
return false;
// Compute barycentric coordinates
float invDenom = 1.0f / (dot00 * dot11 - dot01 * dot01);
float u = (dot11 * dot02 - dot01 * dot12) * invDenom;
float v = (dot00 * dot12 - dot01 * dot02) * invDenom;
float u = v1[2] * v2[0] - v1[0] * v2[2];
float v = v0[0] * v2[2] - v0[2] * v2[0];
// The (sloppy) epsilon is needed to allow to get height of points which
// 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)
if (denom < 0)
{
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;
}
@@ -779,6 +780,30 @@ public static partial class Detour
float d = dtVdistSqr(p0, p0Start, p1, p1Start);
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)
/// @param[in] u A vector [(x, y, z)]
/// @param[in] v A vector [(x, y, z)]
@@ -1,5 +1,6 @@
using System;
using System.Diagnostics;
using System.Linq;
/**
@typedef dtPolyRef
@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;
dtPoly poly = null;
uint ip = 0;
getTileAndPolyByRefUnsafe(polyRef, ref tile, ref poly, ref ip);
// Off-mesh connections don't have detail polygons.
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, posStart, tile.verts, v0Start);
float d1 = dtVdist(pos, posStart, tile.verts, v1Start);
float u = d0 / (d0 + d1);
dtVlerp(closest, 0, tile.verts, v0Start, tile.verts, v1Start, u);
posOverPoly = false;
return;
}
//uint ip = (uint)(poly - tile.polys);
uint ip = (uint)tile.polys.ToList().IndexOf(poly);
dtPolyDetail pd = tile.detailMeshes[ip];
float dmin = float.MaxValue;
float tmin = 0;
int pmin = 0;
int pmax = 0;
float[] v = new float[0];
for (int i = 0; i < pd.triCount; i++)
{
int trisIndex = (int)((pd.triBase + i) * 4);
const int ANY_BOUNDARY_EDGE =
((int)dtDetailTriEdgeFlags.DT_DETAIL_EDGE_BOUNDARY << 0) |
((int)dtDetailTriEdgeFlags.DT_DETAIL_EDGE_BOUNDARY << 2) |
((int)dtDetailTriEdgeFlags.DT_DETAIL_EDGE_BOUNDARY << 4);
if (onlyBoundary && (tile.detailTris[trisIndex + 3] & ANY_BOUNDARY_EDGE) == 0)
continue;
v = new float[3];
for (int j = 0; j < 3; ++j)
{
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];
// 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, 0, pos, posStart);
if (!dtDistancePtPolyEdgesSqr(pos, posStart, 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;
}
}
//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 (!dtPointInPolygon(pos, verts, nv))
return false;
posOverPoly = false;
}
else
{
posOverPoly = true;
}
if (height == 0)
return true;
// Find height at the location.
for (int j = 0; j < pd.triCount; ++j)
@@ -812,12 +829,54 @@ public static partial class Detour
}
}
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;
break;
height = h;
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)
@@ -841,7 +900,7 @@ public static partial class Detour
float[] diff = new float[3];
bool posOverPoly = false;
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
// 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.
if (getTileAt(header.x, header.y, header.layer) != null)
return DT_FAILURE;
return DT_FAILURE | DT_ALREADY_OCCUPIED;
// Allocate a tile.
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
};
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.
public enum dtPolyTypes
{
@@ -616,7 +621,8 @@ public static partial class Detour
/// The detail mesh's unique vertices. [(x, y, z) * dtMeshHeader::detailVertCount]
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;
/// 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.
};
/// 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.
/// The values are used to allocate space during the initialization of a navigation mesh.
// @see dtNavMesh::init()
@@ -36,6 +36,7 @@ using System;
using System.Diagnostics;
using dtPolyRef = System.UInt64;
using dtStatus = System.UInt32;
using System.Collections.Generic;
// 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
@@ -310,6 +311,9 @@ public static partial class Detour
{
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.
dtMeshTile tile = null;
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] randomPt The random location. [(x, y, z)]
// @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_nodePool != null);
Debug.Assert(m_openList != null);
// 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;
dtMeshTile startTile = null;
@@ -439,7 +446,7 @@ public static partial class Detour
dtStatus status = DT_SUCCESS;
float radiusSqr = dtSqr(radius);
float radiusSqr = dtSqr(maxRadius);
float areaSum = 0.0f;
dtMeshTile randomTile = null;
@@ -617,104 +624,13 @@ public static partial class Detour
public dtStatus closestPointOnPoly(dtPolyRef polyRef, float[] pos, float[] closest, ref bool posOverPoly)
{
Debug.Assert(m_nav != null);
dtMeshTile tile = null;
dtPoly poly = null;
uint ip = 0;
if (dtStatusFailed(m_nav.getTileAndPolyByRef(polyRef, ref tile, ref poly, ref ip)))
return DT_FAILURE | DT_INVALID_PARAM;
if (tile == null)
if (!m_nav.isValidPolyRef(polyRef) ||
pos == null || !dtVisfinite(pos) ||
closest == null)
return DT_FAILURE | DT_INVALID_PARAM;
// Off-mesh connections don't have detail polygons.
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;
}
}
m_nav.closestPointOnPoly(polyRef, pos, closest, ref posOverPoly);
return DT_SUCCESS;
}
@@ -745,6 +661,9 @@ public static partial class Detour
if (dtStatusFailed(m_nav.getTileAndPolyByRef(polyRef, ref tile, ref poly)))
return DT_FAILURE | DT_INVALID_PARAM;
if (pos == null || !dtVisfinite(pos) || closest == null)
return DT_FAILURE | DT_INVALID_PARAM;
// Collect vertices.
float[] verts = new float[DT_VERTS_PER_POLYGON * 3];
float[] edged = new float[DT_VERTS_PER_POLYGON];
@@ -792,10 +711,10 @@ public static partial class Detour
// @returns The status flags for the query.
// @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.
///
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);
@@ -805,57 +724,26 @@ public static partial class Detour
if (dtStatusFailed(m_nav.getTileAndPolyByRef(polyRef, ref tile, ref poly, ref ip)))
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)
{
//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 = dtVdist2D(pos, 0, tile.verts, v0Start);
float d1 = dtVdist2D(pos, 0, tile.verts, v1Start);
float u = d0 / (d0 + d1);
float t = 0;
dtDistancePtSegSqr2D(pos, 0, tile.verts, v0Start, tile.verts, v1Start, ref t);
//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;
}
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)
{
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;
return m_nav.getPolyHeight(tile, poly, pos, height) ? DT_SUCCESS : DT_FAILURE | DT_INVALID_PARAM;
}
// @}
@@ -884,6 +772,8 @@ public static partial class Detour
nearestRef = 0;
// queryPolygons below will check rest of params
dtFindNearestPolyQuery query = new(this, center);
dtStatus status = queryPolygons(center, halfExtents, filter, query);
@@ -1049,6 +939,13 @@ public static partial class Detour
{
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[] bmax = new float[3];
dtVsub(bmin, center, halfExtents);
@@ -1106,12 +1003,11 @@ public static partial class Detour
pathCount = 0;
if (maxPath <= 0)
return DT_FAILURE | DT_INVALID_PARAM;
// Validate input
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;
if (startRef == endRef)
@@ -1372,11 +1268,10 @@ public static partial class Detour
m_query.options = options;
m_query.raycastLimitSqr = float.MaxValue;
if (startRef == 0 || endRef == 0)
return DT_FAILURE | DT_INVALID_PARAM;
// 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;
// trade quality with performance?
@@ -1646,6 +1541,9 @@ public static partial class Detour
{
pathCount = 0;
if (path == null || maxPath <= 0)
return DT_FAILURE | DT_INVALID_PARAM;
if (dtStatusFailed(m_query.status))
{
// Reset query.
@@ -1747,10 +1645,8 @@ public static partial class Detour
{
pathCount = 0;
if (existingSize == 0)
{
return DT_FAILURE;
}
if (existing == null || existingSize <= 0 || path == null || maxPath <= 0)
return DT_FAILURE | DT_INVALID_PARAM;
if (dtStatusFailed(m_query.status))
{
@@ -1971,10 +1867,10 @@ public static partial class Detour
straightPathCount = 0;
if (maxStraightPath == 0)
return DT_FAILURE | DT_INVALID_PARAM;
if (path[0] == 0)
if (startPos == null || !dtVisfinite(startPos) ||
endPos == null || !dtVisfinite(endPos) ||
path == null || pathSize <= 0 || path[0] == 0 ||
maxStraightPath <= 0)
return DT_FAILURE | DT_INVALID_PARAM;
dtStatus stat = 0;
@@ -2225,9 +2121,11 @@ public static partial class Detour
visitedCount = 0;
// Validate input
if (startRef == 0)
return DT_FAILURE | DT_INVALID_PARAM;
if (!m_nav.isValidPolyRef(startRef))
if (!m_nav.isValidPolyRef(startRef) ||
startPos == null || !dtVisfinite(startPos) ||
endPos == null || !dtVisfinite(endPos) ||
filter == null || resultPos == null || visited == null ||
maxVisitedSize <= 0)
return DT_FAILURE | DT_INVALID_PARAM;
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)
{
dtRaycastHit hit = new();
hit.path = path;
hit.maxPath = maxPath;
@@ -2647,15 +2544,19 @@ public static partial class Detour
{
Debug.Assert(m_nav != null);
if (hit == null)
return DT_FAILURE | DT_INVALID_PARAM;
hit.t = 0;
hit.pathCount = 0;
hit.pathCost = 0;
// Validate input
if (startRef == 0 || !m_nav.isValidPolyRef(startRef))
return DT_FAILURE | DT_INVALID_PARAM;
if (prevRef != 0 && !m_nav.isValidPolyRef(prevRef))
if (!m_nav.isValidPolyRef(startRef) ||
startPos == null || !dtVisfinite(startPos) ||
endPos == null || !dtVisfinite(endPos) ||
filter == null ||
(prevRef != 0 && !m_nav.isValidPolyRef(prevRef)))
return DT_FAILURE | DT_INVALID_PARAM;
float[] dir = new float[3];
@@ -2925,7 +2826,10 @@ public static partial class Detour
resultCount = 0;
// 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;
m_nodePool.clear();
@@ -3113,6 +3017,11 @@ public static partial class Detour
resultCount = 0;
if (!m_nav.isValidPolyRef(startRef) ||
verts == null || nverts < 3 ||
filter == null || maxResult < 0)
return DT_FAILURE | DT_INVALID_PARAM;
// Validate input
if (startRef == 0 || !m_nav.isValidPolyRef(startRef))
return DT_FAILURE | DT_INVALID_PARAM;
@@ -3305,8 +3214,10 @@ public static partial class Detour
resultCount = 0;
// 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;
const int MAX_STACK = 48;
@@ -3543,6 +3454,9 @@ public static partial class Detour
if (dtStatusFailed(m_nav.getTileAndPolyByRef(polyRef, ref tile, ref poly)))
return DT_FAILURE | DT_INVALID_PARAM;
if (filter == null || segmentVerts == null || maxSegments < 0)
return DT_FAILURE | DT_INVALID_PARAM;
int n = 0;
const int MAX_INTERVAL = 16;
dtSegInterval[] ints = new dtSegInterval[MAX_INTERVAL];
@@ -3705,7 +3619,10 @@ public static partial class Detour
Debug.Assert(m_openList != null);
// 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;
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_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_ALREADY_OCCUPIED = 1 << 7; // A tile has already been assigned to the given x,y coordinate
// Returns true of status is success.
public static bool dtStatusSucceed(dtStatus status)
@@ -239,28 +239,28 @@ namespace Game.DataStorage
orbitInfo.StartDelay = circularMovementInfos.Read<uint>(1);
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!");
orbitInfo.Radius = 0.0f;
}
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!");
orbitInfo.BlendFromRadius = 0.0f;
}
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!");
orbitInfo.InitialAngle = 0.0f;
}
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!");
orbitInfo.ZOffset = 0.0f;
+1 -1
View File
@@ -3377,7 +3377,7 @@ namespace Game.Entities
stmt.AddValue(0, GetGUID().GetCounter());
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)
{
+2 -2
View File
@@ -25,7 +25,7 @@ namespace Game.Maps
{
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)
@@ -40,7 +40,7 @@ namespace Game.Maps
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)
@@ -703,10 +703,14 @@ namespace Game.Movement
ulong[] visited = new ulong[MAX_VISIT_POLY];
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);
_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;
Detour.dtVcopy(iterPos, result);
@@ -752,7 +756,9 @@ namespace Game.Movement
}
// Move position at the other side of the off-mesh link.
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;
}
}