Recast: only check edge dir if slope threshold is exceeded

Prevents the creation of traverse links that run parallel with the edge when linking to poly edges from external tiles.
This commit is contained in:
Kawe Mazidjatari 2024-08-12 16:35:12 +02:00
parent b585c96106
commit ef0f9a7770

View File

@ -406,8 +406,8 @@ enum TraverseType_e // todo(amos): move elsewhere
struct TraverseType_s // todo(amos): move elsewhere struct TraverseType_s // todo(amos): move elsewhere
{ {
float minSlope; float minSlope; // todo(amos): use height difference instead of slope angles.
float maxSlope; float maxSlope; // todo(amos): use height difference instead of slope angles.
unsigned char minDist; unsigned char minDist;
unsigned char maxDist; unsigned char maxDist;
@ -504,10 +504,13 @@ TraverseType_e GetBestTraverseType(const float slopeAngle, const unsigned char t
return bestTraverseType; return bestTraverseType;
} }
// todo(amos): find the best threshold...
// todo(amos): use height difference instead of slope angles.
#define TRAVERSE_OVERLAP_SLOPE_THRESHOLD 5.0f
bool CanOverlapPoly(const TraverseType_e traverseType) bool CanOverlapPoly(const TraverseType_e traverseType)
{ {
// todo(amos): find the best threshold... return s_traverseTypes[traverseType].minSlope >= TRAVERSE_OVERLAP_SLOPE_THRESHOLD;
return s_traverseTypes[traverseType].minSlope > 5.0f;
} }
static bool traverseLinkInPolygon(const dtMeshTile* tile, const float* midPoint) static bool traverseLinkInPolygon(const dtMeshTile* tile, const float* midPoint)
@ -623,6 +626,11 @@ void Editor::connectTileTraverseLinks(dtMeshTile* const baseTile, const bool lin
if (distance == 0) if (distance == 0)
continue; continue;
// todo(amos): use height difference instead of slope angles.
const float slopeAngle = rdMathFabsf(rdCalcSlopeAngle(basePolyEdgeMid, landPolyEdgeMid));
if (slopeAngle < TRAVERSE_OVERLAP_SLOPE_THRESHOLD)
{
float baseEdgeDir[3], landEdgeDir[3]; float baseEdgeDir[3], landEdgeDir[3];
rdVsub(baseEdgeDir, basePolyEpos, basePolySpos); rdVsub(baseEdgeDir, basePolyEpos, basePolySpos);
rdVsub(landEdgeDir, landPolyEpos, landPolySpos); rdVsub(landEdgeDir, landPolyEpos, landPolySpos);
@ -636,14 +644,18 @@ void Editor::connectTileTraverseLinks(dtMeshTile* const baseTile, const bool lin
// of the poly on the HVAC also facing north, the link // of the poly on the HVAC also facing north, the link
// will go through the HVAC and thus cause the NPC to // will go through the HVAC and thus cause the NPC to
// jump through it. // jump through it.
// Another case where this is necessary is when having
// a land edge that connects with the base edge, this
// prevents the algorithm from establishing a parallel
// traverse link.
if (dotProduct > 0) if (dotProduct > 0)
continue; continue;
}
float t, s; float t, s;
if (rdIntersectSegSeg2D(basePolySpos, basePolyEpos, landPolySpos, landPolyEpos, t, s)) if (rdIntersectSegSeg2D(basePolySpos, basePolyEpos, landPolySpos, landPolyEpos, t, s))
continue; continue;
const float slopeAngle = rdMathFabsf(rdCalcSlopeAngle(basePolyEdgeMid, landPolyEdgeMid));
const bool samePolyGroup = basePoly->groupId == landPoly->groupId; const bool samePolyGroup = basePoly->groupId == landPoly->groupId;
const TraverseType_e traverseType = GetBestTraverseType(slopeAngle, distance, samePolyGroup); const TraverseType_e traverseType = GetBestTraverseType(slopeAngle, distance, samePolyGroup);