Skip to content

Commit

Permalink
Prepare tile cache allocator
Browse files Browse the repository at this point in the history
  • Loading branch information
ikpil committed Feb 1, 2025
1 parent 5bc5cb3 commit 7aaa382
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 26 deletions.
13 changes: 1 addition & 12 deletions src/DotRecast.Detour.TileCache/DtTempContour.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,5 @@ public DtTempContour()
nverts = 0;
poly = new List<int>();
}

public int Npoly()
{
return poly.Count;
}

public void Clear()
{
nverts = 0;
verts.Clear();
}
};
}
}
4 changes: 3 additions & 1 deletion src/DotRecast.Detour.TileCache/DtTileCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public class DtTileCache
private readonly DtTileCacheParams m_params;
private readonly DtTileCacheStorageParams m_storageParams;

private readonly DtTileCacheAlloc m_talloc;
private readonly IRcCompressor m_tcomp;
private readonly IDtTileCacheMeshProcess m_tmproc;

Expand All @@ -58,6 +59,7 @@ public DtTileCache(DtTileCacheParams option, DtTileCacheStorageParams storagePar
m_params = option;
m_storageParams = storageParams;
m_navmesh = navmesh;
m_talloc = new DtTileCacheAlloc(); // TODO: ikpil, improve pooling system
m_tcomp = tcomp;
m_tmproc = tmprocs;

Expand Down Expand Up @@ -636,7 +638,7 @@ public void BuildNavMeshTile(long refs)

// Build navmesh
DtTileCacheBuilder.BuildTileCacheRegions(layer, walkableClimbVx);
DtTileCacheContourSet lcset = DtTileCacheBuilder.BuildTileCacheContours(layer, walkableClimbVx, m_params.maxSimplificationError);
DtTileCacheContourSet lcset = DtTileCacheBuilder.BuildTileCacheContours(m_talloc, layer, walkableClimbVx, m_params.maxSimplificationError);
DtTileCachePolyMesh polyMesh = DtTileCacheBuilder.BuildTileCachePolyMesh(lcset, m_navmesh.GetMaxVertsPerPoly());

// Early out if the mesh tile is empty.
Expand Down
21 changes: 21 additions & 0 deletions src/DotRecast.Detour.TileCache/DtTileCacheAlloc.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
namespace DotRecast.Detour.TileCache
{
// TODO: @ikpil, better pooling system
public class DtTileCacheAlloc
{
public virtual T[] Alloc<T>(long size)
{
return new T[size];
}

public virtual void Free<T>(T ptr)
{
// ..
}

public virtual void Reset()
{
// ..
}
}
}
37 changes: 24 additions & 13 deletions src/DotRecast.Detour.TileCache/DtTileCacheBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public static class DtTileCacheBuilder
public const byte DT_TILECACHE_NULL_AREA = 0;
public const byte DT_TILECACHE_WALKABLE_AREA = 63;
public const int DT_TILECACHE_NULL_IDX = 0xffff;
public const uint VERTEX_BUCKET_COUNT2 = (1 << 8);

private static readonly int[] DirOffsetX = { -1, 0, 1, 0, };
private static readonly int[] DirOffsetY = { 0, 1, 0, -1 };
Expand Down Expand Up @@ -275,7 +276,7 @@ public static bool CanMerge(int oldRegId, int newRegId, DtLayerMonotoneRegion[]
continue;

int nnei = reg.nneis;
for (int j = 0; j < nnei ; ++j)
for (int j = 0; j < nnei; ++j)
{
if (regs[reg.neis[j]].regId == newRegId)
count++;
Expand Down Expand Up @@ -357,7 +358,8 @@ public static void WalkContour(DtTileCacheLayer layer, int x, int y, DtTempConto
int w = layer.header.width;
int h = layer.header.height;

cont.Clear();
cont.nverts = 0;
cont.verts.Clear();

int startX = x;
int startY = y;
Expand Down Expand Up @@ -472,7 +474,7 @@ public static void SimplifyContour(DtTempContour cont, float maxError)
cont.poly.Add(i);
}

if (cont.Npoly() < 2)
if (cont.poly.Count < 2)
{
// If there is no transitions at all,
// create some initial points for the simplification process.
Expand Down Expand Up @@ -509,9 +511,9 @@ public static void SimplifyContour(DtTempContour cont, float maxError)

// Add points until all raw points are within
// error tolerance to the simplified shape.
for (int i = 0; i < cont.Npoly();)
for (int i = 0; i < cont.poly.Count;)
{
int ii = (i + 1) % cont.Npoly();
int ii = (i + 1) % cont.poly.Count;

int ai = cont.poly[i];
int ax = cont.verts[ai * 4];
Expand Down Expand Up @@ -569,14 +571,14 @@ public static void SimplifyContour(DtTempContour cont, float maxError)

// Remap vertices
int start = 0;
for (int i = 1; i < cont.Npoly(); ++i)
for (int i = 1; i < cont.poly.Count; ++i)
if (cont.poly[i] < cont.poly[start])
start = i;

cont.nverts = 0;
for (int i = 0; i < cont.Npoly(); ++i)
for (int i = 0; i < cont.poly.Count; ++i)
{
int j = (start + i) % cont.Npoly();
int j = (start + i) % cont.poly.Count;
int src = cont.poly[j] * 4;
int dst = cont.nverts * 4;
cont.verts[dst] = cont.verts[src];
Expand Down Expand Up @@ -637,7 +639,7 @@ public static int GetCornerHeight(DtTileCacheLayer layer, int x, int y, int z, i
}

// TODO: move this somewhere else, once the layer meshing is done.
public static DtTileCacheContourSet BuildTileCacheContours(DtTileCacheLayer layer, int walkableClimb, float maxError)
public static DtTileCacheContourSet BuildTileCacheContours(DtTileCacheAlloc alloc, DtTileCacheLayer layer, int walkableClimb, float maxError)
{
int w = layer.header.width;
int h = layer.header.height;
Expand All @@ -651,6 +653,16 @@ public static DtTileCacheContourSet BuildTileCacheContours(DtTileCacheLayer laye
}

// Allocate temp buffer for contour tracing.
// TODO: @ikpil, improve pooling system
// int maxTempVerts = (w + h) * 2 * 2; // Twice around the layer.
// dtFixedArray<unsigned char> tempVerts(alloc, maxTempVerts*4);
// if (!tempVerts)
// return DT_FAILURE | DT_OUT_OF_MEMORY;
//
// dtFixedArray<unsigned short> tempPoly(alloc, maxTempVerts);
// if (!tempPoly)
// return DT_FAILURE | DT_OUT_OF_MEMORY;

DtTempContour temp = new DtTempContour();

// Find contours.
Expand Down Expand Up @@ -712,7 +724,6 @@ public static DtTileCacheContourSet BuildTileCacheContours(DtTileCacheLayer laye
return lcset;
}

const uint VERTEX_BUCKET_COUNT2 = (1 << 8);

public static int ComputeVertexHash2(int x, int y, int z)
{
Expand Down Expand Up @@ -1615,13 +1626,13 @@ public static void RemoveVertex(DtTileCachePolyMesh mesh, int rem, int maxTris)
{
if (mesh.npolys >= maxTris)
break;

int p = mesh.npolys * maxVertsPerPoly * 2;
Array.Fill(mesh.polys, DT_TILECACHE_NULL_IDX, p, maxVertsPerPoly * 2);

for (int j = 0; j < maxVertsPerPoly; ++j)
mesh.polys[p + j] = polys[i * maxVertsPerPoly + j];

mesh.areas[mesh.npolys] = pareas[i];
mesh.npolys++;
if (mesh.npolys > maxTris)
Expand Down

0 comments on commit 7aaa382

Please sign in to comment.