forked from mirror/DotRecast
rename RcRecast, DtDetour
This commit is contained in:
parent
3f750ba499
commit
40306a5302
|
@ -1,11 +1,11 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using DotRecast.Core.Numerics;
|
using DotRecast.Core.Numerics;
|
||||||
using DotRecast.Recast;
|
using DotRecast.Recast;
|
||||||
using static DotRecast.Recast.RcConstants;
|
|
||||||
|
|
||||||
|
|
||||||
namespace DotRecast.Detour.Extras.Jumplink
|
namespace DotRecast.Detour.Extras.Jumplink
|
||||||
{
|
{
|
||||||
|
using static RcRecast;
|
||||||
|
|
||||||
public class EdgeExtractor
|
public class EdgeExtractor
|
||||||
{
|
{
|
||||||
public JumpEdge[] ExtractEdges(RcPolyMesh mesh)
|
public JumpEdge[] ExtractEdges(RcPolyMesh mesh)
|
||||||
|
|
|
@ -22,6 +22,8 @@ using DotRecast.Core;
|
||||||
|
|
||||||
namespace DotRecast.Detour.Extras.Unity.Astar
|
namespace DotRecast.Detour.Extras.Unity.Astar
|
||||||
{
|
{
|
||||||
|
using static DtDetour;
|
||||||
|
|
||||||
public class GraphMeshDataReader : ZipBinaryReader
|
public class GraphMeshDataReader : ZipBinaryReader
|
||||||
{
|
{
|
||||||
public const float INT_PRECISION_FACTOR = 1000f;
|
public const float INT_PRECISION_FACTOR = 1000f;
|
||||||
|
@ -116,8 +118,8 @@ namespace DotRecast.Detour.Extras.Unity.Astar
|
||||||
tiles[tileIndex].detailVerts = detailVerts;
|
tiles[tileIndex].detailVerts = detailVerts;
|
||||||
tiles[tileIndex].detailTris = detailTris;
|
tiles[tileIndex].detailTris = detailTris;
|
||||||
DtMeshHeader header = new DtMeshHeader();
|
DtMeshHeader header = new DtMeshHeader();
|
||||||
header.magic = DtNavMesh.DT_NAVMESH_MAGIC;
|
header.magic = DT_NAVMESH_MAGIC;
|
||||||
header.version = DtNavMesh.DT_NAVMESH_VERSION;
|
header.version = DT_NAVMESH_VERSION;
|
||||||
header.x = x;
|
header.x = x;
|
||||||
header.y = z;
|
header.y = z;
|
||||||
header.polyCount = nodeCount;
|
header.polyCount = nodeCount;
|
||||||
|
|
|
@ -21,6 +21,8 @@ using System.Collections.Generic;
|
||||||
|
|
||||||
namespace DotRecast.Detour.Extras.Unity.Astar
|
namespace DotRecast.Detour.Extras.Unity.Astar
|
||||||
{
|
{
|
||||||
|
using static DtDetour;
|
||||||
|
|
||||||
public class LinkBuilder
|
public class LinkBuilder
|
||||||
{
|
{
|
||||||
// Process connections and transform them into recast neighbour flags
|
// Process connections and transform them into recast neighbour flags
|
||||||
|
@ -65,19 +67,19 @@ namespace DotRecast.Detour.Extras.Unity.Astar
|
||||||
{
|
{
|
||||||
if (neighbourTile.header.bmin.X > tile.header.bmin.X)
|
if (neighbourTile.header.bmin.X > tile.header.bmin.X)
|
||||||
{
|
{
|
||||||
node.neis[DtPolyUtils.FindEdge(node, tile, neighbourTile.header.bmin.X, 0)] = DtNavMesh.DT_EXT_LINK;
|
node.neis[DtPolyUtils.FindEdge(node, tile, neighbourTile.header.bmin.X, 0)] = DT_EXT_LINK;
|
||||||
}
|
}
|
||||||
else if (neighbourTile.header.bmin.X < tile.header.bmin.X)
|
else if (neighbourTile.header.bmin.X < tile.header.bmin.X)
|
||||||
{
|
{
|
||||||
node.neis[DtPolyUtils.FindEdge(node, tile, tile.header.bmin.X, 0)] = DtNavMesh.DT_EXT_LINK | 4;
|
node.neis[DtPolyUtils.FindEdge(node, tile, tile.header.bmin.X, 0)] = DT_EXT_LINK | 4;
|
||||||
}
|
}
|
||||||
else if (neighbourTile.header.bmin.Z > tile.header.bmin.Z)
|
else if (neighbourTile.header.bmin.Z > tile.header.bmin.Z)
|
||||||
{
|
{
|
||||||
node.neis[DtPolyUtils.FindEdge(node, tile, neighbourTile.header.bmin.Z, 2)] = DtNavMesh.DT_EXT_LINK | 2;
|
node.neis[DtPolyUtils.FindEdge(node, tile, neighbourTile.header.bmin.Z, 2)] = DT_EXT_LINK | 2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
node.neis[DtPolyUtils.FindEdge(node, tile, tile.header.bmin.Z, 2)] = DtNavMesh.DT_EXT_LINK | 6;
|
node.neis[DtPolyUtils.FindEdge(node, tile, tile.header.bmin.Z, 2)] = DT_EXT_LINK | 6;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,8 @@ using DotRecast.Detour.TileCache.Io;
|
||||||
|
|
||||||
namespace DotRecast.Detour.TileCache
|
namespace DotRecast.Detour.TileCache
|
||||||
{
|
{
|
||||||
|
using static DtDetour;
|
||||||
|
|
||||||
public class DtTileCache
|
public class DtTileCache
|
||||||
{
|
{
|
||||||
private int m_tileLutSize; // < Tile hash lookup size (must be pot).
|
private int m_tileLutSize; // < Tile hash lookup size (must be pot).
|
||||||
|
@ -160,7 +162,7 @@ namespace DotRecast.Detour.TileCache
|
||||||
List<long> tiles = new List<long>();
|
List<long> tiles = new List<long>();
|
||||||
|
|
||||||
// Find tile based on hash.
|
// Find tile based on hash.
|
||||||
int h = DtNavMesh.ComputeTileHash(tx, ty, m_tileLutMask);
|
int h = ComputeTileHash(tx, ty, m_tileLutMask);
|
||||||
DtCompressedTile tile = m_posLookup[h];
|
DtCompressedTile tile = m_posLookup[h];
|
||||||
while (tile != null)
|
while (tile != null)
|
||||||
{
|
{
|
||||||
|
@ -178,7 +180,7 @@ namespace DotRecast.Detour.TileCache
|
||||||
DtCompressedTile GetTileAt(int tx, int ty, int tlayer)
|
DtCompressedTile GetTileAt(int tx, int ty, int tlayer)
|
||||||
{
|
{
|
||||||
// Find tile based on hash.
|
// Find tile based on hash.
|
||||||
int h = DtNavMesh.ComputeTileHash(tx, ty, m_tileLutMask);
|
int h = ComputeTileHash(tx, ty, m_tileLutMask);
|
||||||
DtCompressedTile tile = m_posLookup[h];
|
DtCompressedTile tile = m_posLookup[h];
|
||||||
while (tile != null)
|
while (tile != null)
|
||||||
{
|
{
|
||||||
|
@ -266,7 +268,7 @@ namespace DotRecast.Detour.TileCache
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insert tile into the position lut.
|
// Insert tile into the position lut.
|
||||||
int h = DtNavMesh.ComputeTileHash(header.tx, header.ty, m_tileLutMask);
|
int h = ComputeTileHash(header.tx, header.ty, m_tileLutMask);
|
||||||
tile.next = m_posLookup[h];
|
tile.next = m_posLookup[h];
|
||||||
m_posLookup[h] = tile;
|
m_posLookup[h] = tile;
|
||||||
|
|
||||||
|
@ -305,7 +307,7 @@ namespace DotRecast.Detour.TileCache
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove tile from hash lookup.
|
// Remove tile from hash lookup.
|
||||||
int h = DtNavMesh.ComputeTileHash(tile.header.tx, tile.header.ty, m_tileLutMask);
|
int h = ComputeTileHash(tile.header.tx, tile.header.ty, m_tileLutMask);
|
||||||
DtCompressedTile prev = null;
|
DtCompressedTile prev = null;
|
||||||
DtCompressedTile cur = m_posLookup[h];
|
DtCompressedTile cur = m_posLookup[h];
|
||||||
while (cur != null)
|
while (cur != null)
|
||||||
|
|
|
@ -0,0 +1,176 @@
|
||||||
|
using DotRecast.Core.Numerics;
|
||||||
|
|
||||||
|
namespace DotRecast.Detour
|
||||||
|
{
|
||||||
|
public static class DtDetour
|
||||||
|
{
|
||||||
|
/** A magic number used to detect compatibility of navigation tile data. */
|
||||||
|
public const int DT_NAVMESH_MAGIC = 'D' << 24 | 'N' << 16 | 'A' << 8 | 'V';
|
||||||
|
|
||||||
|
/** A version number used to detect compatibility of navigation tile data. */
|
||||||
|
public const int DT_NAVMESH_VERSION = 7;
|
||||||
|
|
||||||
|
public const int DT_NAVMESH_VERSION_RECAST4J_FIRST = 0x8807;
|
||||||
|
public const int DT_NAVMESH_VERSION_RECAST4J_NO_POLY_FIRSTLINK = 0x8808;
|
||||||
|
public const int DT_NAVMESH_VERSION_RECAST4J_32BIT_BVTREE = 0x8809;
|
||||||
|
public const int DT_NAVMESH_VERSION_RECAST4J_LAST = 0x8809;
|
||||||
|
|
||||||
|
/** A magic number used to detect the compatibility of navigation tile states. */
|
||||||
|
public const int DT_NAVMESH_STATE_MAGIC = 'D' << 24 | 'N' << 16 | 'M' << 8 | 'S';
|
||||||
|
|
||||||
|
/** A version number used to detect compatibility of navigation tile states. */
|
||||||
|
public const int DT_NAVMESH_STATE_VERSION = 1;
|
||||||
|
|
||||||
|
public const int DT_SALT_BITS = 16;
|
||||||
|
public const int DT_TILE_BITS = 28;
|
||||||
|
public const int DT_POLY_BITS = 20;
|
||||||
|
|
||||||
|
/// A flag that indicates that an entity links to an external entity.
|
||||||
|
/// (E.g. A polygon edge is a portal that links to another polygon.)
|
||||||
|
public const int DT_EXT_LINK = 0x8000;
|
||||||
|
|
||||||
|
/// A value that indicates the entity does not link to anything.
|
||||||
|
public const int DT_NULL_LINK = unchecked((int)0xffffffff);
|
||||||
|
|
||||||
|
/// A flag that indicates that an off-mesh connection can be traversed in
|
||||||
|
/// both directions. (Is bidirectional.)
|
||||||
|
public const int DT_OFFMESH_CON_BIDIR = 1;
|
||||||
|
|
||||||
|
/// The maximum number of user defined area ids.
|
||||||
|
public const int DT_MAX_AREAS = 64;
|
||||||
|
|
||||||
|
/// Limit raycasting during any angle pahfinding
|
||||||
|
/// The limit is given as a multiple of the character radius
|
||||||
|
public const float DT_RAY_CAST_LIMIT_PROPORTIONS = 50.0f;
|
||||||
|
|
||||||
|
/// @{
|
||||||
|
/// @name Encoding and Decoding
|
||||||
|
/// These functions are generally meant for internal use only.
|
||||||
|
/// Derives a standard polygon reference.
|
||||||
|
/// @note This function is generally meant for internal use only.
|
||||||
|
/// @param[in] salt The tile's salt value.
|
||||||
|
/// @param[in] it The index of the tile.
|
||||||
|
/// @param[in] ip The index of the polygon within the tile.
|
||||||
|
public static long EncodePolyId(int salt, int it, int ip)
|
||||||
|
{
|
||||||
|
return (((long)salt) << (DT_POLY_BITS + DT_TILE_BITS)) | ((long)it << DT_POLY_BITS) | (long)ip;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Decodes a standard polygon reference.
|
||||||
|
/// @note This function is generally meant for internal use only.
|
||||||
|
/// @param[in] ref The polygon reference to decode.
|
||||||
|
/// @param[out] salt The tile's salt value.
|
||||||
|
/// @param[out] it The index of the tile.
|
||||||
|
/// @param[out] ip The index of the polygon within the tile.
|
||||||
|
/// @see #encodePolyId
|
||||||
|
public static void DecodePolyId(long refs, out int salt, out int it, out int ip)
|
||||||
|
{
|
||||||
|
long saltMask = (1L << DT_SALT_BITS) - 1;
|
||||||
|
long tileMask = (1L << DT_TILE_BITS) - 1;
|
||||||
|
long polyMask = (1L << DT_POLY_BITS) - 1;
|
||||||
|
salt = (int)((refs >> (DT_POLY_BITS + DT_TILE_BITS)) & saltMask);
|
||||||
|
it = (int)((refs >> DT_POLY_BITS) & tileMask);
|
||||||
|
ip = (int)(refs & polyMask);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Extracts a tile's salt value from the specified polygon reference.
|
||||||
|
/// @note This function is generally meant for internal use only.
|
||||||
|
/// @param[in] ref The polygon reference.
|
||||||
|
/// @see #encodePolyId
|
||||||
|
public static int DecodePolyIdSalt(long refs)
|
||||||
|
{
|
||||||
|
long saltMask = (1L << DT_SALT_BITS) - 1;
|
||||||
|
return (int)((refs >> (DT_POLY_BITS + DT_TILE_BITS)) & saltMask);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Extracts the tile's index from the specified polygon reference.
|
||||||
|
/// @note This function is generally meant for internal use only.
|
||||||
|
/// @param[in] ref The polygon reference.
|
||||||
|
/// @see #encodePolyId
|
||||||
|
public static int DecodePolyIdTile(long refs)
|
||||||
|
{
|
||||||
|
long tileMask = (1L << DT_TILE_BITS) - 1;
|
||||||
|
return (int)((refs >> DT_POLY_BITS) & tileMask);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Extracts the polygon's index (within its tile) from the specified
|
||||||
|
/// polygon reference.
|
||||||
|
/// @note This function is generally meant for internal use only.
|
||||||
|
/// @param[in] ref The polygon reference.
|
||||||
|
/// @see #encodePolyId
|
||||||
|
public static int DecodePolyIdPoly(long refs)
|
||||||
|
{
|
||||||
|
long polyMask = (1L << DT_POLY_BITS) - 1;
|
||||||
|
return (int)(refs & polyMask);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int ComputeTileHash(int x, int y, int mask)
|
||||||
|
{
|
||||||
|
uint h1 = 0x8da6b343; // Large multiplicative constants;
|
||||||
|
uint h2 = 0xd8163841; // here arbitrarily chosen primes
|
||||||
|
uint n = h1 * (uint)x + h2 * (uint)y;
|
||||||
|
return (int)(n & mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float GetSlabCoord(float[] verts, int va, int side)
|
||||||
|
{
|
||||||
|
if (side == 0 || side == 4)
|
||||||
|
{
|
||||||
|
return verts[va];
|
||||||
|
}
|
||||||
|
else if (side == 2 || side == 6)
|
||||||
|
{
|
||||||
|
return verts[va + 2];
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void CalcSlabEndPoints(float[] verts, int va, int vb, ref RcVec2f bmin, ref RcVec2f bmax, int side)
|
||||||
|
{
|
||||||
|
if (side == 0 || side == 4)
|
||||||
|
{
|
||||||
|
if (verts[va + 2] < verts[vb + 2])
|
||||||
|
{
|
||||||
|
bmin.X = verts[va + 2];
|
||||||
|
bmin.Y = verts[va + 1];
|
||||||
|
bmax.X = verts[vb + 2];
|
||||||
|
bmax.Y = verts[vb + 1];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bmin.X = verts[vb + 2];
|
||||||
|
bmin.Y = verts[vb + 1];
|
||||||
|
bmax.X = verts[va + 2];
|
||||||
|
bmax.Y = verts[va + 1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (side == 2 || side == 6)
|
||||||
|
{
|
||||||
|
if (verts[va + 0] < verts[vb + 0])
|
||||||
|
{
|
||||||
|
bmin.X = verts[va + 0];
|
||||||
|
bmin.Y = verts[va + 1];
|
||||||
|
bmax.X = verts[vb + 0];
|
||||||
|
bmax.Y = verts[vb + 1];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bmin.X = verts[vb + 0];
|
||||||
|
bmin.Y = verts[vb + 1];
|
||||||
|
bmax.X = verts[va + 0];
|
||||||
|
bmax.Y = verts[va + 1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get flags for edge in detail triangle.
|
||||||
|
/// @param[in] triFlags The flags for the triangle (last component of detail vertices above).
|
||||||
|
/// @param[in] edgeIndex The index of the first vertex of the edge. For instance, if 0,
|
||||||
|
/// returns flags for edge AB.
|
||||||
|
public static int GetDetailTriEdgeFlags(int triFlags, int edgeIndex)
|
||||||
|
{
|
||||||
|
return (triFlags >> (edgeIndex * 2)) & 0x3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,6 +22,8 @@ using System.Collections.Generic;
|
||||||
|
|
||||||
namespace DotRecast.Detour
|
namespace DotRecast.Detour
|
||||||
{
|
{
|
||||||
|
using static DtDetour;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines a navigation mesh tile.
|
* Defines a navigation mesh tile.
|
||||||
*/
|
*/
|
||||||
|
@ -41,7 +43,7 @@ namespace DotRecast.Detour
|
||||||
public readonly List<DtLink> links = new List<DtLink>();
|
public readonly List<DtLink> links = new List<DtLink>();
|
||||||
|
|
||||||
/** Index to the next free link. */
|
/** Index to the next free link. */
|
||||||
public int linksFreeList = DtNavMesh.DT_NULL_LINK; // FIXME: Remove
|
public int linksFreeList = DT_NULL_LINK; // FIXME: Remove
|
||||||
|
|
||||||
/** Tile flags. (See: #dtTileFlags) */
|
/** Tile flags. (See: #dtTileFlags) */
|
||||||
public int flags;
|
public int flags;
|
||||||
|
|
|
@ -25,56 +25,19 @@ using DotRecast.Core.Numerics;
|
||||||
|
|
||||||
namespace DotRecast.Detour
|
namespace DotRecast.Detour
|
||||||
{
|
{
|
||||||
|
using static DtDetour;
|
||||||
|
|
||||||
public class DtNavMesh
|
public class DtNavMesh
|
||||||
{
|
{
|
||||||
/** A magic number used to detect compatibility of navigation tile data. */
|
|
||||||
public const int DT_NAVMESH_MAGIC = 'D' << 24 | 'N' << 16 | 'A' << 8 | 'V';
|
|
||||||
|
|
||||||
/** A version number used to detect compatibility of navigation tile data. */
|
|
||||||
public const int DT_NAVMESH_VERSION = 7;
|
|
||||||
|
|
||||||
public const int DT_NAVMESH_VERSION_RECAST4J_FIRST = 0x8807;
|
|
||||||
public const int DT_NAVMESH_VERSION_RECAST4J_NO_POLY_FIRSTLINK = 0x8808;
|
|
||||||
public const int DT_NAVMESH_VERSION_RECAST4J_32BIT_BVTREE = 0x8809;
|
|
||||||
public const int DT_NAVMESH_VERSION_RECAST4J_LAST = 0x8809;
|
|
||||||
|
|
||||||
/** A magic number used to detect the compatibility of navigation tile states. */
|
|
||||||
public const int DT_NAVMESH_STATE_MAGIC = 'D' << 24 | 'N' << 16 | 'M' << 8 | 'S';
|
|
||||||
|
|
||||||
/** A version number used to detect compatibility of navigation tile states. */
|
|
||||||
public const int DT_NAVMESH_STATE_VERSION = 1;
|
|
||||||
|
|
||||||
public const int DT_SALT_BITS = 16;
|
|
||||||
public const int DT_TILE_BITS = 28;
|
|
||||||
public const int DT_POLY_BITS = 20;
|
|
||||||
|
|
||||||
/// A flag that indicates that an entity links to an external entity.
|
|
||||||
/// (E.g. A polygon edge is a portal that links to another polygon.)
|
|
||||||
public const int DT_EXT_LINK = 0x8000;
|
|
||||||
|
|
||||||
/// A value that indicates the entity does not link to anything.
|
|
||||||
public const int DT_NULL_LINK = unchecked((int)0xffffffff);
|
|
||||||
|
|
||||||
/// A flag that indicates that an off-mesh connection can be traversed in
|
|
||||||
/// both directions. (Is bidirectional.)
|
|
||||||
public const int DT_OFFMESH_CON_BIDIR = 1;
|
|
||||||
|
|
||||||
/// The maximum number of user defined area ids.
|
|
||||||
public const int DT_MAX_AREAS = 64;
|
|
||||||
|
|
||||||
/// Limit raycasting during any angle pahfinding
|
|
||||||
/// The limit is given as a multiple of the character radius
|
|
||||||
public const float DT_RAY_CAST_LIMIT_PROPORTIONS = 50.0f;
|
|
||||||
|
|
||||||
private readonly DtNavMeshParams m_params; //< Current initialization params. TODO: do not store this info twice.
|
private readonly DtNavMeshParams m_params; //< Current initialization params. TODO: do not store this info twice.
|
||||||
private readonly RcVec3f m_orig; // < Origin of the tile (0,0)
|
private readonly RcVec3f m_orig; // < Origin of the tile (0,0)
|
||||||
private readonly float m_tileWidth;// < Dimensions of each tile.
|
private readonly float m_tileWidth; // < Dimensions of each tile.
|
||||||
private readonly float m_tileHeight; // < Dimensions of each tile.
|
private readonly float m_tileHeight; // < Dimensions of each tile.
|
||||||
private readonly int m_maxTiles; // < Max number of tiles.
|
private readonly int m_maxTiles; // < Max number of tiles.
|
||||||
private readonly int m_tileLutMask; // < Tile hash lookup mask.
|
private readonly int m_tileLutMask; // < Tile hash lookup mask.
|
||||||
|
|
||||||
private readonly Dictionary<int, List<DtMeshTile>> m_posLookup = new Dictionary<int, List<DtMeshTile>>(); //< Tile hash lookup.
|
private readonly Dictionary<int, List<DtMeshTile>> m_posLookup; //< Tile hash lookup.
|
||||||
private readonly LinkedList<DtMeshTile> m_nextFree = new LinkedList<DtMeshTile>(); //< Freelist of tiles.
|
private readonly LinkedList<DtMeshTile> m_nextFree; //< Freelist of tiles.
|
||||||
private readonly DtMeshTile[] m_tiles; //< List of tiles.
|
private readonly DtMeshTile[] m_tiles; //< List of tiles.
|
||||||
|
|
||||||
/** The maximum number of vertices per navigation polygon. */
|
/** The maximum number of vertices per navigation polygon. */
|
||||||
|
@ -98,6 +61,8 @@ namespace DotRecast.Detour
|
||||||
m_maxTiles = option.maxTiles;
|
m_maxTiles = option.maxTiles;
|
||||||
m_maxVertPerPoly = maxVertsPerPoly;
|
m_maxVertPerPoly = maxVertsPerPoly;
|
||||||
m_tileLutMask = Math.Max(1, DtUtils.NextPow2(option.maxTiles)) - 1;
|
m_tileLutMask = Math.Max(1, DtUtils.NextPow2(option.maxTiles)) - 1;
|
||||||
|
m_posLookup = new Dictionary<int, List<DtMeshTile>>();
|
||||||
|
m_nextFree = new LinkedList<DtMeshTile>();
|
||||||
m_tiles = new DtMeshTile[m_maxTiles];
|
m_tiles = new DtMeshTile[m_maxTiles];
|
||||||
for (int i = 0; i < m_maxTiles; i++)
|
for (int i = 0; i < m_maxTiles; i++)
|
||||||
{
|
{
|
||||||
|
@ -155,67 +120,6 @@ namespace DotRecast.Detour
|
||||||
return EncodePolyId(tile.salt, it, 0);
|
return EncodePolyId(tile.salt, it, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @{
|
|
||||||
/// @name Encoding and Decoding
|
|
||||||
/// These functions are generally meant for internal use only.
|
|
||||||
/// Derives a standard polygon reference.
|
|
||||||
/// @note This function is generally meant for internal use only.
|
|
||||||
/// @param[in] salt The tile's salt value.
|
|
||||||
/// @param[in] it The index of the tile.
|
|
||||||
/// @param[in] ip The index of the polygon within the tile.
|
|
||||||
public static long EncodePolyId(int salt, int it, int ip)
|
|
||||||
{
|
|
||||||
return (((long)salt) << (DT_POLY_BITS + DT_TILE_BITS)) | ((long)it << DT_POLY_BITS) | (long)ip;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Decodes a standard polygon reference.
|
|
||||||
/// @note This function is generally meant for internal use only.
|
|
||||||
/// @param[in] ref The polygon reference to decode.
|
|
||||||
/// @param[out] salt The tile's salt value.
|
|
||||||
/// @param[out] it The index of the tile.
|
|
||||||
/// @param[out] ip The index of the polygon within the tile.
|
|
||||||
/// @see #encodePolyId
|
|
||||||
static void DecodePolyId(long refs, out int salt, out int it, out int ip)
|
|
||||||
{
|
|
||||||
long saltMask = (1L << DT_SALT_BITS) - 1;
|
|
||||||
long tileMask = (1L << DT_TILE_BITS) - 1;
|
|
||||||
long polyMask = (1L << DT_POLY_BITS) - 1;
|
|
||||||
salt = (int)((refs >> (DT_POLY_BITS + DT_TILE_BITS)) & saltMask);
|
|
||||||
it = (int)((refs >> DT_POLY_BITS) & tileMask);
|
|
||||||
ip = (int)(refs & polyMask);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Extracts a tile's salt value from the specified polygon reference.
|
|
||||||
/// @note This function is generally meant for internal use only.
|
|
||||||
/// @param[in] ref The polygon reference.
|
|
||||||
/// @see #encodePolyId
|
|
||||||
static int DecodePolyIdSalt(long refs)
|
|
||||||
{
|
|
||||||
long saltMask = (1L << DT_SALT_BITS) - 1;
|
|
||||||
return (int)((refs >> (DT_POLY_BITS + DT_TILE_BITS)) & saltMask);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Extracts the tile's index from the specified polygon reference.
|
|
||||||
/// @note This function is generally meant for internal use only.
|
|
||||||
/// @param[in] ref The polygon reference.
|
|
||||||
/// @see #encodePolyId
|
|
||||||
public static int DecodePolyIdTile(long refs)
|
|
||||||
{
|
|
||||||
long tileMask = (1L << DT_TILE_BITS) - 1;
|
|
||||||
return (int)((refs >> DT_POLY_BITS) & tileMask);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Extracts the polygon's index (within its tile) from the specified
|
|
||||||
/// polygon reference.
|
|
||||||
/// @note This function is generally meant for internal use only.
|
|
||||||
/// @param[in] ref The polygon reference.
|
|
||||||
/// @see #encodePolyId
|
|
||||||
static int DecodePolyIdPoly(long refs)
|
|
||||||
{
|
|
||||||
long polyMask = (1L << DT_POLY_BITS) - 1;
|
|
||||||
return (int)(refs & polyMask);
|
|
||||||
}
|
|
||||||
|
|
||||||
private int AllocLink(DtMeshTile tile)
|
private int AllocLink(DtMeshTile tile)
|
||||||
{
|
{
|
||||||
if (tile.linksFreeList == DT_NULL_LINK)
|
if (tile.linksFreeList == DT_NULL_LINK)
|
||||||
|
@ -509,7 +413,7 @@ namespace DotRecast.Detour
|
||||||
tile.flags = flags;
|
tile.flags = flags;
|
||||||
tile.links.Clear();
|
tile.links.Clear();
|
||||||
tile.polyLinks = new int[data.polys.Length];
|
tile.polyLinks = new int[data.polys.Length];
|
||||||
Array.Fill(tile.polyLinks, DtNavMesh.DT_NULL_LINK);
|
Array.Fill(tile.polyLinks, DT_NULL_LINK);
|
||||||
|
|
||||||
// Insert tile into the position lut.
|
// Insert tile into the position lut.
|
||||||
GetTileListByPos(header.x, header.y).Add(tile);
|
GetTileListByPos(header.x, header.y).Add(tile);
|
||||||
|
@ -622,7 +526,7 @@ namespace DotRecast.Detour
|
||||||
|
|
||||||
tile.flags = 0;
|
tile.flags = 0;
|
||||||
tile.links.Clear();
|
tile.links.Clear();
|
||||||
tile.linksFreeList = DtNavMesh.DT_NULL_LINK;
|
tile.linksFreeList = DT_NULL_LINK;
|
||||||
|
|
||||||
// Update salt, salt should never be zero.
|
// Update salt, salt should never be zero.
|
||||||
tile.salt = (tile.salt + 1) & ((1 << DT_SALT_BITS) - 1);
|
tile.salt = (tile.salt + 1) & ((1 << DT_SALT_BITS) - 1);
|
||||||
|
@ -956,59 +860,7 @@ namespace DotRecast.Detour
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
static float GetSlabCoord(float[] verts, int va, int side)
|
private bool OverlapSlabs(RcVec2f amin, RcVec2f amax, RcVec2f bmin, RcVec2f bmax, float px, float py)
|
||||||
{
|
|
||||||
if (side == 0 || side == 4)
|
|
||||||
{
|
|
||||||
return verts[va];
|
|
||||||
}
|
|
||||||
else if (side == 2 || side == 6)
|
|
||||||
{
|
|
||||||
return verts[va + 2];
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void CalcSlabEndPoints(float[] verts, int va, int vb, ref RcVec2f bmin, ref RcVec2f bmax, int side)
|
|
||||||
{
|
|
||||||
if (side == 0 || side == 4)
|
|
||||||
{
|
|
||||||
if (verts[va + 2] < verts[vb + 2])
|
|
||||||
{
|
|
||||||
bmin.X = verts[va + 2];
|
|
||||||
bmin.Y = verts[va + 1];
|
|
||||||
bmax.X = verts[vb + 2];
|
|
||||||
bmax.Y = verts[vb + 1];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bmin.X = verts[vb + 2];
|
|
||||||
bmin.Y = verts[vb + 1];
|
|
||||||
bmax.X = verts[va + 2];
|
|
||||||
bmax.Y = verts[va + 1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (side == 2 || side == 6)
|
|
||||||
{
|
|
||||||
if (verts[va + 0] < verts[vb + 0])
|
|
||||||
{
|
|
||||||
bmin.X = verts[va + 0];
|
|
||||||
bmin.Y = verts[va + 1];
|
|
||||||
bmax.X = verts[vb + 0];
|
|
||||||
bmax.Y = verts[vb + 1];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bmin.X = verts[vb + 0];
|
|
||||||
bmin.Y = verts[vb + 1];
|
|
||||||
bmax.X = verts[va + 0];
|
|
||||||
bmax.Y = verts[va + 1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool OverlapSlabs(RcVec2f amin, RcVec2f amax, RcVec2f bmin, RcVec2f bmax, float px, float py)
|
|
||||||
{
|
{
|
||||||
// Check for horizontal overlap.
|
// Check for horizontal overlap.
|
||||||
// The segment is shrunken a little so that slabs which touch
|
// The segment is shrunken a little so that slabs which touch
|
||||||
|
@ -1496,14 +1348,6 @@ namespace DotRecast.Detour
|
||||||
return EncodePolyId(tile.salt, tile.index, 0);
|
return EncodePolyId(tile.salt, tile.index, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int ComputeTileHash(int x, int y, int mask)
|
|
||||||
{
|
|
||||||
uint h1 = 0x8da6b343; // Large multiplicative constants;
|
|
||||||
uint h2 = 0xd8163841; // here arbitrarily chosen primes
|
|
||||||
uint n = h1 * (uint)x + h2 * (uint)y;
|
|
||||||
return (int)(n & mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Gets the endpoints for an off-mesh connection, ordered by "direction of travel".
|
/// Gets the endpoints for an off-mesh connection, ordered by "direction of travel".
|
||||||
/// @param[in] prevRef The reference of the polygon before the connection.
|
/// @param[in] prevRef The reference of the polygon before the connection.
|
||||||
/// @param[in] polyRef The reference of the off-mesh connection polygon.
|
/// @param[in] polyRef The reference of the off-mesh connection polygon.
|
||||||
|
@ -1745,20 +1589,6 @@ namespace DotRecast.Detour
|
||||||
return center;
|
return center;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get flags for edge in detail triangle.
|
|
||||||
*
|
|
||||||
* @param triFlags
|
|
||||||
* The flags for the triangle (last component of detail vertices above).
|
|
||||||
* @param edgeIndex
|
|
||||||
* The index of the first vertex of the edge. For instance, if 0,
|
|
||||||
* @return flags for edge AB.
|
|
||||||
*/
|
|
||||||
public static int GetDetailTriEdgeFlags(int triFlags, int edgeIndex)
|
|
||||||
{
|
|
||||||
return (triFlags >> (edgeIndex * 2)) & 0x3;
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<DtMeshTile> GetTileListByPos(int x, int z)
|
private List<DtMeshTile> GetTileListByPos(int x, int z)
|
||||||
{
|
{
|
||||||
var tileHash = ComputeTileHash(x, z, m_tileLutMask);
|
var tileHash = ComputeTileHash(x, z, m_tileLutMask);
|
||||||
|
|
|
@ -24,6 +24,8 @@ using DotRecast.Core.Numerics;
|
||||||
|
|
||||||
namespace DotRecast.Detour
|
namespace DotRecast.Detour
|
||||||
{
|
{
|
||||||
|
using static DtDetour;
|
||||||
|
|
||||||
public static class DtNavMeshBuilder
|
public static class DtNavMeshBuilder
|
||||||
{
|
{
|
||||||
const int MESH_NULL_IDX = 0xffff;
|
const int MESH_NULL_IDX = 0xffff;
|
||||||
|
@ -424,8 +426,8 @@ namespace DotRecast.Detour
|
||||||
DtOffMeshConnection[] offMeshCons = new DtOffMeshConnection[storedOffMeshConCount];
|
DtOffMeshConnection[] offMeshCons = new DtOffMeshConnection[storedOffMeshConCount];
|
||||||
|
|
||||||
// Store header
|
// Store header
|
||||||
header.magic = DtNavMesh.DT_NAVMESH_MAGIC;
|
header.magic = DT_NAVMESH_MAGIC;
|
||||||
header.version = DtNavMesh.DT_NAVMESH_VERSION;
|
header.version = DT_NAVMESH_VERSION;
|
||||||
header.x = option.tileX;
|
header.x = option.tileX;
|
||||||
header.y = option.tileZ;
|
header.y = option.tileZ;
|
||||||
header.layer = option.tileLayer;
|
header.layer = option.tileLayer;
|
||||||
|
@ -497,13 +499,13 @@ namespace DotRecast.Detour
|
||||||
if (dir == 0xf) // Border
|
if (dir == 0xf) // Border
|
||||||
p.neis[j] = 0;
|
p.neis[j] = 0;
|
||||||
else if (dir == 0) // Portal x-
|
else if (dir == 0) // Portal x-
|
||||||
p.neis[j] = DtNavMesh.DT_EXT_LINK | 4;
|
p.neis[j] = DT_EXT_LINK | 4;
|
||||||
else if (dir == 1) // Portal z+
|
else if (dir == 1) // Portal z+
|
||||||
p.neis[j] = DtNavMesh.DT_EXT_LINK | 2;
|
p.neis[j] = DT_EXT_LINK | 2;
|
||||||
else if (dir == 2) // Portal x+
|
else if (dir == 2) // Portal x+
|
||||||
p.neis[j] = DtNavMesh.DT_EXT_LINK | 0;
|
p.neis[j] = DT_EXT_LINK | 0;
|
||||||
else if (dir == 3) // Portal z-
|
else if (dir == 3) // Portal z-
|
||||||
p.neis[j] = DtNavMesh.DT_EXT_LINK | 6;
|
p.neis[j] = DT_EXT_LINK | 6;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -622,7 +624,7 @@ namespace DotRecast.Detour
|
||||||
}
|
}
|
||||||
|
|
||||||
con.rad = option.offMeshConRad[i];
|
con.rad = option.offMeshConRad[i];
|
||||||
con.flags = option.offMeshConDir[i] != 0 ? DtNavMesh.DT_OFFMESH_CON_BIDIR : 0;
|
con.flags = option.offMeshConDir[i] != 0 ? DT_OFFMESH_CON_BIDIR : 0;
|
||||||
con.side = offMeshConClass[i * 2 + 1];
|
con.side = offMeshConClass[i * 2 + 1];
|
||||||
if (option.offMeshConUserID != null)
|
if (option.offMeshConUserID != null)
|
||||||
con.userId = option.offMeshConUserID[i];
|
con.userId = option.offMeshConUserID[i];
|
||||||
|
|
|
@ -26,6 +26,8 @@ using DotRecast.Core.Numerics;
|
||||||
|
|
||||||
namespace DotRecast.Detour
|
namespace DotRecast.Detour
|
||||||
{
|
{
|
||||||
|
using static DtDetour;
|
||||||
|
|
||||||
public class DtNavMeshQuery
|
public class DtNavMeshQuery
|
||||||
{
|
{
|
||||||
/// < Add a vertex at every polygon edge crossing.
|
/// < Add a vertex at every polygon edge crossing.
|
||||||
|
@ -300,7 +302,7 @@ namespace DotRecast.Detour
|
||||||
parentRef = m_nodePool.GetNodeAtIdx(bestNode.pidx).id;
|
parentRef = m_nodePool.GetNodeAtIdx(bestNode.pidx).id;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = bestTile.polyLinks[bestPoly.index]; i != DtNavMesh.DT_NULL_LINK; i = bestTile.links[i].next)
|
for (int i = bestTile.polyLinks[bestPoly.index]; i != DT_NULL_LINK; i = bestTile.links[i].next)
|
||||||
{
|
{
|
||||||
DtLink link = bestTile.links[i];
|
DtLink link = bestTile.links[i];
|
||||||
long neighbourRef = link.refs;
|
long neighbourRef = link.refs;
|
||||||
|
@ -775,7 +777,7 @@ namespace DotRecast.Detour
|
||||||
// so it is enough to compute it from the first tile.
|
// so it is enough to compute it from the first tile.
|
||||||
DtMeshTile tile = m_nav.GetTileByRef(startRef);
|
DtMeshTile tile = m_nav.GetTileByRef(startRef);
|
||||||
float agentRadius = tile.data.header.walkableRadius;
|
float agentRadius = tile.data.header.walkableRadius;
|
||||||
raycastLimitSqr = RcMath.Sqr(agentRadius * DtNavMesh.DT_RAY_CAST_LIMIT_PROPORTIONS);
|
raycastLimitSqr = RcMath.Sqr(agentRadius * DT_RAY_CAST_LIMIT_PROPORTIONS);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (startRef == endRef)
|
if (startRef == endRef)
|
||||||
|
@ -851,7 +853,7 @@ namespace DotRecast.Detour
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = bestTile.polyLinks[bestPoly.index]; i != DtNavMesh.DT_NULL_LINK; i = bestTile.links[i].next)
|
for (int i = bestTile.polyLinks[bestPoly.index]; i != DT_NULL_LINK; i = bestTile.links[i].next)
|
||||||
{
|
{
|
||||||
long neighbourRef = bestTile.links[i].refs;
|
long neighbourRef = bestTile.links[i].refs;
|
||||||
|
|
||||||
|
@ -1046,7 +1048,7 @@ namespace DotRecast.Detour
|
||||||
// so it is enough to compute it from the first tile.
|
// so it is enough to compute it from the first tile.
|
||||||
DtMeshTile tile = m_nav.GetTileByRef(startRef);
|
DtMeshTile tile = m_nav.GetTileByRef(startRef);
|
||||||
float agentRadius = tile.data.header.walkableRadius;
|
float agentRadius = tile.data.header.walkableRadius;
|
||||||
m_query.raycastLimitSqr = RcMath.Sqr(agentRadius * DtNavMesh.DT_RAY_CAST_LIMIT_PROPORTIONS);
|
m_query.raycastLimitSqr = RcMath.Sqr(agentRadius * DT_RAY_CAST_LIMIT_PROPORTIONS);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (startRef == endRef)
|
if (startRef == endRef)
|
||||||
|
@ -1172,7 +1174,7 @@ namespace DotRecast.Detour
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = bestTile.polyLinks[bestPoly.index]; i != DtNavMesh.DT_NULL_LINK; i = bestTile.links[i].next)
|
for (int i = bestTile.polyLinks[bestPoly.index]; i != DT_NULL_LINK; i = bestTile.links[i].next)
|
||||||
{
|
{
|
||||||
long neighbourRef = bestTile.links[i].refs;
|
long neighbourRef = bestTile.links[i].refs;
|
||||||
|
|
||||||
|
@ -1862,10 +1864,10 @@ namespace DotRecast.Detour
|
||||||
// Find links to neighbours.
|
// Find links to neighbours.
|
||||||
int nneis = 0;
|
int nneis = 0;
|
||||||
|
|
||||||
if ((curPoly.neis[j] & DtNavMesh.DT_EXT_LINK) != 0)
|
if ((curPoly.neis[j] & DT_EXT_LINK) != 0)
|
||||||
{
|
{
|
||||||
// Tile border.
|
// Tile border.
|
||||||
for (int k = curTile.polyLinks[curPoly.index]; k != DtNavMesh.DT_NULL_LINK; k = curTile.links[k].next)
|
for (int k = curTile.polyLinks[curPoly.index]; k != DT_NULL_LINK; k = curTile.links[k].next)
|
||||||
{
|
{
|
||||||
DtLink link = curTile.links[k];
|
DtLink link = curTile.links[k];
|
||||||
if (link.edge == j)
|
if (link.edge == j)
|
||||||
|
@ -1960,7 +1962,8 @@ namespace DotRecast.Detour
|
||||||
visited[n++] = node.id;
|
visited[n++] = node.id;
|
||||||
if (n >= maxVisitedSize)
|
if (n >= maxVisitedSize)
|
||||||
{
|
{
|
||||||
status |= DtStatus.DT_BUFFER_TOO_SMALL;;
|
status |= DtStatus.DT_BUFFER_TOO_SMALL;
|
||||||
|
;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2010,7 +2013,7 @@ namespace DotRecast.Detour
|
||||||
|
|
||||||
// Find the link that points to the 'to' polygon.
|
// Find the link that points to the 'to' polygon.
|
||||||
DtLink link = null;
|
DtLink link = null;
|
||||||
for (int i = fromTile.polyLinks[fromPoly.index]; i != DtNavMesh.DT_NULL_LINK; i = fromTile.links[i].next)
|
for (int i = fromTile.polyLinks[fromPoly.index]; i != DT_NULL_LINK; i = fromTile.links[i].next)
|
||||||
{
|
{
|
||||||
if (fromTile.links[i].refs == to)
|
if (fromTile.links[i].refs == to)
|
||||||
{
|
{
|
||||||
|
@ -2028,7 +2031,7 @@ namespace DotRecast.Detour
|
||||||
if (fromPoly.GetPolyType() == DtPolyTypes.DT_POLYTYPE_OFFMESH_CONNECTION)
|
if (fromPoly.GetPolyType() == DtPolyTypes.DT_POLYTYPE_OFFMESH_CONNECTION)
|
||||||
{
|
{
|
||||||
// Find link that points to first vertex.
|
// Find link that points to first vertex.
|
||||||
for (int i = fromTile.polyLinks[fromPoly.index]; i != DtNavMesh.DT_NULL_LINK; i = fromTile.links[i].next)
|
for (int i = fromTile.polyLinks[fromPoly.index]; i != DT_NULL_LINK; i = fromTile.links[i].next)
|
||||||
{
|
{
|
||||||
if (fromTile.links[i].refs == to)
|
if (fromTile.links[i].refs == to)
|
||||||
{
|
{
|
||||||
|
@ -2050,7 +2053,7 @@ namespace DotRecast.Detour
|
||||||
|
|
||||||
if (toPoly.GetPolyType() == DtPolyTypes.DT_POLYTYPE_OFFMESH_CONNECTION)
|
if (toPoly.GetPolyType() == DtPolyTypes.DT_POLYTYPE_OFFMESH_CONNECTION)
|
||||||
{
|
{
|
||||||
for (int i = toTile.polyLinks[toPoly.index]; i != DtNavMesh.DT_NULL_LINK; i = toTile.links[i].next)
|
for (int i = toTile.polyLinks[toPoly.index]; i != DT_NULL_LINK; i = toTile.links[i].next)
|
||||||
{
|
{
|
||||||
if (toTile.links[i].refs == from)
|
if (toTile.links[i].refs == from)
|
||||||
{
|
{
|
||||||
|
@ -2326,7 +2329,7 @@ namespace DotRecast.Detour
|
||||||
// Follow neighbours.
|
// Follow neighbours.
|
||||||
long nextRef = 0;
|
long nextRef = 0;
|
||||||
|
|
||||||
for (int i = tile.polyLinks[poly.index]; i != DtNavMesh.DT_NULL_LINK; i = tile.links[i].next)
|
for (int i = tile.polyLinks[poly.index]; i != DT_NULL_LINK; i = tile.links[i].next)
|
||||||
{
|
{
|
||||||
DtLink link = tile.links[i];
|
DtLink link = tile.links[i];
|
||||||
|
|
||||||
|
@ -2567,7 +2570,7 @@ namespace DotRecast.Detour
|
||||||
resultParent.Add(parentRef);
|
resultParent.Add(parentRef);
|
||||||
resultCost.Add(bestNode.total);
|
resultCost.Add(bestNode.total);
|
||||||
|
|
||||||
for (int i = bestTile.polyLinks[bestPoly.index]; i != DtNavMesh.DT_NULL_LINK; i = bestTile.links[i].next)
|
for (int i = bestTile.polyLinks[bestPoly.index]; i != DT_NULL_LINK; i = bestTile.links[i].next)
|
||||||
{
|
{
|
||||||
DtLink link = bestTile.links[i];
|
DtLink link = bestTile.links[i];
|
||||||
long neighbourRef = link.refs;
|
long neighbourRef = link.refs;
|
||||||
|
@ -2744,7 +2747,7 @@ namespace DotRecast.Detour
|
||||||
resultParent.Add(parentRef);
|
resultParent.Add(parentRef);
|
||||||
resultCost.Add(bestNode.total);
|
resultCost.Add(bestNode.total);
|
||||||
|
|
||||||
for (int i = bestTile.polyLinks[bestPoly.index]; i != DtNavMesh.DT_NULL_LINK; i = bestTile.links[i].next)
|
for (int i = bestTile.polyLinks[bestPoly.index]; i != DT_NULL_LINK; i = bestTile.links[i].next)
|
||||||
{
|
{
|
||||||
DtLink link = bestTile.links[i];
|
DtLink link = bestTile.links[i];
|
||||||
long neighbourRef = link.refs;
|
long neighbourRef = link.refs;
|
||||||
|
@ -2899,7 +2902,7 @@ namespace DotRecast.Detour
|
||||||
long curRef = curNode.id;
|
long curRef = curNode.id;
|
||||||
m_nav.GetTileAndPolyByRefUnsafe(curRef, out var curTile, out var curPoly);
|
m_nav.GetTileAndPolyByRefUnsafe(curRef, out var curTile, out var curPoly);
|
||||||
|
|
||||||
for (int i = curTile.polyLinks[curPoly.index]; i != DtNavMesh.DT_NULL_LINK; i = curTile.links[i].next)
|
for (int i = curTile.polyLinks[curPoly.index]; i != DT_NULL_LINK; i = curTile.links[i].next)
|
||||||
{
|
{
|
||||||
DtLink link = curTile.links[i];
|
DtLink link = curTile.links[i];
|
||||||
long neighbourRef = link.refs;
|
long neighbourRef = link.refs;
|
||||||
|
@ -2967,7 +2970,7 @@ namespace DotRecast.Detour
|
||||||
|
|
||||||
// Connected polys do not overlap.
|
// Connected polys do not overlap.
|
||||||
bool connected = false;
|
bool connected = false;
|
||||||
for (int k = curTile.polyLinks[curPoly.index]; k != DtNavMesh.DT_NULL_LINK; k = curTile.links[k].next)
|
for (int k = curTile.polyLinks[curPoly.index]; k != DT_NULL_LINK; k = curTile.links[k].next)
|
||||||
{
|
{
|
||||||
if (curTile.links[k].refs == pastRef)
|
if (curTile.links[k].refs == pastRef)
|
||||||
{
|
{
|
||||||
|
@ -3073,10 +3076,10 @@ namespace DotRecast.Detour
|
||||||
{
|
{
|
||||||
// Skip non-solid edges.
|
// Skip non-solid edges.
|
||||||
ints.Clear();
|
ints.Clear();
|
||||||
if ((poly.neis[j] & DtNavMesh.DT_EXT_LINK) != 0)
|
if ((poly.neis[j] & DT_EXT_LINK) != 0)
|
||||||
{
|
{
|
||||||
// Tile border.
|
// Tile border.
|
||||||
for (int k = tile.polyLinks[poly.index]; k != DtNavMesh.DT_NULL_LINK; k = tile.links[k].next)
|
for (int k = tile.polyLinks[poly.index]; k != DT_NULL_LINK; k = tile.links[k].next)
|
||||||
{
|
{
|
||||||
DtLink link = tile.links[k];
|
DtLink link = tile.links[k];
|
||||||
if (link.edge == j)
|
if (link.edge == j)
|
||||||
|
@ -3240,11 +3243,11 @@ namespace DotRecast.Detour
|
||||||
for (int i = 0, j = bestPoly.vertCount - 1; i < bestPoly.vertCount; j = i++)
|
for (int i = 0, j = bestPoly.vertCount - 1; i < bestPoly.vertCount; j = i++)
|
||||||
{
|
{
|
||||||
// Skip non-solid edges.
|
// Skip non-solid edges.
|
||||||
if ((bestPoly.neis[j] & DtNavMesh.DT_EXT_LINK) != 0)
|
if ((bestPoly.neis[j] & DT_EXT_LINK) != 0)
|
||||||
{
|
{
|
||||||
// Tile border.
|
// Tile border.
|
||||||
bool solid = true;
|
bool solid = true;
|
||||||
for (int k = bestTile.polyLinks[bestPoly.index]; k != DtNavMesh.DT_NULL_LINK; k = bestTile.links[k].next)
|
for (int k = bestTile.polyLinks[bestPoly.index]; k != DT_NULL_LINK; k = bestTile.links[k].next)
|
||||||
{
|
{
|
||||||
DtLink link = bestTile.links[k];
|
DtLink link = bestTile.links[k];
|
||||||
if (link.edge == j)
|
if (link.edge == j)
|
||||||
|
@ -3300,7 +3303,7 @@ namespace DotRecast.Detour
|
||||||
bestvi = RcVecUtils.Create(bestTile.data.verts, vi);
|
bestvi = RcVecUtils.Create(bestTile.data.verts, vi);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = bestTile.polyLinks[bestPoly.index]; i != DtNavMesh.DT_NULL_LINK; i = bestTile.links[i].next)
|
for (int i = bestTile.polyLinks[bestPoly.index]; i != DT_NULL_LINK; i = bestTile.links[i].next)
|
||||||
{
|
{
|
||||||
DtLink link = bestTile.links[i];
|
DtLink link = bestTile.links[i];
|
||||||
long neighbourRef = link.refs;
|
long neighbourRef = link.refs;
|
||||||
|
|
|
@ -24,6 +24,8 @@ using DotRecast.Core.Numerics;
|
||||||
|
|
||||||
namespace DotRecast.Detour
|
namespace DotRecast.Detour
|
||||||
{
|
{
|
||||||
|
using static DtDetour;
|
||||||
|
|
||||||
public static class DtPathUtils
|
public static class DtPathUtils
|
||||||
{
|
{
|
||||||
private const int MAX_STEER_POINTS = 3;
|
private const int MAX_STEER_POINTS = 3;
|
||||||
|
@ -107,7 +109,7 @@ namespace DotRecast.Detour
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
for (int k = tile.polyLinks[poly.index]; k != DtNavMesh.DT_NULL_LINK; k = tile.links[k].next)
|
for (int k = tile.polyLinks[poly.index]; k != DT_NULL_LINK; k = tile.links[k].next)
|
||||||
{
|
{
|
||||||
DtLink link = tile.links[k];
|
DtLink link = tile.links[k];
|
||||||
if (link.refs != 0)
|
if (link.refs != 0)
|
||||||
|
|
|
@ -23,6 +23,8 @@ using DotRecast.Core.Numerics;
|
||||||
|
|
||||||
namespace DotRecast.Detour
|
namespace DotRecast.Detour
|
||||||
{
|
{
|
||||||
|
using static DtDetour;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <b>The Default Implementation</b>
|
* <b>The Default Implementation</b>
|
||||||
*
|
*
|
||||||
|
@ -50,7 +52,7 @@ namespace DotRecast.Detour
|
||||||
*/
|
*/
|
||||||
public class DtQueryDefaultFilter : IDtQueryFilter
|
public class DtQueryDefaultFilter : IDtQueryFilter
|
||||||
{
|
{
|
||||||
private readonly float[] m_areaCost = new float[DtNavMesh.DT_MAX_AREAS]; //< Cost per area type. (Used by default implementation.)
|
private readonly float[] m_areaCost = new float[DT_MAX_AREAS]; //< Cost per area type. (Used by default implementation.)
|
||||||
private int m_includeFlags; //< Flags for polygons that can be visited. (Used by default implementation.)
|
private int m_includeFlags; //< Flags for polygons that can be visited. (Used by default implementation.)
|
||||||
private int m_excludeFlags; //< Flags for polygons that should not be visited. (Used by default implementation.)
|
private int m_excludeFlags; //< Flags for polygons that should not be visited. (Used by default implementation.)
|
||||||
|
|
||||||
|
@ -58,7 +60,7 @@ namespace DotRecast.Detour
|
||||||
{
|
{
|
||||||
m_includeFlags = 0xffff;
|
m_includeFlags = 0xffff;
|
||||||
m_excludeFlags = 0;
|
m_excludeFlags = 0;
|
||||||
for (int i = 0; i < DtNavMesh.DT_MAX_AREAS; ++i)
|
for (int i = 0; i < DT_MAX_AREAS; ++i)
|
||||||
{
|
{
|
||||||
m_areaCost[i] = 1.0f;
|
m_areaCost[i] = 1.0f;
|
||||||
}
|
}
|
||||||
|
@ -68,12 +70,12 @@ namespace DotRecast.Detour
|
||||||
{
|
{
|
||||||
m_includeFlags = includeFlags;
|
m_includeFlags = includeFlags;
|
||||||
m_excludeFlags = excludeFlags;
|
m_excludeFlags = excludeFlags;
|
||||||
for (int i = 0; i < Math.Min(DtNavMesh.DT_MAX_AREAS, areaCost.Length); ++i)
|
for (int i = 0; i < Math.Min(DT_MAX_AREAS, areaCost.Length); ++i)
|
||||||
{
|
{
|
||||||
m_areaCost[i] = areaCost[i];
|
m_areaCost[i] = areaCost[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = areaCost.Length; i < DtNavMesh.DT_MAX_AREAS; ++i)
|
for (int i = areaCost.Length; i < DT_MAX_AREAS; ++i)
|
||||||
{
|
{
|
||||||
m_areaCost[i] = 1.0f;
|
m_areaCost[i] = 1.0f;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,8 @@ using DotRecast.Core;
|
||||||
|
|
||||||
namespace DotRecast.Detour.Io
|
namespace DotRecast.Detour.Io
|
||||||
{
|
{
|
||||||
|
using static DtDetour;
|
||||||
|
|
||||||
public class DtMeshDataReader
|
public class DtMeshDataReader
|
||||||
{
|
{
|
||||||
public const int DT_POLY_DETAIL_SIZE = 10;
|
public const int DT_POLY_DETAIL_SIZE = 10;
|
||||||
|
@ -53,10 +55,10 @@ namespace DotRecast.Detour.Io
|
||||||
DtMeshHeader header = new DtMeshHeader();
|
DtMeshHeader header = new DtMeshHeader();
|
||||||
data.header = header;
|
data.header = header;
|
||||||
header.magic = buf.GetInt();
|
header.magic = buf.GetInt();
|
||||||
if (header.magic != DtNavMesh.DT_NAVMESH_MAGIC)
|
if (header.magic != DT_NAVMESH_MAGIC)
|
||||||
{
|
{
|
||||||
header.magic = IOUtils.SwapEndianness(header.magic);
|
header.magic = IOUtils.SwapEndianness(header.magic);
|
||||||
if (header.magic != DtNavMesh.DT_NAVMESH_MAGIC)
|
if (header.magic != DT_NAVMESH_MAGIC)
|
||||||
{
|
{
|
||||||
throw new IOException("Invalid magic");
|
throw new IOException("Invalid magic");
|
||||||
}
|
}
|
||||||
|
@ -65,16 +67,16 @@ namespace DotRecast.Detour.Io
|
||||||
}
|
}
|
||||||
|
|
||||||
header.version = buf.GetInt();
|
header.version = buf.GetInt();
|
||||||
if (header.version != DtNavMesh.DT_NAVMESH_VERSION)
|
if (header.version != DT_NAVMESH_VERSION)
|
||||||
{
|
{
|
||||||
if (header.version < DtNavMesh.DT_NAVMESH_VERSION_RECAST4J_FIRST
|
if (header.version < DT_NAVMESH_VERSION_RECAST4J_FIRST
|
||||||
|| header.version > DtNavMesh.DT_NAVMESH_VERSION_RECAST4J_LAST)
|
|| header.version > DT_NAVMESH_VERSION_RECAST4J_LAST)
|
||||||
{
|
{
|
||||||
throw new IOException("Invalid version " + header.version);
|
throw new IOException("Invalid version " + header.version);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cCompatibility = header.version == DtNavMesh.DT_NAVMESH_VERSION;
|
bool cCompatibility = header.version == DT_NAVMESH_VERSION;
|
||||||
header.x = buf.GetInt();
|
header.x = buf.GetInt();
|
||||||
header.y = buf.GetInt();
|
header.y = buf.GetInt();
|
||||||
header.layer = buf.GetInt();
|
header.layer = buf.GetInt();
|
||||||
|
@ -141,7 +143,7 @@ namespace DotRecast.Detour.Io
|
||||||
for (int i = 0; i < polys.Length; i++)
|
for (int i = 0; i < polys.Length; i++)
|
||||||
{
|
{
|
||||||
polys[i] = new DtPoly(i, maxVertPerPoly);
|
polys[i] = new DtPoly(i, maxVertPerPoly);
|
||||||
if (header.version < DtNavMesh.DT_NAVMESH_VERSION_RECAST4J_NO_POLY_FIRSTLINK)
|
if (header.version < DT_NAVMESH_VERSION_RECAST4J_NO_POLY_FIRSTLINK)
|
||||||
{
|
{
|
||||||
buf.GetInt(); // polys[i].firstLink
|
buf.GetInt(); // polys[i].firstLink
|
||||||
}
|
}
|
||||||
|
@ -200,7 +202,7 @@ namespace DotRecast.Detour.Io
|
||||||
for (int i = 0; i < nodes.Length; i++)
|
for (int i = 0; i < nodes.Length; i++)
|
||||||
{
|
{
|
||||||
nodes[i] = new DtBVNode();
|
nodes[i] = new DtBVNode();
|
||||||
if (header.version < DtNavMesh.DT_NAVMESH_VERSION_RECAST4J_32BIT_BVTREE)
|
if (header.version < DT_NAVMESH_VERSION_RECAST4J_32BIT_BVTREE)
|
||||||
{
|
{
|
||||||
for (int j = 0; j < 3; j++)
|
for (int j = 0; j < 3; j++)
|
||||||
{
|
{
|
||||||
|
|
|
@ -21,13 +21,15 @@ using DotRecast.Core;
|
||||||
|
|
||||||
namespace DotRecast.Detour.Io
|
namespace DotRecast.Detour.Io
|
||||||
{
|
{
|
||||||
|
using static DtDetour;
|
||||||
|
|
||||||
public class DtMeshDataWriter : DtWriter
|
public class DtMeshDataWriter : DtWriter
|
||||||
{
|
{
|
||||||
public void Write(BinaryWriter stream, DtMeshData data, RcByteOrder order, bool cCompatibility)
|
public void Write(BinaryWriter stream, DtMeshData data, RcByteOrder order, bool cCompatibility)
|
||||||
{
|
{
|
||||||
DtMeshHeader header = data.header;
|
DtMeshHeader header = data.header;
|
||||||
Write(stream, header.magic, order);
|
Write(stream, header.magic, order);
|
||||||
Write(stream, cCompatibility ? DtNavMesh.DT_NAVMESH_VERSION : DtNavMesh.DT_NAVMESH_VERSION_RECAST4J_LAST, order);
|
Write(stream, cCompatibility ? DT_NAVMESH_VERSION : DT_NAVMESH_VERSION_RECAST4J_LAST, order);
|
||||||
Write(stream, header.x, order);
|
Write(stream, header.x, order);
|
||||||
Write(stream, header.y, order);
|
Write(stream, header.y, order);
|
||||||
Write(stream, header.layer, order);
|
Write(stream, header.layer, order);
|
||||||
|
|
|
@ -22,6 +22,8 @@ using DotRecast.Core;
|
||||||
|
|
||||||
namespace DotRecast.Detour.Io
|
namespace DotRecast.Detour.Io
|
||||||
{
|
{
|
||||||
|
using static DtDetour;
|
||||||
|
|
||||||
public class DtMeshSetReader
|
public class DtMeshSetReader
|
||||||
{
|
{
|
||||||
private readonly DtMeshDataReader meshReader = new DtMeshDataReader();
|
private readonly DtMeshDataReader meshReader = new DtMeshDataReader();
|
||||||
|
@ -147,7 +149,7 @@ namespace DotRecast.Detour.Io
|
||||||
int salt = ((refs >> (m_polyBits + m_tileBits)) & saltMask);
|
int salt = ((refs >> (m_polyBits + m_tileBits)) & saltMask);
|
||||||
int it = ((refs >> m_polyBits) & tileMask);
|
int it = ((refs >> m_polyBits) & tileMask);
|
||||||
int ip = refs & polyMask;
|
int ip = refs & polyMask;
|
||||||
return DtNavMesh.EncodePolyId(salt, it, ip);
|
return EncodePolyId(salt, it, ip);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -23,14 +23,14 @@ using DotRecast.Core.Numerics;
|
||||||
using DotRecast.Detour;
|
using DotRecast.Detour;
|
||||||
using DotRecast.Recast.Toolset.Builder;
|
using DotRecast.Recast.Toolset.Builder;
|
||||||
using DotRecast.Recast.Toolset.Geom;
|
using DotRecast.Recast.Toolset.Geom;
|
||||||
using static DotRecast.Recast.RcCommons;
|
using static DotRecast.Recast.RcRecast;
|
||||||
|
|
||||||
namespace DotRecast.Recast.Demo.Draw;
|
namespace DotRecast.Recast.Demo.Draw;
|
||||||
|
|
||||||
public class NavMeshRenderer
|
public class NavMeshRenderer
|
||||||
{
|
{
|
||||||
private readonly RecastDebugDraw _debugDraw;
|
private readonly RecastDebugDraw _debugDraw;
|
||||||
private readonly int _navMeshDrawFlags = RecastDebugDraw.DRAWNAVMESH_OFFMESHCONS | RecastDebugDraw.DRAWNAVMESH_CLOSEDLIST;
|
private readonly int _navMeshDrawFlags = RecastDebugDraw.DU_DRAWNAVMESH_OFFMESHCONS | RecastDebugDraw.DU_DRAWNAVMESH_CLOSEDLIST;
|
||||||
|
|
||||||
public NavMeshRenderer(RecastDebugDraw debugDraw)
|
public NavMeshRenderer(RecastDebugDraw debugDraw)
|
||||||
{
|
{
|
||||||
|
|
|
@ -22,16 +22,20 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using DotRecast.Core.Numerics;
|
using DotRecast.Core.Numerics;
|
||||||
using DotRecast.Detour;
|
using DotRecast.Detour;
|
||||||
|
using DotRecast.Detour.Crowd;
|
||||||
|
using DotRecast.Detour.Dynamic.Colliders;
|
||||||
using DotRecast.Recast.Toolset.Builder;
|
using DotRecast.Recast.Toolset.Builder;
|
||||||
using Silk.NET.OpenGL;
|
using Silk.NET.OpenGL;
|
||||||
|
|
||||||
namespace DotRecast.Recast.Demo.Draw;
|
namespace DotRecast.Recast.Demo.Draw;
|
||||||
|
|
||||||
|
using static DtDetour;
|
||||||
|
|
||||||
public class RecastDebugDraw : DebugDraw
|
public class RecastDebugDraw : DebugDraw
|
||||||
{
|
{
|
||||||
public static readonly int DRAWNAVMESH_OFFMESHCONS = 0x01;
|
public static readonly int DU_DRAWNAVMESH_OFFMESHCONS = 0x01;
|
||||||
public static readonly int DRAWNAVMESH_CLOSEDLIST = 0x02;
|
public static readonly int DU_DRAWNAVMESH_CLOSEDLIST = 0x02;
|
||||||
public static readonly int DRAWNAVMESH_COLOR_TILES = 0x04;
|
public static readonly int DU_DRAWNAVMESH_COLOR_TILES = 0x04;
|
||||||
|
|
||||||
public RecastDebugDraw(GL gl) : base(gl)
|
public RecastDebugDraw(GL gl) : base(gl)
|
||||||
{
|
{
|
||||||
|
@ -101,7 +105,7 @@ public class RecastDebugDraw : DebugDraw
|
||||||
|
|
||||||
public void DebugDrawNavMeshWithClosedList(DtNavMesh mesh, DtNavMeshQuery query, int flags)
|
public void DebugDrawNavMeshWithClosedList(DtNavMesh mesh, DtNavMeshQuery query, int flags)
|
||||||
{
|
{
|
||||||
DtNavMeshQuery q = (flags & DRAWNAVMESH_CLOSEDLIST) != 0 ? query : null;
|
DtNavMeshQuery q = (flags & DU_DRAWNAVMESH_CLOSEDLIST) != 0 ? query : null;
|
||||||
for (int i = 0; i < mesh.GetMaxTiles(); ++i)
|
for (int i = 0; i < mesh.GetMaxTiles(); ++i)
|
||||||
{
|
{
|
||||||
DtMeshTile tile = mesh.GetTile(i);
|
DtMeshTile tile = mesh.GetTile(i);
|
||||||
|
@ -116,7 +120,7 @@ public class RecastDebugDraw : DebugDraw
|
||||||
{
|
{
|
||||||
long @base = mesh.GetPolyRefBase(tile);
|
long @base = mesh.GetPolyRefBase(tile);
|
||||||
|
|
||||||
int tileNum = DtNavMesh.DecodePolyIdTile(@base);
|
int tileNum = DecodePolyIdTile(@base);
|
||||||
int tileColor = DuIntToCol(tileNum, 128);
|
int tileColor = DuIntToCol(tileNum, 128);
|
||||||
DepthMask(false);
|
DepthMask(false);
|
||||||
Begin(DebugDrawPrimitives.TRIS);
|
Begin(DebugDrawPrimitives.TRIS);
|
||||||
|
@ -135,7 +139,7 @@ public class RecastDebugDraw : DebugDraw
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((flags & DRAWNAVMESH_COLOR_TILES) != 0)
|
if ((flags & DU_DRAWNAVMESH_COLOR_TILES) != 0)
|
||||||
{
|
{
|
||||||
col = tileColor;
|
col = tileColor;
|
||||||
}
|
}
|
||||||
|
@ -163,7 +167,7 @@ public class RecastDebugDraw : DebugDraw
|
||||||
// Draw outer poly boundaries
|
// Draw outer poly boundaries
|
||||||
DrawPolyBoundaries(tile, DuRGBA(0, 48, 64, 220), 2.5f, false);
|
DrawPolyBoundaries(tile, DuRGBA(0, 48, 64, 220), 2.5f, false);
|
||||||
|
|
||||||
if ((flags & DRAWNAVMESH_OFFMESHCONS) != 0)
|
if ((flags & DU_DRAWNAVMESH_OFFMESHCONS) != 0)
|
||||||
{
|
{
|
||||||
Begin(DebugDrawPrimitives.LINES, 2.0f);
|
Begin(DebugDrawPrimitives.LINES, 2.0f);
|
||||||
for (int i = 0; i < tile.data.header.polyCount; ++i)
|
for (int i = 0; i < tile.data.header.polyCount; ++i)
|
||||||
|
@ -198,7 +202,7 @@ public class RecastDebugDraw : DebugDraw
|
||||||
// Check to see if start and end end-points have links.
|
// Check to see if start and end end-points have links.
|
||||||
bool startSet = false;
|
bool startSet = false;
|
||||||
bool endSet = false;
|
bool endSet = false;
|
||||||
for (int k = tile.polyLinks[p.index]; k != DtNavMesh.DT_NULL_LINK; k = tile.links[k].next)
|
for (int k = tile.polyLinks[p.index]; k != DT_NULL_LINK; k = tile.links[k].next)
|
||||||
{
|
{
|
||||||
if (tile.links[k].edge == 0)
|
if (tile.links[k].edge == 0)
|
||||||
{
|
{
|
||||||
|
@ -319,10 +323,10 @@ public class RecastDebugDraw : DebugDraw
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((p.neis[j] & DtNavMesh.DT_EXT_LINK) != 0)
|
if ((p.neis[j] & DT_EXT_LINK) != 0)
|
||||||
{
|
{
|
||||||
bool con = false;
|
bool con = false;
|
||||||
for (int k = tile.polyLinks[p.index]; k != DtNavMesh.DT_NULL_LINK; k = tile.links[k].next)
|
for (int k = tile.polyLinks[p.index]; k != DT_NULL_LINK; k = tile.links[k].next)
|
||||||
{
|
{
|
||||||
if (tile.links[k].edge == j)
|
if (tile.links[k].edge == j)
|
||||||
{
|
{
|
||||||
|
@ -394,7 +398,7 @@ public class RecastDebugDraw : DebugDraw
|
||||||
|
|
||||||
for (int m = 0, n = 2; m < 3; n = m++)
|
for (int m = 0, n = 2; m < 3; n = m++)
|
||||||
{
|
{
|
||||||
if ((DtNavMesh.GetDetailTriEdgeFlags(tile.data.detailTris[t + 3], n) & DtDetailTriEdgeFlags.DT_DETAIL_EDGE_BOUNDARY) == 0)
|
if ((GetDetailTriEdgeFlags(tile.data.detailTris[t + 3], n) & DtDetailTriEdgeFlags.DT_DETAIL_EDGE_BOUNDARY) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (((tile.data.detailTris[t + 3] >> (n * 2)) & 0x3) == 0)
|
if (((tile.data.detailTris[t + 3] >> (n * 2)) & 0x3) == 0)
|
||||||
|
@ -498,7 +502,7 @@ public class RecastDebugDraw : DebugDraw
|
||||||
{
|
{
|
||||||
color = DuRGBA(0, 192, 255, 64);
|
color = DuRGBA(0, 192, 255, 64);
|
||||||
}
|
}
|
||||||
else if (area == RcConstants.RC_NULL_AREA)
|
else if (area == RcRecast.RC_NULL_AREA)
|
||||||
{
|
{
|
||||||
color = DuRGBA(0, 0, 0, 64);
|
color = DuRGBA(0, 0, 0, 64);
|
||||||
}
|
}
|
||||||
|
@ -670,7 +674,7 @@ public class RecastDebugDraw : DebugDraw
|
||||||
int v3 = c.rverts[j * 4 + 3];
|
int v3 = c.rverts[j * 4 + 3];
|
||||||
float off = 0;
|
float off = 0;
|
||||||
int colv = color;
|
int colv = color;
|
||||||
if ((v3 & RcConstants.RC_BORDER_VERTEX) != 0)
|
if ((v3 & RcRecast.RC_BORDER_VERTEX) != 0)
|
||||||
{
|
{
|
||||||
colv = DuRGBA(255, 255, 255, a);
|
colv = DuRGBA(255, 255, 255, a);
|
||||||
off = ch * 2;
|
off = ch * 2;
|
||||||
|
@ -717,7 +721,7 @@ public class RecastDebugDraw : DebugDraw
|
||||||
int vb0 = c.verts[j * 4];
|
int vb0 = c.verts[j * 4];
|
||||||
int vb1 = c.verts[j * 4 + 1];
|
int vb1 = c.verts[j * 4 + 1];
|
||||||
int vb2 = c.verts[j * 4 + 2];
|
int vb2 = c.verts[j * 4 + 2];
|
||||||
int col = (va3 & RcConstants.RC_AREA_BORDER) != 0 ? bcolor : color;
|
int col = (va3 & RcRecast.RC_AREA_BORDER) != 0 ? bcolor : color;
|
||||||
|
|
||||||
float fx = orig.X + va0 * cs;
|
float fx = orig.X + va0 * cs;
|
||||||
float fy = orig.Y + (va1 + 1 + (i & 1)) * ch;
|
float fy = orig.Y + (va1 + 1 + (i & 1)) * ch;
|
||||||
|
@ -748,7 +752,7 @@ public class RecastDebugDraw : DebugDraw
|
||||||
int v3 = c.verts[j * 4 + 3];
|
int v3 = c.verts[j * 4 + 3];
|
||||||
float off = 0;
|
float off = 0;
|
||||||
int colv = color;
|
int colv = color;
|
||||||
if ((v3 & RcConstants.RC_BORDER_VERTEX) != 0)
|
if ((v3 & RcRecast.RC_BORDER_VERTEX) != 0)
|
||||||
{
|
{
|
||||||
colv = DuRGBA(255, 255, 255, a);
|
colv = DuRGBA(255, 255, 255, a);
|
||||||
off = ch * 2;
|
off = ch * 2;
|
||||||
|
@ -828,7 +832,7 @@ public class RecastDebugDraw : DebugDraw
|
||||||
{
|
{
|
||||||
fcol[0] = DuRGBA(64, 128, 160, 255);
|
fcol[0] = DuRGBA(64, 128, 160, 255);
|
||||||
}
|
}
|
||||||
else if (s.area == RcConstants.RC_NULL_AREA)
|
else if (s.area == RcRecast.RC_NULL_AREA)
|
||||||
{
|
{
|
||||||
fcol[0] = DuRGBA(64, 64, 64, 255);
|
fcol[0] = DuRGBA(64, 64, 64, 255);
|
||||||
}
|
}
|
||||||
|
@ -950,7 +954,7 @@ public class RecastDebugDraw : DebugDraw
|
||||||
{
|
{
|
||||||
color = DuRGBA(0, 192, 255, 64);
|
color = DuRGBA(0, 192, 255, 64);
|
||||||
}
|
}
|
||||||
else if (area == RcConstants.RC_NULL_AREA)
|
else if (area == RcRecast.RC_NULL_AREA)
|
||||||
{
|
{
|
||||||
color = DuRGBA(0, 0, 0, 64);
|
color = DuRGBA(0, 0, 0, 64);
|
||||||
}
|
}
|
||||||
|
@ -962,7 +966,7 @@ public class RecastDebugDraw : DebugDraw
|
||||||
int[] vi = new int[3];
|
int[] vi = new int[3];
|
||||||
for (int j = 2; j < nvp; ++j)
|
for (int j = 2; j < nvp; ++j)
|
||||||
{
|
{
|
||||||
if (mesh.polys[p + j] == RcConstants.RC_MESH_NULL_IDX)
|
if (mesh.polys[p + j] == RcRecast.RC_MESH_NULL_IDX)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -993,7 +997,7 @@ public class RecastDebugDraw : DebugDraw
|
||||||
int p = i * nvp * 2;
|
int p = i * nvp * 2;
|
||||||
for (int j = 0; j < nvp; ++j)
|
for (int j = 0; j < nvp; ++j)
|
||||||
{
|
{
|
||||||
if (mesh.polys[p + j] == RcConstants.RC_MESH_NULL_IDX)
|
if (mesh.polys[p + j] == RcRecast.RC_MESH_NULL_IDX)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1003,7 +1007,7 @@ public class RecastDebugDraw : DebugDraw
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
int nj = (j + 1 >= nvp || mesh.polys[p + j + 1] == RcConstants.RC_MESH_NULL_IDX) ? 0 : j + 1;
|
int nj = (j + 1 >= nvp || mesh.polys[p + j + 1] == RcRecast.RC_MESH_NULL_IDX) ? 0 : j + 1;
|
||||||
int[] vi = { mesh.polys[p + j], mesh.polys[p + nj] };
|
int[] vi = { mesh.polys[p + j], mesh.polys[p + nj] };
|
||||||
|
|
||||||
for (int k = 0; k < 2; ++k)
|
for (int k = 0; k < 2; ++k)
|
||||||
|
@ -1027,7 +1031,7 @@ public class RecastDebugDraw : DebugDraw
|
||||||
int p = i * nvp * 2;
|
int p = i * nvp * 2;
|
||||||
for (int j = 0; j < nvp; ++j)
|
for (int j = 0; j < nvp; ++j)
|
||||||
{
|
{
|
||||||
if (mesh.polys[p + j] == RcConstants.RC_MESH_NULL_IDX)
|
if (mesh.polys[p + j] == RcRecast.RC_MESH_NULL_IDX)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1037,7 +1041,7 @@ public class RecastDebugDraw : DebugDraw
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
int nj = (j + 1 >= nvp || mesh.polys[p + j + 1] == RcConstants.RC_MESH_NULL_IDX) ? 0 : j + 1;
|
int nj = (j + 1 >= nvp || mesh.polys[p + j + 1] == RcRecast.RC_MESH_NULL_IDX) ? 0 : j + 1;
|
||||||
int[] vi = { mesh.polys[p + j], mesh.polys[p + nj] };
|
int[] vi = { mesh.polys[p + j], mesh.polys[p + nj] };
|
||||||
|
|
||||||
int col = colb;
|
int col = colb;
|
||||||
|
@ -1328,7 +1332,7 @@ public class RecastDebugDraw : DebugDraw
|
||||||
|
|
||||||
for (int side = 0; side < 8; ++side)
|
for (int side = 0; side < 8; ++side)
|
||||||
{
|
{
|
||||||
int m = DtNavMesh.DT_EXT_LINK | (short)side;
|
int m = DT_EXT_LINK | (short)side;
|
||||||
|
|
||||||
for (int i = 0; i < tile.data.header.polyCount; ++i)
|
for (int i = 0; i < tile.data.header.polyCount; ++i)
|
||||||
{
|
{
|
||||||
|
|
|
@ -462,7 +462,7 @@ public class RecastDemo : IRecastDemoChannel
|
||||||
var settings = _sample.GetSettings();
|
var settings = _sample.GetSettings();
|
||||||
RcVec3f bmin = _sample.GetInputGeom().GetMeshBoundsMin();
|
RcVec3f bmin = _sample.GetInputGeom().GetMeshBoundsMin();
|
||||||
RcVec3f bmax = _sample.GetInputGeom().GetMeshBoundsMax();
|
RcVec3f bmax = _sample.GetInputGeom().GetMeshBoundsMax();
|
||||||
RcCommons.CalcGridSize(bmin, bmax, settings.cellSize, out var gw, out var gh);
|
RcRecast.CalcGridSize(bmin, bmax, settings.cellSize, out var gw, out var gh);
|
||||||
settingsView.SetVoxels(gw, gh);
|
settingsView.SetVoxels(gw, gh);
|
||||||
settingsView.SetTiles(tileNavMeshBuilder.GetTiles(_sample.GetInputGeom(), settings.cellSize, settings.tileSize));
|
settingsView.SetTiles(tileNavMeshBuilder.GetTiles(_sample.GetInputGeom(), settings.cellSize, settings.tileSize));
|
||||||
settingsView.SetMaxTiles(tileNavMeshBuilder.GetMaxTiles(_sample.GetInputGeom(), settings.cellSize, settings.tileSize));
|
settingsView.SetMaxTiles(tileNavMeshBuilder.GetMaxTiles(_sample.GetInputGeom(), settings.cellSize, settings.tileSize));
|
||||||
|
|
|
@ -158,7 +158,7 @@ namespace DotRecast.Recast.Toolset.Builder
|
||||||
|
|
||||||
private int GetTileBits(IInputGeomProvider geom, float cellSize, int tileSize)
|
private int GetTileBits(IInputGeomProvider geom, float cellSize, int tileSize)
|
||||||
{
|
{
|
||||||
RcCommons.CalcGridSize(geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax(), cellSize, out var gw, out var gh);
|
RcRecast.CalcGridSize(geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax(), cellSize, out var gw, out var gh);
|
||||||
int tw = (gw + tileSize - 1) / tileSize;
|
int tw = (gw + tileSize - 1) / tileSize;
|
||||||
int th = (gh + tileSize - 1) / tileSize;
|
int th = (gh + tileSize - 1) / tileSize;
|
||||||
int tileBits = Math.Min(DtUtils.Ilog2(DtUtils.NextPow2(tw * th)), 14);
|
int tileBits = Math.Min(DtUtils.Ilog2(DtUtils.NextPow2(tw * th)), 14);
|
||||||
|
@ -167,7 +167,7 @@ namespace DotRecast.Recast.Toolset.Builder
|
||||||
|
|
||||||
public int[] GetTiles(DemoInputGeomProvider geom, float cellSize, int tileSize)
|
public int[] GetTiles(DemoInputGeomProvider geom, float cellSize, int tileSize)
|
||||||
{
|
{
|
||||||
RcCommons.CalcGridSize(geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax(), cellSize, out var gw, out var gh);
|
RcRecast.CalcGridSize(geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax(), cellSize, out var gw, out var gh);
|
||||||
int tw = (gw + tileSize - 1) / tileSize;
|
int tw = (gw + tileSize - 1) / tileSize;
|
||||||
int th = (gh + tileSize - 1) / tileSize;
|
int th = (gh + tileSize - 1) / tileSize;
|
||||||
return new int[] { tw, th };
|
return new int[] { tw, th };
|
||||||
|
|
|
@ -42,7 +42,7 @@ namespace DotRecast.Recast.Toolset.Tools
|
||||||
// Init cache
|
// Init cache
|
||||||
var bmin = geom.GetMeshBoundsMin();
|
var bmin = geom.GetMeshBoundsMin();
|
||||||
var bmax = geom.GetMeshBoundsMax();
|
var bmax = geom.GetMeshBoundsMax();
|
||||||
RcCommons.CalcGridSize(bmin, bmax, setting.cellSize, out var gw, out var gh);
|
RcRecast.CalcGridSize(bmin, bmax, setting.cellSize, out var gw, out var gh);
|
||||||
int ts = setting.tileSize;
|
int ts = setting.tileSize;
|
||||||
int tw = (gw + ts - 1) / ts;
|
int tw = (gw + ts - 1) / ts;
|
||||||
int th = (gh + ts - 1) / ts;
|
int th = (gh + ts - 1) / ts;
|
||||||
|
|
|
@ -23,7 +23,7 @@ namespace DotRecast.Recast.Toolset.Tools
|
||||||
var bmin = geom.GetMeshBoundsMin();
|
var bmin = geom.GetMeshBoundsMin();
|
||||||
var bmax = geom.GetMeshBoundsMax();
|
var bmax = geom.GetMeshBoundsMax();
|
||||||
int gw = 0, gh = 0;
|
int gw = 0, gh = 0;
|
||||||
RcCommons.CalcGridSize(bmin, bmax, settings.cellSize, out gw, out gh);
|
RcRecast.CalcGridSize(bmin, bmax, settings.cellSize, out gw, out gh);
|
||||||
|
|
||||||
int ts = settings.tileSize;
|
int ts = settings.tileSize;
|
||||||
int tw = (gw + ts - 1) / ts;
|
int tw = (gw + ts - 1) / ts;
|
||||||
|
@ -47,7 +47,7 @@ namespace DotRecast.Recast.Toolset.Tools
|
||||||
var bmin = geom.GetMeshBoundsMin();
|
var bmin = geom.GetMeshBoundsMin();
|
||||||
var bmax = geom.GetMeshBoundsMax();
|
var bmax = geom.GetMeshBoundsMax();
|
||||||
int gw = 0, gh = 0;
|
int gw = 0, gh = 0;
|
||||||
RcCommons.CalcGridSize(bmin, bmax, settings.cellSize, out gw, out gh);
|
RcRecast.CalcGridSize(bmin, bmax, settings.cellSize, out gw, out gh);
|
||||||
|
|
||||||
int ts = settings.tileSize;
|
int ts = settings.tileSize;
|
||||||
int tw = (gw + ts - 1) / ts;
|
int tw = (gw + ts - 1) / ts;
|
||||||
|
|
|
@ -25,8 +25,7 @@ using DotRecast.Core.Numerics;
|
||||||
|
|
||||||
namespace DotRecast.Recast
|
namespace DotRecast.Recast
|
||||||
{
|
{
|
||||||
using static RcConstants;
|
using static RcRecast;
|
||||||
using static RcCommons;
|
|
||||||
|
|
||||||
public static class RcAreas
|
public static class RcAreas
|
||||||
{
|
{
|
||||||
|
|
|
@ -30,7 +30,7 @@ using DotRecast.Recast.Geom;
|
||||||
|
|
||||||
namespace DotRecast.Recast
|
namespace DotRecast.Recast
|
||||||
{
|
{
|
||||||
using static RcCommons;
|
using static RcRecast;
|
||||||
using static RcAreas;
|
using static RcAreas;
|
||||||
|
|
||||||
public class RcBuilder
|
public class RcBuilder
|
||||||
|
|
|
@ -92,7 +92,7 @@ namespace DotRecast.Recast
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
RcCommons.CalcGridSize(this.bmin, this.bmax, cfg.Cs, out width, out height);
|
RcRecast.CalcGridSize(this.bmin, this.bmax, cfg.Cs, out width, out height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,17 +20,14 @@ freely, subject to the following restrictions:
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using DotRecast.Core;
|
using DotRecast.Core;
|
||||||
using static DotRecast.Recast.RcConstants;
|
|
||||||
|
|
||||||
|
|
||||||
namespace DotRecast.Recast
|
namespace DotRecast.Recast
|
||||||
{
|
{
|
||||||
using static RcCommons;
|
using static RcRecast;
|
||||||
|
|
||||||
|
|
||||||
public static class RcCompacts
|
public static class RcCompacts
|
||||||
{
|
{
|
||||||
private const int MAX_HEIGHT = RcConstants.RC_SPAN_MAX_HEIGHT;
|
private const int MAX_HEIGHT = RC_SPAN_MAX_HEIGHT;
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
/// @name Compact Heightfield Functions
|
/// @name Compact Heightfield Functions
|
||||||
|
|
|
@ -1,93 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
|
|
||||||
recast4j copyright (c) 2015-2019 Piotr Piastucki piotr@jtilia.org
|
|
||||||
DotRecast Copyright (c) 2023 Choi Ikpil ikpil@naver.com
|
|
||||||
|
|
||||||
This software is provided 'as-is', without any express or implied
|
|
||||||
warranty. In no event will the authors be held liable for any damages
|
|
||||||
arising from the use of this software.
|
|
||||||
Permission is granted to anyone to use this software for any purpose,
|
|
||||||
including commercial applications, and to alter it and redistribute it
|
|
||||||
freely, subject to the following restrictions:
|
|
||||||
1. The origin of this software must not be misrepresented; you must not
|
|
||||||
claim that you wrote the original software. If you use this software
|
|
||||||
in a product, an acknowledgment in the product documentation would be
|
|
||||||
appreciated but is not required.
|
|
||||||
2. Altered source versions must be plainly marked as such, and must not be
|
|
||||||
misrepresented as being the original software.
|
|
||||||
3. This notice may not be removed or altered from any source distribution.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace DotRecast.Recast
|
|
||||||
{
|
|
||||||
public static class RcConstants
|
|
||||||
{
|
|
||||||
/// Represents the null area.
|
|
||||||
/// When a data element is given this value it is considered to no longer be
|
|
||||||
/// assigned to a usable area. (E.g. It is un-walkable.)
|
|
||||||
public const int RC_NULL_AREA = 0;
|
|
||||||
|
|
||||||
/// The default area id used to indicate a walkable polygon.
|
|
||||||
/// This is also the maximum allowed area id, and the only non-null area id
|
|
||||||
/// recognized by some steps in the build process.
|
|
||||||
public const int RC_WALKABLE_AREA = 63;
|
|
||||||
|
|
||||||
/// The value returned by #rcGetCon if the specified direction is not connected
|
|
||||||
/// to another span. (Has no neighbor.)
|
|
||||||
public const int RC_NOT_CONNECTED = 0x3f;
|
|
||||||
|
|
||||||
/// Defines the number of bits allocated to rcSpan::smin and rcSpan::smax.
|
|
||||||
public const int RC_SPAN_HEIGHT_BITS = 20;
|
|
||||||
|
|
||||||
/// Defines the maximum value for rcSpan::smin and rcSpan::smax.
|
|
||||||
public const int RC_SPAN_MAX_HEIGHT = (1 << RC_SPAN_HEIGHT_BITS) - 1;
|
|
||||||
|
|
||||||
/// The number of spans allocated per span spool.
|
|
||||||
/// @see rcSpanPool
|
|
||||||
public const int RC_SPANS_PER_POOL = 2048;
|
|
||||||
|
|
||||||
/// Heighfield border flag.
|
|
||||||
/// If a heightfield region ID has this bit set, then the region is a border
|
|
||||||
/// region and its spans are considered unwalkable.
|
|
||||||
/// (Used during the region and contour build process.)
|
|
||||||
/// @see rcCompactSpan::reg
|
|
||||||
public const int RC_BORDER_REG = 0x8000;
|
|
||||||
|
|
||||||
/// Polygon touches multiple regions.
|
|
||||||
/// If a polygon has this region ID it was merged with or created
|
|
||||||
/// from polygons of different regions during the polymesh
|
|
||||||
/// build step that removes redundant border vertices.
|
|
||||||
/// (Used during the polymesh and detail polymesh build processes)
|
|
||||||
/// @see rcPolyMesh::regs
|
|
||||||
public const int RC_MULTIPLE_REGS = 0;
|
|
||||||
|
|
||||||
// Border vertex flag.
|
|
||||||
/// If a region ID has this bit set, then the associated element lies on
|
|
||||||
/// a tile border. If a contour vertex's region ID has this bit set, the
|
|
||||||
/// vertex will later be removed in order to match the segments and vertices
|
|
||||||
/// at tile boundaries.
|
|
||||||
/// (Used during the build process.)
|
|
||||||
/// @see rcCompactSpan::reg, #rcContour::verts, #rcContour::rverts
|
|
||||||
public const int RC_BORDER_VERTEX = 0x10000;
|
|
||||||
|
|
||||||
/// Area border flag.
|
|
||||||
/// If a region ID has this bit set, then the associated element lies on
|
|
||||||
/// the border of an area.
|
|
||||||
/// (Used during the region and contour build process.)
|
|
||||||
/// @see rcCompactSpan::reg, #rcContour::verts, #rcContour::rverts
|
|
||||||
public const int RC_AREA_BORDER = 0x20000;
|
|
||||||
|
|
||||||
/// Applied to the region id field of contour vertices in order to extract the region id.
|
|
||||||
/// The region id field of a vertex may have several flags applied to it. So the
|
|
||||||
/// fields value can't be used directly.
|
|
||||||
/// @see rcContour::verts, rcContour::rverts
|
|
||||||
public const int RC_CONTOUR_REG_MASK = 0xffff;
|
|
||||||
|
|
||||||
/// A value which indicates an invalid index within a mesh.
|
|
||||||
/// @note This does not necessarily indicate an error.
|
|
||||||
/// @see rcPolyMesh::polys
|
|
||||||
public const int RC_MESH_NULL_IDX = 0xffff;
|
|
||||||
|
|
||||||
public const int RC_LOG_WARNING = 1;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -24,8 +24,8 @@ using DotRecast.Core;
|
||||||
|
|
||||||
namespace DotRecast.Recast
|
namespace DotRecast.Recast
|
||||||
{
|
{
|
||||||
using static RcConstants;
|
|
||||||
using static RcCommons;
|
using static RcRecast;
|
||||||
|
|
||||||
public static class RcContours
|
public static class RcContours
|
||||||
{
|
{
|
||||||
|
|
|
@ -20,11 +20,11 @@ freely, subject to the following restrictions:
|
||||||
using System;
|
using System;
|
||||||
using DotRecast.Core;
|
using DotRecast.Core;
|
||||||
using DotRecast.Core.Numerics;
|
using DotRecast.Core.Numerics;
|
||||||
using static DotRecast.Recast.RcConstants;
|
|
||||||
|
|
||||||
|
|
||||||
namespace DotRecast.Recast
|
namespace DotRecast.Recast
|
||||||
{
|
{
|
||||||
|
using static RcRecast;
|
||||||
|
|
||||||
public static class RcFilledVolumeRasterization
|
public static class RcFilledVolumeRasterization
|
||||||
{
|
{
|
||||||
private const float EPSILON = 0.00001f;
|
private const float EPSILON = 0.00001f;
|
||||||
|
|
|
@ -23,8 +23,8 @@ using DotRecast.Core;
|
||||||
|
|
||||||
namespace DotRecast.Recast
|
namespace DotRecast.Recast
|
||||||
{
|
{
|
||||||
using static RcConstants;
|
|
||||||
using static RcCommons;
|
using static RcRecast;
|
||||||
|
|
||||||
public static class RcFilters
|
public static class RcFilters
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,12 +25,12 @@ using DotRecast.Core.Numerics;
|
||||||
|
|
||||||
namespace DotRecast.Recast
|
namespace DotRecast.Recast
|
||||||
{
|
{
|
||||||
using static RcConstants;
|
|
||||||
using static RcCommons;
|
using static RcRecast;
|
||||||
|
|
||||||
public static class RcLayers
|
public static class RcLayers
|
||||||
{
|
{
|
||||||
const int RC_MAX_LAYERS = RcConstants.RC_NOT_CONNECTED;
|
const int RC_MAX_LAYERS = RcRecast.RC_NOT_CONNECTED;
|
||||||
const int RC_MAX_NEIS = 16;
|
const int RC_MAX_NEIS = 16;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -22,11 +22,11 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using DotRecast.Core;
|
using DotRecast.Core;
|
||||||
using DotRecast.Core.Numerics;
|
using DotRecast.Core.Numerics;
|
||||||
using static DotRecast.Recast.RcConstants;
|
|
||||||
|
|
||||||
namespace DotRecast.Recast
|
namespace DotRecast.Recast
|
||||||
{
|
{
|
||||||
using static RcCommons;
|
using static RcRecast;
|
||||||
|
|
||||||
|
|
||||||
public static class RcMeshDetails
|
public static class RcMeshDetails
|
||||||
|
@ -35,7 +35,7 @@ namespace DotRecast.Recast
|
||||||
public const int MAX_TRIS = 255; // Max tris for delaunay is 2n-2-k (n=num verts, k=num hull verts).
|
public const int MAX_TRIS = 255; // Max tris for delaunay is 2n-2-k (n=num verts, k=num hull verts).
|
||||||
public const int MAX_VERTS_PER_EDGE = 32;
|
public const int MAX_VERTS_PER_EDGE = 32;
|
||||||
|
|
||||||
public const int RC_UNSET_HEIGHT = RcConstants.RC_SPAN_MAX_HEIGHT;
|
public const int RC_UNSET_HEIGHT = RcRecast.RC_SPAN_MAX_HEIGHT;
|
||||||
public const int EV_UNDEF = -1;
|
public const int EV_UNDEF = -1;
|
||||||
public const int EV_HULL = -2;
|
public const int EV_HULL = -2;
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ using DotRecast.Core.Numerics;
|
||||||
|
|
||||||
namespace DotRecast.Recast
|
namespace DotRecast.Recast
|
||||||
{
|
{
|
||||||
using static RcConstants;
|
using static RcRecast;
|
||||||
|
|
||||||
public static class RcMeshs
|
public static class RcMeshs
|
||||||
{
|
{
|
||||||
|
|
|
@ -21,10 +21,12 @@ freely, subject to the following restrictions:
|
||||||
using System;
|
using System;
|
||||||
using DotRecast.Core;
|
using DotRecast.Core;
|
||||||
using DotRecast.Core.Numerics;
|
using DotRecast.Core.Numerics;
|
||||||
using static DotRecast.Recast.RcConstants;
|
|
||||||
|
|
||||||
namespace DotRecast.Recast
|
namespace DotRecast.Recast
|
||||||
{
|
{
|
||||||
|
using static RcRecast;
|
||||||
|
|
||||||
public static class RcRasterizations
|
public static class RcRasterizations
|
||||||
{
|
{
|
||||||
/// Check whether two bounding boxes overlap
|
/// Check whether two bounding boxes overlap
|
||||||
|
|
|
@ -24,10 +24,76 @@ using DotRecast.Core.Numerics;
|
||||||
|
|
||||||
namespace DotRecast.Recast
|
namespace DotRecast.Recast
|
||||||
{
|
{
|
||||||
using static RcConstants;
|
public static class RcRecast
|
||||||
|
|
||||||
public static class RcCommons
|
|
||||||
{
|
{
|
||||||
|
/// Represents the null area.
|
||||||
|
/// When a data element is given this value it is considered to no longer be
|
||||||
|
/// assigned to a usable area. (E.g. It is un-walkable.)
|
||||||
|
public const int RC_NULL_AREA = 0;
|
||||||
|
|
||||||
|
/// The default area id used to indicate a walkable polygon.
|
||||||
|
/// This is also the maximum allowed area id, and the only non-null area id
|
||||||
|
/// recognized by some steps in the build process.
|
||||||
|
public const int RC_WALKABLE_AREA = 63;
|
||||||
|
|
||||||
|
/// The value returned by #rcGetCon if the specified direction is not connected
|
||||||
|
/// to another span. (Has no neighbor.)
|
||||||
|
public const int RC_NOT_CONNECTED = 0x3f;
|
||||||
|
|
||||||
|
/// Defines the number of bits allocated to rcSpan::smin and rcSpan::smax.
|
||||||
|
public const int RC_SPAN_HEIGHT_BITS = 20;
|
||||||
|
|
||||||
|
/// Defines the maximum value for rcSpan::smin and rcSpan::smax.
|
||||||
|
public const int RC_SPAN_MAX_HEIGHT = (1 << RC_SPAN_HEIGHT_BITS) - 1;
|
||||||
|
|
||||||
|
/// The number of spans allocated per span spool.
|
||||||
|
/// @see rcSpanPool
|
||||||
|
public const int RC_SPANS_PER_POOL = 2048;
|
||||||
|
|
||||||
|
/// Heighfield border flag.
|
||||||
|
/// If a heightfield region ID has this bit set, then the region is a border
|
||||||
|
/// region and its spans are considered unwalkable.
|
||||||
|
/// (Used during the region and contour build process.)
|
||||||
|
/// @see rcCompactSpan::reg
|
||||||
|
public const int RC_BORDER_REG = 0x8000;
|
||||||
|
|
||||||
|
/// Polygon touches multiple regions.
|
||||||
|
/// If a polygon has this region ID it was merged with or created
|
||||||
|
/// from polygons of different regions during the polymesh
|
||||||
|
/// build step that removes redundant border vertices.
|
||||||
|
/// (Used during the polymesh and detail polymesh build processes)
|
||||||
|
/// @see rcPolyMesh::regs
|
||||||
|
public const int RC_MULTIPLE_REGS = 0;
|
||||||
|
|
||||||
|
// Border vertex flag.
|
||||||
|
/// If a region ID has this bit set, then the associated element lies on
|
||||||
|
/// a tile border. If a contour vertex's region ID has this bit set, the
|
||||||
|
/// vertex will later be removed in order to match the segments and vertices
|
||||||
|
/// at tile boundaries.
|
||||||
|
/// (Used during the build process.)
|
||||||
|
/// @see rcCompactSpan::reg, #rcContour::verts, #rcContour::rverts
|
||||||
|
public const int RC_BORDER_VERTEX = 0x10000;
|
||||||
|
|
||||||
|
/// Area border flag.
|
||||||
|
/// If a region ID has this bit set, then the associated element lies on
|
||||||
|
/// the border of an area.
|
||||||
|
/// (Used during the region and contour build process.)
|
||||||
|
/// @see rcCompactSpan::reg, #rcContour::verts, #rcContour::rverts
|
||||||
|
public const int RC_AREA_BORDER = 0x20000;
|
||||||
|
|
||||||
|
/// Applied to the region id field of contour vertices in order to extract the region id.
|
||||||
|
/// The region id field of a vertex may have several flags applied to it. So the
|
||||||
|
/// fields value can't be used directly.
|
||||||
|
/// @see rcContour::verts, rcContour::rverts
|
||||||
|
public const int RC_CONTOUR_REG_MASK = 0xffff;
|
||||||
|
|
||||||
|
/// A value which indicates an invalid index within a mesh.
|
||||||
|
/// @note This does not necessarily indicate an error.
|
||||||
|
/// @see rcPolyMesh::polys
|
||||||
|
public const int RC_MESH_NULL_IDX = 0xffff;
|
||||||
|
|
||||||
|
public const int RC_LOG_WARNING = 1;
|
||||||
|
|
||||||
private static readonly int[] DirOffsetX = { -1, 0, 1, 0, };
|
private static readonly int[] DirOffsetX = { -1, 0, 1, 0, };
|
||||||
private static readonly int[] DirOffsetY = { 0, 1, 0, -1 };
|
private static readonly int[] DirOffsetY = { 0, 1, 0, -1 };
|
||||||
private static readonly int[] DirForOffset = { 3, 0, -1, 2, 1 };
|
private static readonly int[] DirForOffset = { 3, 0, -1, 2, 1 };
|
|
@ -25,8 +25,8 @@ using DotRecast.Core;
|
||||||
|
|
||||||
namespace DotRecast.Recast
|
namespace DotRecast.Recast
|
||||||
{
|
{
|
||||||
using static RcConstants;
|
|
||||||
using static RcCommons;
|
using static RcRecast;
|
||||||
|
|
||||||
public static class RcRegions
|
public static class RcRegions
|
||||||
{
|
{
|
||||||
|
|
|
@ -28,7 +28,7 @@ namespace DotRecast.Recast
|
||||||
|
|
||||||
public RcSpanPool()
|
public RcSpanPool()
|
||||||
{
|
{
|
||||||
items = new RcSpan[RcConstants.RC_SPANS_PER_POOL];
|
items = new RcSpan[RcRecast.RC_SPANS_PER_POOL];
|
||||||
for (int i = 0; i < items.Length; ++i)
|
for (int i = 0; i < items.Length; ++i)
|
||||||
{
|
{
|
||||||
items[i] = new RcSpan();
|
items[i] = new RcSpan();
|
||||||
|
|
|
@ -55,7 +55,7 @@ namespace DotRecast.Recast
|
||||||
{
|
{
|
||||||
int[] tris = node.tris;
|
int[] tris = node.tris;
|
||||||
int ntris = tris.Length / 3;
|
int ntris = tris.Length / 3;
|
||||||
int[] m_triareas = RcCommons.MarkWalkableTriangles(ctx, cfg.WalkableSlopeAngle, verts, tris, ntris, cfg.WalkableAreaMod);
|
int[] m_triareas = RcRecast.MarkWalkableTriangles(ctx, cfg.WalkableSlopeAngle, verts, tris, ntris, cfg.WalkableAreaMod);
|
||||||
RcRasterizations.RasterizeTriangles(ctx, verts, tris, m_triareas, ntris, solid, cfg.WalkableClimb);
|
RcRasterizations.RasterizeTriangles(ctx, verts, tris, m_triareas, ntris, solid, cfg.WalkableClimb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ namespace DotRecast.Recast
|
||||||
{
|
{
|
||||||
int[] tris = geom.GetTris();
|
int[] tris = geom.GetTris();
|
||||||
int ntris = tris.Length / 3;
|
int ntris = tris.Length / 3;
|
||||||
int[] m_triareas = RcCommons.MarkWalkableTriangles(ctx, cfg.WalkableSlopeAngle, verts, tris, ntris, cfg.WalkableAreaMod);
|
int[] m_triareas = RcRecast.MarkWalkableTriangles(ctx, cfg.WalkableSlopeAngle, verts, tris, ntris, cfg.WalkableAreaMod);
|
||||||
RcRasterizations.RasterizeTriangles(ctx, verts, tris, m_triareas, ntris, solid, cfg.WalkableClimb);
|
RcRasterizations.RasterizeTriangles(ctx, verts, tris, m_triareas, ntris, solid, cfg.WalkableClimb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,7 @@ public class MeshSetReaderWriterTest
|
||||||
|
|
||||||
RcVec3f bmin = geom.GetMeshBoundsMin();
|
RcVec3f bmin = geom.GetMeshBoundsMin();
|
||||||
RcVec3f bmax = geom.GetMeshBoundsMax();
|
RcVec3f bmax = geom.GetMeshBoundsMax();
|
||||||
RcCommons.CalcTileCount(bmin, bmax, m_cellSize, m_tileSize, m_tileSize, out var tw, out var th);
|
RcRecast.CalcTileCount(bmin, bmax, m_cellSize, m_tileSize, m_tileSize, out var tw, out var th);
|
||||||
for (int y = 0; y < th; ++y)
|
for (int y = 0; y < th; ++y)
|
||||||
{
|
{
|
||||||
for (int x = 0; x < tw; ++x)
|
for (int x = 0; x < tw; ++x)
|
||||||
|
|
|
@ -21,6 +21,7 @@ using NUnit.Framework;
|
||||||
|
|
||||||
namespace DotRecast.Detour.Test;
|
namespace DotRecast.Detour.Test;
|
||||||
|
|
||||||
|
using static DtDetour;
|
||||||
|
|
||||||
public class NavMeshBuilderTest
|
public class NavMeshBuilderTest
|
||||||
{
|
{
|
||||||
|
@ -57,7 +58,7 @@ public class NavMeshBuilderTest
|
||||||
|
|
||||||
Assert.That(nmd.offMeshCons[0].rad, Is.EqualTo(0.1f));
|
Assert.That(nmd.offMeshCons[0].rad, Is.EqualTo(0.1f));
|
||||||
Assert.That(nmd.offMeshCons[0].poly, Is.EqualTo(118));
|
Assert.That(nmd.offMeshCons[0].poly, Is.EqualTo(118));
|
||||||
Assert.That(nmd.offMeshCons[0].flags, Is.EqualTo(DtNavMesh.DT_OFFMESH_CON_BIDIR));
|
Assert.That(nmd.offMeshCons[0].flags, Is.EqualTo(DT_OFFMESH_CON_BIDIR));
|
||||||
Assert.That(nmd.offMeshCons[0].side, Is.EqualTo(0xFF));
|
Assert.That(nmd.offMeshCons[0].side, Is.EqualTo(0xFF));
|
||||||
Assert.That(nmd.offMeshCons[0].userId, Is.EqualTo(0x4567));
|
Assert.That(nmd.offMeshCons[0].userId, Is.EqualTo(0x4567));
|
||||||
Assert.That(nmd.polys[118].vertCount, Is.EqualTo(2));
|
Assert.That(nmd.polys[118].vertCount, Is.EqualTo(2));
|
||||||
|
|
|
@ -44,7 +44,7 @@ public class AbstractTileCacheTest
|
||||||
public DtTileCache GetTileCache(IInputGeomProvider geom, RcByteOrder order, bool cCompatibility)
|
public DtTileCache GetTileCache(IInputGeomProvider geom, RcByteOrder order, bool cCompatibility)
|
||||||
{
|
{
|
||||||
DtTileCacheParams option = new DtTileCacheParams();
|
DtTileCacheParams option = new DtTileCacheParams();
|
||||||
RcCommons.CalcTileCount(geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax(), m_cellSize, m_tileSize, m_tileSize, out var tw, out var th);
|
RcRecast.CalcTileCount(geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax(), m_cellSize, m_tileSize, m_tileSize, out var tw, out var th);
|
||||||
option.ch = m_cellHeight;
|
option.ch = m_cellHeight;
|
||||||
option.cs = m_cellSize;
|
option.cs = m_cellSize;
|
||||||
option.orig = geom.GetMeshBoundsMin();
|
option.orig = geom.GetMeshBoundsMin();
|
||||||
|
|
|
@ -73,7 +73,7 @@ public class TestTileLayerBuilder : DtTileCacheLayerBuilder
|
||||||
|
|
||||||
RcVec3f bmin = geom.GetMeshBoundsMin();
|
RcVec3f bmin = geom.GetMeshBoundsMin();
|
||||||
RcVec3f bmax = geom.GetMeshBoundsMax();
|
RcVec3f bmax = geom.GetMeshBoundsMax();
|
||||||
RcCommons.CalcTileCount(bmin, bmax, CellSize, m_tileSize, m_tileSize, out tw, out th);
|
RcRecast.CalcTileCount(bmin, bmax, CellSize, m_tileSize, m_tileSize, out tw, out th);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<byte[]> Build(RcByteOrder order, bool cCompatibility, int threads)
|
public List<byte[]> Build(RcByteOrder order, bool cCompatibility, int threads)
|
||||||
|
|
|
@ -24,7 +24,7 @@ using NUnit.Framework;
|
||||||
|
|
||||||
namespace DotRecast.Recast.Test;
|
namespace DotRecast.Recast.Test;
|
||||||
|
|
||||||
using static RcConstants;
|
|
||||||
|
|
||||||
|
|
||||||
public class RecastLayersTest
|
public class RecastLayersTest
|
||||||
|
|
|
@ -25,10 +25,9 @@ using NUnit.Framework;
|
||||||
|
|
||||||
namespace DotRecast.Recast.Test;
|
namespace DotRecast.Recast.Test;
|
||||||
|
|
||||||
using static RcConstants;
|
using static RcRecast;
|
||||||
using static RcAreas;
|
using static RcAreas;
|
||||||
|
|
||||||
|
|
||||||
public class RecastSoloMeshTest
|
public class RecastSoloMeshTest
|
||||||
{
|
{
|
||||||
private const float m_cellSize = 0.3f;
|
private const float m_cellSize = 0.3f;
|
||||||
|
@ -139,7 +138,7 @@ public class RecastSoloMeshTest
|
||||||
// Find triangles which are walkable based on their slope and rasterize them.
|
// Find triangles which are walkable based on their slope and rasterize them.
|
||||||
// If your input data is multiple meshes, you can transform them here, calculate
|
// If your input data is multiple meshes, you can transform them here, calculate
|
||||||
// the are type for each of the meshes and rasterize them.
|
// the are type for each of the meshes and rasterize them.
|
||||||
int[] m_triareas = RcCommons.MarkWalkableTriangles(m_ctx, cfg.WalkableSlopeAngle, verts, tris, ntris, cfg.WalkableAreaMod);
|
int[] m_triareas = RcRecast.MarkWalkableTriangles(m_ctx, cfg.WalkableSlopeAngle, verts, tris, ntris, cfg.WalkableAreaMod);
|
||||||
RcRasterizations.RasterizeTriangles(m_ctx, verts, tris, m_triareas, ntris, m_solid, cfg.WalkableClimb);
|
RcRasterizations.RasterizeTriangles(m_ctx, verts, tris, m_triareas, ntris, m_solid, cfg.WalkableClimb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,8 +21,7 @@ using DotRecast.Core;
|
||||||
|
|
||||||
namespace DotRecast.Recast.Test;
|
namespace DotRecast.Recast.Test;
|
||||||
|
|
||||||
using static RcConstants;
|
using static RcRecast;
|
||||||
|
|
||||||
|
|
||||||
public class RecastTest
|
public class RecastTest
|
||||||
{
|
{
|
||||||
|
@ -39,18 +38,18 @@ public class RecastTest
|
||||||
RcContext ctx = new RcContext();
|
RcContext ctx = new RcContext();
|
||||||
{
|
{
|
||||||
int[] areas = { 42 };
|
int[] areas = { 42 };
|
||||||
RcCommons.ClearUnwalkableTriangles(ctx, walkableSlopeAngle, verts, nv, unwalkable_tri, nt, areas);
|
RcRecast.ClearUnwalkableTriangles(ctx, walkableSlopeAngle, verts, nv, unwalkable_tri, nt, areas);
|
||||||
Assert.That(areas[0], Is.EqualTo(RC_NULL_AREA), "Sets area ID of unwalkable triangle to RC_NULL_AREA");
|
Assert.That(areas[0], Is.EqualTo(RC_NULL_AREA), "Sets area ID of unwalkable triangle to RC_NULL_AREA");
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
int[] areas = { 42 };
|
int[] areas = { 42 };
|
||||||
RcCommons.ClearUnwalkableTriangles(ctx, walkableSlopeAngle, verts, nv, walkable_tri, nt, areas);
|
RcRecast.ClearUnwalkableTriangles(ctx, walkableSlopeAngle, verts, nv, walkable_tri, nt, areas);
|
||||||
Assert.That(areas[0], Is.EqualTo(42), "Does not modify walkable triangle aread ID's");
|
Assert.That(areas[0], Is.EqualTo(42), "Does not modify walkable triangle aread ID's");
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
int[] areas = { 42 };
|
int[] areas = { 42 };
|
||||||
walkableSlopeAngle = 0;
|
walkableSlopeAngle = 0;
|
||||||
RcCommons.ClearUnwalkableTriangles(ctx, walkableSlopeAngle, verts, nv, walkable_tri, nt, areas);
|
RcRecast.ClearUnwalkableTriangles(ctx, walkableSlopeAngle, verts, nv, walkable_tri, nt, areas);
|
||||||
Assert.That(areas[0], Is.EqualTo(RC_NULL_AREA), "Slopes equal to the max slope are considered unwalkable.");
|
Assert.That(areas[0], Is.EqualTo(RC_NULL_AREA), "Slopes equal to the max slope are considered unwalkable.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue