diff --git a/src/DotRecast.Detour.TileCache/DtTempContour.cs b/src/DotRecast.Detour.TileCache/DtTempContour.cs index 208c8e48..b08daebe 100644 --- a/src/DotRecast.Detour.TileCache/DtTempContour.cs +++ b/src/DotRecast.Detour.TileCache/DtTempContour.cs @@ -14,16 +14,5 @@ public DtTempContour() nverts = 0; poly = new List(); } - - public int Npoly() - { - return poly.Count; - } - - public void Clear() - { - nverts = 0; - verts.Clear(); - } - }; + } } \ No newline at end of file diff --git a/src/DotRecast.Detour.TileCache/DtTileCache.cs b/src/DotRecast.Detour.TileCache/DtTileCache.cs index 02a6f910..ae0c5131 100644 --- a/src/DotRecast.Detour.TileCache/DtTileCache.cs +++ b/src/DotRecast.Detour.TileCache/DtTileCache.cs @@ -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; @@ -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; @@ -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. diff --git a/src/DotRecast.Detour.TileCache/DtTileCacheAlloc.cs b/src/DotRecast.Detour.TileCache/DtTileCacheAlloc.cs new file mode 100644 index 00000000..4d30a767 --- /dev/null +++ b/src/DotRecast.Detour.TileCache/DtTileCacheAlloc.cs @@ -0,0 +1,21 @@ +namespace DotRecast.Detour.TileCache +{ + // TODO: @ikpil, better pooling system + public class DtTileCacheAlloc + { + public virtual T[] Alloc(long size) + { + return new T[size]; + } + + public virtual void Free(T ptr) + { + // .. + } + + public virtual void Reset() + { + // .. + } + } +} \ No newline at end of file diff --git a/src/DotRecast.Detour.TileCache/DtTileCacheBuilder.cs b/src/DotRecast.Detour.TileCache/DtTileCacheBuilder.cs index 2247ef38..0cb9333c 100644 --- a/src/DotRecast.Detour.TileCache/DtTileCacheBuilder.cs +++ b/src/DotRecast.Detour.TileCache/DtTileCacheBuilder.cs @@ -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 }; @@ -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++; @@ -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; @@ -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. @@ -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]; @@ -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]; @@ -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; @@ -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 tempVerts(alloc, maxTempVerts*4); + // if (!tempVerts) + // return DT_FAILURE | DT_OUT_OF_MEMORY; + // + // dtFixedArray tempPoly(alloc, maxTempVerts); + // if (!tempPoly) + // return DT_FAILURE | DT_OUT_OF_MEMORY; + DtTempContour temp = new DtTempContour(); // Find contours. @@ -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) { @@ -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)