mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
Recast: increase max span height bits
Increase to 29 bits for span limits, previously this was 13 and since the next field in the struct was a pointer, we end up using the 4 bytes padding so the struct size didn't increase. The reason for this increase is that rcSpan::smin and rcSpan::smax overflow when building a navmesh with a low cell height. This is especially an issue with maps that contain mountains. For the season 1 kings canyon map, the tiles containg the polygons for the firing range will be entirely flat due to the massive height difference between the base map and the firing range which resides under the map, causing it to be clamped to the previous MAX_HEIGHT value.
This commit is contained in:
parent
5e36f58956
commit
c4cdbe38ce
@ -281,7 +281,7 @@ struct rcConfig
|
||||
};
|
||||
|
||||
/// Defines the number of bits allocated to rcSpan::smin and rcSpan::smax.
|
||||
static const int RC_SPAN_HEIGHT_BITS = 13;
|
||||
static const int RC_SPAN_HEIGHT_BITS = 29;
|
||||
/// Defines the maximum value for rcSpan::smin and rcSpan::smax.
|
||||
static const int RC_SPAN_MAX_HEIGHT = (1 << RC_SPAN_HEIGHT_BITS) - 1;
|
||||
|
||||
@ -343,7 +343,7 @@ struct rcCompactSpan
|
||||
unsigned short z; ///< The lower extent of the span. (Measured from the heightfield's base.)
|
||||
unsigned short reg; ///< The id of the region the span belongs to. (Or zero if not in a region.)
|
||||
unsigned int con : 24; ///< Packed neighbor connection data.
|
||||
unsigned int h : 8; ///< The height of the span. (Measured from #y.)
|
||||
unsigned int h : 8; ///< The height of the span. (Measured from #z.)
|
||||
};
|
||||
|
||||
/// A compact, static heightfield representing unobstructed space.
|
||||
|
@ -446,8 +446,6 @@ bool rcBuildCompactHeightfield(rcContext* context, const int walkableHeight, con
|
||||
}
|
||||
memset(compactHeightfield.areas, RC_NULL_AREA, sizeof(unsigned char) * spanCount);
|
||||
|
||||
const int MAX_HEIGHT = 0xffff;
|
||||
|
||||
// Fill in cells and spans.
|
||||
int currentCellIndex = 0;
|
||||
const int numColumns = xSize * ySize;
|
||||
@ -470,8 +468,8 @@ bool rcBuildCompactHeightfield(rcContext* context, const int walkableHeight, con
|
||||
if (span->area != RC_NULL_AREA)
|
||||
{
|
||||
const int bot = (int)span->smax;
|
||||
const int top = span->next ? (int)span->next->smin : MAX_HEIGHT;
|
||||
compactHeightfield.spans[currentCellIndex].z = (unsigned short)rdClamp(bot, 0, 0xffff);
|
||||
const int top = span->next ? (int)span->next->smin : RC_SPAN_MAX_HEIGHT;
|
||||
compactHeightfield.spans[currentCellIndex].z = (unsigned short)rdClamp(bot, 0, RC_SPAN_MAX_HEIGHT);
|
||||
compactHeightfield.spans[currentCellIndex].h = (unsigned char)rdClamp(top - bot, 0, 0xff);
|
||||
compactHeightfield.areas[currentCellIndex] = span->area;
|
||||
currentCellIndex++;
|
||||
|
@ -66,7 +66,6 @@ void rcFilterLedgeSpans(rcContext* context, const int walkableHeight, const int
|
||||
|
||||
const int xSize = heightfield.width;
|
||||
const int ySize = heightfield.height;
|
||||
const int MAX_HEIGHT = 0xffff; // TODO (graham): Move this to a more visible constant and update usages.
|
||||
|
||||
// Mark border spans.
|
||||
for (int y = 0; y < ySize; ++y)
|
||||
@ -82,10 +81,10 @@ void rcFilterLedgeSpans(rcContext* context, const int walkableHeight, const int
|
||||
}
|
||||
|
||||
const int bot = (int)(span->smax);
|
||||
const int top = span->next ? (int)(span->next->smin) : MAX_HEIGHT;
|
||||
const int top = span->next ? (int)(span->next->smin) : RC_SPAN_MAX_HEIGHT;
|
||||
|
||||
// Find neighbours minimum height.
|
||||
int minNeighborHeight = MAX_HEIGHT;
|
||||
int minNeighborHeight = RC_SPAN_MAX_HEIGHT;
|
||||
|
||||
// Min and max height of accessible neighbours.
|
||||
int accessibleNeighborMinHeight = span->smax;
|
||||
@ -104,7 +103,7 @@ void rcFilterLedgeSpans(rcContext* context, const int walkableHeight, const int
|
||||
|
||||
// From minus infinity to the first span.
|
||||
const rcSpan* neighborSpan = heightfield.spans[dx + dy * xSize];
|
||||
int neighborTop = neighborSpan ? (int)neighborSpan->smin : MAX_HEIGHT;
|
||||
int neighborTop = neighborSpan ? (int)neighborSpan->smin : RC_SPAN_MAX_HEIGHT;
|
||||
|
||||
// Skip neighbour if the gap between the spans is too small.
|
||||
if (rdMin(top, neighborTop) - bot >= walkableHeight)
|
||||
@ -117,7 +116,7 @@ void rcFilterLedgeSpans(rcContext* context, const int walkableHeight, const int
|
||||
for (neighborSpan = heightfield.spans[dx + dy * xSize]; neighborSpan; neighborSpan = neighborSpan->next)
|
||||
{
|
||||
const int neighborBot = (int)neighborSpan->smax;
|
||||
neighborTop = neighborSpan->next ? (int)neighborSpan->next->smin : MAX_HEIGHT;
|
||||
neighborTop = neighborSpan->next ? (int)neighborSpan->next->smin : RC_SPAN_MAX_HEIGHT;
|
||||
|
||||
// Skip neighbour if the gap between the spans is too small.
|
||||
if (rdMin(top, neighborTop) - rdMax(bot, neighborBot) >= walkableHeight)
|
||||
@ -164,7 +163,6 @@ void rcFilterWalkableLowHeightSpans(rcContext* context, const int walkableHeight
|
||||
|
||||
const int xSize = heightfield.width;
|
||||
const int ySize = heightfield.height;
|
||||
const int MAX_HEIGHT = 0xffff;
|
||||
|
||||
// Remove walkable flag from spans which do not have enough
|
||||
// space above them for the agent to stand there.
|
||||
@ -175,7 +173,7 @@ void rcFilterWalkableLowHeightSpans(rcContext* context, const int walkableHeight
|
||||
for (rcSpan* span = heightfield.spans[x + y*xSize]; span; span = span->next)
|
||||
{
|
||||
const int bot = (int)(span->smax);
|
||||
const int top = span->next ? (int)(span->next->smin) : MAX_HEIGHT;
|
||||
const int top = span->next ? (int)(span->next->smin) : RC_SPAN_MAX_HEIGHT;
|
||||
if ((top - bot) < walkableHeight)
|
||||
{
|
||||
span->area = RC_NULL_AREA;
|
||||
|
Loading…
x
Reference in New Issue
Block a user