Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions PluginAPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ struct NavigationOptions
bool paused = false; // pathing is paused
bool track = true; // if spawn is to be tracked
FacingType facing = FacingType::Forward; // Forward = normal, Backward = move along path facing backward.
int searchRadius = 0; // the max search radius of the path
glm::vec3 searchOrigin; // the starting position / origin of the search

// set a new default log level while the path is running. info is the default.
spdlog::level::level_enum logLevel = spdlog::level::info;
Expand Down
2 changes: 1 addition & 1 deletion dependencies/recast/Detour/Include/DetourNavMeshQuery.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
// setting is to use non-virtual functions, the actual implementations of the functions
// are declared as inline for maximum speed.

//#define DT_VIRTUAL_QUERYFILTER 1
#define DT_VIRTUAL_QUERYFILTER 1

/// Defines polygon filtering and traversal costs for navigation mesh query operations.
/// @ingroup detour
Expand Down
18 changes: 18 additions & 0 deletions plugin/MQ2Navigation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1699,6 +1699,24 @@ void MQ2NavigationPlugin::ParseOptions(std::string_view line, int idx, Navigatio
{
args->tag = value;
}
else if (key == "searchradius")
{
options.searchRadius = GetIntFromString(value, 0);
}
else if (key == "searchorigin")
{
std::vector <std::string_view> parts = mq::split_view(value, ' ', false);
if (parts.size() == 3)
{
options.searchOrigin = { GetFloatFromString(parts[0], 0), GetFloatFromString(parts[1], 0), GetFloatFromString(parts[2], 0) };
}
else if (parts.size() == 2)
{
options.searchOrigin = { GetFloatFromString(parts[0], 0), pLocalPlayer->FloorHeight, GetFloatFromString(parts[2], 0) };
}
else
SPDLOG_ERROR("Invalid argument for searchorigin: {}", value);
}
}
catch (const std::exception& ex)
{
Expand Down
27 changes: 26 additions & 1 deletion plugin/NavigationPath.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ void NavigationPath::SetNavMesh(const std::shared_ptr<dtNavMesh>& navMesh,

m_query.reset();

m_filter = dtQueryFilter{};
m_filter = NavPathFilter{};
m_filter.setIncludeFlags(+PolyFlags::All);
m_filter.setExcludeFlags(+PolyFlags::Disabled);
if (auto* mesh = g_mq2Nav->Get<NavMesh>())
Expand Down Expand Up @@ -330,6 +330,11 @@ std::unique_ptr<StraightPath> NavigationPath::RecomputePath(
glm::vec3 spos;

// TODO: Cache the last known valid starting position to detect when moving off the mesh
if (m_destinationInfo && m_destinationInfo->options.searchRadius > 0)
{
m_filter.SetSearchOrigin(m_destinationInfo->options.searchOrigin);
m_filter.SetSearchRadius(m_destinationInfo->options.searchRadius);
}

m_query->findNearestPoly(
glm::value_ptr(startPos),
Expand Down Expand Up @@ -924,4 +929,24 @@ void NavigationLine::Update()
}
}

bool NavPathFilter::passFilter(const dtPolyRef ref, const dtMeshTile* tile, const dtPoly* poly) const
{
if (m_searchRadius > 0)
{
glm::vec3 polyCenter = glm::vec3{ 0, 0, 0 };

for (int i = 0; i < poly->vertCount; ++i)
{
const float* v = &tile->verts[poly->verts[i] * 3];
polyCenter += glm::vec3{ v[0], v[1], v[2] };
}

polyCenter /= poly->vertCount;

if (distSqr(m_searchOrigin, polyCenter) > (m_searchRadius * m_searchRadius))
return false;
}
return dtQueryFilter::passFilter(ref, tile, poly);
}

//----------------------------------------------------------------------------
18 changes: 17 additions & 1 deletion plugin/NavigationPath.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,21 @@ struct StraightPath
int alloc = 0;
};

class NavPathFilter : public dtQueryFilter
{
private:
int m_searchRadius = 0;
glm::vec3 m_searchOrigin;

public:
inline NavPathFilter() { };
inline virtual ~NavPathFilter() override { };
virtual bool passFilter(const dtPolyRef ref, const dtMeshTile* tile, const dtPoly* poly) const override;
void SetSearchRadius(int radius) { m_searchRadius = radius; }
//int GetSearchRadius() const { return m_searchRadius; }
void SetSearchOrigin(const glm::vec3& pos) { m_searchOrigin = pos; }
};

class NavigationPath
{
friend class NavigationLine;
Expand Down Expand Up @@ -176,7 +191,7 @@ class NavigationPath
std::vector<int> m_renderPath;
bool m_followingLink = false;

dtQueryFilter m_filter;
NavPathFilter m_filter;
glm::vec3 m_extents = { 5, 10, 5 }; // note: X, Z, Y

mq::Signal<>::ScopedConnection m_navMeshConn;
Expand Down Expand Up @@ -257,3 +272,4 @@ class NavigationLine : public Renderable
};

extern NavigationLine::LineStyle gNavigationLineStyle;