Core/MMaps: updated detour to be current with tc (still doesn't find the right path sometimes)

This commit is contained in:
hondacrx
2018-08-28 14:42:01 -04:00
parent 8c35e4f830
commit a187bfd169
7 changed files with 521 additions and 268 deletions
@@ -35,12 +35,11 @@ using dtTileRef = System.UInt64;
public static partial class Detour
{
public const uint DT_SALT_BITS = 16;
public const uint DT_TILE_BITS = 28;
public const uint DT_POLY_BITS = 20;
public const uint DT_SALT_BITS = 12;
public const uint DT_TILE_BITS = 21;
public const uint DT_POLY_BITS = 31;
}
public static partial class Detour
{
public static bool overlapSlabs(float[] amin, float[] amax, float[] bmin, float[] bmax, float px, float py)
@@ -85,6 +84,7 @@ public static partial class Detour
return va[2];
return 0;
}
public static float getSlabCoord(float[] va, int vaStart, int side)
{
if (side == 0 || side == 4)
@@ -94,7 +94,6 @@ public static partial class Detour
return 0;
}
public static void calcSlabEndPoints(float[] va, int vaStart, float[] vb, int vbStart, float[] bmin, float[] bmax, int side)
{
if (side == 0 || side == 4)
@@ -157,28 +156,6 @@ public static partial class Detour
}
/*
dtNavMesh* dtAllocNavMesh()
{
void* mem = dtAlloc(sizeof(dtNavMesh), DT_ALLOC_PERM);
if (!mem) return 0;
return new(mem) dtNavMesh;
}
*/
// @par
///
/// This function will only free the memory for tiles with the #DT_TILE_FREE_DATA
/// flag set.
/*
void dtFreeNavMesh(dtNavMesh* navmesh)
{
if (!navmesh) return;
navmesh.~dtNavMesh();
dtFree(navmesh);
}
*/
//////////////////////////////////////////////////////////////////////////////////////////
/**
@class dtNavMesh
The navigation mesh consists of one or more tiles defining three primary types of structural data:
@@ -207,7 +184,7 @@ public static partial class Detour
@see dtNavMeshQuery, dtCreateNavMeshData, dtNavMeshCreateParams, #dtAllocNavMesh, #dtFreeNavMesh
*/
/// A navigation mesh based on tiles of convex polygons.
// A navigation mesh based on tiles of convex polygons.
// @ingroup detour
public class dtNavMesh
{
@@ -276,7 +253,7 @@ public static partial class Detour
{
dtPolyRef saltMask = (dtPolyRef)(1 << (int)DT_SALT_BITS) - 1;
dtPolyRef tileMask = (dtPolyRef)((1 << (int)DT_TILE_BITS) - 1);
dtPolyRef polyMask = (dtPolyRef)((1 << (int)DT_POLY_BITS) - 1);
dtPolyRef polyMask = (dtPolyRef)((1ul << (int)DT_POLY_BITS) - 1);
salt = (uint)((polyRef >> (int)(DT_POLY_BITS + DT_TILE_BITS)) & saltMask);
it = (uint)((polyRef >> (int)DT_POLY_BITS) & tileMask);
ip = (uint)(polyRef & polyMask);
@@ -308,7 +285,7 @@ public static partial class Detour
/// @see #encodePolyId
public uint decodePolyIdPoly(dtPolyRef polyRef)
{
dtPolyRef polyMask = (dtPolyRef)((1 << (int)DT_POLY_BITS) - 1);
dtPolyRef polyMask = (dtPolyRef)((1ul << (int)DT_POLY_BITS) - 1);
return (uint)(polyRef & polyMask);
}
@@ -1110,7 +1087,10 @@ public static partial class Detour
tile.flags = flags;
connectIntLinks(tile);
// Base off-mesh connections to their starting polygons and connect connections inside the tile.
baseOffMeshLinks(tile);
connectExtOffMeshLinks(tile, tile, -1);
// Create connections with neighbour tiles.
const int MAX_NEIS = 32;
@@ -1121,11 +1101,11 @@ public static partial class Detour
nneis = getTilesAt(header.x, header.y, neis, MAX_NEIS);
for (int j = 0; j < nneis; ++j)
{
if (neis[j] != tile)
{
connectExtLinks(tile, neis[j], -1);
connectExtLinks(neis[j], tile, -1);
}
if (neis[j] == tile)
continue;
connectExtLinks(tile, neis[j], -1);
connectExtLinks(neis[j], tile, -1);
connectExtOffMeshLinks(tile, neis[j], -1);
connectExtOffMeshLinks(neis[j], tile, -1);
}
@@ -68,6 +68,18 @@ public static partial class Detour
DT_STRAIGHTPATH_ALL_CROSSINGS = 0x02, //< Add a vertex at every polygon edge crossing.
};
/// Options for dtNavMeshQuery::initSlicedFindPath and updateSlicedFindPath
enum dtFindPathOptions
{
DT_FINDPATH_ANY_ANGLE = 0x02, ///< use raycasts during pathfind to "shortcut" (raycast still consider costs)
};
/// Options for dtNavMeshQuery::raycast
enum dtRaycastOptions
{
DT_RAYCAST_USE_COSTS = 0x01, ///< Raycast should calculate movement cost along the ray and fill RaycastHit::cost
};
/// Flags representing the type of a navigation mesh polygon.
public enum dtPolyTypes
{
@@ -85,31 +97,11 @@ public static partial class Detour
/// Index to first link in linked list. (Or #DT_NULL_LINK if there is no link.)
public uint firstLink;
/// The indices of the polygon's vertices.
/// The actual vertices are located in dtMeshTile::verts.
// The indices of the polygon's vertices.
// The actual vertices are located in dtMeshTile::verts.
public ushort[] verts = new ushort[DT_VERTS_PER_POLYGON];
/// Packed data representing neighbor polygons references and flags for each edge.
/*
@var ushort dtPoly::neis[DT_VERTS_PER_POLYGON]
@par
Each entry represents data for the edge starting at the vertex of the same index.
E.g. The entry at index n represents the edge data for vertex[n] to vertex[n+1].
A value of zero indicates the edge has no polygon connection. (It makes up the
border of the navigation mesh.)
The information can be extracted as follows:
@code
neighborRef = neis[n] & 0xff; // Get the neighbor polygon reference.
if (neis[n] & #DT_EX_LINK)
{
// The edge is an external (portal) edge.
}
@endcode
* */
// Packed data representing neighbor polygons references and flags for each edge.
public ushort[] neis = new ushort[DT_VERTS_PER_POLYGON];
/// The user defined polygon flags.
@@ -377,26 +369,9 @@ public static partial class Detour
public float walkableRadius; //< The radius of the agents using the tile.
public float walkableClimb; //< The maximum climb height of the agents using the tile.
public float[] bmin = new float[3]; //< The minimum bounds of the tile's AABB. [(x, y, z)]
public float[] bmax = new float[3]; //< The maximum bounds of the tile's AABB. [(x, y, z)]
public float[] bmax = new float[3]; //< The maximum bounds of the tile's AABB. [(x, y, z)]
/// The bounding volume quantization factor.
/*
@var float dtMeshHeader::bvQuantFactor
@par
This value is used for converting between world and bounding volume coordinates.
For example:
@code
const float cs = 1.0f / tile.header.bvQuantFactor;
const dtBVNode* n = &tile.bvTree[i];
if (n.i >= 0)
{
// This is a leaf node.
float worldMinX = tile.header.bmin[0] + n.bmin[0]*cs;
float worldMinY = tile.header.bmin[0] + n.bmin[1]*cs;
// Etc...
}
@endcode */
public float bvQuantFactor;
public int FromBytes(byte[] array, int start)
@@ -557,8 +532,6 @@ public static partial class Detour
offMeshCons[i] = new dtOffMeshConnection();
start = offMeshCons[i].FromBytes(array, start);
}
//flags = BitConverter.ToInt32(array, start);
//start += sizeof(int);
return start;
}
@@ -599,7 +572,6 @@ public static partial class Detour
{
bytes.AddRange(offMeshCons[i].ToBytes());
}
bytes.AddRange(BitConverter.GetBytes(flags));
return bytes.ToArray();
}
File diff suppressed because it is too large Load Diff
@@ -23,6 +23,7 @@ public partial class Detour
{
DT_NODE_OPEN = 0x01,
DT_NODE_CLOSED = 0x02,
DT_NODE_PARENT_DETACHED = 0x04, // parent of the node is not adjacent. Found using raycast.
};
public const dtNodeIndex DT_NULL_IDX = dtNodeIndex.MaxValue; //(dtNodeIndex)~0;
@@ -32,8 +33,9 @@ public partial class Detour
public float[] pos = new float[3]; //< Position of the node.
public float cost; //< Cost from previous node to current node.
public float total; //< Cost up to the node.
public uint pidx;// : 30; //< Index to parent node.
public byte flags;// : 2; //< Node flags 0/open/closed.
public uint pidx;// : 24; //< Index to parent node.
public uint state;// : 2; ///< extra state information. A polyRef can have multiple nodes with different extra info. see DT_MAX_STATES_PER_NODE
public byte flags;// : 3; //< Node flags 0/open/closed.
public dtPolyRef id; //< Polygon ref the node corresponds to.
///
public static int getSizeOf()
@@ -73,7 +75,6 @@ public partial class Detour
//////////////////////////////////////////////////////////////////////////////////////////
public dtNodePool(int maxNodes, int hashSize)
{
m_maxNodes = maxNodes;
m_hashSize = hashSize;
@@ -164,14 +165,14 @@ public partial class Detour
return null;
}
public dtNode getNode(dtPolyRef id)
public dtNode getNode(dtPolyRef id, byte state = 0)
{
uint bucket = (uint)(dtHashRef(id) & (m_hashSize - 1));
dtNodeIndex i = m_first[bucket];
dtNode node = null;
while (i != DT_NULL_IDX)
{
if (m_nodes[i].id == id)
if (m_nodes[i].id == id && m_nodes[i].state == state)
return m_nodes[i];
i = m_next[i];
}
@@ -188,6 +189,7 @@ public partial class Detour
node.cost = 0;
node.total = 0;
node.id = id;
node.state = state;
node.flags = 0;
m_next[i] = m_first[bucket];
+1 -1
View File
@@ -172,7 +172,7 @@ namespace Game.Chat
for (int i = 0; i < navmesh.getMaxTiles(); ++i)
{
Detour.dtMeshTile tile = navmesh.getTile(i);
if (tile == null)
if (tile.header == null)
continue;
handler.SendSysMessage("[{0:D2}, {1:D2}]", tile.header.x, tile.header.y);
+1 -5
View File
@@ -16,12 +16,9 @@
*/
using Framework.Constants;
using Game.DataStorage;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
namespace Game
@@ -152,13 +149,12 @@ namespace Game
}
var bytes = reader.ReadBytes((int)fileHeader.size);
Detour.dtRawTileData data = new Detour.dtRawTileData();
data.FromBytes(bytes, 0);
ulong tileRef = 0;
// memory allocated for data is now managed by detour, and will be deallocated when the tile is removed
if (Detour.dtStatusSucceed(mmap.navMesh.addTile(data, 0, 0, ref tileRef)))
if (Detour.dtStatusSucceed(mmap.navMesh.addTile(data, 1, 0, ref tileRef)))
{
mmap.loadedTileRefs.Add(packedGridPos, tileRef);
++loadedTiles;
@@ -340,6 +340,7 @@ namespace Game.Movement
// generate suffix
uint suffixPolyLength = 0;
ulong[] tempPolyRefs = new ulong[_pathPolyRefs.Length];
uint dtResult;
if (_straightLine)
@@ -354,7 +355,7 @@ namespace Game.Movement
_filter,
ref hit,
hitNormal,
_pathPolyRefs,
tempPolyRefs,
ref suffixPolyLength,
74 - (int)prefixPolyLength);
@@ -374,7 +375,7 @@ namespace Game.Movement
suffixEndPoint, // start position
endPoint, // end position
_filter, // polygon search filter
_pathPolyRefs,
tempPolyRefs,
ref suffixPolyLength,
74 - (int)prefixPolyLength);
}
@@ -389,6 +390,9 @@ namespace Game.Movement
Log.outDebug(LogFilter.Maps, "m_polyLength={0} prefixPolyLength={1} suffixPolyLength={2} \n", _polyLength, prefixPolyLength, suffixPolyLength);
for (var i = 0; i < _pathPolyRefs.Length - (prefixPolyLength - 1); ++i)
_pathPolyRefs[(prefixPolyLength - 1) + i] = tempPolyRefs[i];
// new path = prefix + suffix - overlap
_polyLength = prefixPolyLength + suffixPolyLength - 1;
}
@@ -797,21 +801,21 @@ namespace Game.Movement
void CreateFilter()
{
NavArea includeFlags = 0;
NavArea excludeFlags = 0;
NavTerrainFlag includeFlags = 0;
NavTerrainFlag excludeFlags = 0;
if (_sourceUnit.IsTypeId(TypeId.Unit))
{
Creature creature = _sourceUnit.ToCreature();
if (creature.CanWalk())
includeFlags |= NavArea.Ground;
includeFlags |= NavTerrainFlag.Ground;
// creatures don't take environmental damage
if (creature.CanSwim())
includeFlags |= (NavArea.Water | NavArea.MagmaSlime);
includeFlags |= (NavTerrainFlag.Water | NavTerrainFlag.MagmaSlime);
}
else
includeFlags = (NavArea.Ground | NavArea.Water | NavArea.MagmaSlime);
includeFlags = (NavTerrainFlag.Ground | NavTerrainFlag.Water | NavTerrainFlag.MagmaSlime);
_filter.setIncludeFlags((ushort)includeFlags);
_filter.setExcludeFlags((ushort)excludeFlags);