draw temp obstacles

This commit is contained in:
ikpil 2023-08-22 23:48:04 +09:00
parent 1c2d211075
commit 1cb03e2c5f
5 changed files with 110 additions and 65 deletions

View File

@ -20,7 +20,7 @@ freely, subject to the following restrictions:
namespace DotRecast.Detour.TileCache
{
public enum ObstacleState
public enum DtObstacleState
{
DT_OBSTACLE_EMPTY,
DT_OBSTACLE_PROCESSING,

View File

@ -27,27 +27,15 @@ namespace DotRecast.Detour.TileCache
{
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 int m_tileLutMask;
private DtCompressedTile m_nextFreeTile; // < Freelist of tiles.
private readonly DtCompressedTile[] m_tiles; // < List of tiles. // TODO: (PP) replace with list
/// < Tile hash lookup mask.
private readonly DtCompressedTile[] m_posLookup;
/// < 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 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 DtTileCacheParams m_params;
@ -65,6 +53,38 @@ namespace DotRecast.Detour.TileCache
private readonly DtTileCacheBuilder builder = new DtTileCacheBuilder();
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)
{
return a.Contains(v);
@ -110,37 +130,6 @@ namespace DotRecast.Detour.TileCache
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)
{
@ -429,13 +418,28 @@ namespace DotRecast.Detour.TileCache
m_nextFreeObstacle = o.next;
}
o.state = ObstacleState.DT_OBSTACLE_PROCESSING;
o.state = DtObstacleState.DT_OBSTACLE_PROCESSING;
o.touched.Clear();
o.pending.Clear();
o.next = null;
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)
{
List<long> results = new List<long>();
@ -516,7 +520,7 @@ namespace DotRecast.Detour.TileCache
else if (req.action == ObstacleRequestAction.REQUEST_REMOVE)
{
// Prepare to remove obstacle.
ob.state = ObstacleState.DT_OBSTACLE_REMOVING;
ob.state = DtObstacleState.DT_OBSTACLE_REMOVING;
// Add tiles to update list.
ob.pending.Clear();
foreach (long j in ob.touched)
@ -546,8 +550,8 @@ namespace DotRecast.Detour.TileCache
for (int i = 0; i < m_obstacles.Count; ++i)
{
DtTileCacheObstacle ob = m_obstacles[i];
if (ob.state == ObstacleState.DT_OBSTACLE_PROCESSING
|| ob.state == ObstacleState.DT_OBSTACLE_REMOVING)
if (ob.state == DtObstacleState.DT_OBSTACLE_PROCESSING
|| ob.state == DtObstacleState.DT_OBSTACLE_REMOVING)
{
// Remove handled tile from pending list.
ob.pending.Remove(refs);
@ -555,13 +559,13 @@ namespace DotRecast.Detour.TileCache
// If all pending tiles processed, change state.
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.
ob.salt = (ob.salt + 1) & ((1 << 16) - 1);
if (ob.salt == 0)
@ -605,7 +609,7 @@ namespace DotRecast.Detour.TileCache
for (int i = 0; i < m_obstacles.Count; ++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;
}
@ -690,7 +694,7 @@ namespace DotRecast.Detour.TileCache
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)
{

View File

@ -37,7 +37,7 @@ namespace DotRecast.Detour.TileCache
public List<long> touched = new List<long>();
public readonly List<long> pending = new List<long>();
public int salt;
public ObstacleState state = ObstacleState.DT_OBSTACLE_EMPTY;
public DtObstacleState state = DtObstacleState.DT_OBSTACLE_EMPTY;
public DtTileCacheObstacle next;
public DtTileCacheObstacle(int index)

View File

@ -1,4 +1,5 @@
using DotRecast.Core;
using DotRecast.Detour.TileCache;
using DotRecast.Detour.TileCache.Io.Compress;
using DotRecast.Recast.Demo.Draw;
using DotRecast.Recast.Toolset;
@ -75,10 +76,45 @@ public class ObstacleSampleTool : ISampleTool
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)
{
var tc = _tool.GetTileCache();
if (null != tc)
tc.Update();
}
public void HandleClickRay(RcVec3f start, RcVec3f direction, bool shift)

View File

@ -44,13 +44,18 @@ namespace DotRecast.Recast.Toolset.Tools
//_tc.RemoveObstacle(refs);
}
public void AddTempObstacle(RcVec3f p)
public long AddTempObstacle(RcVec3f p)
{
if (null == _tc)
return;
return 0;
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)