Add path height correction on world load

This commit is contained in:
David Markowitz 2023-08-06 15:41:38 -07:00
parent cefdfc696a
commit 8117773c56
4 changed files with 22 additions and 7 deletions

View File

@ -118,7 +118,7 @@ void dNavMesh::LoadNavmesh() {
m_NavMesh = mesh; m_NavMesh = mesh;
} }
float dNavMesh::GetHeightAtPoint(const NiPoint3& location) { float dNavMesh::GetHeightAtPoint(const NiPoint3& location, const float halfExtentsHeight) const {
if (m_NavMesh == nullptr) { if (m_NavMesh == nullptr) {
return location.y; return location.y;
} }
@ -130,7 +130,7 @@ float dNavMesh::GetHeightAtPoint(const NiPoint3& location) {
pos[2] = location.z; pos[2] = location.z;
dtPolyRef nearestRef = 0; dtPolyRef nearestRef = 0;
float polyPickExt[3] = { 32.0f, 32.0f, 32.0f }; float polyPickExt[3] = { 32.0f, halfExtentsHeight, 32.0f };
dtQueryFilter filter{}; dtQueryFilter filter{};
m_NavQuery->findNearestPoly(pos, polyPickExt, &filter, &nearestRef, 0); m_NavQuery->findNearestPoly(pos, polyPickExt, &filter, &nearestRef, 0);

View File

@ -15,7 +15,15 @@ public:
dNavMesh(uint32_t zoneId); dNavMesh(uint32_t zoneId);
~dNavMesh(); ~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<NiPoint3> GetPath(const NiPoint3& startPos, const NiPoint3& endPos, float speed = 10.0f); std::vector<NiPoint3> GetPath(const NiPoint3& startPos, const NiPoint3& endPos, float speed = 10.0f);
class dtNavMesh* GetdtNavMesh() { return m_NavMesh; } class dtNavMesh* GetdtNavMesh() { return m_NavMesh; }

View File

@ -3,4 +3,5 @@ set(DZONEMANAGER_SOURCES "dZoneManager.cpp"
"Spawner.cpp" "Spawner.cpp"
"Zone.cpp") "Zone.cpp")
add_library(dZoneManager STATIC ${DZONEMANAGER_SOURCES}) add_library(dZoneManager STATIC ${DZONEMANAGER_SOURCES})
target_link_libraries(dZoneManager dPhysics)

View File

@ -13,6 +13,7 @@
#include "CDZoneTableTable.h" #include "CDZoneTableTable.h"
#include "Spawner.h" #include "Spawner.h"
#include "dZoneManager.h" #include "dZoneManager.h"
#include "dpWorld.h"
#include "eTriggerCommandType.h" #include "eTriggerCommandType.h"
#include "eTriggerEventType.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); path.pathWaypoints.push_back(waypoint);
} }
m_Paths.push_back(path); m_Paths.push_back(path);
} }