refactor: 2 step loop -> 1 step loop

This commit is contained in:
ikpil 2024-01-10 13:47:42 +09:00
parent 85c3cfdcf6
commit 278fb6cc1b
1 changed files with 34 additions and 37 deletions

View File

@ -37,7 +37,6 @@ namespace DotRecast.Recast
/// @name Compact Heightfield Functions /// @name Compact Heightfield Functions
/// @see rcCompactHeightfield /// @see rcCompactHeightfield
/// @{ /// @{
/// Builds a compact heightfield representing open space, from a heightfield representing solid space. /// Builds a compact heightfield representing open space, from a heightfield representing solid space.
/// ///
/// This is just the beginning of the process of fully building a compact heightfield. /// This is just the beginning of the process of fully building a compact heightfield.
@ -61,27 +60,27 @@ namespace DotRecast.Recast
{ {
using var timer = context.ScopedTimer(RcTimerLabel.RC_TIMER_BUILD_COMPACTHEIGHTFIELD); using var timer = context.ScopedTimer(RcTimerLabel.RC_TIMER_BUILD_COMPACTHEIGHTFIELD);
RcCompactHeightfield chf = new RcCompactHeightfield(); int xSize = heightfield.width;
int w = heightfield.width; int zSize = heightfield.height;
int h = heightfield.height;
int spanCount = GetHeightFieldSpanCount(context, heightfield); int spanCount = GetHeightFieldSpanCount(context, heightfield);
// Fill in header. // Fill in header.
chf.width = w; RcCompactHeightfield compactHeightfield = new RcCompactHeightfield();
chf.height = h; compactHeightfield.width = xSize;
chf.borderSize = heightfield.borderSize; compactHeightfield.height = zSize;
chf.spanCount = spanCount; compactHeightfield.borderSize = heightfield.borderSize;
chf.walkableHeight = walkableHeight; compactHeightfield.spanCount = spanCount;
chf.walkableClimb = walkableClimb; compactHeightfield.walkableHeight = walkableHeight;
chf.maxRegions = 0; compactHeightfield.walkableClimb = walkableClimb;
chf.bmin = heightfield.bmin; compactHeightfield.maxRegions = 0;
chf.bmax = heightfield.bmax; compactHeightfield.bmin = heightfield.bmin;
chf.bmax.Y += walkableHeight * heightfield.ch; compactHeightfield.bmax = heightfield.bmax;
chf.cs = heightfield.cs; compactHeightfield.bmax.Y += walkableHeight * heightfield.ch;
chf.ch = heightfield.ch; compactHeightfield.cs = heightfield.cs;
chf.cells = new RcCompactCell[w * h]; compactHeightfield.ch = heightfield.ch;
compactHeightfield.cells = new RcCompactCell[xSize * zSize];
//chf.spans = new RcCompactSpan[spanCount]; //chf.spans = new RcCompactSpan[spanCount];
chf.areas = new int[spanCount]; compactHeightfield.areas = new int[spanCount];
var tempSpans = Enumerable var tempSpans = Enumerable
.Range(0, spanCount) .Range(0, spanCount)
@ -90,11 +89,11 @@ namespace DotRecast.Recast
// Fill in cells and spans. // Fill in cells and spans.
int idx = 0; int idx = 0;
for (int y = 0; y < h; ++y) for (int y = 0; y < zSize; ++y)
{ {
for (int x = 0; x < w; ++x) for (int x = 0; x < xSize; ++x)
{ {
RcSpan s = heightfield.spans[x + y * w]; RcSpan s = heightfield.spans[x + y * xSize];
// If there are no spans at this cell, just leave the data to index=0, count=0. // If there are no spans at this cell, just leave the data to index=0, count=0.
if (s == null) if (s == null)
continue; continue;
@ -109,7 +108,7 @@ namespace DotRecast.Recast
int top = s.next != null ? (int)s.next.smin : MAX_HEIGHT; int top = s.next != null ? (int)s.next.smin : MAX_HEIGHT;
tempSpans[idx].y = Math.Clamp(bot, 0, MAX_HEIGHT); tempSpans[idx].y = Math.Clamp(bot, 0, MAX_HEIGHT);
tempSpans[idx].h = Math.Clamp(top - bot, 0, MAX_HEIGHT); tempSpans[idx].h = Math.Clamp(top - bot, 0, MAX_HEIGHT);
chf.areas[idx] = s.area; compactHeightfield.areas[idx] = s.area;
idx++; idx++;
tmpCount++; tmpCount++;
} }
@ -117,17 +116,17 @@ namespace DotRecast.Recast
s = s.next; s = s.next;
} }
chf.cells[x + y * w] = new RcCompactCell(tmpIdx, tmpCount); compactHeightfield.cells[x + y * xSize] = new RcCompactCell(tmpIdx, tmpCount);
} }
} }
// Find neighbour connections. // Find neighbour connections.
int tooHighNeighbour = 0; int tooHighNeighbour = 0;
for (int y = 0; y < h; ++y) for (int y = 0; y < zSize; ++y)
{ {
for (int x = 0; x < w; ++x) for (int x = 0; x < xSize; ++x)
{ {
ref RcCompactCell c = ref chf.cells[x + y * w]; ref RcCompactCell c = ref compactHeightfield.cells[x + y * xSize];
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)
{ {
ref RcCompactSpanBuilder s = ref tempSpans[i]; ref RcCompactSpanBuilder s = ref tempSpans[i];
@ -138,12 +137,12 @@ namespace DotRecast.Recast
int nx = x + GetDirOffsetX(dir); int nx = x + GetDirOffsetX(dir);
int ny = y + GetDirOffsetY(dir); int ny = y + GetDirOffsetY(dir);
// First check that the neighbour cell is in bounds. // First check that the neighbour cell is in bounds.
if (nx < 0 || ny < 0 || nx >= w || ny >= h) if (nx < 0 || ny < 0 || nx >= xSize || ny >= zSize)
continue; continue;
// 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 RcCompactCell nc = ref chf.cells[nx + ny * w]; ref RcCompactCell nc = ref compactHeightfield.cells[nx + ny * xSize];
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)
{ {
ref RcCompactSpanBuilder ns = ref tempSpans[k]; ref RcCompactSpanBuilder ns = ref tempSpans[k];
@ -177,9 +176,9 @@ namespace DotRecast.Recast
+ " (max: " + MAX_LAYERS + ")"); + " (max: " + MAX_LAYERS + ")");
} }
chf.spans = tempSpans.Select(x => x.Build()).ToArray(); compactHeightfield.spans = tempSpans.Select(x => x.Build()).ToArray();
return chf; return compactHeightfield;
} }
/// Returns the number of spans contained in the specified heightfield. /// Returns the number of spans contained in the specified heightfield.
@ -189,16 +188,14 @@ namespace DotRecast.Recast
/// @returns The number of spans in the heightfield. /// @returns The number of spans in the heightfield.
private static int GetHeightFieldSpanCount(RcContext context, RcHeightfield heightfield) private static int GetHeightFieldSpanCount(RcContext context, RcHeightfield heightfield)
{ {
int w = heightfield.width; int numCols = heightfield.width * heightfield.height;
int h = heightfield.height;
int spanCount = 0; int spanCount = 0;
for (int y = 0; y < h; ++y) for (int columnIndex = 0; columnIndex < numCols; ++columnIndex)
{ {
for (int x = 0; x < w; ++x) for (RcSpan span = heightfield.spans[columnIndex]; span != null; span = span.next)
{ {
for (RcSpan s = heightfield.spans[x + y * w]; s != null; s = s.next) if (span.area != RC_NULL_AREA)
{ {
if (s.area != RC_NULL_AREA)
spanCount++; spanCount++;
} }
} }