forked from mirror/DotRecast
draw temp obstacles
This commit is contained in:
parent
1c2d211075
commit
1cb03e2c5f
|
@ -20,7 +20,7 @@ freely, subject to the following restrictions:
|
||||||
|
|
||||||
namespace DotRecast.Detour.TileCache
|
namespace DotRecast.Detour.TileCache
|
||||||
{
|
{
|
||||||
public enum ObstacleState
|
public enum DtObstacleState
|
||||||
{
|
{
|
||||||
DT_OBSTACLE_EMPTY,
|
DT_OBSTACLE_EMPTY,
|
||||||
DT_OBSTACLE_PROCESSING,
|
DT_OBSTACLE_PROCESSING,
|
|
@ -27,27 +27,15 @@ namespace DotRecast.Detour.TileCache
|
||||||
{
|
{
|
||||||
public class DtTileCache
|
public class DtTileCache
|
||||||
{
|
{
|
||||||
private int m_tileLutSize;
|
private int m_tileLutSize; // < Tile hash lookup size (must be pot).
|
||||||
|
private int m_tileLutMask; // < Tile hash lookup mask.
|
||||||
|
private readonly DtCompressedTile[] m_posLookup; // < Tile hash lookup.
|
||||||
|
|
||||||
/// < Tile hash lookup size (must be pot).
|
private DtCompressedTile m_nextFreeTile; // < Freelist of tiles.
|
||||||
private int m_tileLutMask;
|
private readonly DtCompressedTile[] m_tiles; // < List of tiles. // TODO: (PP) replace with list
|
||||||
|
|
||||||
/// < Tile hash lookup mask.
|
private readonly int m_saltBits; // < Number of salt bits in the tile ID.
|
||||||
private readonly DtCompressedTile[] m_posLookup;
|
private readonly int m_tileBits; // < Number of tile bits in the tile ID.
|
||||||
|
|
||||||
/// < Tile hash lookup.
|
|
||||||
private DtCompressedTile m_nextFreeTile;
|
|
||||||
|
|
||||||
/// < Freelist of tiles.
|
|
||||||
private readonly DtCompressedTile[] m_tiles;
|
|
||||||
|
|
||||||
/// < List of tiles. // TODO: (PP) replace with list
|
|
||||||
private readonly int m_saltBits;
|
|
||||||
|
|
||||||
/// < Number of salt bits in the tile ID.
|
|
||||||
private readonly int m_tileBits;
|
|
||||||
|
|
||||||
/// < Number of tile bits in the tile ID.
|
|
||||||
private readonly DtNavMesh m_navmesh;
|
private readonly DtNavMesh m_navmesh;
|
||||||
|
|
||||||
private readonly DtTileCacheParams m_params;
|
private readonly DtTileCacheParams m_params;
|
||||||
|
@ -65,6 +53,38 @@ namespace DotRecast.Detour.TileCache
|
||||||
private readonly DtTileCacheBuilder builder = new DtTileCacheBuilder();
|
private readonly DtTileCacheBuilder builder = new DtTileCacheBuilder();
|
||||||
private readonly DtTileCacheLayerHeaderReader tileReader = new DtTileCacheLayerHeaderReader();
|
private readonly DtTileCacheLayerHeaderReader tileReader = new DtTileCacheLayerHeaderReader();
|
||||||
|
|
||||||
|
public DtTileCache(DtTileCacheParams option, DtTileCacheStorageParams storageParams, DtNavMesh navmesh, IRcCompressor tcomp, IDtTileCacheMeshProcess tmprocs)
|
||||||
|
{
|
||||||
|
m_params = option;
|
||||||
|
m_storageParams = storageParams;
|
||||||
|
m_navmesh = navmesh;
|
||||||
|
m_tcomp = tcomp;
|
||||||
|
m_tmproc = tmprocs;
|
||||||
|
|
||||||
|
m_tileLutSize = DtUtils.NextPow2(m_params.maxTiles / 4);
|
||||||
|
if (m_tileLutSize == 0)
|
||||||
|
{
|
||||||
|
m_tileLutSize = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_tileLutMask = m_tileLutSize - 1;
|
||||||
|
m_tiles = new DtCompressedTile[m_params.maxTiles];
|
||||||
|
m_posLookup = new DtCompressedTile[m_tileLutSize];
|
||||||
|
for (int i = m_params.maxTiles - 1; i >= 0; --i)
|
||||||
|
{
|
||||||
|
m_tiles[i] = new DtCompressedTile(i);
|
||||||
|
m_tiles[i].next = m_nextFreeTile;
|
||||||
|
m_nextFreeTile = m_tiles[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
m_tileBits = DtUtils.Ilog2(DtUtils.NextPow2(m_params.maxTiles));
|
||||||
|
m_saltBits = Math.Min(31, 32 - m_tileBits);
|
||||||
|
if (m_saltBits < 10)
|
||||||
|
{
|
||||||
|
throw new Exception("Too few salt bits: " + m_saltBits);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private bool Contains(List<long> a, long v)
|
private bool Contains(List<long> a, long v)
|
||||||
{
|
{
|
||||||
return a.Contains(v);
|
return a.Contains(v);
|
||||||
|
@ -110,37 +130,6 @@ namespace DotRecast.Detour.TileCache
|
||||||
return (int)(refs & tileMask);
|
return (int)(refs & tileMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
public DtTileCache(DtTileCacheParams option, DtTileCacheStorageParams storageParams, DtNavMesh navmesh, IRcCompressor tcomp, IDtTileCacheMeshProcess tmprocs)
|
|
||||||
{
|
|
||||||
m_params = option;
|
|
||||||
m_storageParams = storageParams;
|
|
||||||
m_navmesh = navmesh;
|
|
||||||
m_tcomp = tcomp;
|
|
||||||
m_tmproc = tmprocs;
|
|
||||||
|
|
||||||
m_tileLutSize = DtUtils.NextPow2(m_params.maxTiles / 4);
|
|
||||||
if (m_tileLutSize == 0)
|
|
||||||
{
|
|
||||||
m_tileLutSize = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_tileLutMask = m_tileLutSize - 1;
|
|
||||||
m_tiles = new DtCompressedTile[m_params.maxTiles];
|
|
||||||
m_posLookup = new DtCompressedTile[m_tileLutSize];
|
|
||||||
for (int i = m_params.maxTiles - 1; i >= 0; --i)
|
|
||||||
{
|
|
||||||
m_tiles[i] = new DtCompressedTile(i);
|
|
||||||
m_tiles[i].next = m_nextFreeTile;
|
|
||||||
m_nextFreeTile = m_tiles[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
m_tileBits = DtUtils.Ilog2(DtUtils.NextPow2(m_params.maxTiles));
|
|
||||||
m_saltBits = Math.Min(31, 32 - m_tileBits);
|
|
||||||
if (m_saltBits < 10)
|
|
||||||
{
|
|
||||||
throw new Exception("Too few salt bits: " + m_saltBits);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public DtCompressedTile GetTileByRef(long refs)
|
public DtCompressedTile GetTileByRef(long refs)
|
||||||
{
|
{
|
||||||
|
@ -429,13 +418,28 @@ namespace DotRecast.Detour.TileCache
|
||||||
m_nextFreeObstacle = o.next;
|
m_nextFreeObstacle = o.next;
|
||||||
}
|
}
|
||||||
|
|
||||||
o.state = ObstacleState.DT_OBSTACLE_PROCESSING;
|
o.state = DtObstacleState.DT_OBSTACLE_PROCESSING;
|
||||||
o.touched.Clear();
|
o.touched.Clear();
|
||||||
o.pending.Clear();
|
o.pending.Clear();
|
||||||
o.next = null;
|
o.next = null;
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int GetObstacleCount()
|
||||||
|
{
|
||||||
|
return m_obstacles.Count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DtTileCacheObstacle GetObstacle(int i)
|
||||||
|
{
|
||||||
|
if (0 > i || i >= m_obstacles.Count)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_obstacles[i];
|
||||||
|
}
|
||||||
|
|
||||||
private List<long> QueryTiles(RcVec3f bmin, RcVec3f bmax)
|
private List<long> QueryTiles(RcVec3f bmin, RcVec3f bmax)
|
||||||
{
|
{
|
||||||
List<long> results = new List<long>();
|
List<long> results = new List<long>();
|
||||||
|
@ -516,7 +520,7 @@ namespace DotRecast.Detour.TileCache
|
||||||
else if (req.action == ObstacleRequestAction.REQUEST_REMOVE)
|
else if (req.action == ObstacleRequestAction.REQUEST_REMOVE)
|
||||||
{
|
{
|
||||||
// Prepare to remove obstacle.
|
// Prepare to remove obstacle.
|
||||||
ob.state = ObstacleState.DT_OBSTACLE_REMOVING;
|
ob.state = DtObstacleState.DT_OBSTACLE_REMOVING;
|
||||||
// Add tiles to update list.
|
// Add tiles to update list.
|
||||||
ob.pending.Clear();
|
ob.pending.Clear();
|
||||||
foreach (long j in ob.touched)
|
foreach (long j in ob.touched)
|
||||||
|
@ -546,8 +550,8 @@ namespace DotRecast.Detour.TileCache
|
||||||
for (int i = 0; i < m_obstacles.Count; ++i)
|
for (int i = 0; i < m_obstacles.Count; ++i)
|
||||||
{
|
{
|
||||||
DtTileCacheObstacle ob = m_obstacles[i];
|
DtTileCacheObstacle ob = m_obstacles[i];
|
||||||
if (ob.state == ObstacleState.DT_OBSTACLE_PROCESSING
|
if (ob.state == DtObstacleState.DT_OBSTACLE_PROCESSING
|
||||||
|| ob.state == ObstacleState.DT_OBSTACLE_REMOVING)
|
|| ob.state == DtObstacleState.DT_OBSTACLE_REMOVING)
|
||||||
{
|
{
|
||||||
// Remove handled tile from pending list.
|
// Remove handled tile from pending list.
|
||||||
ob.pending.Remove(refs);
|
ob.pending.Remove(refs);
|
||||||
|
@ -555,13 +559,13 @@ namespace DotRecast.Detour.TileCache
|
||||||
// If all pending tiles processed, change state.
|
// If all pending tiles processed, change state.
|
||||||
if (0 == ob.pending.Count)
|
if (0 == ob.pending.Count)
|
||||||
{
|
{
|
||||||
if (ob.state == ObstacleState.DT_OBSTACLE_PROCESSING)
|
if (ob.state == DtObstacleState.DT_OBSTACLE_PROCESSING)
|
||||||
{
|
{
|
||||||
ob.state = ObstacleState.DT_OBSTACLE_PROCESSED;
|
ob.state = DtObstacleState.DT_OBSTACLE_PROCESSED;
|
||||||
}
|
}
|
||||||
else if (ob.state == ObstacleState.DT_OBSTACLE_REMOVING)
|
else if (ob.state == DtObstacleState.DT_OBSTACLE_REMOVING)
|
||||||
{
|
{
|
||||||
ob.state = ObstacleState.DT_OBSTACLE_EMPTY;
|
ob.state = DtObstacleState.DT_OBSTACLE_EMPTY;
|
||||||
// Update salt, salt should never be zero.
|
// Update salt, salt should never be zero.
|
||||||
ob.salt = (ob.salt + 1) & ((1 << 16) - 1);
|
ob.salt = (ob.salt + 1) & ((1 << 16) - 1);
|
||||||
if (ob.salt == 0)
|
if (ob.salt == 0)
|
||||||
|
@ -605,7 +609,7 @@ namespace DotRecast.Detour.TileCache
|
||||||
for (int i = 0; i < m_obstacles.Count; ++i)
|
for (int i = 0; i < m_obstacles.Count; ++i)
|
||||||
{
|
{
|
||||||
DtTileCacheObstacle ob = m_obstacles[i];
|
DtTileCacheObstacle ob = m_obstacles[i];
|
||||||
if (ob.state == ObstacleState.DT_OBSTACLE_EMPTY || ob.state == ObstacleState.DT_OBSTACLE_REMOVING)
|
if (ob.state == DtObstacleState.DT_OBSTACLE_EMPTY || ob.state == DtObstacleState.DT_OBSTACLE_REMOVING)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -690,7 +694,7 @@ namespace DotRecast.Detour.TileCache
|
||||||
bmax.z = header.bmin.z + (header.maxy + 1) * cs;
|
bmax.z = header.bmin.z + (header.maxy + 1) * cs;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetObstacleBounds(DtTileCacheObstacle ob, ref RcVec3f bmin, ref RcVec3f bmax)
|
public void GetObstacleBounds(DtTileCacheObstacle ob, ref RcVec3f bmin, ref RcVec3f bmax)
|
||||||
{
|
{
|
||||||
if (ob.type == TileCacheObstacleType.CYLINDER)
|
if (ob.type == TileCacheObstacleType.CYLINDER)
|
||||||
{
|
{
|
||||||
|
|
|
@ -37,7 +37,7 @@ namespace DotRecast.Detour.TileCache
|
||||||
public List<long> touched = new List<long>();
|
public List<long> touched = new List<long>();
|
||||||
public readonly List<long> pending = new List<long>();
|
public readonly List<long> pending = new List<long>();
|
||||||
public int salt;
|
public int salt;
|
||||||
public ObstacleState state = ObstacleState.DT_OBSTACLE_EMPTY;
|
public DtObstacleState state = DtObstacleState.DT_OBSTACLE_EMPTY;
|
||||||
public DtTileCacheObstacle next;
|
public DtTileCacheObstacle next;
|
||||||
|
|
||||||
public DtTileCacheObstacle(int index)
|
public DtTileCacheObstacle(int index)
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using DotRecast.Core;
|
using DotRecast.Core;
|
||||||
|
using DotRecast.Detour.TileCache;
|
||||||
using DotRecast.Detour.TileCache.Io.Compress;
|
using DotRecast.Detour.TileCache.Io.Compress;
|
||||||
using DotRecast.Recast.Demo.Draw;
|
using DotRecast.Recast.Demo.Draw;
|
||||||
using DotRecast.Recast.Toolset;
|
using DotRecast.Recast.Toolset;
|
||||||
|
@ -75,10 +76,45 @@ public class ObstacleSampleTool : ISampleTool
|
||||||
|
|
||||||
public void HandleRender(NavMeshRenderer renderer)
|
public void HandleRender(NavMeshRenderer renderer)
|
||||||
{
|
{
|
||||||
|
DrawObstacles(renderer.GetDebugDraw());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void DrawObstacles(RecastDebugDraw dd)
|
||||||
|
{
|
||||||
|
var tc = _tool.GetTileCache();
|
||||||
|
if (null == tc)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Draw obstacles
|
||||||
|
for (int i = 0; i < tc.GetObstacleCount(); ++i)
|
||||||
|
{
|
||||||
|
var ob = tc.GetObstacle(i);
|
||||||
|
if (ob.state == DtObstacleState.DT_OBSTACLE_EMPTY)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
RcVec3f bmin = RcVec3f.Zero;
|
||||||
|
RcVec3f bmax = RcVec3f.Zero;
|
||||||
|
tc.GetObstacleBounds(ob, ref bmin, ref bmax);
|
||||||
|
|
||||||
|
int col = 0;
|
||||||
|
if (ob.state == DtObstacleState.DT_OBSTACLE_PROCESSING)
|
||||||
|
col = DebugDraw.DuRGBA(255, 255, 0, 128);
|
||||||
|
else if (ob.state == DtObstacleState.DT_OBSTACLE_PROCESSED)
|
||||||
|
col = DebugDraw.DuRGBA(255, 192, 0, 192);
|
||||||
|
else if (ob.state == DtObstacleState.DT_OBSTACLE_REMOVING)
|
||||||
|
col = DebugDraw.DuRGBA(220, 0, 0, 128);
|
||||||
|
|
||||||
|
dd.DebugDrawCylinder(bmin[0], bmin[1], bmin[2], bmax[0], bmax[1], bmax[2], col);
|
||||||
|
dd.DebugDrawCylinderWire(bmin[0], bmin[1], bmin[2], bmax[0], bmax[1], bmax[2], DebugDraw.DuDarkenCol(col), 2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void HandleUpdate(float dt)
|
public void HandleUpdate(float dt)
|
||||||
{
|
{
|
||||||
|
var tc = _tool.GetTileCache();
|
||||||
|
if (null != tc)
|
||||||
|
tc.Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void HandleClickRay(RcVec3f start, RcVec3f direction, bool shift)
|
public void HandleClickRay(RcVec3f start, RcVec3f direction, bool shift)
|
||||||
|
|
|
@ -44,13 +44,18 @@ namespace DotRecast.Recast.Toolset.Tools
|
||||||
//_tc.RemoveObstacle(refs);
|
//_tc.RemoveObstacle(refs);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddTempObstacle(RcVec3f p)
|
public long AddTempObstacle(RcVec3f p)
|
||||||
{
|
{
|
||||||
if (null == _tc)
|
if (null == _tc)
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
p.y -= 0.5f;
|
p.y -= 0.5f;
|
||||||
_tc.AddObstacle(p, 1.0f, 2.0f);
|
return _tc.AddObstacle(p, 1.0f, 2.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DtTileCache GetTileCache()
|
||||||
|
{
|
||||||
|
return _tc;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DtTileCache CreateTileCache(IInputGeomProvider geom, RcNavMeshBuildSettings setting, RcByteOrder order, bool cCompatibility)
|
public DtTileCache CreateTileCache(IInputGeomProvider geom, RcNavMeshBuildSettings setting, RcByteOrder order, bool cCompatibility)
|
||||||
|
|
Loading…
Reference in New Issue