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 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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user