forked from mirror/DotRecast
Changed `Dictionary<int, List<DtMeshTile>>` to `DtMeshTile[]` to optimize memory usage
This commit is contained in:
parent
9a03ade6c9
commit
c7f03d00ff
|
@ -17,6 +17,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
- Changed `PolyQueryInvoker` to `DtActionPolyQuery`
|
- Changed `PolyQueryInvoker` to `DtActionPolyQuery`
|
||||||
- Changed `DtTileCacheBuilder` to a static class
|
- Changed `DtTileCacheBuilder` to a static class
|
||||||
- Changed `DtTileCacheLayerHeaderReader` to a static class
|
- Changed `DtTileCacheLayerHeaderReader` to a static class
|
||||||
|
- Changed `Dictionary<int, List<DtMeshTile>>` to `DtMeshTile[]` to optimize memory usage
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
- Nothing
|
- Nothing
|
||||||
|
|
|
@ -33,6 +33,7 @@ namespace DotRecast.Detour
|
||||||
public DtLink[] links; // The tile links. [Size: dtMeshHeader::maxLinkCount]
|
public DtLink[] links; // The tile links. [Size: dtMeshHeader::maxLinkCount]
|
||||||
|
|
||||||
public int flags; //< Tile flags. (See: #dtTileFlags)
|
public int flags; //< Tile flags. (See: #dtTileFlags)
|
||||||
|
public DtMeshTile next; //< The next free tile, or the next tile in the spatial grid.
|
||||||
|
|
||||||
public DtMeshTile(int index)
|
public DtMeshTile(int index)
|
||||||
{
|
{
|
||||||
|
|
|
@ -39,8 +39,8 @@ namespace DotRecast.Detour
|
||||||
private int m_tileLutSize; //< Tile hash lookup size (must be pot).
|
private int m_tileLutSize; //< Tile hash lookup size (must be pot).
|
||||||
private int m_tileLutMask; // < Tile hash lookup mask.
|
private int m_tileLutMask; // < Tile hash lookup mask.
|
||||||
|
|
||||||
private Dictionary<int, List<DtMeshTile>> m_posLookup; //< Tile hash lookup.
|
private DtMeshTile[] m_posLookup; //< Tile hash lookup.
|
||||||
private LinkedList<DtMeshTile> m_nextFree; //< Freelist of tiles.
|
private DtMeshTile m_nextFree; //< Freelist of tiles.
|
||||||
private DtMeshTile[] m_tiles; //< List of tiles.
|
private DtMeshTile[] m_tiles; //< List of tiles.
|
||||||
|
|
||||||
/** The maximum number of vertices per navigation polygon. */
|
/** The maximum number of vertices per navigation polygon. */
|
||||||
|
@ -64,13 +64,14 @@ namespace DotRecast.Detour
|
||||||
m_tileLutMask = m_tileLutSize - 1;
|
m_tileLutMask = m_tileLutSize - 1;
|
||||||
|
|
||||||
m_tiles = new DtMeshTile[m_maxTiles];
|
m_tiles = new DtMeshTile[m_maxTiles];
|
||||||
m_posLookup = new Dictionary<int, List<DtMeshTile>>();
|
m_posLookup = new DtMeshTile[m_tileLutSize];
|
||||||
m_nextFree = new LinkedList<DtMeshTile>();
|
m_nextFree = null;
|
||||||
for (int i = 0; i < m_maxTiles; i++)
|
for (int i = m_maxTiles-1; i >= 0; --i)
|
||||||
{
|
{
|
||||||
m_tiles[i] = new DtMeshTile(i);
|
m_tiles[i] = new DtMeshTile(i);
|
||||||
m_tiles[i].salt = 1;
|
m_tiles[i].salt = 1;
|
||||||
m_nextFree.AddLast(m_tiles[i]);
|
m_tiles[i].next = m_nextFree;
|
||||||
|
m_nextFree = m_tiles[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
return DtStatus.DT_SUCCESS;
|
return DtStatus.DT_SUCCESS;
|
||||||
|
@ -384,15 +385,13 @@ namespace DotRecast.Detour
|
||||||
DtMeshTile tile = null;
|
DtMeshTile tile = null;
|
||||||
if (lastRef == 0)
|
if (lastRef == 0)
|
||||||
{
|
{
|
||||||
// Make sure we could allocate a tile.
|
if (null != m_nextFree)
|
||||||
if (0 == m_nextFree.Count)
|
|
||||||
{
|
{
|
||||||
throw new Exception("Could not allocate a tile");
|
tile = m_nextFree;
|
||||||
|
m_nextFree = tile.next;
|
||||||
|
tile.next = null;
|
||||||
|
m_tileCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
tile = m_nextFree.First?.Value;
|
|
||||||
m_nextFree.RemoveFirst();
|
|
||||||
m_tileCount++;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -405,14 +404,25 @@ namespace DotRecast.Detour
|
||||||
|
|
||||||
// Try to find the specific tile id from the free list.
|
// Try to find the specific tile id from the free list.
|
||||||
DtMeshTile target = m_tiles[tileIndex];
|
DtMeshTile target = m_tiles[tileIndex];
|
||||||
// Remove from freelist
|
DtMeshTile prev = null;
|
||||||
if (!m_nextFree.Remove(target))
|
tile = m_nextFree;
|
||||||
|
|
||||||
|
while (null != tile && tile != target)
|
||||||
{
|
{
|
||||||
// Could not find the correct location.
|
prev = tile;
|
||||||
return DtStatus.DT_FAILURE | DtStatus.DT_OUT_OF_MEMORY;
|
tile = tile.next;
|
||||||
}
|
}
|
||||||
|
|
||||||
tile = target;
|
// Could not find the correct location.
|
||||||
|
if (tile != target)
|
||||||
|
return DtStatus.DT_FAILURE | DtStatus.DT_OUT_OF_MEMORY;
|
||||||
|
|
||||||
|
// Remove from freelist
|
||||||
|
if (null == prev)
|
||||||
|
m_nextFree = tile.next;
|
||||||
|
else
|
||||||
|
prev.next = tile.next;
|
||||||
|
|
||||||
// Restore salt.
|
// Restore salt.
|
||||||
tile.salt = DecodePolyIdSalt(lastRef);
|
tile.salt = DecodePolyIdSalt(lastRef);
|
||||||
}
|
}
|
||||||
|
@ -424,7 +434,10 @@ namespace DotRecast.Detour
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insert tile into the position lut.
|
// Insert tile into the position lut.
|
||||||
GetTileListByPos(header.x, header.y).Add(tile);
|
int h = ComputeTileHash(header.x, header.y, m_tileLutMask);
|
||||||
|
tile.next = m_posLookup[h];
|
||||||
|
m_posLookup[h] = tile;
|
||||||
|
|
||||||
|
|
||||||
// Patch header pointers.
|
// Patch header pointers.
|
||||||
tile.data = data;
|
tile.data = data;
|
||||||
|
@ -450,13 +463,19 @@ namespace DotRecast.Detour
|
||||||
tile.flags = flags;
|
tile.flags = flags;
|
||||||
|
|
||||||
ConnectIntLinks(tile);
|
ConnectIntLinks(tile);
|
||||||
|
|
||||||
// Base off-mesh connections to their starting polygons and connect connections inside the tile.
|
// Base off-mesh connections to their starting polygons and connect connections inside the tile.
|
||||||
BaseOffMeshLinks(tile);
|
BaseOffMeshLinks(tile);
|
||||||
ConnectExtOffMeshLinks(tile, tile, -1);
|
ConnectExtOffMeshLinks(tile, tile, -1);
|
||||||
|
|
||||||
|
// Create connections with neighbour tiles.
|
||||||
|
const int MAX_NEIS = 32;
|
||||||
|
DtMeshTile[] neis = new DtMeshTile[MAX_NEIS];
|
||||||
|
int nneis;
|
||||||
|
|
||||||
// Connect with layers in current tile.
|
// Connect with layers in current tile.
|
||||||
List<DtMeshTile> neis = GetTilesAt(header.x, header.y);
|
nneis = GetTilesAt(header.x, header.y, neis, MAX_NEIS);
|
||||||
for (int j = 0; j < neis.Count; ++j)
|
for (int j = 0; j < nneis; ++j)
|
||||||
{
|
{
|
||||||
if (neis[j] == tile)
|
if (neis[j] == tile)
|
||||||
{
|
{
|
||||||
|
@ -472,8 +491,8 @@ namespace DotRecast.Detour
|
||||||
// Connect with neighbour tiles.
|
// Connect with neighbour tiles.
|
||||||
for (int i = 0; i < 8; ++i)
|
for (int i = 0; i < 8; ++i)
|
||||||
{
|
{
|
||||||
neis = GetNeighbourTilesAt(header.x, header.y, i);
|
nneis = GetNeighbourTilesAt(header.x, header.y, i, neis, MAX_NEIS);
|
||||||
for (int j = 0; j < neis.Count; ++j)
|
for (int j = 0; j < nneis; ++j)
|
||||||
{
|
{
|
||||||
ConnectExtLinks(tile, neis[j], i);
|
ConnectExtLinks(tile, neis[j], i);
|
||||||
ConnectExtLinks(neis[j], tile, DtUtils.OppositeTile(i));
|
ConnectExtLinks(neis[j], tile, DtUtils.OppositeTile(i));
|
||||||
|
@ -516,30 +535,44 @@ namespace DotRecast.Detour
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove tile from hash lookup.
|
// Remove tile from hash lookup.
|
||||||
GetTileListByPos(tile.data.header.x, tile.data.header.y).Remove(tile);
|
int h = ComputeTileHash(tile.data.header.x, tile.data.header.y, m_tileLutMask);
|
||||||
|
DtMeshTile prev = null;
|
||||||
// Remove connections to neighbour tiles.
|
DtMeshTile cur = m_posLookup[h];
|
||||||
// Create connections with neighbour tiles.
|
while (null != cur)
|
||||||
|
|
||||||
// Disconnect from other layers in current tile.
|
|
||||||
List<DtMeshTile> nneis = GetTilesAt(tile.data.header.x, tile.data.header.y);
|
|
||||||
foreach (DtMeshTile j in nneis)
|
|
||||||
{
|
{
|
||||||
if (j == tile)
|
if (cur == tile)
|
||||||
{
|
{
|
||||||
continue;
|
if (null != prev)
|
||||||
|
prev.next = cur.next;
|
||||||
|
else
|
||||||
|
m_posLookup[h] = cur.next;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
UnconnectLinks(j, tile);
|
prev = cur;
|
||||||
|
cur = cur.next;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove connections to neighbour tiles.
|
||||||
|
const int MAX_NEIS = 32;
|
||||||
|
DtMeshTile[] neis = new DtMeshTile[MAX_NEIS];
|
||||||
|
int nneis = 0;
|
||||||
|
|
||||||
|
// Disconnect from other layers in current tile.
|
||||||
|
nneis = GetTilesAt(tile.data.header.x, tile.data.header.y, neis, MAX_NEIS);
|
||||||
|
for (int j = 0; j < nneis; ++j)
|
||||||
|
{
|
||||||
|
if (neis[j] == tile) continue;
|
||||||
|
UnconnectLinks(neis[j], tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disconnect from neighbour tiles.
|
// Disconnect from neighbour tiles.
|
||||||
for (int i = 0; i < 8; ++i)
|
for (int i = 0; i < 8; ++i)
|
||||||
{
|
{
|
||||||
nneis = GetNeighbourTilesAt(tile.data.header.x, tile.data.header.y, i);
|
nneis = GetNeighbourTilesAt(tile.data.header.x, tile.data.header.y, i, neis, MAX_NEIS);
|
||||||
foreach (DtMeshTile j in nneis)
|
for (int j = 0; j < nneis; ++j)
|
||||||
{
|
{
|
||||||
UnconnectLinks(j, tile);
|
UnconnectLinks(neis[j], tile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -557,7 +590,8 @@ namespace DotRecast.Detour
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add to free list.
|
// Add to free list.
|
||||||
m_nextFree.AddFirst(tile);
|
tile.next = m_nextFree;
|
||||||
|
m_nextFree = tile;
|
||||||
m_tileCount--;
|
m_tileCount--;
|
||||||
return GetTileRef(tile);
|
return GetTileRef(tile);
|
||||||
}
|
}
|
||||||
|
@ -1270,19 +1304,27 @@ namespace DotRecast.Detour
|
||||||
|
|
||||||
DtMeshTile GetTileAt(int x, int y, int layer)
|
DtMeshTile GetTileAt(int x, int y, int layer)
|
||||||
{
|
{
|
||||||
foreach (DtMeshTile tile in GetTileListByPos(x, y))
|
// Find tile based on hash.
|
||||||
|
int h = ComputeTileHash(x, y, m_tileLutMask);
|
||||||
|
DtMeshTile tile = m_posLookup[h];
|
||||||
|
while (null != tile)
|
||||||
{
|
{
|
||||||
if (tile.data.header != null && tile.data.header.x == x && tile.data.header.y == y
|
if (null != tile.data &&
|
||||||
&& tile.data.header.layer == layer)
|
null != tile.data.header &&
|
||||||
|
tile.data.header.x == x &&
|
||||||
|
tile.data.header.y == y &&
|
||||||
|
tile.data.header.layer == layer)
|
||||||
{
|
{
|
||||||
return tile;
|
return tile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tile = tile.next;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<DtMeshTile> GetNeighbourTilesAt(int x, int y, int side)
|
int GetNeighbourTilesAt(int x, int y, int side, DtMeshTile[] tiles, int maxTiles)
|
||||||
{
|
{
|
||||||
int nx = x, ny = y;
|
int nx = x, ny = y;
|
||||||
switch (side)
|
switch (side)
|
||||||
|
@ -1317,21 +1359,31 @@ namespace DotRecast.Detour
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return GetTilesAt(nx, ny);
|
return GetTilesAt(nx, ny, tiles, maxTiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<DtMeshTile> GetTilesAt(int x, int y)
|
public int GetTilesAt(int x, int y, DtMeshTile[] tiles, int maxTiles)
|
||||||
{
|
{
|
||||||
List<DtMeshTile> tiles = new List<DtMeshTile>();
|
int n = 0;
|
||||||
foreach (DtMeshTile tile in GetTileListByPos(x, y))
|
|
||||||
|
// Find tile based on hash.
|
||||||
|
int h = ComputeTileHash(x, y, m_tileLutMask);
|
||||||
|
DtMeshTile tile = m_posLookup[h];
|
||||||
|
while (null != tile)
|
||||||
{
|
{
|
||||||
if (tile.data.header != null && tile.data.header.x == x && tile.data.header.y == y)
|
if (null != tile.data &&
|
||||||
|
null != tile.data.header &&
|
||||||
|
tile.data.header.x == x &&
|
||||||
|
tile.data.header.y == y)
|
||||||
{
|
{
|
||||||
tiles.Add(tile);
|
if (n < maxTiles)
|
||||||
|
tiles[n++] = tile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tile = tile.next;
|
||||||
}
|
}
|
||||||
|
|
||||||
return tiles;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long GetTileRefAt(int x, int y, int layer)
|
public long GetTileRefAt(int x, int y, int layer)
|
||||||
|
@ -1453,9 +1505,9 @@ namespace DotRecast.Detour
|
||||||
return m_tileCount;
|
return m_tileCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int GetAvailableTileCount()
|
public bool IsAvailableTileCount()
|
||||||
{
|
{
|
||||||
return m_nextFree.Count;
|
return null != m_nextFree;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DtStatus SetPolyFlags(long refs, int flags)
|
public DtStatus SetPolyFlags(long refs, int flags)
|
||||||
|
@ -1613,18 +1665,6 @@ namespace DotRecast.Detour
|
||||||
return center;
|
return center;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<DtMeshTile> GetTileListByPos(int x, int z)
|
|
||||||
{
|
|
||||||
var tileHash = ComputeTileHash(x, z, m_tileLutMask);
|
|
||||||
if (!m_posLookup.TryGetValue(tileHash, out var tiles))
|
|
||||||
{
|
|
||||||
tiles = new List<DtMeshTile>();
|
|
||||||
m_posLookup.Add(tileHash, tiles);
|
|
||||||
}
|
|
||||||
|
|
||||||
return tiles;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ComputeBounds(out RcVec3f bmin, out RcVec3f bmax)
|
public void ComputeBounds(out RcVec3f bmin, out RcVec3f bmax)
|
||||||
{
|
{
|
||||||
bmin = new RcVec3f(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity);
|
bmin = new RcVec3f(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity);
|
||||||
|
|
|
@ -764,39 +764,27 @@ namespace DotRecast.Detour
|
||||||
// Find tiles the query touches.
|
// Find tiles the query touches.
|
||||||
RcVec3f bmin = RcVec3f.Subtract(center, halfExtents);
|
RcVec3f bmin = RcVec3f.Subtract(center, halfExtents);
|
||||||
RcVec3f bmax = RcVec3f.Add(center, halfExtents);
|
RcVec3f bmax = RcVec3f.Add(center, halfExtents);
|
||||||
foreach (var t in QueryTiles(center, halfExtents))
|
|
||||||
{
|
|
||||||
QueryPolygonsInTile(t, bmin, bmax, filter, query);
|
|
||||||
}
|
|
||||||
|
|
||||||
return DtStatus.DT_SUCCESS;
|
// Find tiles the query touches.
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Finds tiles that overlap the search box.
|
|
||||||
*/
|
|
||||||
public IList<DtMeshTile> QueryTiles(RcVec3f center, RcVec3f halfExtents)
|
|
||||||
{
|
|
||||||
if (!center.IsFinite() || !halfExtents.IsFinite())
|
|
||||||
{
|
|
||||||
return RcImmutableArray<DtMeshTile>.Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
RcVec3f bmin = RcVec3f.Subtract(center, halfExtents);
|
|
||||||
RcVec3f bmax = RcVec3f.Add(center, halfExtents);
|
|
||||||
m_nav.CalcTileLoc(bmin, out var minx, out var miny);
|
m_nav.CalcTileLoc(bmin, out var minx, out var miny);
|
||||||
m_nav.CalcTileLoc(bmax, out var maxx, out var maxy);
|
m_nav.CalcTileLoc(bmax, out var maxx, out var maxy);
|
||||||
|
|
||||||
List<DtMeshTile> tiles = new List<DtMeshTile>();
|
const int MAX_NEIS = 32;
|
||||||
|
DtMeshTile[] neis = new DtMeshTile[MAX_NEIS];
|
||||||
|
|
||||||
for (int y = miny; y <= maxy; ++y)
|
for (int y = miny; y <= maxy; ++y)
|
||||||
{
|
{
|
||||||
for (int x = minx; x <= maxx; ++x)
|
for (int x = minx; x <= maxx; ++x)
|
||||||
{
|
{
|
||||||
tiles.AddRange(m_nav.GetTilesAt(x, y));
|
int nneis = m_nav.GetTilesAt(x, y, neis, MAX_NEIS);
|
||||||
|
for (int j = 0; j < nneis; ++j)
|
||||||
|
{
|
||||||
|
QueryPolygonsInTile(neis[j], bmin, bmax, filter, query);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return tiles;
|
return DtStatus.DT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @par
|
/// @par
|
||||||
|
|
|
@ -68,8 +68,8 @@ namespace DotRecast.Recast.Toolset.Tools
|
||||||
tileTriCount = 0; // ...
|
tileTriCount = 0; // ...
|
||||||
tileMemUsage = 0; // ...
|
tileMemUsage = 0; // ...
|
||||||
|
|
||||||
var availableTileCount = navMesh.GetAvailableTileCount();
|
var availableTile = navMesh.IsAvailableTileCount();
|
||||||
if (0 >= availableTileCount)
|
if (!availableTile)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,6 @@ using NUnit.Framework;
|
||||||
|
|
||||||
namespace DotRecast.Detour.Test.Io;
|
namespace DotRecast.Detour.Test.Io;
|
||||||
|
|
||||||
|
|
||||||
public class MeshSetReaderTest
|
public class MeshSetReaderTest
|
||||||
{
|
{
|
||||||
private readonly DtMeshSetReader reader = new DtMeshSetReader();
|
private readonly DtMeshSetReader reader = new DtMeshSetReader();
|
||||||
|
@ -39,20 +38,28 @@ public class MeshSetReaderTest
|
||||||
Assert.That(mesh.GetMaxTiles(), Is.EqualTo(128));
|
Assert.That(mesh.GetMaxTiles(), Is.EqualTo(128));
|
||||||
Assert.That(mesh.GetParams().maxPolys, Is.EqualTo(0x8000));
|
Assert.That(mesh.GetParams().maxPolys, Is.EqualTo(0x8000));
|
||||||
Assert.That(mesh.GetParams().tileWidth, Is.EqualTo(9.6f).Within(0.001f));
|
Assert.That(mesh.GetParams().tileWidth, Is.EqualTo(9.6f).Within(0.001f));
|
||||||
List<DtMeshTile> tiles = mesh.GetTilesAt(4, 7);
|
|
||||||
Assert.That(tiles.Count, Is.EqualTo(1));
|
const int MAX_NEIS = 32;
|
||||||
|
DtMeshTile[] tiles = new DtMeshTile[MAX_NEIS];
|
||||||
|
int nneis = 0;
|
||||||
|
|
||||||
|
nneis = mesh.GetTilesAt(4, 7, tiles, MAX_NEIS);
|
||||||
|
Assert.That(nneis, Is.EqualTo(1));
|
||||||
Assert.That(tiles[0].data.polys.Length, Is.EqualTo(7));
|
Assert.That(tiles[0].data.polys.Length, Is.EqualTo(7));
|
||||||
Assert.That(tiles[0].data.verts.Length, Is.EqualTo(22 * 3));
|
Assert.That(tiles[0].data.verts.Length, Is.EqualTo(22 * 3));
|
||||||
tiles = mesh.GetTilesAt(1, 6);
|
|
||||||
Assert.That(tiles.Count, Is.EqualTo(1));
|
nneis = mesh.GetTilesAt(1, 6, tiles, MAX_NEIS);
|
||||||
|
Assert.That(nneis, Is.EqualTo(1));
|
||||||
Assert.That(tiles[0].data.polys.Length, Is.EqualTo(7));
|
Assert.That(tiles[0].data.polys.Length, Is.EqualTo(7));
|
||||||
Assert.That(tiles[0].data.verts.Length, Is.EqualTo(26 * 3));
|
Assert.That(tiles[0].data.verts.Length, Is.EqualTo(26 * 3));
|
||||||
tiles = mesh.GetTilesAt(6, 2);
|
|
||||||
Assert.That(tiles.Count, Is.EqualTo(1));
|
nneis = mesh.GetTilesAt(6, 2, tiles, MAX_NEIS);
|
||||||
|
Assert.That(nneis, Is.EqualTo(1));
|
||||||
Assert.That(tiles[0].data.polys.Length, Is.EqualTo(1));
|
Assert.That(tiles[0].data.polys.Length, Is.EqualTo(1));
|
||||||
Assert.That(tiles[0].data.verts.Length, Is.EqualTo(4 * 3));
|
Assert.That(tiles[0].data.verts.Length, Is.EqualTo(4 * 3));
|
||||||
tiles = mesh.GetTilesAt(7, 6);
|
|
||||||
Assert.That(tiles.Count, Is.EqualTo(1));
|
nneis = mesh.GetTilesAt(7, 6, tiles, MAX_NEIS);
|
||||||
|
Assert.That(nneis, Is.EqualTo(1));
|
||||||
Assert.That(tiles[0].data.polys.Length, Is.EqualTo(8));
|
Assert.That(tiles[0].data.polys.Length, Is.EqualTo(8));
|
||||||
Assert.That(tiles[0].data.verts.Length, Is.EqualTo(24 * 3));
|
Assert.That(tiles[0].data.verts.Length, Is.EqualTo(24 * 3));
|
||||||
}
|
}
|
||||||
|
@ -68,20 +75,28 @@ public class MeshSetReaderTest
|
||||||
Assert.That(mesh.GetMaxTiles(), Is.EqualTo(128));
|
Assert.That(mesh.GetMaxTiles(), Is.EqualTo(128));
|
||||||
Assert.That(mesh.GetParams().maxPolys, Is.EqualTo(0x8000));
|
Assert.That(mesh.GetParams().maxPolys, Is.EqualTo(0x8000));
|
||||||
Assert.That(mesh.GetParams().tileWidth, Is.EqualTo(9.6f).Within(0.001f));
|
Assert.That(mesh.GetParams().tileWidth, Is.EqualTo(9.6f).Within(0.001f));
|
||||||
List<DtMeshTile> tiles = mesh.GetTilesAt(6, 9);
|
|
||||||
Assert.That(tiles.Count, Is.EqualTo(1));
|
const int MAX_NEIS = 32;
|
||||||
|
DtMeshTile[] tiles = new DtMeshTile[MAX_NEIS];
|
||||||
|
int nneis = 0;
|
||||||
|
|
||||||
|
nneis = mesh.GetTilesAt(6, 9, tiles, MAX_NEIS);
|
||||||
|
Assert.That(nneis, Is.EqualTo(1));
|
||||||
Assert.That(tiles[0].data.polys.Length, Is.EqualTo(2));
|
Assert.That(tiles[0].data.polys.Length, Is.EqualTo(2));
|
||||||
Assert.That(tiles[0].data.verts.Length, Is.EqualTo(7 * 3));
|
Assert.That(tiles[0].data.verts.Length, Is.EqualTo(7 * 3));
|
||||||
tiles = mesh.GetTilesAt(2, 9);
|
|
||||||
Assert.That(tiles.Count, Is.EqualTo(1));
|
nneis = mesh.GetTilesAt(2, 9, tiles, MAX_NEIS);
|
||||||
|
Assert.That(nneis, Is.EqualTo(1));
|
||||||
Assert.That(tiles[0].data.polys.Length, Is.EqualTo(2));
|
Assert.That(tiles[0].data.polys.Length, Is.EqualTo(2));
|
||||||
Assert.That(tiles[0].data.verts.Length, Is.EqualTo(9 * 3));
|
Assert.That(tiles[0].data.verts.Length, Is.EqualTo(9 * 3));
|
||||||
tiles = mesh.GetTilesAt(4, 3);
|
|
||||||
Assert.That(tiles.Count, Is.EqualTo(1));
|
nneis = mesh.GetTilesAt(4, 3, tiles, MAX_NEIS);
|
||||||
|
Assert.That(nneis, Is.EqualTo(1));
|
||||||
Assert.That(tiles[0].data.polys.Length, Is.EqualTo(3));
|
Assert.That(tiles[0].data.polys.Length, Is.EqualTo(3));
|
||||||
Assert.That(tiles[0].data.verts.Length, Is.EqualTo(6 * 3));
|
Assert.That(tiles[0].data.verts.Length, Is.EqualTo(6 * 3));
|
||||||
tiles = mesh.GetTilesAt(2, 8);
|
|
||||||
Assert.That(tiles.Count, Is.EqualTo(1));
|
nneis = mesh.GetTilesAt(2, 8, tiles, MAX_NEIS);
|
||||||
|
Assert.That(nneis, Is.EqualTo(1));
|
||||||
Assert.That(tiles[0].data.polys.Length, Is.EqualTo(5));
|
Assert.That(tiles[0].data.polys.Length, Is.EqualTo(5));
|
||||||
Assert.That(tiles[0].data.verts.Length, Is.EqualTo(17 * 3));
|
Assert.That(tiles[0].data.verts.Length, Is.EqualTo(17 * 3));
|
||||||
}
|
}
|
||||||
|
@ -97,20 +112,28 @@ public class MeshSetReaderTest
|
||||||
Assert.That(mesh.GetMaxTiles(), Is.EqualTo(128));
|
Assert.That(mesh.GetMaxTiles(), Is.EqualTo(128));
|
||||||
Assert.That(mesh.GetParams().maxPolys, Is.EqualTo(0x8000));
|
Assert.That(mesh.GetParams().maxPolys, Is.EqualTo(0x8000));
|
||||||
Assert.That(mesh.GetParams().tileWidth, Is.EqualTo(9.6f).Within(0.001f));
|
Assert.That(mesh.GetParams().tileWidth, Is.EqualTo(9.6f).Within(0.001f));
|
||||||
List<DtMeshTile> tiles = mesh.GetTilesAt(6, 9);
|
|
||||||
Assert.That(tiles.Count, Is.EqualTo(1));
|
const int MAX_NEIS = 32;
|
||||||
|
DtMeshTile[] tiles = new DtMeshTile[MAX_NEIS];
|
||||||
|
int nneis = 0;
|
||||||
|
|
||||||
|
nneis = mesh.GetTilesAt(6, 9, tiles, MAX_NEIS);
|
||||||
|
Assert.That(nneis, Is.EqualTo(1));
|
||||||
Assert.That(tiles[0].data.polys.Length, Is.EqualTo(2));
|
Assert.That(tiles[0].data.polys.Length, Is.EqualTo(2));
|
||||||
Assert.That(tiles[0].data.verts.Length, Is.EqualTo(7 * 3));
|
Assert.That(tiles[0].data.verts.Length, Is.EqualTo(7 * 3));
|
||||||
tiles = mesh.GetTilesAt(2, 9);
|
|
||||||
Assert.That(tiles.Count, Is.EqualTo(1));
|
nneis = mesh.GetTilesAt(2, 9, tiles, MAX_NEIS);
|
||||||
|
Assert.That(nneis, Is.EqualTo(1));
|
||||||
Assert.That(tiles[0].data.polys.Length, Is.EqualTo(2));
|
Assert.That(tiles[0].data.polys.Length, Is.EqualTo(2));
|
||||||
Assert.That(tiles[0].data.verts.Length, Is.EqualTo(9 * 3));
|
Assert.That(tiles[0].data.verts.Length, Is.EqualTo(9 * 3));
|
||||||
tiles = mesh.GetTilesAt(4, 3);
|
|
||||||
Assert.That(tiles.Count, Is.EqualTo(1));
|
nneis = mesh.GetTilesAt(4, 3, tiles, MAX_NEIS);
|
||||||
|
Assert.That(nneis, Is.EqualTo(1));
|
||||||
Assert.That(tiles[0].data.polys.Length, Is.EqualTo(3));
|
Assert.That(tiles[0].data.polys.Length, Is.EqualTo(3));
|
||||||
Assert.That(tiles[0].data.verts.Length, Is.EqualTo(6 * 3));
|
Assert.That(tiles[0].data.verts.Length, Is.EqualTo(6 * 3));
|
||||||
tiles = mesh.GetTilesAt(2, 8);
|
|
||||||
Assert.That(tiles.Count, Is.EqualTo(1));
|
nneis = mesh.GetTilesAt(2, 8, tiles, MAX_NEIS);
|
||||||
|
Assert.That(nneis, Is.EqualTo(1));
|
||||||
Assert.That(tiles[0].data.polys.Length, Is.EqualTo(5));
|
Assert.That(tiles[0].data.polys.Length, Is.EqualTo(5));
|
||||||
Assert.That(tiles[0].data.verts.Length, Is.EqualTo(17 * 3));
|
Assert.That(tiles[0].data.verts.Length, Is.EqualTo(17 * 3));
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,20 +107,28 @@ public class MeshSetReaderWriterTest
|
||||||
Assert.That(mesh.GetMaxTiles(), Is.EqualTo(128));
|
Assert.That(mesh.GetMaxTiles(), Is.EqualTo(128));
|
||||||
Assert.That(mesh.GetParams().maxPolys, Is.EqualTo(0x8000));
|
Assert.That(mesh.GetParams().maxPolys, Is.EqualTo(0x8000));
|
||||||
Assert.That(mesh.GetParams().tileWidth, Is.EqualTo(9.6f).Within(0.001f));
|
Assert.That(mesh.GetParams().tileWidth, Is.EqualTo(9.6f).Within(0.001f));
|
||||||
List<DtMeshTile> tiles = mesh.GetTilesAt(6, 9);
|
|
||||||
Assert.That(tiles.Count, Is.EqualTo(1));
|
const int MAX_NEIS = 32;
|
||||||
|
DtMeshTile[] tiles = new DtMeshTile[MAX_NEIS];
|
||||||
|
int nneis = 0;
|
||||||
|
|
||||||
|
nneis = mesh.GetTilesAt(6, 9, tiles, MAX_NEIS);
|
||||||
|
Assert.That(nneis, Is.EqualTo(1));
|
||||||
Assert.That(tiles[0].data.polys.Length, Is.EqualTo(2));
|
Assert.That(tiles[0].data.polys.Length, Is.EqualTo(2));
|
||||||
Assert.That(tiles[0].data.verts.Length, Is.EqualTo(7 * 3));
|
Assert.That(tiles[0].data.verts.Length, Is.EqualTo(7 * 3));
|
||||||
tiles = mesh.GetTilesAt(2, 9);
|
|
||||||
Assert.That(tiles.Count, Is.EqualTo(1));
|
nneis = mesh.GetTilesAt(2, 9, tiles, MAX_NEIS);
|
||||||
|
Assert.That(nneis, Is.EqualTo(1));
|
||||||
Assert.That(tiles[0].data.polys.Length, Is.EqualTo(2));
|
Assert.That(tiles[0].data.polys.Length, Is.EqualTo(2));
|
||||||
Assert.That(tiles[0].data.verts.Length, Is.EqualTo(9 * 3));
|
Assert.That(tiles[0].data.verts.Length, Is.EqualTo(9 * 3));
|
||||||
tiles = mesh.GetTilesAt(4, 3);
|
|
||||||
Assert.That(tiles.Count, Is.EqualTo(1));
|
nneis = mesh.GetTilesAt(4, 3, tiles, MAX_NEIS);
|
||||||
|
Assert.That(nneis, Is.EqualTo(1));
|
||||||
Assert.That(tiles[0].data.polys.Length, Is.EqualTo(3));
|
Assert.That(tiles[0].data.polys.Length, Is.EqualTo(3));
|
||||||
Assert.That(tiles[0].data.verts.Length, Is.EqualTo(6 * 3));
|
Assert.That(tiles[0].data.verts.Length, Is.EqualTo(6 * 3));
|
||||||
tiles = mesh.GetTilesAt(2, 8);
|
|
||||||
Assert.That(tiles.Count, Is.EqualTo(1));
|
nneis = mesh.GetTilesAt(2, 8, tiles, MAX_NEIS);
|
||||||
|
Assert.That(nneis, Is.EqualTo(1));
|
||||||
Assert.That(tiles[0].data.polys.Length, Is.EqualTo(5));
|
Assert.That(tiles[0].data.polys.Length, Is.EqualTo(5));
|
||||||
Assert.That(tiles[0].data.verts.Length, Is.EqualTo(17 * 3));
|
Assert.That(tiles[0].data.verts.Length, Is.EqualTo(17 * 3));
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,6 @@ using NUnit.Framework;
|
||||||
|
|
||||||
namespace DotRecast.Detour.TileCache.Test;
|
namespace DotRecast.Detour.TileCache.Test;
|
||||||
|
|
||||||
|
|
||||||
public class TempObstaclesTest : AbstractTileCacheTest
|
public class TempObstaclesTest : AbstractTileCacheTest
|
||||||
{
|
{
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -43,21 +42,29 @@ public class TempObstaclesTest : AbstractTileCacheTest
|
||||||
tc.BuildNavMeshTile(refs);
|
tc.BuildNavMeshTile(refs);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<DtMeshTile> tiles = tc.GetNavMesh().GetTilesAt(1, 4);
|
const int MAX_NEIS = 32;
|
||||||
|
DtMeshTile[] tiles = new DtMeshTile[MAX_NEIS];
|
||||||
|
int nneis = 0;
|
||||||
|
|
||||||
|
nneis = tc.GetNavMesh().GetTilesAt(1, 4, tiles, MAX_NEIS);
|
||||||
DtMeshTile tile = tiles[0];
|
DtMeshTile tile = tiles[0];
|
||||||
Assert.That(tile.data.header.vertCount, Is.EqualTo(16));
|
Assert.That(tile.data.header.vertCount, Is.EqualTo(16));
|
||||||
Assert.That(tile.data.header.polyCount, Is.EqualTo(6));
|
Assert.That(tile.data.header.polyCount, Is.EqualTo(6));
|
||||||
|
|
||||||
long o = tc.AddObstacle(new RcVec3f(-1.815208f, 9.998184f, -20.307983f), 1f, 2f);
|
long o = tc.AddObstacle(new RcVec3f(-1.815208f, 9.998184f, -20.307983f), 1f, 2f);
|
||||||
bool upToDate = tc.Update();
|
bool upToDate = tc.Update();
|
||||||
Assert.That(upToDate, Is.True);
|
Assert.That(upToDate, Is.True);
|
||||||
tiles = tc.GetNavMesh().GetTilesAt(1, 4);
|
|
||||||
|
nneis = tc.GetNavMesh().GetTilesAt(1, 4, tiles, MAX_NEIS);
|
||||||
tile = tiles[0];
|
tile = tiles[0];
|
||||||
Assert.That(tile.data.header.vertCount, Is.EqualTo(22));
|
Assert.That(tile.data.header.vertCount, Is.EqualTo(22));
|
||||||
Assert.That(tile.data.header.polyCount, Is.EqualTo(11));
|
Assert.That(tile.data.header.polyCount, Is.EqualTo(11));
|
||||||
|
|
||||||
tc.RemoveObstacle(o);
|
tc.RemoveObstacle(o);
|
||||||
upToDate = tc.Update();
|
upToDate = tc.Update();
|
||||||
Assert.That(upToDate, Is.True);
|
Assert.That(upToDate, Is.True);
|
||||||
tiles = tc.GetNavMesh().GetTilesAt(1, 4);
|
|
||||||
|
nneis = tc.GetNavMesh().GetTilesAt(1, 4, tiles, MAX_NEIS);
|
||||||
tile = tiles[0];
|
tile = tiles[0];
|
||||||
Assert.That(tile.data.header.vertCount, Is.EqualTo(16));
|
Assert.That(tile.data.header.vertCount, Is.EqualTo(16));
|
||||||
Assert.That(tile.data.header.polyCount, Is.EqualTo(6));
|
Assert.That(tile.data.header.polyCount, Is.EqualTo(6));
|
||||||
|
@ -77,24 +84,32 @@ public class TempObstaclesTest : AbstractTileCacheTest
|
||||||
tc.BuildNavMeshTile(refs);
|
tc.BuildNavMeshTile(refs);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<DtMeshTile> tiles = tc.GetNavMesh().GetTilesAt(1, 4);
|
const int MAX_NEIS = 32;
|
||||||
|
DtMeshTile[] tiles = new DtMeshTile[MAX_NEIS];
|
||||||
|
int nneis = 0;
|
||||||
|
|
||||||
|
nneis = tc.GetNavMesh().GetTilesAt(1, 4, tiles, MAX_NEIS);
|
||||||
DtMeshTile tile = tiles[0];
|
DtMeshTile tile = tiles[0];
|
||||||
Assert.That(tile.data.header.vertCount, Is.EqualTo(16));
|
Assert.That(tile.data.header.vertCount, Is.EqualTo(16));
|
||||||
Assert.That(tile.data.header.polyCount, Is.EqualTo(6));
|
Assert.That(tile.data.header.polyCount, Is.EqualTo(6));
|
||||||
|
|
||||||
long o = tc.AddBoxObstacle(
|
long o = tc.AddBoxObstacle(
|
||||||
new RcVec3f(-2.315208f, 9.998184f, -20.807983f),
|
new RcVec3f(-2.315208f, 9.998184f, -20.807983f),
|
||||||
new RcVec3f(-1.315208f, 11.998184f, -19.807983f)
|
new RcVec3f(-1.315208f, 11.998184f, -19.807983f)
|
||||||
);
|
);
|
||||||
bool upToDate = tc.Update();
|
bool upToDate = tc.Update();
|
||||||
Assert.That(upToDate, Is.True);
|
Assert.That(upToDate, Is.True);
|
||||||
tiles = tc.GetNavMesh().GetTilesAt(1, 4);
|
|
||||||
|
nneis = tc.GetNavMesh().GetTilesAt(1, 4, tiles, MAX_NEIS);
|
||||||
tile = tiles[0];
|
tile = tiles[0];
|
||||||
Assert.That(tile.data.header.vertCount, Is.EqualTo(22));
|
Assert.That(tile.data.header.vertCount, Is.EqualTo(22));
|
||||||
Assert.That(tile.data.header.polyCount, Is.EqualTo(11));
|
Assert.That(tile.data.header.polyCount, Is.EqualTo(11));
|
||||||
|
|
||||||
tc.RemoveObstacle(o);
|
tc.RemoveObstacle(o);
|
||||||
upToDate = tc.Update();
|
upToDate = tc.Update();
|
||||||
Assert.That(upToDate, Is.True);
|
Assert.That(upToDate, Is.True);
|
||||||
tiles = tc.GetNavMesh().GetTilesAt(1, 4);
|
|
||||||
|
nneis = tc.GetNavMesh().GetTilesAt(1, 4, tiles, MAX_NEIS);
|
||||||
tile = tiles[0];
|
tile = tiles[0];
|
||||||
Assert.That(tile.data.header.vertCount, Is.EqualTo(16));
|
Assert.That(tile.data.header.vertCount, Is.EqualTo(16));
|
||||||
Assert.That(tile.data.header.polyCount, Is.EqualTo(6));
|
Assert.That(tile.data.header.polyCount, Is.EqualTo(6));
|
||||||
|
|
Loading…
Reference in New Issue