From 8117773c568e729b410bc4b7a5e3348b1f5202e9 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Sun, 6 Aug 2023 15:41:38 -0700 Subject: [PATCH] Add path height correction on world load --- dNavigation/dNavMesh.cpp | 4 ++-- dNavigation/dNavMesh.h | 10 +++++++++- dZoneManager/CMakeLists.txt | 3 ++- dZoneManager/Zone.cpp | 12 +++++++++--- 4 files changed, 22 insertions(+), 7 deletions(-) diff --git a/dNavigation/dNavMesh.cpp b/dNavigation/dNavMesh.cpp index fdba4a2d..c3366299 100644 --- a/dNavigation/dNavMesh.cpp +++ b/dNavigation/dNavMesh.cpp @@ -118,7 +118,7 @@ void dNavMesh::LoadNavmesh() { m_NavMesh = mesh; } -float dNavMesh::GetHeightAtPoint(const NiPoint3& location) { +float dNavMesh::GetHeightAtPoint(const NiPoint3& location, const float halfExtentsHeight) const { if (m_NavMesh == nullptr) { return location.y; } @@ -130,7 +130,7 @@ float dNavMesh::GetHeightAtPoint(const NiPoint3& location) { pos[2] = location.z; dtPolyRef nearestRef = 0; - float polyPickExt[3] = { 32.0f, 32.0f, 32.0f }; + float polyPickExt[3] = { 32.0f, halfExtentsHeight, 32.0f }; dtQueryFilter filter{}; m_NavQuery->findNearestPoly(pos, polyPickExt, &filter, &nearestRef, 0); diff --git a/dNavigation/dNavMesh.h b/dNavigation/dNavMesh.h index dc3db854..600b8b86 100644 --- a/dNavigation/dNavMesh.h +++ b/dNavigation/dNavMesh.h @@ -15,7 +15,15 @@ public: dNavMesh(uint32_t zoneId); ~dNavMesh(); - float GetHeightAtPoint(const NiPoint3& location); + /** + * Get the height at a point + * + * @param location The location to check for height at. This is the center of the search area. + * @param halfExtentsHeight The half extents height of the search area. This is the distance from the center to the top and bottom of the search area. + * The larger the value of halfExtentsHeight is, the larger the performance cost of the query. + * @return float The height at the point. If the point is not on the navmesh, the height of the point is returned. + */ + float GetHeightAtPoint(const NiPoint3& location, const float halfExtentsHeight = 32.0f) const; std::vector GetPath(const NiPoint3& startPos, const NiPoint3& endPos, float speed = 10.0f); class dtNavMesh* GetdtNavMesh() { return m_NavMesh; } diff --git a/dZoneManager/CMakeLists.txt b/dZoneManager/CMakeLists.txt index 1dd3841b..bbb22ba7 100644 --- a/dZoneManager/CMakeLists.txt +++ b/dZoneManager/CMakeLists.txt @@ -3,4 +3,5 @@ set(DZONEMANAGER_SOURCES "dZoneManager.cpp" "Spawner.cpp" "Zone.cpp") -add_library(dZoneManager STATIC ${DZONEMANAGER_SOURCES}) +add_library(dZoneManager STATIC ${DZONEMANAGER_SOURCES}) +target_link_libraries(dZoneManager dPhysics) diff --git a/dZoneManager/Zone.cpp b/dZoneManager/Zone.cpp index 6b153706..534e18b3 100644 --- a/dZoneManager/Zone.cpp +++ b/dZoneManager/Zone.cpp @@ -13,6 +13,7 @@ #include "CDZoneTableTable.h" #include "Spawner.h" #include "dZoneManager.h" +#include "dpWorld.h" #include "eTriggerCommandType.h" #include "eTriggerEventType.h" @@ -544,10 +545,15 @@ void Zone::LoadPath(std::istream& file) { } } + // We verify the waypoint heights against the navmesh because in many movement paths, + // the waypoint is located near 0 height, + if (path.pathType == PathType::Movement) { + if (dpWorld::Instance().IsLoaded()) { + // 1000 should be large enough for every world. + waypoint.position.y = dpWorld::Instance().GetNavMesh()->GetHeightAtPoint(waypoint.position, 1000.0f); + } + } path.pathWaypoints.push_back(waypoint); } - - - m_Paths.push_back(path); }