Changed 'heights', 'areas', 'cons', and 'regs' arrays to byte arrays for uniformity and efficiency in DtTileCacheLayer

This commit is contained in:
ikpil 2024-06-11 00:44:20 +09:00
parent 3417ecae36
commit 65c572a4c2
6 changed files with 43 additions and 45 deletions

View File

@ -14,6 +14,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Changed ### Changed
- Changed to reuse samples and edges list in BuildPolyDetail() - Changed to reuse samples and edges list in BuildPolyDetail()
- Changed 'heights', 'areas', 'cons', and 'regs' arrays to byte arrays for uniformity and efficiency in DtTileCacheLayer
### Removed ### Removed
- Removed RcMeshDetails.VdistSq2(float[], float[]) - Removed RcMeshDetails.VdistSq2(float[], float[])

View File

@ -7,8 +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<int> neis = new List<int>(DT_LAYER_MAX_NEIS); public List<byte> neis = new List<byte>(DT_LAYER_MAX_NEIS);
public int regId; public byte regId;
public int areaId; public byte areaId;
}; };
} }

View File

@ -43,7 +43,7 @@ namespace DotRecast.Detour.TileCache
int w = layer.header.width; int w = layer.header.width;
int h = layer.header.height; int h = layer.header.height;
Array.Fill(layer.regs, (short)0x00FF); Array.Fill(layer.regs, (byte)0xFF);
int nsweeps = w; int nsweeps = w;
RcLayerSweepSpan[] sweeps = new RcLayerSweepSpan[nsweeps]; RcLayerSweepSpan[] sweeps = new RcLayerSweepSpan[nsweeps];
for (int i = 0; i < sweeps.Length; i++) for (int i = 0; i < sweeps.Length; i++)
@ -53,7 +53,7 @@ namespace DotRecast.Detour.TileCache
// Partition walkable area into monotone regions. // Partition walkable area into monotone regions.
int[] prevCount = new int[256]; int[] prevCount = new int[256];
int regId = 0; byte regId = 0;
for (int y = 0; y < h; ++y) for (int y = 0; y < h; ++y)
{ {
@ -92,7 +92,7 @@ namespace DotRecast.Detour.TileCache
int yidx = x + (y - 1) * w; int yidx = x + (y - 1) * w;
if (y > 0 && IsConnected(layer, idx, yidx, walkableClimb)) if (y > 0 && IsConnected(layer, idx, yidx, walkableClimb))
{ {
int nr = layer.regs[yidx]; byte nr = layer.regs[yidx];
if (nr != 0xff) if (nr != 0xff)
{ {
// Set neighbour when first valid neighbour is // Set neighbour when first valid neighbour is
@ -146,12 +146,12 @@ namespace DotRecast.Detour.TileCache
{ {
int idx = x + y * w; int idx = x + y * w;
if (layer.regs[idx] != 0xff) if (layer.regs[idx] != 0xff)
layer.regs[idx] = (short)sweeps[layer.regs[idx]].id; layer.regs[idx] = sweeps[layer.regs[idx]].id;
} }
} }
// Allocate and init layer regions. // Allocate and init layer regions.
int nregs = regId; byte nregs = regId;
DtLayerMonotoneRegion[] regs = new DtLayerMonotoneRegion[nregs]; DtLayerMonotoneRegion[] regs = new DtLayerMonotoneRegion[nregs];
for (int i = 0; i < nregs; ++i) for (int i = 0; i < nregs; ++i)
@ -166,7 +166,7 @@ namespace DotRecast.Detour.TileCache
for (int x = 0; x < w; ++x) for (int x = 0; x < w; ++x)
{ {
int idx = x + y * w; int idx = x + y * w;
int ri = layer.regs[idx]; byte ri = layer.regs[idx];
if (ri == 0xff) if (ri == 0xff)
continue; continue;
@ -178,7 +178,7 @@ namespace DotRecast.Detour.TileCache
int ymi = x + (y - 1) * w; int ymi = x + (y - 1) * w;
if (y > 0 && IsConnected(layer, idx, ymi, walkableClimb)) if (y > 0 && IsConnected(layer, idx, ymi, walkableClimb))
{ {
int 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, rai);
@ -188,7 +188,7 @@ namespace DotRecast.Detour.TileCache
} }
} }
for (int i = 0; i < nregs; ++i) for (byte i = 0; i < nregs; ++i)
regs[i].regId = i; regs[i].regId = i;
for (int i = 0; i < nregs; ++i) for (int i = 0; i < nregs; ++i)
@ -217,7 +217,7 @@ namespace DotRecast.Detour.TileCache
if (merge != -1) if (merge != -1)
{ {
int oldId = reg.regId; int oldId = reg.regId;
int newId = regs[merge].regId; byte newId = regs[merge].regId;
for (int j = 0; j < nregs; ++j) for (int j = 0; j < nregs; ++j)
if (regs[j].regId == oldId) if (regs[j].regId == oldId)
regs[j].regId = newId; regs[j].regId = newId;
@ -225,7 +225,7 @@ namespace DotRecast.Detour.TileCache
} }
// Compact ids. // Compact ids.
int[] remap = new int[256]; byte[] remap = new byte[256];
// Find number of unique regions. // Find number of unique regions.
regId = 0; regId = 0;
for (int i = 0; i < nregs; ++i) for (int i = 0; i < nregs; ++i)
@ -242,11 +242,11 @@ namespace DotRecast.Detour.TileCache
for (int i = 0; i < w * h; ++i) for (int i = 0; i < w * h; ++i)
{ {
if (layer.regs[i] != 0xff) if (layer.regs[i] != 0xff)
layer.regs[i] = (short)regs[layer.regs[i]].regId; layer.regs[i] = regs[layer.regs[i]].regId;
} }
} }
public static void AddUniqueLast(List<int> a, int v) public static void AddUniqueLast(List<byte> a, byte v)
{ {
int n = a.Count; int n = a.Count;
if (n > 0 && a[n - 1] == v) if (n > 0 && a[n - 1] == v)
@ -1800,7 +1800,7 @@ namespace DotRecast.Detour.TileCache
return mesh; return mesh;
} }
public static void MarkCylinderArea(DtTileCacheLayer layer, RcVec3f orig, float cs, float ch, RcVec3f pos, float radius, float height, int areaId) public static void MarkCylinderArea(DtTileCacheLayer layer, RcVec3f orig, float cs, float ch, RcVec3f pos, float radius, float height, byte areaId)
{ {
RcVec3f bmin = new RcVec3f(); RcVec3f bmin = new RcVec3f();
RcVec3f bmax = new RcVec3f(); RcVec3f bmax = new RcVec3f();
@ -1856,12 +1856,12 @@ namespace DotRecast.Detour.TileCache
int y = layer.heights[x + z * w]; int y = layer.heights[x + z * w];
if (y < miny || y > maxy) if (y < miny || y > maxy)
continue; continue;
layer.areas[x + z * w] = (short)areaId; layer.areas[x + z * w] = areaId;
} }
} }
} }
public static void MarkBoxArea(DtTileCacheLayer layer, RcVec3f orig, float cs, float ch, RcVec3f bmin, RcVec3f bmax, int areaId) public static void MarkBoxArea(DtTileCacheLayer layer, RcVec3f orig, float cs, float ch, RcVec3f bmin, RcVec3f bmax, byte areaId)
{ {
int w = layer.header.width; int w = layer.header.width;
int h = layer.header.height; int h = layer.header.height;
@ -1900,7 +1900,7 @@ namespace DotRecast.Detour.TileCache
int y = layer.heights[x + z * w]; int y = layer.heights[x + z * w];
if (y < miny || y > maxy) if (y < miny || y > maxy)
continue; continue;
layer.areas[x + z * w] = (short)areaId; layer.areas[x + z * w] = areaId;
} }
} }
} }
@ -1975,22 +1975,22 @@ namespace DotRecast.Detour.TileCache
int gridSize = layer.header.width * layer.header.height; int gridSize = layer.header.width * layer.header.height;
byte[] grids = comp.Decompress(compressed, buf.Position(), compressed.Length - buf.Position(), gridSize * 3); byte[] grids = comp.Decompress(compressed, buf.Position(), compressed.Length - buf.Position(), gridSize * 3);
layer.heights = new short[gridSize]; layer.heights = new byte[gridSize];
layer.areas = new short[gridSize]; layer.areas = new byte[gridSize];
layer.cons = new short[gridSize]; layer.cons = new byte[gridSize];
layer.regs = new short[gridSize]; layer.regs = new byte[gridSize];
for (int i = 0; i < gridSize; i++) for (int i = 0; i < gridSize; i++)
{ {
layer.heights[i] = (short)(grids[i] & 0xFF); layer.heights[i] = (byte)(grids[i] & 0xFF);
layer.areas[i] = (short)(grids[i + gridSize] & 0xFF); layer.areas[i] = (byte)(grids[i + gridSize] & 0xFF);
layer.cons[i] = (short)(grids[i + gridSize * 2] & 0xFF); layer.cons[i] = (byte)(grids[i + gridSize * 2] & 0xFF);
} }
return layer; return layer;
} }
public static void MarkBoxArea(DtTileCacheLayer layer, RcVec3f orig, float cs, float ch, RcVec3f center, RcVec3f extents, public static void MarkBoxArea(DtTileCacheLayer layer, RcVec3f orig, float cs, float ch, RcVec3f center, RcVec3f extents,
float[] rotAux, int areaId) float[] rotAux, byte areaId)
{ {
int w = layer.header.width; int w = layer.header.width;
int h = layer.header.height; int h = layer.header.height;
@ -2043,7 +2043,7 @@ namespace DotRecast.Detour.TileCache
int y = layer.heights[x + z * w]; int y = layer.heights[x + z * w];
if (y < miny || y > maxy) if (y < miny || y > maxy)
continue; continue;
layer.areas[x + z * w] = (short)areaId; layer.areas[x + z * w] = areaId;
} }
} }
} }

