forked from bit/DotRecastNetSim
167 lines
6.4 KiB
C#
167 lines
6.4 KiB
C#
using DotRecast.Core;
|
|
using DotRecast.Detour;
|
|
using DotRecast.Detour.TileCache;
|
|
using DotRecast.Detour.TileCache.Io.Compress;
|
|
using DotRecast.Recast.Geom;
|
|
using DotRecast.Recast.Toolset.Geom;
|
|
|
|
namespace DotRecast.Recast.Toolset.Tools
|
|
{
|
|
public class RcObstacleTool : IRcToolable
|
|
{
|
|
private readonly IDtTileCacheCompressorFactory _comp;
|
|
private readonly DemoDtTileCacheMeshProcess _proc;
|
|
private DtTileCache _tc;
|
|
|
|
public RcObstacleTool(IDtTileCacheCompressorFactory comp)
|
|
{
|
|
_comp = comp;
|
|
_proc = new DemoDtTileCacheMeshProcess();
|
|
}
|
|
|
|
public string GetName()
|
|
{
|
|
return "Create Temp Obstacles";
|
|
}
|
|
|
|
public bool Build(IInputGeomProvider geom, RcNavMeshBuildSettings setting, RcByteOrder order, bool cCompatibility)
|
|
{
|
|
DtStatus status;
|
|
|
|
if (null == geom || null == geom.GetMesh())
|
|
{
|
|
//m_ctx->log(RC_LOG_ERROR, "buildTiledNavigation: No vertices and triangles.");
|
|
return false;
|
|
}
|
|
|
|
_proc.Init(geom);
|
|
|
|
// Init cache
|
|
var bmin = geom.GetMeshBoundsMin();
|
|
var bmax = geom.GetMeshBoundsMax();
|
|
RcUtils.CalcGridSize(bmin, bmax, setting.cellSize, out var gw, out var gh);
|
|
int ts = setting.tileSize;
|
|
int tw = (gw + ts-1) / ts;
|
|
int th = (gh + ts-1) / ts;
|
|
|
|
// Generation params.
|
|
// RcConfig cfg = new RcConfig();
|
|
// cfg.cs = m_cellSize;
|
|
// cfg.ch = m_cellHeight;
|
|
// cfg.walkableSlopeAngle = m_agentMaxSlope;
|
|
// cfg.walkableHeight = (int)ceilf(m_agentHeight / cfg.ch);
|
|
// cfg.walkableClimb = (int)floorf(m_agentMaxClimb / cfg.ch);
|
|
// cfg.walkableRadius = (int)ceilf(m_agentRadius / cfg.cs);
|
|
// cfg.maxEdgeLen = (int)(m_edgeMaxLen / m_cellSize);
|
|
// cfg.maxSimplificationError = m_edgeMaxError;
|
|
// cfg.minRegionArea = (int)rcSqr(m_regionMinSize); // Note: area = size*size
|
|
// cfg.mergeRegionArea = (int)rcSqr(m_regionMergeSize); // Note: area = size*size
|
|
// cfg.maxVertsPerPoly = (int)m_vertsPerPoly;
|
|
// cfg.tileSize = (int)m_tileSize;
|
|
// cfg.borderSize = cfg.walkableRadius + 3; // Reserve enough padding.
|
|
// cfg.width = cfg.tileSize + cfg.borderSize*2;
|
|
// cfg.height = cfg.tileSize + cfg.borderSize*2;
|
|
// cfg.detailSampleDist = m_detailSampleDist < 0.9f ? 0 : m_cellSize * m_detailSampleDist;
|
|
// cfg.detailSampleMaxError = m_cellHeight * m_detailSampleMaxError;
|
|
// rcVcopy(cfg.bmin, bmin);
|
|
// rcVcopy(cfg.bmax, bmax);
|
|
|
|
_tc = CreateTileCache(geom, setting, tw, th, order, cCompatibility);
|
|
|
|
for (int y = 0; y < th; ++y)
|
|
{
|
|
for (int x = 0; x < tw; ++x)
|
|
{
|
|
// TileCacheData tiles[MAX_LAYERS];
|
|
// memset(tiles, 0, sizeof(tiles));
|
|
// int ntiles = rasterizeTileLayers(x, y, cfg, tiles, MAX_LAYERS);
|
|
//
|
|
// for (int i = 0; i < ntiles; ++i)
|
|
// {
|
|
// TileCacheData* tile = &tiles[i];
|
|
// status = m_tileCache->addTile(tile->data, tile->dataSize, DT_COMPRESSEDTILE_FREE_DATA, 0);
|
|
// if (dtStatusFailed(status))
|
|
// {
|
|
// dtFree(tile->data);
|
|
// tile->data = 0;
|
|
// continue;
|
|
// }
|
|
//
|
|
// m_cacheLayerCount++;
|
|
// m_cacheCompressedSize += tile->dataSize;
|
|
// m_cacheRawSize += calcLayerBufferSize(tcparams.width, tcparams.height);
|
|
// }
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public void ClearAllTempObstacles()
|
|
{
|
|
if (null == _tc)
|
|
return;
|
|
|
|
for (int i = 0; i < _tc.GetObstacleCount(); ++i)
|
|
{
|
|
DtTileCacheObstacle ob = _tc.GetObstacle(i);
|
|
if (ob.state == DtObstacleState.DT_OBSTACLE_EMPTY)
|
|
continue;
|
|
|
|
_tc.RemoveObstacle(_tc.GetObstacleRef(ob));
|
|
}
|
|
}
|
|
|
|
public void RemoveTempObstacle(RcVec3f sp, RcVec3f sq)
|
|
{
|
|
if (null == _tc)
|
|
return;
|
|
|
|
//DtObstacleRef refs = hitTestObstacle(m_tileCache, sp, sq);
|
|
//_tc.RemoveObstacle(refs);
|
|
}
|
|
|
|
public long AddTempObstacle(RcVec3f p)
|
|
{
|
|
if (null == _tc)
|
|
return 0;
|
|
|
|
p.y -= 0.5f;
|
|
return _tc.AddObstacle(p, 1.0f, 2.0f);
|
|
}
|
|
|
|
public DtTileCache GetTileCache()
|
|
{
|
|
return _tc;
|
|
}
|
|
|
|
public DtTileCache CreateTileCache(IInputGeomProvider geom, RcNavMeshBuildSettings setting, int tw, int th, RcByteOrder order, bool cCompatibility)
|
|
{
|
|
DtTileCacheParams option = new DtTileCacheParams();
|
|
option.ch = setting.cellHeight;
|
|
option.cs = setting.cellSize;
|
|
option.orig = geom.GetMeshBoundsMin();
|
|
option.height = setting.tileSize;
|
|
option.width = setting.tileSize;
|
|
option.walkableHeight = setting.agentHeight;
|
|
option.walkableRadius = setting.agentRadius;
|
|
option.walkableClimb = setting.agentMaxClimb;
|
|
option.maxSimplificationError = setting.edgeMaxError;
|
|
option.maxTiles = tw * th * 4; // for test EXPECTED_LAYERS_PER_TILE;
|
|
option.maxObstacles = 128;
|
|
|
|
DtNavMeshParams navMeshParams = new DtNavMeshParams();
|
|
navMeshParams.orig = geom.GetMeshBoundsMin();
|
|
navMeshParams.tileWidth = setting.tileSize * setting.cellSize;
|
|
navMeshParams.tileHeight = setting.tileSize * setting.cellSize;
|
|
navMeshParams.maxTiles = 256; // ..
|
|
navMeshParams.maxPolys = 16384;
|
|
|
|
var navMesh = new DtNavMesh(navMeshParams, 6);
|
|
var comp = _comp.Create(cCompatibility ? 0 : 1);
|
|
var storageParams = new DtTileCacheStorageParams(order, cCompatibility);
|
|
DtTileCache tc = new DtTileCache(option, storageParams, navMesh, comp, _proc);
|
|
return tc;
|
|
}
|
|
}
|
|
} |