diff --git a/src/thirdparty/recast/Detour/Source/DetourNavMesh.cpp b/src/thirdparty/recast/Detour/Source/DetourNavMesh.cpp index 91ba65a6..96547299 100644 --- a/src/thirdparty/recast/Detour/Source/DetourNavMesh.cpp +++ b/src/thirdparty/recast/Detour/Source/DetourNavMesh.cpp @@ -806,8 +806,7 @@ dtStatus dtNavMesh::connectTraverseLinks(const dtTileRef tileRef, const dtTraver float baseTmin; float baseTmax; - if (!rdCalcSubEdgeArea2D(basePolySpos, basePolyEpos, baseDetailPolyEdgeSpos, baseDetailPolyEdgeEpos, baseTmin, baseTmax)) - continue; + rdCalcSubEdgeArea2D(basePolySpos, basePolyEpos, baseDetailPolyEdgeSpos, baseDetailPolyEdgeEpos, baseTmin, baseTmax); float baseEdgeDir[3]; rdVsub(baseEdgeDir, baseDetailPolyEdgeEpos, baseDetailPolyEdgeSpos); @@ -862,7 +861,9 @@ dtStatus dtNavMesh::connectTraverseLinks(const dtTileRef tileRef, const dtTraver const dtPolyRef landPolyRefBase = getPolyRefBase(landTile); bool firstLandTileLinkUsed = false; - for (int o = 0; o < landHeader->polyCount; ++o) + bool moveToNextTile = false; + + for (int o = 0; (o < landHeader->polyCount) && !moveToNextTile; ++o) { dtPoly* const landPoly = &landTile->polys[o]; @@ -874,7 +875,7 @@ dtStatus dtNavMesh::connectTraverseLinks(const dtTileRef tileRef, const dtTraver dtPolyDetail* const landDetail = &landTile->detailMeshes[o]; - for (int p = 0; p < landPoly->vertCount; ++p) + for (int p = 0; (p < landPoly->vertCount) && !moveToNextTile; ++p) { if (landPoly->neis[p] != 0) continue; @@ -883,7 +884,7 @@ dtStatus dtNavMesh::connectTraverseLinks(const dtTileRef tileRef, const dtTraver const float* const landPolySpos = &landTile->verts[landPoly->verts[p]*3]; const float* const landPolyEpos = &landTile->verts[landPoly->verts[(p+1)%landPoly->vertCount]*3]; - for (int q = 0; q < landDetail->triCount; ++q) + for (int q = 0; (q < landDetail->triCount) && !moveToNextTile; ++q) { const unsigned char* landTri = &landTile->detailTris[(landDetail->triBase+q)*4]; const float* landTriVerts[3]; @@ -901,7 +902,10 @@ dtStatus dtNavMesh::connectTraverseLinks(const dtTileRef tileRef, const dtTraver if (params.linkToNeighbor) { if (firstLandTileLinkUsed && !landTile->linkCountAvailable(1)) - continue; + { + moveToNextTile = true; + break; + } else if (firstBaseTileLinkUsed && !baseTile->linkCountAvailable(1)) return DT_FAILURE | DT_OUT_OF_MEMORY; @@ -921,8 +925,7 @@ dtStatus dtNavMesh::connectTraverseLinks(const dtTileRef tileRef, const dtTraver float landTmin; float landTmax; - if (!rdCalcSubEdgeArea2D(landPolySpos, landPolyEpos, landDetailPolyEdgeSpos, landDetailPolyEdgeEpos, landTmin, landTmax)) - continue; + rdCalcSubEdgeArea2D(landPolySpos, landPolyEpos, landDetailPolyEdgeSpos, landDetailPolyEdgeEpos, landTmin, landTmax); float landPolyEdgeMid[3]; rdVsad(landPolyEdgeMid, landDetailPolyEdgeSpos, landDetailPolyEdgeEpos, 0.5f); @@ -936,22 +939,6 @@ dtStatus dtNavMesh::connectTraverseLinks(const dtTileRef tileRef, const dtTraver float landEdgeDir[3]; rdVsub(landEdgeDir, landDetailPolyEdgeEpos, landDetailPolyEdgeSpos); - const float dotProduct = rdVdot(baseEdgeDir, landEdgeDir); - - // Edges facing the same direction should not be linked. - // Doing so causes links to go through from underneath - // geometry. E.g. we have an HVAC on a roof, and we try - // to link our roof poly edge facing north to the edge - // of the poly on the HVAC also facing north, the link - // will go through the HVAC and thus cause the NPC to - // 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) - continue; - const float elevation = rdMathFabsf(basePolyEdgeMid[2] - landPolyEdgeMid[2]); const float slopeAngle = rdMathFabsf(rdCalcSlopeAngle(basePolyEdgeMid, landPolyEdgeMid)); const bool baseOverlaps = rdCalcEdgeOverlap2D(baseDetailPolyEdgeSpos, baseDetailPolyEdgeEpos, landDetailPolyEdgeSpos, landDetailPolyEdgeEpos, baseEdgeDir) > params.minEdgeOverlap; diff --git a/src/thirdparty/recast/Shared/Include/SharedCommon.h b/src/thirdparty/recast/Shared/Include/SharedCommon.h index bc16011d..1090be46 100644 --- a/src/thirdparty/recast/Shared/Include/SharedCommon.h +++ b/src/thirdparty/recast/Shared/Include/SharedCommon.h @@ -514,8 +514,7 @@ void rdCalcEdgeNormalPt2D(const float* v1, const float* v2, float* out); /// @param[in] subEdgeEnd Second vert of the detail edge. [(x, y, z)] /// @param[out] tmin The normalized distance ratio from polygon edge start to detail edge start. /// @param[out] tmax The normalized distance ratio from polygon edge start to detail edge end. -/// @return False if tmin and tmax don't correspond to the winding order of the edge. -bool rdCalcSubEdgeArea2D(const float* edgeStart, const float* edgeEnd, const float* subEdgeStart, +void rdCalcSubEdgeArea2D(const float* edgeStart, const float* edgeEnd, const float* subEdgeStart, const float* subEdgeEnd, float& tmin, float& tmax); /// Derives the overlap between 2 edges. diff --git a/src/thirdparty/recast/Shared/Source/SharedCommon.cpp b/src/thirdparty/recast/Shared/Source/SharedCommon.cpp index 83199209..37cd7a43 100644 --- a/src/thirdparty/recast/Shared/Source/SharedCommon.cpp +++ b/src/thirdparty/recast/Shared/Source/SharedCommon.cpp @@ -597,26 +597,19 @@ void rdCalcEdgeNormalPt2D(const float* v1, const float* v2, float* out) rdCalcEdgeNormal2D(dir, out); } -bool rdCalcSubEdgeArea2D(const float* edgeStart, const float* edgeEnd, const float* subEdgeStart, +void rdCalcSubEdgeArea2D(const float* edgeStart, const float* edgeEnd, const float* subEdgeStart, const float* subEdgeEnd, float& tmin, float& tmax) { const float edgeLen = rdVdist2D(edgeStart, edgeEnd); const float subEdgeStartDist = rdVdist2D(edgeStart, subEdgeStart); const float subEdgeEndDist = rdVdist2D(edgeStart, subEdgeEnd); - tmin = subEdgeStartDist / edgeLen; - tmax = subEdgeEndDist / edgeLen; + tmax = subEdgeStartDist / edgeLen; + tmin = subEdgeEndDist / edgeLen; - // note(amos): If the min is larger than the max, we most likely have a - // malformed detail polygon, e.g. a triangle that is flipped causing its - // boundary edge's start vert to be closer to the end vert of the polygon - // when comparing the distances in the same winding order. This can happen - // on more complex geometry or when the error tollerance is raised. Either - // way return false to notify caller that the calculation has failed. + // Can happen when the sub edge equals the main edge. if (tmin > tmax) - return false; - - return true; + rdSwap(tmin, tmax); } float rdCalcEdgeOverlap2D(const float* edge1Start, const float* edge1End,