Moved navmesh into its own object and started serialization & deserialization of nav mesh

This commit is contained in:
Antoine Pilote
2024-08-05 23:29:58 -04:00
parent 755ef9c6e0
commit c296685e32
4 changed files with 209 additions and 5 deletions

View File

@@ -13,6 +13,7 @@
#include "src/Core/Maths.h"
#include "src/AI/RecastConfig.h"
#include "NavMesh.h"
namespace Nuake {
@@ -31,7 +32,7 @@ namespace Nuake {
m_Meshes.push_back({ mesh, transform });
}
void NavManager::BuildNavMesh(const RecastConfig& config)
Ref<NavMesh> NavManager::BuildNavMesh(const RecastConfig& config)
{
// Merge all meshes togheter
std::vector<Vector3> vertices;
@@ -277,7 +278,16 @@ namespace Nuake {
Logger::Log("Could not init Detour navmesh query", "NavManager", CRITICAL);
}
Ref<NavMesh> navMesh = CreateRef<NavMesh>(m_DetourNavMesh, m_DetourNavQuery);
const std::string& deserializedNavMesh = navMesh->Serialize().dump(4);
Logger::Log(deserializedNavMesh, "debug", VERBOSE);
Ref<NavMesh> navMesh2 = CreateRef<NavMesh>();
navMesh->Deserialize(json::parse(deserializedNavMesh));
m_Meshes.clear();
return navMesh;
}
void NavManager::DrawNavMesh()
@@ -345,9 +355,6 @@ namespace Nuake {
}
}
}
}
}

View File

