refactor: readonly struct

This commit is contained in:
ikpil 2023-11-03 00:22:32 +09:00
parent 170b019517
commit 5aa482d35e
10 changed files with 259 additions and 204 deletions

View File

@ -486,11 +486,11 @@ public class RecastDebugDraw : DebugDraw
{ {
float fx = chf.bmin.X + x * cs; float fx = chf.bmin.X + x * cs;
float fz = chf.bmin.Z + y * cs; float fz = chf.bmin.Z + y * cs;
ref readonly RcCompactCell c = ref chf.cells[x + y * chf.width]; ref RcCompactCell c = ref chf.cells[x + y * chf.width];
for (int i = c.index, ni = c.index + c.count; i < ni; ++i) for (int i = c.index, ni = c.index + c.count; i < ni; ++i)
{ {
RcCompactSpan s = chf.spans[i]; ref RcCompactSpan s = ref chf.spans[i];
int area = chf.areas[i]; int area = chf.areas[i];
int color; int color;
@ -859,11 +859,11 @@ public class RecastDebugDraw : DebugDraw
{ {
float fx = chf.bmin.X + x * cs; float fx = chf.bmin.X + x * cs;
float fz = chf.bmin.Z + y * cs; float fz = chf.bmin.Z + y * cs;
ref readonly RcCompactCell c = ref chf.cells[x + y * chf.width]; ref RcCompactCell c = ref chf.cells[x + y * chf.width];
for (int i = c.index, ni = c.index + c.count; i < ni; ++i) for (int i = c.index, ni = c.index + c.count; i < ni; ++i)
{ {
RcCompactSpan s = chf.spans[i]; ref RcCompactSpan s = ref chf.spans[i];
float fy = chf.bmin.Y + (s.y) * ch; float fy = chf.bmin.Y + (s.y) * ch;
int color; int color;
if (s.reg != 0) if (s.reg != 0)
@ -912,11 +912,11 @@ public class RecastDebugDraw : DebugDraw
{ {
float fx = chf.bmin.X + x * cs; float fx = chf.bmin.X + x * cs;
float fz = chf.bmin.Z + y * cs; float fz = chf.bmin.Z + y * cs;
ref readonly RcCompactCell c = ref chf.cells[x + y * chf.width]; ref RcCompactCell c = ref chf.cells[x + y * chf.width];
for (int i = c.index, ni = c.index + c.count; i < ni; ++i) for (int i = c.index, ni = c.index + c.count; i < ni; ++i)
{ {
RcCompactSpan s = chf.spans[i]; ref RcCompactSpan s = ref chf.spans[i];
float fy = chf.bmin.Y + (s.y + 1) * ch; float fy = chf.bmin.Y + (s.y + 1) * ch;
char cd = (char)(chf.dist[i] * dscale); char cd = (char)(chf.dist[i] * dscale);
int color = DuRGBA(cd, cd, cd, 255); int color = DuRGBA(cd, cd, cd, 255);

View File

@ -60,7 +60,7 @@ namespace DotRecast.Recast
{ {
for (int x = 0; x < xSize; ++x) for (int x = 0; x < xSize; ++x)
{ {
ref readonly RcCompactCell cell = ref compactHeightfield.cells[x + z * zStride]; ref RcCompactCell cell = ref compactHeightfield.cells[x + z * zStride];
for (int spanIndex = cell.index, maxSpanIndex = cell.index + cell.count; spanIndex < maxSpanIndex; ++spanIndex) for (int spanIndex = cell.index, maxSpanIndex = cell.index + cell.count; spanIndex < maxSpanIndex; ++spanIndex)
{ {
if (compactHeightfield.areas[spanIndex] == RC_NULL_AREA) if (compactHeightfield.areas[spanIndex] == RC_NULL_AREA)
@ -69,13 +69,13 @@ namespace DotRecast.Recast
} }
else else
{ {
RcCompactSpan span = compactHeightfield.spans[spanIndex]; ref RcCompactSpan span = ref compactHeightfield.spans[spanIndex];
// Check that there is a non-null adjacent span in each of the 4 cardinal directions. // Check that there is a non-null adjacent span in each of the 4 cardinal directions.
int neighborCount = 0; int neighborCount = 0;
for (int direction = 0; direction < 4; ++direction) for (int direction = 0; direction < 4; ++direction)
{ {
int neighborConnection = GetCon(span, direction); int neighborConnection = GetCon(ref span, direction);
if (neighborConnection == RC_NOT_CONNECTED) if (neighborConnection == RC_NOT_CONNECTED)
{ {
break; break;
@ -83,7 +83,7 @@ namespace DotRecast.Recast
int neighborX = x + GetDirOffsetX(direction); int neighborX = x + GetDirOffsetX(direction);
int neighborZ = z + GetDirOffsetY(direction); int neighborZ = z + GetDirOffsetY(direction);
int neighborSpanIndex = compactHeightfield.cells[neighborX + neighborZ * zStride].index + GetCon(span, direction); int neighborSpanIndex = compactHeightfield.cells[neighborX + neighborZ * zStride].index + GetCon(ref span, direction);
if (compactHeightfield.areas[neighborSpanIndex] == RC_NULL_AREA) if (compactHeightfield.areas[neighborSpanIndex] == RC_NULL_AREA)
{ {
break; break;
@ -109,19 +109,19 @@ namespace DotRecast.Recast
{ {
for (int x = 0; x < xSize; ++x) for (int x = 0; x < xSize; ++x)
{ {
ref readonly RcCompactCell cell = ref compactHeightfield.cells[x + z * zStride]; ref RcCompactCell cell = ref compactHeightfield.cells[x + z * zStride];
int maxSpanIndex = cell.index + cell.count; int maxSpanIndex = cell.index + cell.count;
for (int spanIndex = cell.index; spanIndex < maxSpanIndex; ++spanIndex) for (int spanIndex = cell.index; spanIndex < maxSpanIndex; ++spanIndex)
{ {
RcCompactSpan span = compactHeightfield.spans[spanIndex]; ref RcCompactSpan span = ref compactHeightfield.spans[spanIndex];
if (GetCon(span, 0) != RC_NOT_CONNECTED) if (GetCon(ref span, 0) != RC_NOT_CONNECTED)
{ {
// (-1,0) // (-1,0)
int aX = x + GetDirOffsetX(0); int aX = x + GetDirOffsetX(0);
int aY = z + GetDirOffsetY(0); int aY = z + GetDirOffsetY(0);
int aIndex = compactHeightfield.cells[aX + aY * xSize].index + GetCon(span, 0); int aIndex = compactHeightfield.cells[aX + aY * xSize].index + GetCon(ref span, 0);
RcCompactSpan aSpan = compactHeightfield.spans[aIndex]; ref RcCompactSpan aSpan = ref compactHeightfield.spans[aIndex];
newDistance = Math.Min(distanceToBoundary[aIndex] + 2, 255); newDistance = Math.Min(distanceToBoundary[aIndex] + 2, 255);
if (newDistance < distanceToBoundary[spanIndex]) if (newDistance < distanceToBoundary[spanIndex])
{ {
@ -129,11 +129,11 @@ namespace DotRecast.Recast
} }
// (-1,-1) // (-1,-1)
if (GetCon(aSpan, 3) != RC_NOT_CONNECTED) if (GetCon(ref aSpan, 3) != RC_NOT_CONNECTED)
{ {
int bX = aX + GetDirOffsetX(3); int bX = aX + GetDirOffsetX(3);
int bY = aY + GetDirOffsetY(3); int bY = aY + GetDirOffsetY(3);
int bIndex = compactHeightfield.cells[bX + bY * xSize].index + GetCon(aSpan, 3); int bIndex = compactHeightfield.cells[bX + bY * xSize].index + GetCon(ref aSpan, 3);
newDistance = Math.Min(distanceToBoundary[bIndex] + 3, 255); newDistance = Math.Min(distanceToBoundary[bIndex] + 3, 255);
if (newDistance < distanceToBoundary[spanIndex]) if (newDistance < distanceToBoundary[spanIndex])
{ {
@ -142,13 +142,13 @@ namespace DotRecast.Recast
} }
} }
if (GetCon(span, 3) != RC_NOT_CONNECTED) if (GetCon(ref span, 3) != RC_NOT_CONNECTED)
{ {
// (0,-1) // (0,-1)
int aX = x + GetDirOffsetX(3); int aX = x + GetDirOffsetX(3);
int aY = z + GetDirOffsetY(3); int aY = z + GetDirOffsetY(3);
int aIndex = compactHeightfield.cells[aX + aY * xSize].index + GetCon(span, 3); int aIndex = compactHeightfield.cells[aX + aY * xSize].index + GetCon(ref span, 3);
RcCompactSpan aSpan = compactHeightfield.spans[aIndex]; ref RcCompactSpan aSpan = ref compactHeightfield.spans[aIndex];
newDistance = Math.Min(distanceToBoundary[aIndex] + 2, 255); newDistance = Math.Min(distanceToBoundary[aIndex] + 2, 255);
if (newDistance < distanceToBoundary[spanIndex]) if (newDistance < distanceToBoundary[spanIndex])
{ {
@ -156,11 +156,11 @@ namespace DotRecast.Recast
} }
// (1,-1) // (1,-1)
if (GetCon(aSpan, 2) != RC_NOT_CONNECTED) if (GetCon(ref aSpan, 2) != RC_NOT_CONNECTED)
{ {
int bX = aX + GetDirOffsetX(2); int bX = aX + GetDirOffsetX(2);
int bY = aY + GetDirOffsetY(2); int bY = aY + GetDirOffsetY(2);
int bIndex = compactHeightfield.cells[bX + bY * xSize].index + GetCon(aSpan, 2); int bIndex = compactHeightfield.cells[bX + bY * xSize].index + GetCon(ref aSpan, 2);
newDistance = Math.Min(distanceToBoundary[bIndex] + 3, 255); newDistance = Math.Min(distanceToBoundary[bIndex] + 3, 255);
if (newDistance < distanceToBoundary[spanIndex]) if (newDistance < distanceToBoundary[spanIndex])
{ {
@ -177,19 +177,19 @@ namespace DotRecast.Recast
{ {
for (int x = xSize - 1; x >= 0; --x) for (int x = xSize - 1; x >= 0; --x)
{ {
ref readonly RcCompactCell cell = ref compactHeightfield.cells[x + z * zStride]; ref RcCompactCell cell = ref compactHeightfield.cells[x + z * zStride];
int maxSpanIndex = cell.index + cell.count; int maxSpanIndex = cell.index + cell.count;
for (int i = cell.index; i < maxSpanIndex; ++i) for (int i = cell.index; i < maxSpanIndex; ++i)
{ {
RcCompactSpan span = compactHeightfield.spans[i]; ref RcCompactSpan span = ref compactHeightfield.spans[i];
if (GetCon(span, 2) != RC_NOT_CONNECTED) if (GetCon(ref span, 2) != RC_NOT_CONNECTED)
{ {
// (1,0) // (1,0)
int aX = x + GetDirOffsetX(2); int aX = x + GetDirOffsetX(2);
int aY = z + GetDirOffsetY(2); int aY = z + GetDirOffsetY(2);
int aIndex = compactHeightfield.cells[aX + aY * xSize].index + GetCon(span, 2); int aIndex = compactHeightfield.cells[aX + aY * xSize].index + GetCon(ref span, 2);
RcCompactSpan aSpan = compactHeightfield.spans[aIndex]; ref RcCompactSpan aSpan = ref compactHeightfield.spans[aIndex];
newDistance = Math.Min(distanceToBoundary[aIndex] + 2, 255); newDistance = Math.Min(distanceToBoundary[aIndex] + 2, 255);
if (newDistance < distanceToBoundary[i]) if (newDistance < distanceToBoundary[i])
{ {
@ -197,11 +197,11 @@ namespace DotRecast.Recast
} }
// (1,1) // (1,1)
if (GetCon(aSpan, 1) != RC_NOT_CONNECTED) if (GetCon(ref aSpan, 1) != RC_NOT_CONNECTED)
{ {
int bX = aX + GetDirOffsetX(1); int bX = aX + GetDirOffsetX(1);
int bY = aY + GetDirOffsetY(1); int bY = aY + GetDirOffsetY(1);
int bIndex = compactHeightfield.cells[bX + bY * xSize].index + GetCon(aSpan, 1); int bIndex = compactHeightfield.cells[bX + bY * xSize].index + GetCon(ref aSpan, 1);
newDistance = Math.Min(distanceToBoundary[bIndex] + 3, 255); newDistance = Math.Min(distanceToBoundary[bIndex] + 3, 255);
if (newDistance < distanceToBoundary[i]) if (newDistance < distanceToBoundary[i])
{ {
@ -210,13 +210,13 @@ namespace DotRecast.Recast
} }
} }
if (GetCon(span, 1) != RC_NOT_CONNECTED) if (GetCon(ref span, 1) != RC_NOT_CONNECTED)
{ {
// (0,1) // (0,1)
int aX = x + GetDirOffsetX(1); int aX = x + GetDirOffsetX(1);
int aY = z + GetDirOffsetY(1); int aY = z + GetDirOffsetY(1);
int aIndex = compactHeightfield.cells[aX + aY * xSize].index + GetCon(span, 1); int aIndex = compactHeightfield.cells[aX + aY * xSize].index + GetCon(ref span, 1);
RcCompactSpan aSpan = compactHeightfield.spans[aIndex]; ref RcCompactSpan aSpan = ref compactHeightfield.spans[aIndex];
newDistance = Math.Min(distanceToBoundary[aIndex] + 2, 255); newDistance = Math.Min(distanceToBoundary[aIndex] + 2, 255);
if (newDistance < distanceToBoundary[i]) if (newDistance < distanceToBoundary[i])
{ {
@ -224,11 +224,11 @@ namespace DotRecast.Recast
} }
// (-1,1) // (-1,1)
if (GetCon(aSpan, 0) != RC_NOT_CONNECTED) if (GetCon(ref aSpan, 0) != RC_NOT_CONNECTED)
{ {
int bX = aX + GetDirOffsetX(0); int bX = aX + GetDirOffsetX(0);
int bY = aY + GetDirOffsetY(0); int bY = aY + GetDirOffsetY(0);
int bIndex = compactHeightfield.cells[bX + bY * xSize].index + GetCon(aSpan, 0); int bIndex = compactHeightfield.cells[bX + bY * xSize].index + GetCon(ref aSpan, 0);
newDistance = Math.Min(distanceToBoundary[bIndex] + 3, 255); newDistance = Math.Min(distanceToBoundary[bIndex] + 3, 255);
if (newDistance < distanceToBoundary[i]) if (newDistance < distanceToBoundary[i])
{ {
@ -275,11 +275,11 @@ namespace DotRecast.Recast
{ {
for (int x = 0; x < xSize; ++x) for (int x = 0; x < xSize; ++x)
{ {
ref readonly RcCompactCell cell = ref compactHeightfield.cells[x + z * zStride]; ref RcCompactCell cell = ref compactHeightfield.cells[x + z * zStride];
int maxSpanIndex = cell.index + cell.count; int maxSpanIndex = cell.index + cell.count;
for (int spanIndex = cell.index; spanIndex < maxSpanIndex; ++spanIndex) for (int spanIndex = cell.index; spanIndex < maxSpanIndex; ++spanIndex)
{ {
RcCompactSpan span = compactHeightfield.spans[spanIndex]; ref RcCompactSpan span = ref compactHeightfield.spans[spanIndex];
if (compactHeightfield.areas[spanIndex] == RC_NULL_AREA) if (compactHeightfield.areas[spanIndex] == RC_NULL_AREA)
{ {
areas[spanIndex] = compactHeightfield.areas[spanIndex]; areas[spanIndex] = compactHeightfield.areas[spanIndex];
@ -294,27 +294,27 @@ namespace DotRecast.Recast
for (int dir = 0; dir < 4; ++dir) for (int dir = 0; dir < 4; ++dir)
{ {
if (GetCon(span, dir) == RC_NOT_CONNECTED) if (GetCon(ref span, dir) == RC_NOT_CONNECTED)
{ {
continue; continue;
} }
int aX = x + GetDirOffsetX(dir); int aX = x + GetDirOffsetX(dir);
int aZ = z + GetDirOffsetY(dir); int aZ = z + GetDirOffsetY(dir);
int aIndex = compactHeightfield.cells[aX + aZ * zStride].index + GetCon(span, dir); int aIndex = compactHeightfield.cells[aX + aZ * zStride].index + GetCon(ref span, dir);
if (compactHeightfield.areas[aIndex] != RC_NULL_AREA) if (compactHeightfield.areas[aIndex] != RC_NULL_AREA)
{ {
neighborAreas[dir * 2 + 0] = compactHeightfield.areas[aIndex]; neighborAreas[dir * 2 + 0] = compactHeightfield.areas[aIndex];
} }
RcCompactSpan aSpan = compactHeightfield.spans[aIndex]; ref RcCompactSpan aSpan = ref compactHeightfield.spans[aIndex];
int dir2 = (dir + 1) & 0x3; int dir2 = (dir + 1) & 0x3;
int neighborConnection2 = GetCon(aSpan, dir2); int neighborConnection2 = GetCon(ref aSpan, dir2);
if (neighborConnection2 != RC_NOT_CONNECTED) if (neighborConnection2 != RC_NOT_CONNECTED)
{ {
int bX = aX + GetDirOffsetX(dir2); int bX = aX + GetDirOffsetX(dir2);
int bZ = aZ + GetDirOffsetY(dir2); int bZ = aZ + GetDirOffsetY(dir2);
int bIndex = compactHeightfield.cells[bX + bZ * zStride].index + GetCon(aSpan, dir2); int bIndex = compactHeightfield.cells[bX + bZ * zStride].index + GetCon(ref aSpan, dir2);
if (compactHeightfield.areas[bIndex] != RC_NULL_AREA) if (compactHeightfield.areas[bIndex] != RC_NULL_AREA)
{ {
neighborAreas[dir * 2 + 1] = compactHeightfield.areas[bIndex]; neighborAreas[dir * 2 + 1] = compactHeightfield.areas[bIndex];
@ -404,11 +404,11 @@ namespace DotRecast.Recast
{ {
for (int x = minX; x <= maxX; ++x) for (int x = minX; x <= maxX; ++x)
{ {
ref readonly RcCompactCell cell = ref compactHeightfield.cells[x + z * zStride]; ref RcCompactCell cell = ref compactHeightfield.cells[x + z * zStride];
int maxSpanIndex = cell.index + cell.count; int maxSpanIndex = cell.index + cell.count;
for (int spanIndex = cell.index; spanIndex < maxSpanIndex; ++spanIndex) for (int spanIndex = cell.index; spanIndex < maxSpanIndex; ++spanIndex)
{ {
RcCompactSpan span = compactHeightfield.spans[spanIndex]; ref RcCompactSpan span = ref compactHeightfield.spans[spanIndex];
// Skip if the span is outside the box extents. // Skip if the span is outside the box extents.
if (span.y < minY || span.y > maxY) if (span.y < minY || span.y > maxY)
@ -523,11 +523,11 @@ namespace DotRecast.Recast
{ {
for (int x = minx; x <= maxx; ++x) for (int x = minx; x <= maxx; ++x)
{ {
ref readonly RcCompactCell cell = ref compactHeightfield.cells[x + z * zStride]; ref RcCompactCell cell = ref compactHeightfield.cells[x + z * zStride];
int maxSpanIndex = cell.index + cell.count; int maxSpanIndex = cell.index + cell.count;
for (int spanIndex = cell.index; spanIndex < maxSpanIndex; ++spanIndex) for (int spanIndex = cell.index; spanIndex < maxSpanIndex; ++spanIndex)
{ {
RcCompactSpan span = compactHeightfield.spans[spanIndex]; ref RcCompactSpan span = ref compactHeightfield.spans[spanIndex];
// Skip if span is removed. // Skip if span is removed.
if (compactHeightfield.areas[spanIndex] == RC_NULL_AREA) if (compactHeightfield.areas[spanIndex] == RC_NULL_AREA)
@ -644,7 +644,7 @@ namespace DotRecast.Recast
{ {
for (int x = minx; x <= maxx; ++x) for (int x = minx; x <= maxx; ++x)
{ {
ref readonly RcCompactCell cell = ref compactHeightfield.cells[x + z * zStride]; ref RcCompactCell cell = ref compactHeightfield.cells[x + z * zStride];
int maxSpanIndex = cell.index + cell.count; int maxSpanIndex = cell.index + cell.count;
float cellX = compactHeightfield.bmin.X + ((float)x + 0.5f) * compactHeightfield.cs; float cellX = compactHeightfield.bmin.X + ((float)x + 0.5f) * compactHeightfield.cs;
@ -661,7 +661,7 @@ namespace DotRecast.Recast
// Mark all overlapping spans // Mark all overlapping spans
for (int spanIndex = cell.index; spanIndex < maxSpanIndex; ++spanIndex) for (int spanIndex = cell.index; spanIndex < maxSpanIndex; ++spanIndex)
{ {
RcCompactSpan span = compactHeightfield.spans[spanIndex]; ref RcCompactSpan span = ref compactHeightfield.spans[spanIndex];
// Skip if span is removed. // Skip if span is removed.
if (compactHeightfield.areas[spanIndex] == RC_NULL_AREA) if (compactHeightfield.areas[spanIndex] == RC_NULL_AREA)

View File

@ -36,7 +36,7 @@ namespace DotRecast.Recast
/// @param[in] span The span to update. /// @param[in] span The span to update.
/// @param[in] direction The direction to set. [Limits: 0 <= value < 4] /// @param[in] direction The direction to set. [Limits: 0 <= value < 4]
/// @param[in] neighborIndex The index of the neighbor span. /// @param[in] neighborIndex The index of the neighbor span.
public static void SetCon(RcCompactSpan span, int direction, int neighborIndex) public static void SetCon(RcCompactSpanBuilder span, int direction, int neighborIndex)
{ {
int shift = direction * 6; int shift = direction * 6;
int con = span.con; int con = span.con;
@ -47,7 +47,7 @@ namespace DotRecast.Recast
/// @param[in] span The span to check. /// @param[in] span The span to check.
/// @param[in] direction The direction to check. [Limits: 0 <= value < 4] /// @param[in] direction The direction to check. [Limits: 0 <= value < 4]
/// @return The neighbor connection data for the specified direction, or #RC_NOT_CONNECTED if there is no connection. /// @return The neighbor connection data for the specified direction, or #RC_NOT_CONNECTED if there is no connection.
public static int GetCon(RcCompactSpan s, int dir) public static int GetCon(ref RcCompactSpan s, int dir)
{ {
int shift = dir * 6; int shift = dir * 6;
return (s.con >> shift) & 0x3f; return (s.con >> shift) & 0x3f;

View File

@ -21,18 +21,26 @@ freely, subject to the following restrictions:
namespace DotRecast.Recast namespace DotRecast.Recast
{ {
/** Represents a span of unobstructed space within a compact heightfield. */ /** Represents a span of unobstructed space within a compact heightfield. */
public class RcCompactSpan public readonly struct RcCompactSpan
{ {
/** The lower extent of the span. (Measured from the heightfield's base.) */ /** The lower extent of the span. (Measured from the heightfield's base.) */
public int y; public readonly int y;
/** The id of the region the span belongs to. (Or zero if not in a region.) */ /** The id of the region the span belongs to. (Or zero if not in a region.) */
public int reg; public readonly int reg;
/** Packed neighbor connection data. */ /** Packed neighbor connection data. */
public int con; public readonly int con;
/** The height of the span. (Measured from #y.) */ /** The height of the span. (Measured from #y.) */
public int h; public readonly int h;
public RcCompactSpan(RcCompactSpanBuilder span)
{
y = span.y;
reg = span.reg;
con = span.con;
h = span.h;
}
} }
} }

View File

@ -0,0 +1,35 @@
namespace DotRecast.Recast
{
public class RcCompactSpanBuilder
{
public int y;
public int reg;
public int con;
public int h;
public static RcCompactSpanBuilder NewBuilder(ref RcCompactSpan span)
{
var builder = new RcCompactSpanBuilder();
builder.y = span.y;
builder.reg = span.reg;
builder.con = span.con;
builder.h = span.h;
return builder;
}
public RcCompactSpanBuilder()
{
}
public RcCompactSpanBuilder WithReg(int reg)
{
this.reg = reg;
return this;
}
public RcCompactSpan Build()
{
return new RcCompactSpan(this);
}
}
}

View File

@ -18,6 +18,7 @@ freely, subject to the following restrictions:
*/ */
using System; using System;
using System.Linq;
using DotRecast.Core; using DotRecast.Core;
using static DotRecast.Recast.RcConstants; using static DotRecast.Recast.RcConstants;
@ -65,13 +66,13 @@ namespace DotRecast.Recast
chf.cs = hf.cs; chf.cs = hf.cs;
chf.ch = hf.ch; chf.ch = hf.ch;
chf.cells = new RcCompactCell[w * h]; chf.cells = new RcCompactCell[w * h];
chf.spans = new RcCompactSpan[spanCount]; //chf.spans = new RcCompactSpan[spanCount];
chf.areas = new int[spanCount]; chf.areas = new int[spanCount];
for (int i = 0; i < chf.spans.Length; i++) var chfSpans = Enumerable
{ .Range(0, spanCount)
chf.spans[i] = new RcCompactSpan(); .Select(x => new RcCompactSpanBuilder())
} .ToArray();
// Fill in cells and spans. // Fill in cells and spans.
int idx = 0; int idx = 0;
@ -92,8 +93,8 @@ namespace DotRecast.Recast
{ {
int bot = s.smax; int bot = s.smax;
int top = s.next != null ? (int)s.next.smin : MAX_HEIGHT; int top = s.next != null ? (int)s.next.smin : MAX_HEIGHT;
chf.spans[idx].y = Math.Clamp(bot, 0, MAX_HEIGHT); chfSpans[idx].y = Math.Clamp(bot, 0, MAX_HEIGHT);
chf.spans[idx].h = Math.Clamp(top - bot, 0, MAX_HEIGHT); chfSpans[idx].h = Math.Clamp(top - bot, 0, MAX_HEIGHT);
chf.areas[idx] = s.area; chf.areas[idx] = s.area;
idx++; idx++;
tmpCount++; tmpCount++;
@ -112,10 +113,10 @@ namespace DotRecast.Recast
{ {
for (int x = 0; x < w; ++x) for (int x = 0; x < w; ++x)
{ {
ref readonly RcCompactCell c = ref chf.cells[x + y * w]; ref RcCompactCell c = ref chf.cells[x + y * w];
for (int i = c.index, ni = c.index + c.count; i < ni; ++i) for (int i = c.index, ni = c.index + c.count; i < ni; ++i)
{ {
RcCompactSpan s = chf.spans[i]; ref RcCompactSpanBuilder s = ref chfSpans[i];
for (int dir = 0; dir < 4; ++dir) for (int dir = 0; dir < 4; ++dir)
{ {
@ -128,10 +129,10 @@ namespace DotRecast.Recast
// Iterate over all neighbour spans and check if any of the is // Iterate over all neighbour spans and check if any of the is
// accessible from current cell. // accessible from current cell.
ref readonly RcCompactCell nc = ref chf.cells[nx + ny * w]; ref RcCompactCell nc = ref chf.cells[nx + ny * w];
for (int k = nc.index, nk = nc.index + nc.count; k < nk; ++k) for (int k = nc.index, nk = nc.index + nc.count; k < nk; ++k)
{ {
RcCompactSpan ns = chf.spans[k]; ref RcCompactSpanBuilder ns = ref chfSpans[k];
int bot = Math.Max(s.y, ns.y); int bot = Math.Max(s.y, ns.y);
int top = Math.Min(s.y + s.h, ns.y + ns.h); int top = Math.Min(s.y + s.h, ns.y + ns.h);
@ -162,6 +163,8 @@ namespace DotRecast.Recast
+ " (max: " + MAX_LAYERS + ")"); + " (max: " + MAX_LAYERS + ")");
} }
chf.spans = chfSpans.Select(x => x.Build()).ToArray();
return chf; return chf;
} }

View File

@ -33,7 +33,7 @@ namespace DotRecast.Recast
{ {
isBorderVertex = false; isBorderVertex = false;
RcCompactSpan s = chf.spans[i]; ref RcCompactSpan s = ref chf.spans[i];
int ch = s.y; int ch = s.y;
int dirp = (dir + 1) & 0x3; int dirp = (dir + 1) & 0x3;
@ -46,39 +46,39 @@ namespace DotRecast.Recast
// border vertices which are in between two areas to be removed. // border vertices which are in between two areas to be removed.
regs[0] = chf.spans[i].reg | (chf.areas[i] << 16); regs[0] = chf.spans[i].reg | (chf.areas[i] << 16);
if (GetCon(s, dir) != RC_NOT_CONNECTED) if (GetCon(ref s, dir) != RC_NOT_CONNECTED)
{ {
int ax = x + GetDirOffsetX(dir); int ax = x + GetDirOffsetX(dir);
int ay = y + GetDirOffsetY(dir); int ay = y + GetDirOffsetY(dir);
int ai = chf.cells[ax + ay * chf.width].index + GetCon(s, dir); int ai = chf.cells[ax + ay * chf.width].index + GetCon(ref s, dir);
RcCompactSpan @as = chf.spans[ai]; ref RcCompactSpan @as = ref chf.spans[ai];
ch = Math.Max(ch, @as.y); ch = Math.Max(ch, @as.y);
regs[1] = chf.spans[ai].reg | (chf.areas[ai] << 16); regs[1] = chf.spans[ai].reg | (chf.areas[ai] << 16);
if (GetCon(@as, dirp) != RC_NOT_CONNECTED) if (GetCon(ref @as, dirp) != RC_NOT_CONNECTED)
{ {
int ax2 = ax + GetDirOffsetX(dirp); int ax2 = ax + GetDirOffsetX(dirp);
int ay2 = ay + GetDirOffsetY(dirp); int ay2 = ay + GetDirOffsetY(dirp);
int ai2 = chf.cells[ax2 + ay2 * chf.width].index + GetCon(@as, dirp); int ai2 = chf.cells[ax2 + ay2 * chf.width].index + GetCon(ref @as, dirp);
RcCompactSpan as2 = chf.spans[ai2]; ref RcCompactSpan as2 = ref chf.spans[ai2];
ch = Math.Max(ch, as2.y); ch = Math.Max(ch, as2.y);
regs[2] = chf.spans[ai2].reg | (chf.areas[ai2] << 16); regs[2] = chf.spans[ai2].reg | (chf.areas[ai2] << 16);
} }
} }
if (GetCon(s, dirp) != RC_NOT_CONNECTED) if (GetCon(ref s, dirp) != RC_NOT_CONNECTED)
{ {
int ax = x + GetDirOffsetX(dirp); int ax = x + GetDirOffsetX(dirp);
int ay = y + GetDirOffsetY(dirp); int ay = y + GetDirOffsetY(dirp);
int ai = chf.cells[ax + ay * chf.width].index + GetCon(s, dirp); int ai = chf.cells[ax + ay * chf.width].index + GetCon(ref s, dirp);
RcCompactSpan @as = chf.spans[ai]; ref RcCompactSpan @as = ref chf.spans[ai];
ch = Math.Max(ch, @as.y); ch = Math.Max(ch, @as.y);
regs[3] = chf.spans[ai].reg | (chf.areas[ai] << 16); regs[3] = chf.spans[ai].reg | (chf.areas[ai] << 16);
if (GetCon(@as, dir) != RC_NOT_CONNECTED) if (GetCon(ref @as, dir) != RC_NOT_CONNECTED)
{ {
int ax2 = ax + GetDirOffsetX(dir); int ax2 = ax + GetDirOffsetX(dir);
int ay2 = ay + GetDirOffsetY(dir); int ay2 = ay + GetDirOffsetY(dir);
int ai2 = chf.cells[ax2 + ay2 * chf.width].index + GetCon(@as, dir); int ai2 = chf.cells[ax2 + ay2 * chf.width].index + GetCon(ref @as, dir);
RcCompactSpan as2 = chf.spans[ai2]; ref RcCompactSpan as2 = ref chf.spans[ai2];
ch = Math.Max(ch, as2.y); ch = Math.Max(ch, as2.y);
regs[2] = chf.spans[ai2].reg | (chf.areas[ai2] << 16); regs[2] = chf.spans[ai2].reg | (chf.areas[ai2] << 16);
} }
@ -146,12 +146,12 @@ namespace DotRecast.Recast
} }
int r = 0; int r = 0;
RcCompactSpan s = chf.spans[i]; ref RcCompactSpan s = ref chf.spans[i];
if (GetCon(s, dir) != RC_NOT_CONNECTED) if (GetCon(ref s, dir) != RC_NOT_CONNECTED)
{ {
int ax = x + GetDirOffsetX(dir); int ax = x + GetDirOffsetX(dir);
int ay = y + GetDirOffsetY(dir); int ay = y + GetDirOffsetY(dir);
int ai = chf.cells[ax + ay * chf.width].index + GetCon(s, dir); int ai = chf.cells[ax + ay * chf.width].index + GetCon(ref s, dir);
r = chf.spans[ai].reg; r = chf.spans[ai].reg;
if (area != chf.areas[ai]) if (area != chf.areas[ai])
isAreaBorder = true; isAreaBorder = true;
@ -174,11 +174,11 @@ namespace DotRecast.Recast
int ni = -1; int ni = -1;
int nx = x + GetDirOffsetX(dir); int nx = x + GetDirOffsetX(dir);
int ny = y + GetDirOffsetY(dir); int ny = y + GetDirOffsetY(dir);
RcCompactSpan s = chf.spans[i]; ref RcCompactSpan s = ref chf.spans[i];
if (GetCon(s, dir) != RC_NOT_CONNECTED) if (GetCon(ref s, dir) != RC_NOT_CONNECTED)
{ {
ref readonly RcCompactCell nc = ref chf.cells[nx + ny * chf.width]; ref RcCompactCell nc = ref chf.cells[nx + ny * chf.width];
ni = nc.index + GetCon(s, dir); ni = nc.index + GetCon(ref s, dir);
} }
if (ni == -1) if (ni == -1)
@ -753,11 +753,11 @@ namespace DotRecast.Recast
{ {
for (int x = 0; x < w; ++x) for (int x = 0; x < w; ++x)
{ {
ref readonly RcCompactCell c = ref chf.cells[x + y * w]; ref RcCompactCell c = ref chf.cells[x + y * w];
for (int i = c.index, ni = c.index + c.count; i < ni; ++i) for (int i = c.index, ni = c.index + c.count; i < ni; ++i)
{ {
int res = 0; int res = 0;
RcCompactSpan s = chf.spans[i]; ref RcCompactSpan s = ref chf.spans[i];
if (chf.spans[i].reg == 0 || (chf.spans[i].reg & RC_BORDER_REG) != 0) if (chf.spans[i].reg == 0 || (chf.spans[i].reg & RC_BORDER_REG) != 0)
{ {
flags[i] = 0; flags[i] = 0;
@ -767,11 +767,11 @@ namespace DotRecast.Recast
for (int dir = 0; dir < 4; ++dir) for (int dir = 0; dir < 4; ++dir)
{ {
int r = 0; int r = 0;
if (GetCon(s, dir) != RC_NOT_CONNECTED) if (GetCon(ref s, dir) != RC_NOT_CONNECTED)
{ {
int ax = x + GetDirOffsetX(dir); int ax = x + GetDirOffsetX(dir);
int ay = y + GetDirOffsetY(dir); int ay = y + GetDirOffsetY(dir);
int ai = chf.cells[ax + ay * w].index + GetCon(s, dir); int ai = chf.cells[ax + ay * w].index + GetCon(ref s, dir);
r = chf.spans[ai].reg; r = chf.spans[ai].reg;
} }
@ -793,7 +793,7 @@ namespace DotRecast.Recast
{ {
for (int x = 0; x < w; ++x) for (int x = 0; x < w; ++x)
{ {
ref readonly RcCompactCell c = ref chf.cells[x + y * w]; ref RcCompactCell c = ref chf.cells[x + y * w];
for (int i = c.index, ni = c.index + c.count; i < ni; ++i) for (int i = c.index, ni = c.index + c.count; i < ni; ++i)
{ {
if (flags[i] == 0 || flags[i] == 0xf) if (flags[i] == 0 || flags[i] == 0xf)

View File

@ -80,21 +80,21 @@ namespace DotRecast.Recast
for (int x = borderSize; x < w - borderSize; ++x) for (int x = borderSize; x < w - borderSize; ++x)
{ {
ref readonly RcCompactCell c = ref chf.cells[x + y * w]; ref RcCompactCell c = ref chf.cells[x + y * w];
for (int i = c.index, ni = c.index + c.count; i < ni; ++i) for (int i = c.index, ni = c.index + c.count; i < ni; ++i)
{ {
RcCompactSpan s = chf.spans[i]; ref RcCompactSpan s = ref chf.spans[i];
if (chf.areas[i] == RC_NULL_AREA) if (chf.areas[i] == RC_NULL_AREA)
continue; continue;
int sid = 0xFF; int sid = 0xFF;
// -x // -x
if (GetCon(s, 0) != RC_NOT_CONNECTED) if (GetCon(ref s, 0) != RC_NOT_CONNECTED)
{ {
int ax = x + GetDirOffsetX(0); int ax = x + GetDirOffsetX(0);
int ay = y + GetDirOffsetY(0); int ay = y + GetDirOffsetY(0);
int ai = chf.cells[ax + ay * w].index + GetCon(s, 0); int ai = chf.cells[ax + ay * w].index + GetCon(ref s, 0);
if (chf.areas[ai] != RC_NULL_AREA && srcReg[ai] != 0xff) if (chf.areas[ai] != RC_NULL_AREA && srcReg[ai] != 0xff)
sid = srcReg[ai]; sid = srcReg[ai];
} }
@ -107,11 +107,11 @@ namespace DotRecast.Recast
} }
// -y // -y
if (GetCon(s, 3) != RC_NOT_CONNECTED) if (GetCon(ref s, 3) != RC_NOT_CONNECTED)
{ {
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(s, 3); int ai = chf.cells[ax + ay * w].index + GetCon(ref s, 3);
int nr = srcReg[ai]; int nr = srcReg[ai];
if (nr != 0xff) if (nr != 0xff)
{ {
@ -165,7 +165,7 @@ namespace DotRecast.Recast
// Remap local sweep ids to region ids. // Remap local sweep ids to region ids.
for (int x = borderSize; x < w - borderSize; ++x) for (int x = borderSize; x < w - borderSize; ++x)
{ {
ref readonly RcCompactCell c = ref chf.cells[x + y * w]; ref RcCompactCell c = ref chf.cells[x + y * w];
for (int i = c.index, ni = c.index + c.count; i < ni; ++i) for (int i = c.index, ni = c.index + c.count; i < ni; ++i)
{ {
if (srcReg[i] != 0xff) if (srcReg[i] != 0xff)
@ -189,13 +189,13 @@ namespace DotRecast.Recast
{ {
for (int x = 0; x < w; ++x) for (int x = 0; x < w; ++x)
{ {
ref readonly RcCompactCell c = ref chf.cells[x + y * w]; ref RcCompactCell c = ref chf.cells[x + y * w];
lregs.Clear(); lregs.Clear();
for (int i = c.index, ni = c.index + c.count; i < ni; ++i) for (int i = c.index, ni = c.index + c.count; i < ni; ++i)
{ {
RcCompactSpan s = chf.spans[i]; ref RcCompactSpan s = ref chf.spans[i];
int ri = srcReg[i]; int ri = srcReg[i];
if (ri == 0xff) if (ri == 0xff)
continue; continue;
@ -209,11 +209,11 @@ namespace DotRecast.Recast
// Update neighbours // Update neighbours
for (int dir = 0; dir < 4; ++dir) for (int dir = 0; dir < 4; ++dir)
{ {
if (GetCon(s, dir) != RC_NOT_CONNECTED) if (GetCon(ref s, dir) != RC_NOT_CONNECTED)
{ {
int ax = x + GetDirOffsetX(dir); int ax = x + GetDirOffsetX(dir);
int ay = y + GetDirOffsetY(dir); int ay = y + GetDirOffsetY(dir);
int ai = chf.cells[ax + ay * w].index + GetCon(s, dir); int ai = chf.cells[ax + ay * w].index + GetCon(ref s, dir);
int rai = srcReg[ai]; int rai = srcReg[ai];
if (rai != 0xff && rai != ri) if (rai != 0xff && rai != ri)
AddUnique(regs[ri].neis, rai); AddUnique(regs[ri].neis, rai);
@ -475,10 +475,10 @@ namespace DotRecast.Recast
{ {
int cx = borderSize + x; int cx = borderSize + x;
int cy = borderSize + y; int cy = borderSize + y;
ref readonly RcCompactCell c = ref chf.cells[cx + cy * w]; ref RcCompactCell c = ref chf.cells[cx + cy * w];
for (int j = c.index, nj = c.index + c.count; j < nj; ++j) for (int j = c.index, nj = c.index + c.count; j < nj; ++j)
{ {
RcCompactSpan s = chf.spans[j]; ref RcCompactSpan s = ref chf.spans[j];
// Skip unassigned regions. // Skip unassigned regions.
if (srcReg[j] == 0xff) if (srcReg[j] == 0xff)
continue; continue;
@ -503,11 +503,11 @@ namespace DotRecast.Recast
char con = (char)0; char con = (char)0;
for (int dir = 0; dir < 4; ++dir) for (int dir = 0; dir < 4; ++dir)
{ {
if (GetCon(s, dir) != RC_NOT_CONNECTED) if (GetCon(ref s, dir) != RC_NOT_CONNECTED)
{ {
int ax = cx + GetDirOffsetX(dir); int ax = cx + GetDirOffsetX(dir);
int ay = cy + GetDirOffsetY(dir); int ay = cy + GetDirOffsetY(dir);
int ai = chf.cells[ax + ay * w].index + GetCon(s, dir); int ai = chf.cells[ax + ay * w].index + GetCon(ref s, dir);
int alid = srcReg[ai] != 0xff ? regs[srcReg[ai]].layerId : 0xff; int alid = srcReg[ai] != 0xff ? regs[srcReg[ai]].layerId : 0xff;
// Portal mask // Portal mask
if (chf.areas[ai] != RC_NULL_AREA && lid != alid) if (chf.areas[ai] != RC_NULL_AREA && lid != alid)
@ -515,7 +515,7 @@ namespace DotRecast.Recast
portal |= (char)(1 << dir); portal |= (char)(1 << dir);
// Update height so that it matches on both // Update height so that it matches on both
// sides of the portal. // sides of the portal.
RcCompactSpan @as = chf.spans[ai]; ref RcCompactSpan @as = ref chf.spans[ai];
if (@as.y > hmin) if (@as.y > hmin)
layer.heights[idx] = Math.Max(layer.heights[idx], (char)(@as.y - hmin)); layer.heights[idx] = Math.Max(layer.heights[idx], (char)(@as.y - hmin));
} }

View File

@ -1131,10 +1131,10 @@ namespace DotRecast.Recast
continue; continue;
} }
ref readonly RcCompactCell c = ref chf.cells[(ax + bs) + (az + bs) * chf.width]; ref RcCompactCell c = ref chf.cells[(ax + bs) + (az + bs) * chf.width];
for (int i = c.index, ni = c.index + c.count; i < ni && dmin > 0; ++i) for (int i = c.index, ni = c.index + c.count; i < ni && dmin > 0; ++i)
{ {
RcCompactSpan s = chf.spans[i]; ref RcCompactSpan s = ref chf.spans[i];
int d = Math.Abs(ay - s.y); int d = Math.Abs(ay - s.y);
if (d < dmin) if (d < dmin)
{ {
@ -1210,12 +1210,12 @@ namespace DotRecast.Recast
dirs[3] = dirs[directDir]; dirs[3] = dirs[directDir];
dirs[directDir] = tmp; dirs[directDir] = tmp;
RcCompactSpan cs = chf.spans[ci]; ref RcCompactSpan cs = ref chf.spans[ci];
for (int i = 0; i < 4; ++i) for (int i = 0; i < 4; ++i)
{ {
int dir = dirs[i]; int dir = dirs[i];
if (GetCon(cs, dir) == RC_NOT_CONNECTED) if (GetCon(ref cs, dir) == RC_NOT_CONNECTED)
{ {
continue; continue;
} }
@ -1239,7 +1239,7 @@ namespace DotRecast.Recast
array.Add(newX); array.Add(newX);
array.Add(newY); array.Add(newY);
array.Add(chf.cells[(newX + bs) + (newY + bs) * chf.width].index + GetCon(cs, dir)); array.Add(chf.cells[(newX + bs) + (newY + bs) * chf.width].index + GetCon(ref cs, dir));
} }
tmp = dirs[3]; tmp = dirs[3];
@ -1253,7 +1253,7 @@ namespace DotRecast.Recast
array.Add(cy + bs); array.Add(cy + bs);
array.Add(ci); array.Add(ci);
Array.Fill(hp.data, RC_UNSET_HEIGHT, 0, (hp.width * hp.height) - (0)); Array.Fill(hp.data, RC_UNSET_HEIGHT, 0, (hp.width * hp.height) - (0));
RcCompactSpan cs2 = chf.spans[ci]; ref RcCompactSpan cs2 = ref chf.spans[ci];
hp.data[cx - hp.xmin + (cy - hp.ymin) * hp.width] = cs2.y; hp.data[cx - hp.xmin + (cy - hp.ymin) * hp.width] = cs2.y;
} }
@ -1290,10 +1290,10 @@ namespace DotRecast.Recast
for (int hx = 0; hx < hp.width; hx++) for (int hx = 0; hx < hp.width; hx++)
{ {
int x = hp.xmin + hx + bs; int x = hp.xmin + hx + bs;
ref readonly RcCompactCell c = ref chf.cells[x + y * chf.width]; ref RcCompactCell c = ref chf.cells[x + y * chf.width];
for (int i = c.index, ni = c.index + c.count; i < ni; ++i) for (int i = c.index, ni = c.index + c.count; i < ni; ++i)
{ {
RcCompactSpan s = chf.spans[i]; ref RcCompactSpan s = ref chf.spans[i];
if (s.reg == region) if (s.reg == region)
{ {
// Store height // Store height
@ -1304,12 +1304,12 @@ namespace DotRecast.Recast
bool border = false; bool border = false;
for (int dir = 0; dir < 4; ++dir) for (int dir = 0; dir < 4; ++dir)
{ {
if (GetCon(s, dir) != RC_NOT_CONNECTED) if (GetCon(ref s, dir) != RC_NOT_CONNECTED)
{ {
int ax = x + GetDirOffsetX(dir); int ax = x + GetDirOffsetX(dir);
int ay = y + GetDirOffsetY(dir); int ay = y + GetDirOffsetY(dir);
int ai = chf.cells[ax + ay * chf.width].index + GetCon(s, dir); int ai = chf.cells[ax + ay * chf.width].index + GetCon(ref s, dir);
RcCompactSpan @as = chf.spans[ai]; ref RcCompactSpan @as = ref chf.spans[ai];
if (@as.reg != region) if (@as.reg != region)
{ {
border = true; border = true;
@ -1355,10 +1355,10 @@ namespace DotRecast.Recast
queue = queue.GetRange(RETRACT_SIZE * 3, queue.Count - (RETRACT_SIZE * 3)); queue = queue.GetRange(RETRACT_SIZE * 3, queue.Count - (RETRACT_SIZE * 3));
} }
RcCompactSpan cs = chf.spans[ci]; ref RcCompactSpan cs = ref chf.spans[ci];
for (int dir = 0; dir < 4; ++dir) for (int dir = 0; dir < 4; ++dir)
{ {
if (GetCon(cs, dir) == RC_NOT_CONNECTED) if (GetCon(ref cs, dir) == RC_NOT_CONNECTED)
{ {
continue; continue;
} }
@ -1378,8 +1378,8 @@ namespace DotRecast.Recast
continue; continue;
} }
int ai = chf.cells[ax + ay * chf.width].index + GetCon(cs, dir); int ai = chf.cells[ax + ay * chf.width].index + GetCon(ref cs, dir);
RcCompactSpan @as = chf.spans[ai]; ref RcCompactSpan @as = ref chf.spans[ai];
hp.data[hx + hy * hp.width] = @as.y; hp.data[hx + hy * hp.width] = @as.y;
Push3(queue, ax, ay, ai); Push3(queue, ax, ay, ai);

View File

@ -49,20 +49,20 @@ namespace DotRecast.Recast
{ {
for (int x = 0; x < w; ++x) for (int x = 0; x < w; ++x)
{ {
ref readonly RcCompactCell c = ref chf.cells[x + y * w]; ref RcCompactCell c = ref chf.cells[x + y * w];
for (int i = c.index, ni = c.index + c.count; i < ni; ++i) for (int i = c.index, ni = c.index + c.count; i < ni; ++i)
{ {
RcCompactSpan s = chf.spans[i]; ref RcCompactSpan s = ref chf.spans[i];
int area = chf.areas[i]; int area = chf.areas[i];
int nc = 0; int nc = 0;
for (int dir = 0; dir < 4; ++dir) for (int dir = 0; dir < 4; ++dir)
{ {
if (GetCon(s, dir) != RC_NOT_CONNECTED) if (GetCon(ref s, dir) != RC_NOT_CONNECTED)
{ {
int ax = x + GetDirOffsetX(dir); int ax = x + GetDirOffsetX(dir);
int ay = y + GetDirOffsetY(dir); int ay = y + GetDirOffsetY(dir);
int ai = chf.cells[ax + ay * w].index + GetCon(s, dir); int ai = chf.cells[ax + ay * w].index + GetCon(ref s, dir);
if (area == chf.areas[ai]) if (area == chf.areas[ai])
{ {
nc++; nc++;
@ -83,29 +83,29 @@ namespace DotRecast.Recast
{ {
for (int x = 0; x < w; ++x) for (int x = 0; x < w; ++x)
{ {
ref readonly RcCompactCell c = ref chf.cells[x + y * w]; ref RcCompactCell c = ref chf.cells[x + y * w];
for (int i = c.index, ni = c.index + c.count; i < ni; ++i) for (int i = c.index, ni = c.index + c.count; i < ni; ++i)
{ {
RcCompactSpan s = chf.spans[i]; ref RcCompactSpan s = ref chf.spans[i];
if (GetCon(s, 0) != RC_NOT_CONNECTED) if (GetCon(ref s, 0) != RC_NOT_CONNECTED)
{ {
// (-1,0) // (-1,0)
int ax = x + GetDirOffsetX(0); int ax = x + GetDirOffsetX(0);
int ay = y + GetDirOffsetY(0); int ay = y + GetDirOffsetY(0);
int ai = chf.cells[ax + ay * w].index + GetCon(s, 0); int ai = chf.cells[ax + ay * w].index + GetCon(ref s, 0);
RcCompactSpan @as = chf.spans[ai]; ref RcCompactSpan @as = ref chf.spans[ai];
if (src[ai] + 2 < src[i]) if (src[ai] + 2 < src[i])
{ {
src[i] = src[ai] + 2; src[i] = src[ai] + 2;
} }
// (-1,-1) // (-1,-1)
if (GetCon(@as, 3) != RC_NOT_CONNECTED) if (GetCon(ref @as, 3) != RC_NOT_CONNECTED)
{ {
int aax = ax + GetDirOffsetX(3); int aax = ax + GetDirOffsetX(3);
int aay = ay + GetDirOffsetY(3); int aay = ay + GetDirOffsetY(3);
int aai = chf.cells[aax + aay * w].index + GetCon(@as, 3); int aai = chf.cells[aax + aay * w].index + GetCon(ref @as, 3);
if (src[aai] + 3 < src[i]) if (src[aai] + 3 < src[i])
{ {
src[i] = src[aai] + 3; src[i] = src[aai] + 3;
@ -113,24 +113,24 @@ namespace DotRecast.Recast
} }
} }
if (GetCon(s, 3) != RC_NOT_CONNECTED) if (GetCon(ref s, 3) != RC_NOT_CONNECTED)
{ {
// (0,-1) // (0,-1)
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(s, 3); int ai = chf.cells[ax + ay * w].index + GetCon(ref s, 3);
RcCompactSpan @as = chf.spans[ai]; ref RcCompactSpan @as = ref chf.spans[ai];
if (src[ai] + 2 < src[i]) if (src[ai] + 2 < src[i])
{ {
src[i] = src[ai] + 2; src[i] = src[ai] + 2;
} }
// (1,-1) // (1,-1)
if (GetCon(@as, 2) != RC_NOT_CONNECTED) if (GetCon(ref @as, 2) != RC_NOT_CONNECTED)
{ {
int aax = ax + GetDirOffsetX(2); int aax = ax + GetDirOffsetX(2);
int aay = ay + GetDirOffsetY(2); int aay = ay + GetDirOffsetY(2);
int aai = chf.cells[aax + aay * w].index + GetCon(@as, 2); int aai = chf.cells[aax + aay * w].index + GetCon(ref @as, 2);
if (src[aai] + 3 < src[i]) if (src[aai] + 3 < src[i])
{ {
src[i] = src[aai] + 3; src[i] = src[aai] + 3;
@ -146,29 +146,29 @@ namespace DotRecast.Recast
{ {
for (int x = w - 1; x >= 0; --x) for (int x = w - 1; x >= 0; --x)
{ {
ref readonly RcCompactCell c = ref chf.cells[x + y * w]; ref RcCompactCell c = ref chf.cells[x + y * w];
for (int i = c.index, ni = c.index + c.count; i < ni; ++i) for (int i = c.index, ni = c.index + c.count; i < ni; ++i)
{ {
RcCompactSpan s = chf.spans[i]; ref RcCompactSpan s = ref chf.spans[i];
if (GetCon(s, 2) != RC_NOT_CONNECTED) if (GetCon(ref s, 2) != RC_NOT_CONNECTED)
{ {
// (1,0) // (1,0)
int ax = x + GetDirOffsetX(2); int ax = x + GetDirOffsetX(2);
int ay = y + GetDirOffsetY(2); int ay = y + GetDirOffsetY(2);
int ai = chf.cells[ax + ay * w].index + GetCon(s, 2); int ai = chf.cells[ax + ay * w].index + GetCon(ref s, 2);
RcCompactSpan @as = chf.spans[ai]; ref RcCompactSpan @as = ref chf.spans[ai];
if (src[ai] + 2 < src[i]) if (src[ai] + 2 < src[i])
{ {
src[i] = src[ai] + 2; src[i] = src[ai] + 2;
} }
// (1,1) // (1,1)
if (GetCon(@as, 1) != RC_NOT_CONNECTED) if (GetCon(ref @as, 1) != RC_NOT_CONNECTED)
{ {
int aax = ax + GetDirOffsetX(1); int aax = ax + GetDirOffsetX(1);
int aay = ay + GetDirOffsetY(1); int aay = ay + GetDirOffsetY(1);
int aai = chf.cells[aax + aay * w].index + GetCon(@as, 1); int aai = chf.cells[aax + aay * w].index + GetCon(ref @as, 1);
if (src[aai] + 3 < src[i]) if (src[aai] + 3 < src[i])
{ {
src[i] = src[aai] + 3; src[i] = src[aai] + 3;
@ -176,24 +176,24 @@ namespace DotRecast.Recast
} }
} }
if (GetCon(s, 1) != RC_NOT_CONNECTED) if (GetCon(ref s, 1) != RC_NOT_CONNECTED)
{ {
// (0,1) // (0,1)
int ax = x + GetDirOffsetX(1); int ax = x + GetDirOffsetX(1);
int ay = y + GetDirOffsetY(1); int ay = y + GetDirOffsetY(1);
int ai = chf.cells[ax + ay * w].index + GetCon(s, 1); int ai = chf.cells[ax + ay * w].index + GetCon(ref s, 1);
RcCompactSpan @as = chf.spans[ai]; ref RcCompactSpan @as = ref chf.spans[ai];
if (src[ai] + 2 < src[i]) if (src[ai] + 2 < src[i])
{ {
src[i] = src[ai] + 2; src[i] = src[ai] + 2;
} }
// (-1,1) // (-1,1)
if (GetCon(@as, 0) != RC_NOT_CONNECTED) if (GetCon(ref @as, 0) != RC_NOT_CONNECTED)
{ {
int aax = ax + GetDirOffsetX(0); int aax = ax + GetDirOffsetX(0);
int aay = ay + GetDirOffsetY(0); int aay = ay + GetDirOffsetY(0);
int aai = chf.cells[aax + aay * w].index + GetCon(@as, 0); int aai = chf.cells[aax + aay * w].index + GetCon(ref @as, 0);
if (src[aai] + 3 < src[i]) if (src[aai] + 3 < src[i])
{ {
src[i] = src[aai] + 3; src[i] = src[aai] + 3;
@ -225,10 +225,10 @@ namespace DotRecast.Recast
{ {
for (int x = 0; x < w; ++x) for (int x = 0; x < w; ++x)
{ {
ref readonly RcCompactCell c = ref chf.cells[x + y * w]; ref RcCompactCell c = ref chf.cells[x + y * w];
for (int i = c.index, ni = c.index + c.count; i < ni; ++i) for (int i = c.index, ni = c.index + c.count; i < ni; ++i)
{ {
RcCompactSpan s = chf.spans[i]; ref RcCompactSpan s = ref chf.spans[i];
int cd = src[i]; int cd = src[i];
if (cd <= thr) if (cd <= thr)
{ {
@ -239,20 +239,20 @@ namespace DotRecast.Recast
int d = cd; int d = cd;
for (int dir = 0; dir < 4; ++dir) for (int dir = 0; dir < 4; ++dir)
{ {
if (GetCon(s, dir) != RC_NOT_CONNECTED) if (GetCon(ref s, dir) != RC_NOT_CONNECTED)
{ {
int ax = x + GetDirOffsetX(dir); int ax = x + GetDirOffsetX(dir);
int ay = y + GetDirOffsetY(dir); int ay = y + GetDirOffsetY(dir);
int ai = chf.cells[ax + ay * w].index + GetCon(s, dir); int ai = chf.cells[ax + ay * w].index + GetCon(ref s, dir);
d += src[ai]; d += src[ai];
RcCompactSpan @as = chf.spans[ai]; ref RcCompactSpan @as = ref chf.spans[ai];
int dir2 = (dir + 1) & 0x3; int dir2 = (dir + 1) & 0x3;
if (GetCon(@as, dir2) != RC_NOT_CONNECTED) if (GetCon(ref @as, dir2) != RC_NOT_CONNECTED)
{ {
int ax2 = ax + GetDirOffsetX(dir2); int ax2 = ax + GetDirOffsetX(dir2);
int ay2 = ay + GetDirOffsetY(dir2); int ay2 = ay + GetDirOffsetY(dir2);
int ai2 = chf.cells[ax2 + ay2 * w].index + GetCon(@as, dir2); int ai2 = chf.cells[ax2 + ay2 * w].index + GetCon(ref @as, dir2);
d += src[ai2]; d += src[ai2];
} }
else else
@ -304,18 +304,18 @@ namespace DotRecast.Recast
stack.RemoveAt(stack.Count - 1); stack.RemoveAt(stack.Count - 1);
RcCompactSpan cs = chf.spans[ci]; ref RcCompactSpan cs = ref chf.spans[ci];
// Check if any of the neighbours already have a valid region set. // Check if any of the neighbours already have a valid region set.
int ar = 0; int ar = 0;
for (int dir = 0; dir < 4; ++dir) for (int dir = 0; dir < 4; ++dir)
{ {
// 8 connected // 8 connected
if (GetCon(cs, dir) != RC_NOT_CONNECTED) if (GetCon(ref cs, dir) != RC_NOT_CONNECTED)
{ {
int ax = cx + GetDirOffsetX(dir); int ax = cx + GetDirOffsetX(dir);
int ay = cy + GetDirOffsetY(dir); int ay = cy + GetDirOffsetY(dir);
int ai = chf.cells[ax + ay * w].index + GetCon(cs, dir); int ai = chf.cells[ax + ay * w].index + GetCon(ref cs, dir);
if (chf.areas[ai] != area) if (chf.areas[ai] != area)
{ {
continue; continue;
@ -333,14 +333,14 @@ namespace DotRecast.Recast
break; break;
} }
RcCompactSpan @as = chf.spans[ai]; ref RcCompactSpan @as = ref chf.spans[ai];
int dir2 = (dir + 1) & 0x3; int dir2 = (dir + 1) & 0x3;
if (GetCon(@as, dir2) != RC_NOT_CONNECTED) if (GetCon(ref @as, dir2) != RC_NOT_CONNECTED)
{ {
int ax2 = ax + GetDirOffsetX(dir2); int ax2 = ax + GetDirOffsetX(dir2);
int ay2 = ay + GetDirOffsetY(dir2); int ay2 = ay + GetDirOffsetY(dir2);
int ai2 = chf.cells[ax2 + ay2 * w].index + GetCon(@as, dir2); int ai2 = chf.cells[ax2 + ay2 * w].index + GetCon(ref @as, dir2);
if (chf.areas[ai2] != area) if (chf.areas[ai2] != area)
{ {
continue; continue;
@ -367,11 +367,11 @@ namespace DotRecast.Recast
// Expand neighbours. // Expand neighbours.
for (int dir = 0; dir < 4; ++dir) for (int dir = 0; dir < 4; ++dir)
{ {
if (GetCon(cs, dir) != RC_NOT_CONNECTED) if (GetCon(ref cs, dir) != RC_NOT_CONNECTED)
{ {
int ax = cx + GetDirOffsetX(dir); int ax = cx + GetDirOffsetX(dir);
int ay = cy + GetDirOffsetY(dir); int ay = cy + GetDirOffsetY(dir);
int ai = chf.cells[ax + ay * w].index + GetCon(cs, dir); int ai = chf.cells[ax + ay * w].index + GetCon(ref cs, dir);
if (chf.areas[ai] != area) if (chf.areas[ai] != area)
{ {
continue; continue;
@ -406,7 +406,7 @@ namespace DotRecast.Recast
{ {
for (int x = 0; x < w; ++x) for (int x = 0; x < w; ++x)
{ {
ref readonly RcCompactCell c = ref chf.cells[x + y * w]; ref RcCompactCell c = ref chf.cells[x + y * w];
for (int i = c.index, ni = c.index + c.count; i < ni; ++i) for (int i = c.index, ni = c.index + c.count; i < ni; ++i)
{ {
if (chf.dist[i] >= level && srcReg[i] == 0 && chf.areas[i] != RC_NULL_AREA) if (chf.dist[i] >= level && srcReg[i] == 0 && chf.areas[i] != RC_NULL_AREA)
@ -453,17 +453,17 @@ namespace DotRecast.Recast
int r = srcReg[i]; int r = srcReg[i];
int d2 = 0xffff; int d2 = 0xffff;
int area = chf.areas[i]; int area = chf.areas[i];
RcCompactSpan s = chf.spans[i]; ref RcCompactSpan s = ref chf.spans[i];
for (int dir = 0; dir < 4; ++dir) for (int dir = 0; dir < 4; ++dir)
{ {
if (GetCon(s, dir) == RC_NOT_CONNECTED) if (GetCon(ref s, dir) == RC_NOT_CONNECTED)
{ {
continue; continue;
} }
int ax = x + GetDirOffsetX(dir); int ax = x + GetDirOffsetX(dir);
int ay = y + GetDirOffsetY(dir); int ay = y + GetDirOffsetY(dir);
int ai = chf.cells[ax + ay * w].index + GetCon(s, dir); int ai = chf.cells[ax + ay * w].index + GetCon(ref s, dir);
if (chf.areas[ai] != area) if (chf.areas[ai] != area)
{ {
continue; continue;
@ -535,7 +535,7 @@ namespace DotRecast.Recast
{ {
for (int x = 0; x < w; ++x) for (int x = 0; x < w; ++x)
{ {
ref readonly RcCompactCell c = ref chf.cells[x + y * w]; ref RcCompactCell c = ref chf.cells[x + y * w];
for (int i = c.index, ni = c.index + c.count; i < ni; ++i) for (int i = c.index, ni = c.index + c.count; i < ni; ++i)
{ {
if (chf.areas[i] == RC_NULL_AREA || srcReg[i] != 0) if (chf.areas[i] == RC_NULL_AREA || srcReg[i] != 0)
@ -739,13 +739,13 @@ namespace DotRecast.Recast
private static bool IsSolidEdge(RcCompactHeightfield chf, int[] srcReg, int x, int y, int i, int dir) private static bool IsSolidEdge(RcCompactHeightfield chf, int[] srcReg, int x, int y, int i, int dir)
{ {
RcCompactSpan s = chf.spans[i]; ref RcCompactSpan s = ref chf.spans[i];
int r = 0; int r = 0;
if (GetCon(s, dir) != RC_NOT_CONNECTED) if (GetCon(ref s, dir) != RC_NOT_CONNECTED)
{ {
int ax = x + GetDirOffsetX(dir); int ax = x + GetDirOffsetX(dir);
int ay = y + GetDirOffsetY(dir); int ay = y + GetDirOffsetY(dir);
int ai = chf.cells[ax + ay * chf.width].index + GetCon(s, dir); int ai = chf.cells[ax + ay * chf.width].index + GetCon(ref s, dir);
r = srcReg[ai]; r = srcReg[ai];
} }
@ -763,13 +763,13 @@ namespace DotRecast.Recast
int startDir = dir; int startDir = dir;
int starti = i; int starti = i;
RcCompactSpan ss = chf.spans[i]; ref RcCompactSpan ss = ref chf.spans[i];
int curReg = 0; int curReg = 0;
if (GetCon(ss, dir) != RC_NOT_CONNECTED) if (GetCon(ref ss, dir) != RC_NOT_CONNECTED)
{ {
int ax = x + GetDirOffsetX(dir); int ax = x + GetDirOffsetX(dir);
int ay = y + GetDirOffsetY(dir); int ay = y + GetDirOffsetY(dir);
int ai = chf.cells[ax + ay * chf.width].index + GetCon(ss, dir); int ai = chf.cells[ax + ay * chf.width].index + GetCon(ref ss, dir);
curReg = srcReg[ai]; curReg = srcReg[ai];
} }
@ -778,17 +778,17 @@ namespace DotRecast.Recast
int iter = 0; int iter = 0;
while (++iter < 40000) while (++iter < 40000)
{ {
RcCompactSpan s = chf.spans[i]; ref RcCompactSpan s = ref chf.spans[i];
if (IsSolidEdge(chf, srcReg, x, y, i, dir)) if (IsSolidEdge(chf, srcReg, x, y, i, dir))
{ {
// Choose the edge corner // Choose the edge corner
int r = 0; int r = 0;
if (GetCon(s, dir) != RC_NOT_CONNECTED) if (GetCon(ref s, dir) != RC_NOT_CONNECTED)
{ {
int ax = x + GetDirOffsetX(dir); int ax = x + GetDirOffsetX(dir);
int ay = y + GetDirOffsetY(dir); int ay = y + GetDirOffsetY(dir);
int ai = chf.cells[ax + ay * chf.width].index + GetCon(s, dir); int ai = chf.cells[ax + ay * chf.width].index + GetCon(ref s, dir);
r = srcReg[ai]; r = srcReg[ai];
} }
@ -805,10 +805,10 @@ namespace DotRecast.Recast
int ni = -1; int ni = -1;
int nx = x + GetDirOffsetX(dir); int nx = x + GetDirOffsetX(dir);
int ny = y + GetDirOffsetY(dir); int ny = y + GetDirOffsetY(dir);
if (GetCon(s, dir) != RC_NOT_CONNECTED) if (GetCon(ref s, dir) != RC_NOT_CONNECTED)
{ {
ref readonly RcCompactCell nc = ref chf.cells[nx + ny * chf.width]; ref RcCompactCell nc = ref chf.cells[nx + ny * chf.width];
ni = nc.index + GetCon(s, dir); ni = nc.index + GetCon(ref s, dir);
} }
if (ni == -1) if (ni == -1)
@ -867,7 +867,7 @@ namespace DotRecast.Recast
{ {
for (int x = 0; x < w; ++x) for (int x = 0; x < w; ++x)
{ {
ref readonly RcCompactCell c = ref chf.cells[x + y * w]; ref RcCompactCell c = ref chf.cells[x + y * w];
for (int i = c.index, ni = c.index + c.count; i < ni; ++i) for (int i = c.index, ni = c.index + c.count; i < ni; ++i)
{ {
int r = srcReg[i]; int r = srcReg[i];
@ -1190,13 +1190,13 @@ namespace DotRecast.Recast
{ {
for (int x = 0; x < w; ++x) for (int x = 0; x < w; ++x)
{ {
ref readonly RcCompactCell c = ref chf.cells[x + y * w]; ref RcCompactCell c = ref chf.cells[x + y * w];
lregs.Clear(); lregs.Clear();
for (int i = c.index, ni = c.index + c.count; i < ni; ++i) for (int i = c.index, ni = c.index + c.count; i < ni; ++i)
{ {
RcCompactSpan s = chf.spans[i]; ref RcCompactSpan s = ref chf.spans[i];
int ri = srcReg[i]; int ri = srcReg[i];
if (ri == 0 || ri >= nreg) if (ri == 0 || ri >= nreg)
{ {
@ -1215,11 +1215,11 @@ namespace DotRecast.Recast
// Update neighbours // Update neighbours
for (int dir = 0; dir < 4; ++dir) for (int dir = 0; dir < 4; ++dir)
{ {
if (GetCon(s, dir) != RC_NOT_CONNECTED) if (GetCon(ref s, dir) != RC_NOT_CONNECTED)
{ {
int ax = x + GetDirOffsetX(dir); int ax = x + GetDirOffsetX(dir);
int ay = y + GetDirOffsetY(dir); int ay = y + GetDirOffsetY(dir);
int ai = chf.cells[ax + ay * w].index + GetCon(s, dir); int ai = chf.cells[ax + ay * w].index + GetCon(ref s, dir);
int rai = srcReg[ai]; int rai = srcReg[ai];
if (rai > 0 && rai < nreg && rai != ri) if (rai > 0 && rai < nreg && rai != ri)
{ {
@ -1445,7 +1445,7 @@ namespace DotRecast.Recast
{ {
for (int x = minx; x < maxx; ++x) for (int x = minx; x < maxx; ++x)
{ {
ref readonly RcCompactCell c = ref chf.cells[x + y * w]; ref RcCompactCell c = ref chf.cells[x + y * w];
for (int i = c.index, ni = c.index + c.count; i < ni; ++i) for (int i = c.index, ni = c.index + c.count; i < ni; ++i)
{ {
if (chf.areas[i] != RC_NULL_AREA) if (chf.areas[i] != RC_NULL_AREA)
@ -1531,11 +1531,11 @@ namespace DotRecast.Recast
for (int x = borderSize; x < w - borderSize; ++x) for (int x = borderSize; x < w - borderSize; ++x)
{ {
ref readonly RcCompactCell c = ref chf.cells[x + y * w]; ref RcCompactCell c = ref chf.cells[x + y * w];
for (int i = c.index, ni = c.index + c.count; i < ni; ++i) for (int i = c.index, ni = c.index + c.count; i < ni; ++i)
{ {
RcCompactSpan s = chf.spans[i]; ref RcCompactSpan s = ref chf.spans[i];
if (chf.areas[i] == RC_NULL_AREA) if (chf.areas[i] == RC_NULL_AREA)
{ {
continue; continue;
@ -1543,11 +1543,11 @@ namespace DotRecast.Recast
// -x // -x
int previd = 0; int previd = 0;
if (GetCon(s, 0) != RC_NOT_CONNECTED) if (GetCon(ref s, 0) != RC_NOT_CONNECTED)
{ {
int ax = x + GetDirOffsetX(0); int ax = x + GetDirOffsetX(0);
int ay = y + GetDirOffsetY(0); int ay = y + GetDirOffsetY(0);
int ai = chf.cells[ax + ay * w].index + GetCon(s, 0); int ai = chf.cells[ax + ay * w].index + GetCon(ref s, 0);
if ((srcReg[ai] & RC_BORDER_REG) == 0 && chf.areas[i] == chf.areas[ai]) if ((srcReg[ai] & RC_BORDER_REG) == 0 && chf.areas[i] == chf.areas[ai])
{ {
previd = srcReg[ai]; previd = srcReg[ai];
@ -1563,11 +1563,11 @@ namespace DotRecast.Recast
} }
// -y // -y
if (GetCon(s, 3) != RC_NOT_CONNECTED) if (GetCon(ref s, 3) != RC_NOT_CONNECTED)
{ {
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(s, 3); int ai = chf.cells[ax + ay * w].index + GetCon(ref s, 3);
if (srcReg[ai] != 0 && (srcReg[ai] & RC_BORDER_REG) == 0 && chf.areas[i] == chf.areas[ai]) if (srcReg[ai] != 0 && (srcReg[ai] & RC_BORDER_REG) == 0 && chf.areas[i] == chf.areas[ai])
{ {
int nr = srcReg[ai]; int nr = srcReg[ai];
@ -1609,7 +1609,7 @@ namespace DotRecast.Recast
// Remap IDs // Remap IDs
for (int x = borderSize; x < w - borderSize; ++x) for (int x = borderSize; x < w - borderSize; ++x)
{ {
ref readonly RcCompactCell c = ref chf.cells[x + y * w]; ref RcCompactCell c = ref chf.cells[x + y * w];
for (int i = c.index, ni = c.index + c.count; i < ni; ++i) for (int i = c.index, ni = c.index + c.count; i < ni; ++i)
{ {
@ -1632,7 +1632,10 @@ namespace DotRecast.Recast
// Store the result out. // Store the result out.
for (int i = 0; i < chf.spanCount; ++i) for (int i = 0; i < chf.spanCount; ++i)
{ {
chf.spans[i].reg = srcReg[i]; chf.spans[i] = RcCompactSpanBuilder
.NewBuilder(ref chf.spans[i])
.WithReg(srcReg[i])
.Build();
} }
} }
@ -1774,7 +1777,10 @@ namespace DotRecast.Recast
// Write the result out. // Write the result out.
for (int i = 0; i < chf.spanCount; ++i) for (int i = 0; i < chf.spanCount; ++i)
{ {
chf.spans[i].reg = srcReg[i]; chf.spans[i] = RcCompactSpanBuilder
.NewBuilder(ref chf.spans[i])
.WithReg(srcReg[i])
.Build();
} }
} }
@ -1831,11 +1837,11 @@ namespace DotRecast.Recast
for (int x = borderSize; x < w - borderSize; ++x) for (int x = borderSize; x < w - borderSize; ++x)
{ {
ref readonly RcCompactCell c = ref chf.cells[x + y * w]; ref RcCompactCell c = ref chf.cells[x + y * w];
for (int i = c.index, ni = c.index + c.count; i < ni; ++i) for (int i = c.index, ni = c.index + c.count; i < ni; ++i)
{ {
RcCompactSpan s = chf.spans[i]; ref RcCompactSpan s = ref chf.spans[i];
if (chf.areas[i] == RC_NULL_AREA) if (chf.areas[i] == RC_NULL_AREA)
{ {
continue; continue;
@ -1843,11 +1849,11 @@ namespace DotRecast.Recast
// -x // -x
int previd = 0; int previd = 0;
if (GetCon(s, 0) != RC_NOT_CONNECTED) if (GetCon(ref s, 0) != RC_NOT_CONNECTED)
{ {
int ax = x + GetDirOffsetX(0); int ax = x + GetDirOffsetX(0);
int ay = y + GetDirOffsetY(0); int ay = y + GetDirOffsetY(0);
int ai = chf.cells[ax + ay * w].index + GetCon(s, 0); int ai = chf.cells[ax + ay * w].index + GetCon(ref s, 0);
if ((srcReg[ai] & RC_BORDER_REG) == 0 && chf.areas[i] == chf.areas[ai]) if ((srcReg[ai] & RC_BORDER_REG) == 0 && chf.areas[i] == chf.areas[ai])
{ {
previd = srcReg[ai]; previd = srcReg[ai];
@ -1863,11 +1869,11 @@ namespace DotRecast.Recast
} }
// -y // -y
if (GetCon(s, 3) != RC_NOT_CONNECTED) if (GetCon(ref s, 3) != RC_NOT_CONNECTED)
{ {
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(s, 3); int ai = chf.cells[ax + ay * w].index + GetCon(ref s, 3);
if (srcReg[ai] != 0 && (srcReg[ai] & RC_BORDER_REG) == 0 && chf.areas[i] == chf.areas[ai]) if (srcReg[ai] != 0 && (srcReg[ai] & RC_BORDER_REG) == 0 && chf.areas[i] == chf.areas[ai])
{ {
int nr = srcReg[ai]; int nr = srcReg[ai];
@ -1909,7 +1915,7 @@ namespace DotRecast.Recast
// Remap IDs // Remap IDs
for (int x = borderSize; x < w - borderSize; ++x) for (int x = borderSize; x < w - borderSize; ++x)
{ {
ref readonly RcCompactCell c = ref chf.cells[x + y * w]; ref RcCompactCell c = ref chf.cells[x + y * w];
for (int i = c.index, ni = c.index + c.count; i < ni; ++i) for (int i = c.index, ni = c.index + c.count; i < ni; ++i)
{ {
@ -1932,7 +1938,10 @@ namespace DotRecast.Recast
// Store the result out. // Store the result out.
for (int i = 0; i < chf.spanCount; ++i) for (int i = 0; i < chf.spanCount; ++i)
{ {
chf.spans[i].reg = srcReg[i]; chf.spans[i] = RcCompactSpanBuilder
.NewBuilder(ref chf.spans[i])
.WithReg(srcReg[i])
.Build();
} }
} }
} }