Changed data structure of 'neis' from List<byte> to byte[] for optimized memory usage and improved access speed in `DtLayerMonotoneRegion`

This commit is contained in:
ikpil 2024-07-12 23:55:35 +09:00
parent 00950b1210
commit 990dbcf97f
7 changed files with 28 additions and 16 deletions

View File

@ -13,7 +13,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Nothing - Nothing
### Changed ### Changed
- Nothing - Changed data structure of 'neis' from List<byte> to byte[] for optimized memory usage and improved access speed in `DtLayerMonotoneRegion`
### Removed ### Removed
- Nothing - Nothing

View File

@ -135,6 +135,14 @@ namespace DotRecast.Core.Numerics
@out[n + 1] = @in[m + 1]; @out[n + 1] = @in[m + 1];
@out[n + 2] = @in[m + 2]; @out[n + 2] = @in[m + 2];
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Copy(Span<float> @out, int n, Span<float> @in, int m)
{
@out[n + 0] = @in[m + 0];
@out[n + 1] = @in[m + 1];
@out[n + 2] = @in[m + 2];
}
/// Returns the distance between two points. /// Returns the distance between two points.
/// @param[in] v1 A point. [(x, y, z)] /// @param[in] v1 A point. [(x, y, z)]

View File

@ -7,7 +7,8 @@ namespace DotRecast.Detour.TileCache
public const int DT_LAYER_MAX_NEIS = 16; public const int DT_LAYER_MAX_NEIS = 16;
public int area; public int area;
public List<byte> neis = new List<byte>(DT_LAYER_MAX_NEIS); public byte[] neis = new byte[DT_LAYER_MAX_NEIS];
public byte nneis;
public byte regId; public byte regId;
public byte areaId; public byte areaId;
}; };

View File

@ -181,8 +181,8 @@ namespace DotRecast.Detour.TileCache
byte rai = layer.regs[ymi]; byte rai = layer.regs[ymi];
if (rai != 0xff && rai != ri) if (rai != 0xff && rai != ri)
{ {
AddUniqueLast(regs[ri].neis, rai); AddUniqueLast(regs[ri].neis, ref regs[ri].nneis, rai);
AddUniqueLast(regs[rai].neis, ri); AddUniqueLast(regs[rai].neis, ref regs[rai].nneis, ri);
} }
} }
} }
@ -197,8 +197,9 @@ namespace DotRecast.Detour.TileCache
int merge = -1; int merge = -1;
int mergea = 0; int mergea = 0;
foreach (int nei in reg.neis) for (int j = 0; j < reg.nneis; ++j)
{ {
byte nei = reg.neis[j];
DtLayerMonotoneRegion regn = regs[nei]; DtLayerMonotoneRegion regn = regs[nei];
if (reg.regId == regn.regId) if (reg.regId == regn.regId)
continue; continue;
@ -246,12 +247,13 @@ namespace DotRecast.Detour.TileCache
} }
} }
public static void AddUniqueLast(List<byte> a, byte v) public static void AddUniqueLast(byte[] a, ref byte an, byte v)
{ {
int n = a.Count; int n = an;
if (n > 0 && a[n - 1] == v) if (n > 0 && a[n - 1] == v)
return; return;
a.Add(v); a[an] = v;
an++;
} }
public static bool IsConnected(DtTileCacheLayer layer, int ia, int ib, int walkableClimb) public static bool IsConnected(DtTileCacheLayer layer, int ia, int ib, int walkableClimb)
@ -271,9 +273,11 @@ namespace DotRecast.Detour.TileCache
DtLayerMonotoneRegion reg = regs[i]; DtLayerMonotoneRegion reg = regs[i];
if (reg.regId != oldRegId) if (reg.regId != oldRegId)
continue; continue;
foreach (int nei in reg.neis)
int nnei = reg.nneis;
for (int j = 0; j < nnei ; ++j)
{ {
if (regs[nei].regId == newRegId) if (regs[reg.neis[j]].regId == newRegId)
count++; count++;
} }
} }

View File

@ -32,7 +32,6 @@ namespace DotRecast.Recast
const int RC_MAX_LAYERS = RcRecast.RC_NOT_CONNECTED; const int RC_MAX_LAYERS = RcRecast.RC_NOT_CONNECTED;
const int RC_MAX_NEIS = 16; const int RC_MAX_NEIS = 16;
private static void AddUnique(List<int> a, int v) private static void AddUnique(List<int> a, int v)
{ {
if (!a.Contains(v)) if (!a.Contains(v))

View File

@ -209,7 +209,7 @@ namespace DotRecast.Recast
/// @param[out] outVerts2Count The number of resulting polygon 2 vertices /// @param[out] outVerts2Count The number of resulting polygon 2 vertices
/// @param[in] axisOffset THe offset along the specified axis /// @param[in] axisOffset THe offset along the specified axis
/// @param[in] axis The separating axis /// @param[in] axis The separating axis
private static void DividePoly(float[] inVerts, int inVertsOffset, int inVertsCount, private static void DividePoly(Span<float> inVerts, int inVertsOffset, int inVertsCount,
int outVerts1, out int outVerts1Count, int outVerts1, out int outVerts1Count,
int outVerts2, out int outVerts2Count, int outVerts2, out int outVerts2Count,
float axisOffset, int axis) float axisOffset, int axis)
@ -322,7 +322,7 @@ namespace DotRecast.Recast
z1 = Math.Clamp(z1, 0, h - 1); z1 = Math.Clamp(z1, 0, h - 1);
// Clip the triangle into all grid cells it touches. // Clip the triangle into all grid cells it touches.
float[] buf = new float[7 * 3 * 4]; Span<float> buf = stackalloc float[7 * 3 * 4];
int @in = 0; int @in = 0;
int inRow = 7 * 3; int inRow = 7 * 3;
int p1 = inRow + 7 * 3; int p1 = inRow + 7 * 3;

View File

@ -1665,8 +1665,8 @@ namespace DotRecast.Recast
ctx.StartTimer(RcTimerLabel.RC_TIMER_BUILD_REGIONS_WATERSHED); ctx.StartTimer(RcTimerLabel.RC_TIMER_BUILD_REGIONS_WATERSHED);
int LOG_NB_STACKS = 3; const int LOG_NB_STACKS = 3;
int NB_STACKS = 1 << LOG_NB_STACKS; const int NB_STACKS = 1 << LOG_NB_STACKS;
List<List<RcLevelStackEntry>> lvlStacks = new List<List<RcLevelStackEntry>>(); List<List<RcLevelStackEntry>> lvlStacks = new List<List<RcLevelStackEntry>>();
for (int i = 0; i < NB_STACKS; ++i) for (int i = 0; i < NB_STACKS; ++i)
{ {
@ -1756,7 +1756,7 @@ namespace DotRecast.Recast
ExpandRegions(expandIters * 8, 0, chf, srcReg, srcDist, stack, true); ExpandRegions(expandIters * 8, 0, chf, srcReg, srcDist, stack, true);
ctx.StopTimer(RcTimerLabel.RC_TIMER_BUILD_REGIONS_WATERSHED); ctx.StopTimer(RcTimerLabel.RC_TIMER_BUILD_REGIONS_WATERSHED);
ctx.StartTimer(RcTimerLabel.RC_TIMER_BUILD_REGIONS_FILTER); ctx.StartTimer(RcTimerLabel.RC_TIMER_BUILD_REGIONS_FILTER);
// Merge regions and filter out small regions. // Merge regions and filter out small regions.