Added FindPath to C# API for path finding

This commit is contained in:
Antoine Pilote
2024-08-09 19:12:42 -04:00
parent 5bd6690f20
commit 3fcd63ff34
9 changed files with 152 additions and 20 deletions

View File

@@ -231,9 +231,9 @@ namespace Nuake {
//params.offMeshConUserID = m_geom->getOffMeshConnectionId();
//params.offMeshConCount = m_geom->getOffMeshConnectionCount();
const float agentHeight = 0.1f;
const float agentHeight = 0.5f;
const float agentRadius = 0.1f;
const float agentMaxClimb = 0.1f;
const float agentMaxClimb = 0.01f;
params.walkableHeight = agentHeight;
params.walkableRadius = agentRadius;
params.walkableClimb = agentMaxClimb;

View File

@@ -27,7 +27,7 @@ namespace Nuake {
m_DetourNavQuery = navMeshQuery;
}
int NavMesh::FindNearestPolygon(const Vector3& searchPosition, const Vector3& searchBox)
NavMesh::PolySearchResult NavMesh::FindNearestPolygon(const Vector3& searchPosition, const Vector3& searchBox)
{
float nearestPoint[3];
float searchPos[3] = { searchPosition.x, searchPosition.y, searchPosition.z };
@@ -38,7 +38,60 @@ namespace Nuake {
dtPolyRef resultPoly = 0;
dtStatus status = m_DetourNavQuery->findNearestPoly(searchPos, searchExtent, &filter, &resultPoly, nearestPoint);
return resultPoly;
PolySearchResult result =
{
.PolyID = static_cast<int>(resultPoly),
.PositionInPoly = { nearestPoint[0], nearestPoint[1], nearestPoint[2] }
};
return result;
}
std::vector<Vector3> NavMesh::FindStraightPath(const Vector3& start, const Vector3& end)
{
// Find start & end polygon
constexpr Vector3 SEARCH_BOX = { 0.6, 0.85, 0.6 };
PolySearchResult startPoly = FindNearestPolygon(start, SEARCH_BOX);
PolySearchResult endPoly = FindNearestPolygon(end, SEARCH_BOX);
// Find poly corridor
constexpr int MAX_PATH = 2048;
constexpr int MAX_POLYS = 256;
dtQueryFilter filter;
filter.setIncludeFlags(1);
dtPolyRef resultPoly[MAX_POLYS];
int resultPathCount = 0;
dtStatus result = m_DetourNavQuery->findPath(startPoly.PolyID, endPoly.PolyID,
&(startPoly.PositionInPoly.x), &(endPoly.PositionInPoly.x),
&filter, resultPoly, &resultPathCount, MAX_PATH);
// Find straight path in corridor
float straightPath[MAX_POLYS * 3];
unsigned char straightPathFlags[MAX_POLYS];
dtPolyRef straightPathPolys[MAX_POLYS];
int nstraightPath;
result = m_DetourNavQuery->findStraightPath(&(startPoly.PositionInPoly.x), &(endPoly.PositionInPoly.x),
resultPoly, resultPathCount, straightPath, straightPathFlags,
straightPathPolys, &nstraightPath, MAX_POLYS);
// Convert path into points
std::vector<Vector3> pathWaypoints;
if (dtStatusFailed(result))
{
Logger::Log("Failed to find straight path.", "navmesh", VERBOSE);
return pathWaypoints;
}
pathWaypoints.reserve(nstraightPath);
for (int i = 0; i < nstraightPath; ++i)
{
float* v = &straightPath[i * 3];
const Vector3 waypoint = { v[0], v[1], v[2] };
pathWaypoints.push_back(waypoint);
}
return pathWaypoints;
}
std::vector<Vector3> NavMesh::FindPath(int polyStart, int polyEnd, const Vector3& nearestPointStart, const Vector3& nearestPointEnd, const int maxPoly)

View File

@@ -6,7 +6,14 @@
namespace Nuake {
class NavMesh : ISerializable {
class NavMesh : ISerializable
{
private:
struct PolySearchResult
{
int PolyID;
Vector3 PositionInPoly;
};
public:
NavMesh(dtNavMesh* navMesh, dtNavMeshQuery* navMeshQuery);
@@ -14,7 +21,9 @@ namespace Nuake {
~NavMesh();
// Query
int FindNearestPolygon(const Vector3 & searchPosition, const Vector3 & searchBox);
PolySearchResult FindNearestPolygon(const Vector3 & searchPosition, const Vector3 & searchBox);
std::vector<Vector3> FindStraightPath(const Vector3& start, const Vector3& end);
std::vector<Vector3> FindPath(int polyStart, int polyEnd, const Vector3& nearestPointStart, const Vector3& nearestPointEnd, const int maxPoly);

View File

@@ -288,7 +288,7 @@ namespace Nuake
std::string FileSystem::GetConfigFolderPath()
{
std::string subFolderPath = OS::GetConfigFolderPath().append("/Nuake/");
if (!DirectoryExists(subFolderPath))
if (!DirectoryExists(subFolderPath, true))
{
MakeDirectory(subFolderPath);
}

View File

@@ -33,7 +33,12 @@ namespace Nuake
BEGIN_SERIALIZE();
SERIALIZE_VEC3(VolumeSize);
SERIALIZE_VAL(OnlyIncludeMapGeometry);
SERIALIZE_OBJECT(NavMeshData);
if (NavMeshData != nullptr)
{
SERIALIZE_OBJECT(NavMeshData);
}
// Generation config
END_SERIALIZE();
}

View File

@@ -24,6 +24,7 @@
#include "src/Scripting/ScriptingEngineNet.h"
#include <Coral/Array.hpp>
#include <src/Scene/Components/NavMeshVolumeComponent.h>
namespace Nuake {
@@ -109,7 +110,8 @@ namespace Nuake {
PARTICLE_EMITTER,
QUAKE_MAP,
BSP_BRUSH,
SPRITE
SPRITE,
NAVMESH
};
bool EntityHasComponent(int id, int componentType)
@@ -145,6 +147,7 @@ namespace Nuake {
case QUAKE_MAP: return entity.HasComponent<QuakeMapComponent>();
case BSP_BRUSH: return entity.HasComponent<BSPBrushComponent>();
case SPRITE: return entity.HasComponent<SpriteComponent>();
case NAVMESH: return entity.HasComponent<NavMeshVolumeComponent>();
default:
return false;
}
@@ -296,6 +299,36 @@ namespace Nuake {
}
}
Coral::Array<float> NavMeshComponentFindPath(int entityId, float startx, float starty, float startz, float endx, float endy, float endz)
{
Entity entity = Entity((entt::entity)(entityId), Engine::GetCurrentScene().get());
if (entity.IsValid() && entity.HasComponent<NavMeshVolumeComponent>())
{
auto& navMeshVolume = entity.GetComponent<NavMeshVolumeComponent>();
if (navMeshVolume.NavMeshData && navMeshVolume.NavMeshData->IsValid())
{
auto& navMesh = navMeshVolume.NavMeshData;
const Vector3& startPosition = { startx, starty, startz };
const Vector3& endPosition = { endx, endy, endz };
auto waypoints = navMesh->FindStraightPath(startPosition, endPosition);
// Convert Vector3 array into float array
Coral::Array<float> returnResult = Coral::Array<float>::New(waypoints.size() * 3);
for (int i = 0; i < waypoints.size(); i++)
{
returnResult[i * 3 + 0] = waypoints[i].x;
returnResult[i * 3 + 1] = waypoints[i].y;
returnResult[i * 3 + 2] = waypoints[i].z;
}
return returnResult;
}
}
return {};
}
void Nuake::SceneNetAPI::RegisterMethods()
{
// Entity
@@ -320,6 +353,8 @@ namespace Nuake {
RegisterMethod("CharacterControllerComponent.IsOnGroundIcall", &IsOnGround);
RegisterMethod("SkinnedModelComponent.PlayIcall", &Play);
RegisterMethod("NavMeshVolumeComponent.FindPathIcall", &NavMeshComponentFindPath);
}
}

View File

@@ -319,4 +319,28 @@ namespace Nuake.Net
public string Sprite { get; set; }
}
public class NavMeshVolumeComponent : IComponent
{
internal static unsafe delegate*<int, float, float, float, float, float, float, NativeArray<float>> FindPathIcall;
public NavMeshVolumeComponent(int entityId) { EntityID = entityId; }
public List<Vector3> FindStraightPath(Vector3 start, Vector3 end)
{
List<Vector3> pathWaypoints = [];
unsafe
{
NativeArray<float> waypoints = FindPathIcall(EntityID, start.X, start.Y, start.Z, end.X, end.Y, end.Z);
for(int i = 0; i < waypoints.Length; i += 3)
{
Vector3 waypointPosition = new Vector3(waypoints[i], waypoints[i + 1], waypoints[i + 2]);
pathWaypoints.Add(waypointPosition);
}
return pathWaypoints;
}
}
}
}

View File

@@ -45,7 +45,8 @@ namespace Nuake.Net
PARTICLE_EMITTER,
QUAKE_MAP,
BSP_BRUSH,
SPRITE
SPRITE,
NAVMESH
}
public int ID { get; set; }
@@ -101,7 +102,8 @@ namespace Nuake.Net
{ typeof(ParticleEmitterComponent), ComponentTypes.PARTICLE_EMITTER },
{ typeof(QuakeMapComponent), ComponentTypes.QUAKE_MAP },
{ typeof(BSPBrushComponent), ComponentTypes.BSP_BRUSH },
{ typeof(SpriteComponent), ComponentTypes.SPRITE }
{ typeof(SpriteComponent), ComponentTypes.SPRITE },
{ typeof(NavMeshVolumeComponent), ComponentTypes.NAVMESH }
};
public bool HasComponent<T>()

View File

@@ -27,17 +27,21 @@ workspace "Nuake"
outputdir = "%{cfg.buildcfg}-%{cfg.system}-%{cfg.architecture}"
include "Nuake/dependencies/glfw_p5.lua"
include "Nuake/dependencies/glad_p5.lua"
include "Nuake/dependencies/assimp_p5.lua"
include "Nuake/dependencies/freetype_p5.lua"
include "Nuake/dependencies/jolt_p5.lua"
include "Nuake/dependencies/soloud_p5.lua"
include "Nuake/dependencies/optick_p5.lua"
include "Nuake/dependencies/coral_p5.lua"
include "Nuake/dependencies/recastnavigation_p5.lua"
group "Dependencies"
include "Nuake/dependencies/glfw_p5.lua"
include "Nuake/dependencies/glad_p5.lua"
include "Nuake/dependencies/assimp_p5.lua"
include "Nuake/dependencies/freetype_p5.lua"
include "Nuake/dependencies/jolt_p5.lua"
include "Nuake/dependencies/soloud_p5.lua"
include "Nuake/dependencies/optick_p5.lua"
include "Nuake/dependencies/coral_p5.lua"
include "Nuake/dependencies/recastnavigation_p5.lua"
group ""
include "NuakeNet/premake5.lua"
project "Nuake"
location "Nuake"
kind "StaticLib"