@@ -1,6 +1,8 @@
#pragma once
#include "src/Core/Core.h"
#include "src/Rendering/Mesh/Mesh.h"
#include "src/AI/NavMesh.h"
#include "NavMeshDebugDrawer.h"
class rcContext;
@@ -30,7 +32,7 @@ namespace Nuake {
void Initialize();
void PushMesh(const Ref<Mesh>& mesh, const Matrix4& transform);
void BuildNavMesh(const RecastConfig& config);
Ref<NavMesh> BuildNavMesh(const RecastConfig& config);
void DrawNavMesh();

165
Nuake/src/AI/NavMesh.cpp Normal file
View File

@@ -0,0 +1,165 @@
#include "NavMesh.h"
#include "Recast.h"
#include "src/Core/String.h"
#include <DetourNavMeshBuilder.h>
#include "DetourNavMeshQuery.h"
#include <src/Core/Logger.h>
namespace Nuake {
struct NavMeshTileHeader
{
dtTileRef tileRef;
int dataSize;
};
struct NavMeshSetHeader
{
int magic;
int version;
int numTiles;
dtNavMeshParams params;
};
NavMesh::NavMesh(dtNavMesh* navMesh, dtNavMeshQuery* navMeshQuery)
{
m_DetourNavMesh = navMesh;
m_DetourNavQuery = navMeshQuery;
}
int NavMesh::FindNearestPolygon(const Vector3& searchPosition, const Vector3& searchBox)
{
float nearestPoint[3];
float searchPos[3] = { searchPosition.x, searchPosition.y, searchPosition.z };
float searchExtent[3] = { searchBox.x, searchBox.y, searchBox.z};
dtQueryFilter filter;
filter.setIncludeFlags(1);
dtPolyRef resultPoly = 0;
dtStatus status = m_DetourNavQuery->findNearestPoly(searchPos, searchExtent, &filter, &resultPoly, nearestPoint);
return resultPoly;
}
std::vector<Vector3> NavMesh::FindPath(int polyStart, int polyEnd, const Vector3& nearestPointStart, const Vector3& nearestPointEnd, const int maxPoly)
{
dtNavMesh* mesh = dtAllocNavMesh();
return std::vector<Vector3>();
}
json NavMesh::Serialize()
{
BEGIN_SERIALIZE();
// Get number of tiles
nlohmann::json headerJson;
headerJson["magic"] = 1337;
headerJson["version"] = 1;
int numTiles = 0;
const auto* navMesh = m_DetourNavMesh;
for (int i = 0; i < m_DetourNavMesh->getMaxTiles(); i++)
{
const dtMeshTile* tile = navMesh->getTile(i);
if (!tile || !tile->header || !tile->dataSize) continue;
numTiles++;
}
const dtNavMeshParams* params = navMesh->getParams();
if (params)
{
nlohmann::json paramsJson;
paramsJson["orig[0]"] = params->orig[0];
paramsJson["orig[1]"] = params->orig[1];
paramsJson["orig[2]"] = params->orig[2];
paramsJson["tileWidth"] = params->tileWidth;
paramsJson["tileHeight"] = params->tileHeight;
paramsJson["maxTiles"] = params->maxTiles;
paramsJson["maxPolys"] = params->maxPolys;
headerJson["params"] = paramsJson;
}
headerJson["numTiles"] = numTiles;
std::vector<nlohmann::json> tilesJson;
for (int i = 0; i < m_DetourNavMesh->getMaxTiles(); i++)
{
const dtMeshTile* tile = navMesh->getTile(i);
if (!tile || !tile->header || !tile->dataSize) continue;
nlohmann::json tileJson;
tileJson["tileRef"] = m_DetourNavMesh->getTileRef(tile);
tileJson["dataSize"] = tile->dataSize;
// Serialize tile data as base64
std::vector<uint8_t> tileData(tile->data, tile->data + tile->dataSize);
tileJson["data"] = String::Base64Encode(tileData);
tilesJson.push_back(tileJson);
}
j["header"] = headerJson;
j["tiles"] = tilesJson;
END_SERIALIZE();
}
bool NavMesh::Deserialize(const json& j)
{
if (j.contains("header"))
{
int magicNumber = j["header"]["magic"];
int version = j["header"]["version"];
int numTiles = j["header"]["numTiles"];
}
//dtStatus status = mesh->init(&header.params);
dtNavMesh* mesh = dtAllocNavMesh();
dtNavMeshParams params;
params.orig[0] = j["header"]["params"]["orig[0]"].get<float>();
params.orig[1] = j["header"]["params"]["orig[1]"].get<float>();
params.orig[2] = j["header"]["params"]["orig[2]"].get<float>();
params.tileWidth = j["header"]["params"]["tileWidth"].get<float>();
params.tileHeight = j["header"]["params"]["tileHeight"].get<float>();
params.maxTiles = j["header"]["params"]["maxTiles"].get<int>();
params.maxPolys = j["header"]["params"]["maxPolys"].get<int>();
dtStatus status = mesh->init(&params);
if (dtStatusFailed(status))
{
return false;
}
for (const auto& tileJson : j["tiles"])
{
auto dataSize = tileJson["dataSize"].get<int>();
std::string base64Data = tileJson["data"].get<std::string>();
// Decode Base64 data
std::vector<uint8_t> tileData = String::Base64Decode(base64Data);
if (dataSize != tileData.size())
{
Logger::Log("Tile data size mismatch", "navmesh", CRITICAL);
continue;
}
auto data = new uint8_t[dataSize];
std::memcpy(data, tileData.data(), dataSize);
mesh->addTile(data, dataSize, DT_TILE_FREE_DATA, tileJson["tileRef"].get<int>(), 0);
}
return true;
}
NavMesh::~NavMesh()
{
delete m_DetourNavMesh;
delete m_DetourNavQuery;
}
}

30
Nuake/src/AI/NavMesh.h Normal file
View File

@@ -0,0 +1,30 @@
#pragma once
#include <src/Core/Maths.h>
#include "src/Resource/Serializable.h"
#include <DetourNavMeshQuery.h>
#include <DetourNavMesh.h>
namespace Nuake {
class NavMesh : ISerializable {
public:
NavMesh(dtNavMesh* navMesh, dtNavMeshQuery* navMeshQuery);
NavMesh() = default;
~NavMesh();
// Query
int FindNearestPolygon(const Vector3 & searchPosition, const Vector3 & searchBox);
std::vector<Vector3> FindPath(int polyStart, int polyEnd, const Vector3& nearestPointStart, const Vector3& nearestPointEnd, const int maxPoly);
json Serialize() override;
bool Deserialize(const json& j) override;
private:
const dtMeshTile* GetTile(int i) const;
dtNavMesh* m_DetourNavMesh;
dtNavMeshQuery* m_DetourNavQuery;
};
}