View File

@ -23,13 +23,10 @@ namespace DotRecast.Detour.TileCache
public class DtTileCacheLayer public class DtTileCacheLayer
{ {
public DtTileCacheLayerHeader header; public DtTileCacheLayerHeader header;
public int regCount; public byte regCount; // < Region count.
public byte[] heights; // unsigned char
/// < Region count. public byte[] areas; // unsigned char
public short[] heights; // char public byte[] cons; // unsigned char
public byte[] regs; // unsigned char
public short[] areas; // char
public short[] cons; // char
public short[] regs; // char
} }
} }

View File

@ -3,7 +3,7 @@
public class RcLayerSweepSpan public class RcLayerSweepSpan
{ {
public int ns; // number samples public int ns; // number samples
public int id; // region id public byte id; // region id
public int nei; // neighbour id public byte nei; // neighbour id
}; };
} }

View File

@ -80,10 +80,10 @@ namespace DotRecast.Recast
int w = chf.width; int w = chf.width;
int h = chf.height; int h = chf.height;
int[] srcReg = new int[chf.spanCount]; byte[] srcReg = new byte[chf.spanCount];
Array.Fill(srcReg, 0xFF); Array.Fill(srcReg, (byte)0xFF);
int nsweeps = chf.width; // Math.Max(chf.width, chf.height); int nsweeps = chf.width;
RcLayerSweepSpan[] sweeps = new RcLayerSweepSpan[nsweeps]; RcLayerSweepSpan[] sweeps = new RcLayerSweepSpan[nsweeps];
for (int i = 0; i < sweeps.Length; i++) for (int i = 0; i < sweeps.Length; i++)
{ {
@ -92,14 +92,14 @@ namespace DotRecast.Recast
// Partition walkable area into monotone regions. // Partition walkable area into monotone regions.
int[] prevCount = new int[256]; int[] prevCount = new int[256];
int regId = 0; byte regId = 0;
// Sweep one line at a time. // Sweep one line at a time.
for (int y = borderSize; y < h - borderSize; ++y) for (int y = borderSize; y < h - borderSize; ++y)
{ {
// Collect spans from this row. // Collect spans from this row.
Array.Fill(prevCount, 0); Array.Fill(prevCount, 0);
int sweepId = 0; byte sweepId = 0;
for (int x = borderSize; x < w - borderSize; ++x) for (int x = borderSize; x < w - borderSize; ++x)
{ {
@ -111,7 +111,7 @@ namespace DotRecast.Recast
if (chf.areas[i] == RC_NULL_AREA) if (chf.areas[i] == RC_NULL_AREA)
continue; continue;
int sid = 0xFF; byte sid = 0xFF;
// -x // -x
if (GetCon(ref s, 0) != RC_NOT_CONNECTED) if (GetCon(ref s, 0) != RC_NOT_CONNECTED)
@ -136,7 +136,7 @@ namespace DotRecast.Recast
int ax = x + GetDirOffsetX(3); int ax = x + GetDirOffsetX(3);
int ay = y + GetDirOffsetY(3); int ay = y + GetDirOffsetY(3);
int ai = chf.cells[ax + ay * w].index + GetCon(ref s, 3); int ai = chf.cells[ax + ay * w].index + GetCon(ref s, 3);
int nr = srcReg[ai]; byte nr = srcReg[ai];
if (nr != 0xff) if (nr != 0xff)
{ {
// Set neighbour when first valid neighbour is encoutered. // Set neighbour when first valid neighbour is encoutered.