diff --git a/Source/Engine/Navigation/NavMeshRuntime.cpp b/Source/Engine/Navigation/NavMeshRuntime.cpp index 95b07924c..d81f46e06 100644 --- a/Source/Engine/Navigation/NavMeshRuntime.cpp +++ b/Source/Engine/Navigation/NavMeshRuntime.cpp @@ -141,6 +141,52 @@ bool NavMeshRuntime::FindPath(const Vector3& startPosition, const Vector3& endPo return true; } +bool NavMeshRuntime::TestPath(const Vector3& startPosition, const Vector3& endPosition) const +{ + ScopeLock lock(Locker); + + const auto query = GetNavMeshQuery(); + if (!query) + { + return false; + } + + dtQueryFilter filter; + Vector3 extent(DEFAULT_NAV_QUERY_EXTENT_HORIZONTAL, DEFAULT_NAV_QUERY_EXTENT_VERTICAL, DEFAULT_NAV_QUERY_EXTENT_HORIZONTAL); + + Vector3 startPositionNavMesh, endPositionNavMesh; + Vector3::Transform(startPosition, Properties.Rotation, startPositionNavMesh); + Vector3::Transform(endPosition, Properties.Rotation, endPositionNavMesh); + + dtPolyRef startPoly = 0; + query->findNearestPoly(&startPositionNavMesh.X, &extent.X, &filter, &startPoly, nullptr); + if (!startPoly) + { + return false; + } + dtPolyRef endPoly = 0; + query->findNearestPoly(&endPositionNavMesh.X, &extent.X, &filter, &endPoly, nullptr); + if (!endPoly) + { + return false; + } + + dtPolyRef path[NAV_MESH_PATH_MAX_SIZE]; + int32 pathSize; + const auto findPathStatus = query->findPath(startPoly, endPoly, &startPositionNavMesh.X, &endPositionNavMesh.X, &filter, path, &pathSize, NAV_MESH_PATH_MAX_SIZE); + if (dtStatusFailed(findPathStatus)) + { + return false; + } + + if (dtStatusDetail(findPathStatus, DT_PARTIAL_RESULT)) + { + return false; + } + + return true; +} + bool NavMeshRuntime::ProjectPoint(const Vector3& point, Vector3& result) const { ScopeLock lock(Locker); diff --git a/Source/Engine/Navigation/NavMeshRuntime.h b/Source/Engine/Navigation/NavMeshRuntime.h index 5d1b8ca63..7da4be0e2 100644 --- a/Source/Engine/Navigation/NavMeshRuntime.h +++ b/Source/Engine/Navigation/NavMeshRuntime.h @@ -105,6 +105,14 @@ public: /// True if found valid path between given two points (it may be partial), otherwise false if failed. bool FindPath(const Vector3& startPosition, const Vector3& endPosition, Array& resultPath) const; + /// + /// Tests the path between the two positions (non-partial). + /// + /// The start position. + /// The end position. + /// True if found valid path between given two points, otherwise false if failed. + bool TestPath(const Vector3& startPosition, const Vector3& endPosition) const; + /// /// Projects the point to nav mesh surface (finds the nearest polygon). /// diff --git a/Source/Engine/Navigation/Navigation.cpp b/Source/Engine/Navigation/Navigation.cpp index 7f8ca5e9a..29b081150 100644 --- a/Source/Engine/Navigation/Navigation.cpp +++ b/Source/Engine/Navigation/Navigation.cpp @@ -224,6 +224,13 @@ bool Navigation::FindPath(const Vector3& startPosition, const Vector3& endPositi return NavMeshes.First()->FindPath(startPosition, endPosition, resultPath); } +bool Navigation::TestPath(const Vector3& startPosition, const Vector3& endPosition) +{ + if (NavMeshes.IsEmpty()) + return false; + return NavMeshes.First()->TestPath(startPosition, endPosition); +} + bool Navigation::ProjectPoint(const Vector3& point, Vector3& result) { if (NavMeshes.IsEmpty()) diff --git a/Source/Engine/Navigation/Navigation.h b/Source/Engine/Navigation/Navigation.h index 2557e31e8..dcd6b9fbb 100644 --- a/Source/Engine/Navigation/Navigation.h +++ b/Source/Engine/Navigation/Navigation.h @@ -32,6 +32,14 @@ public: /// True if found valid path between given two points (it may be partial), otherwise false if failed. API_FUNCTION() static bool FindPath(const Vector3& startPosition, const Vector3& endPosition, API_PARAM(Out) Array& resultPath); + /// + /// Tests the path between the two positions (non-partial). + /// + /// The start position. + /// The end position. + /// True if found valid path between given two points, otherwise false if failed. + API_FUNCTION() static bool TestPath(const Vector3& startPosition, const Vector3& endPosition); + /// /// Projects the point to nav mesh surface (finds the nearest polygon). ///