implemented usage of virtual entry points when planning the travleroute
GCC PCH / build (push) Canceled after 0s
clang PCH / build (push) Canceled after 0s

This commit is contained in:
Nico committed 2026-10-18 13:39:31 +00:00
1 parent 9d4a862b7d
commit 366615bcb9
2 files changed
+151 -1

No files matched your search

+115
View File
@@ -30,6 +30,121 @@
#include "Metric.h" #include "Metric.h"
#include "PhasingHandler.h" #include "PhasingHandler.h"
// VCORE_POSITION_MMAP_BEGIN
VcorePositionPathResult PathGenerator::AnalyzePositions(uint32 meshMapId, uint32 instanceMapId,
uint32 instanceId, Position const& start, Position const& destination, uint16 includeFlags)
{
VcorePositionPathResult result;
G3D::Vector3 const startPos(start.GetPositionX(), start.GetPositionY(), start.GetPositionZ());
G3D::Vector3 const endPos(destination.GetPositionX(), destination.GetPositionY(), destination.GetPositionZ());
result.DirectDistance = (endPos - startPos).length();
result.FinalDistance = result.DirectDistance;
if (!Trinity::IsValidMapCoord(startPos.x, startPos.y, startPos.z) ||
!Trinity::IsValidMapCoord(endPos.x, endPos.y, endPos.z) || !includeFlags)
{
result.Result = VcorePositionPathResult::Status::InvalidCoordinates;
return result;
}
if (!DisableMgr::IsPathfindingEnabled(meshMapId))
return result; // NavMeshUnavailable
MMAP::MMapManager* manager = MMAP::MMapFactory::createOrGetMMapManager();
dtNavMeshQuery const* query = manager->GetNavMeshQuery(meshMapId, instanceMapId, instanceId);
dtNavMesh const* mesh = query ? query->getAttachedNavMesh() : nullptr;
if (!query || !mesh)
return result;
// Detour uses Y,Z,X; world coordinates use X,Y,Z.
float const from[3] = {startPos.y, startPos.z, startPos.x};
float const to[3] = {endPos.y, endPos.z, endPos.x};
for (float const* point : {from, to})
{
int tileX = -1, tileY = -1;
mesh->calcTileLoc(point, &tileX, &tileY);
if (tileX < 0 || tileY < 0 || !mesh->getTileAt(tileX, tileY, 0))
{
result.Result = VcorePositionPathResult::Status::TileUnavailable;
return result;
}
}
dtQueryFilter filter;
filter.setIncludeFlags(includeFlags);
filter.setExcludeFlags(0);
float const extents[3] = {3.0f, 5.0f, 3.0f};
float nearestStart[3] = {}, nearestEnd[3] = {};
dtPolyRef startPoly = 0, endPoly = 0;
if (dtStatusFailed(query->findNearestPoly(from, extents, &filter, &startPoly, nearestStart)) ||
dtStatusFailed(query->findNearestPoly(to, extents, &filter, &endPoly, nearestEnd)) ||
!startPoly || !endPoly)
{
result.Result = VcorePositionPathResult::Status::NoPolygon;
return result;
}
// A distant projection is not proof that the requested world point is walkable.
if (dtVdist(from, nearestStart) > 3.0f || dtVdist(to, nearestEnd) > 3.0f)
{
result.Result = VcorePositionPathResult::Status::NoPolygon;
return result;
}
dtPolyRef polys[MAX_PATH_LENGTH] = {};
int polyCount = 0;
dtStatus const pathStatus = query->findPath(startPoly, endPoly, nearestStart, nearestEnd,
&filter, polys, &polyCount, MAX_PATH_LENGTH);
if (dtStatusFailed(pathStatus) || polyCount <= 0)
{
result.Result = VcorePositionPathResult::Status::NoPath;
return result;
}
bool const reachedEndPoly = polys[polyCount - 1] == endPoly;
float reachableEnd[3] = {nearestEnd[0], nearestEnd[1], nearestEnd[2]};
if (!reachedEndPoly &&
dtStatusFailed(query->closestPointOnPoly(polys[polyCount - 1], nearestEnd, reachableEnd, nullptr)))
{
result.Result = VcorePositionPathResult::Status::NoPath;
return result;
}
// Use an explicit bounded straight-path representation, not a forced shortcut.
constexpr int MaxPoints = 256;
float straight[MaxPoints * 3] = {};
int pointCount = 0;
dtStatus const straightStatus = query->findStraightPath(nearestStart, reachableEnd, polys,
polyCount, straight, nullptr, nullptr, &pointCount, MaxPoints);
if (dtStatusFailed(straightStatus) || pointCount <= 0)
{
result.Result = VcorePositionPathResult::Status::NoPath;
return result;
}
result.Points.reserve(pointCount);
for (int i = 0; i < pointCount; ++i)
{
G3D::Vector3 const p(straight[i * 3 + 2], straight[i * 3], straight[i * 3 + 1]);
if (!result.Points.empty())
result.PathLength += (p - result.Points.back()).length();
result.Points.push_back(p);
}
result.FinalDistance = (endPos - result.Points.back()).length();
bool const truncated = (pathStatus & DT_BUFFER_TOO_SMALL) ||
(straightStatus & DT_BUFFER_TOO_SMALL) || pointCount >= MaxPoints ||
polyCount >= MAX_PATH_LENGTH;
if (truncated)
result.Result = VcorePositionPathResult::Status::Truncated;
else if (reachedEndPoly && result.FinalDistance <= 1.5f)
result.Result = VcorePositionPathResult::Status::Complete;
else
result.Result = VcorePositionPathResult::Status::Partial;
return result;
}
// VCORE_POSITION_MMAP_END
////////////////// PathGenerator ////////////////// ////////////////// PathGenerator //////////////////
PathGenerator::PathGenerator(WorldObject const* owner) : PathGenerator::PathGenerator(WorldObject const* owner) :
_polyLength(0), _type(PATHFIND_BLANK), _useStraightPath(false), _polyLength(0), _type(PATHFIND_BLANK), _useStraightPath(false),
+36 -1
View File
@@ -23,6 +23,7 @@
#include "MMapDefines.h" #include "MMapDefines.h"
#include "MoveSplineInitArgs.h" #include "MoveSplineInitArgs.h"
#include <G3D/Vector3.h> #include <G3D/Vector3.h>
#include <vector>
class Unit; class Unit;
class WorldObject; class WorldObject;
@@ -54,6 +55,34 @@ enum PathType
PATHFIND_FARFROMPOLY = PATHFIND_FARFROMPOLY_START | PATHFIND_FARFROMPOLY_END, // start or end positions are far from the mmap poligon PATHFIND_FARFROMPOLY = PATHFIND_FARFROMPOLY_START | PATHFIND_FARFROMPOLY_END, // start or end positions are far from the mmap poligon
}; };
// VCORE_POSITION_MMAP_BEGIN
// Ground-only navmesh probe without a Player or WorldObject.
// meshMapId may differ from instanceMapId for phased/terrain-swapped maps.
// The caller must run this on the map/world thread that owns the navmesh query.
struct VcorePositionPathResult
{
enum class Status : uint8
{
InvalidCoordinates,
NavMeshUnavailable,
TileUnavailable,
NoPolygon,
NoPath,
Partial,
Complete,
Truncated
};
Status Result = Status::NavMeshUnavailable;
float DirectDistance = 0.0f;
float PathLength = 0.0f;
float FinalDistance = 0.0f;
std::vector<G3D::Vector3> Points;
bool IsComplete() const { return Result == Status::Complete; }
};
// VCORE_POSITION_MMAP_END
class TC_GAME_API PathGenerator class TC_GAME_API PathGenerator
{ {
public: public:
@@ -65,7 +94,13 @@ class TC_GAME_API PathGenerator
PathGenerator& operator=(PathGenerator const& right) = delete; PathGenerator& operator=(PathGenerator const& right) = delete;
PathGenerator& operator=(PathGenerator&& right) = delete; PathGenerator& operator=(PathGenerator&& right) = delete;
// Calculate the path from owner to given destination // Vcore: query loaded MMAP data between arbitrary coordinates; no character required.
// The result describes ground navmesh reachability, not dynamic world collision.
static VcorePositionPathResult AnalyzePositions(uint32 meshMapId, uint32 instanceMapId,
uint32 instanceId, Position const& start, Position const& destination,
uint16 includeFlags = NAV_GROUND);
// Calculate the path from owner to given destination
// return: true if new path was calculated, false otherwise (no change needed) // return: true if new path was calculated, false otherwise (no change needed)
bool CalculatePath(float destX, float destY, float destZ, bool forceDest = false); bool CalculatePath(float destX, float destY, float destZ, bool forceDest = false);
bool CalculatePath(Position const& destination, bool forceDest = false); bool CalculatePath(Position const& destination, bool forceDest = false);