Refactor NavMesh into NavMeshRuntime and make it internal

This commit is contained in:
Wojtek Figat
2020-12-15 15:48:42 +01:00
parent 3c3e0b93f0
commit 4a79df860d
7 changed files with 65 additions and 68 deletions

View File

@@ -14,7 +14,6 @@ NavLink::NavLink(const SpawnParams& params)
void NavLink::UpdateBounds()
{
// Cache bounds
const auto start = _transform.LocalToWorld(Start);
const auto end = _transform.LocalToWorld(End);
BoundingBox::FromPoints(start, end, _box);

View File

@@ -18,9 +18,9 @@
#include "NavigationScene.h"
#include "NavigationSettings.h"
#include "NavMeshBoundsVolume.h"
#include "NavMesh.h"
#include "NavLink.h"
#include "Navigation.h"
#include "NavMeshRuntime.h"
#include <ThirdParty/recastnavigation/Recast.h>
#include <ThirdParty/recastnavigation/DetourNavMeshBuilder.h>
#include <ThirdParty/recastnavigation/DetourNavMesh.h>
@@ -184,9 +184,9 @@ void RasterizeGeometry(const BoundingBox& tileBounds, rcContext* context, rcConf
bool GetNavMeshTileBounds(NavigationScene* scene, int32 x, int32 y, float tileSize, BoundingBox& tileBounds)
{
// Build initial tile bounds (with infinite extent)
tileBounds.Minimum.X = x * tileSize;
tileBounds.Minimum.X = (float)x * tileSize;
tileBounds.Minimum.Y = -NAV_MESH_TILE_MAX_EXTENT;
tileBounds.Minimum.Z = y * tileSize;
tileBounds.Minimum.Z = (float)y * tileSize;
tileBounds.Maximum.X = tileBounds.Minimum.X + tileSize;
tileBounds.Maximum.Y = NAV_MESH_TILE_MAX_EXTENT;
tileBounds.Maximum.Z = tileBounds.Minimum.Z + tileSize;
@@ -224,7 +224,7 @@ bool GetNavMeshTileBounds(NavigationScene* scene, int32 x, int32 y, float tileSi
return foundAnyVolume;
}
void RemoveTile(NavMesh* navMesh, NavigationScene* scene, int32 x, int32 y, int32 layer)
void RemoveTile(NavMeshRuntime* navMesh, NavigationScene* scene, int32 x, int32 y, int32 layer)
{
ScopeLock lock(navMesh->Locker);
@@ -250,7 +250,7 @@ bool GenerateTile(NavigationScene* scene, int32 x, int32 y, BoundingBox& tileBou
int32 layer = 0;
// Expand tile bounds by a certain margin
const float tileBorderSize = (1 + config.borderSize) * config.cs;
const float tileBorderSize = (1.0f + (float)config.borderSize) * config.cs;
tileBounds.Minimum -= tileBorderSize;
tileBounds.Maximum += tileBorderSize;
@@ -347,7 +347,7 @@ bool GenerateTile(NavigationScene* scene, int32 x, int32 y, BoundingBox& tileBou
rcFreeCompactHeightfield(compactHeightfield);
rcFreeContourSet(contourSet);
for (int i = 0; i < polyMesh->npolys; ++i)
for (int i = 0; i < polyMesh->npolys; i++)
{
polyMesh->flags[i] = polyMesh->areas[i] == RC_WALKABLE_AREA ? 1 : 0;
}
@@ -355,7 +355,7 @@ bool GenerateTile(NavigationScene* scene, int32 x, int32 y, BoundingBox& tileBou
if (polyMesh->nverts == 0)
{
// Empty tile
RemoveTile(Navigation::GetNavMesh(), scene, x, y, layer);
RemoveTile(NavMeshRuntime::Get(), scene, x, y, layer);
return false;
}
@@ -373,9 +373,9 @@ bool GenerateTile(NavigationScene* scene, int32 x, int32 y, BoundingBox& tileBou
params.detailVertsCount = detailMesh->nverts;
params.detailTris = detailMesh->tris;
params.detailTriCount = detailMesh->ntris;
params.walkableHeight = config.walkableHeight * config.ch;
params.walkableRadius = config.walkableRadius * config.cs;
params.walkableClimb = config.walkableClimb * config.ch;
params.walkableHeight = (float)config.walkableHeight * config.ch;
params.walkableRadius = (float)config.walkableRadius * config.cs;
params.walkableClimb = (float)config.walkableClimb * config.ch;
params.tileX = x;
params.tileY = y;
params.tileLayer = layer;
@@ -438,7 +438,7 @@ bool GenerateTile(NavigationScene* scene, int32 x, int32 y, BoundingBox& tileBou
{
PROFILE_CPU_NAMED("Navigation.CreateTile");
ScopeLock lock(Navigation::GetNavMesh()->Locker);
ScopeLock lock(NavMeshRuntime::Get()->Locker);
// Add tile data
scene->IsDataDirty = true;
@@ -451,7 +451,7 @@ bool GenerateTile(NavigationScene* scene, int32 x, int32 y, BoundingBox& tileBou
tile.Data.Copy(navData, navDataSize);
// Add tile to navmesh
Navigation::GetNavMesh()->AddTile(scene, tile);
NavMeshRuntime::Get()->AddTile(scene, tile);
}
dtFree(navData);
@@ -635,7 +635,7 @@ void BuildTileAsync(NavigationScene* scene, int32 x, int32 y, rcConfig& config,
void BuildWholeScene(NavigationScene* scene)
{
const float tileSize = GetTileSize();
const auto navMesh = Navigation::GetNavMesh();
const auto navMesh = NavMeshRuntime::Get();
// Compute total navigation area bounds
const BoundingBox worldBounds = scene->GetNavigationBounds();
@@ -674,9 +674,9 @@ void BuildWholeScene(NavigationScene* scene)
{
PROFILE_CPU_NAMED("StartBuildingTiles");
for (int32 y = tilesMin.Z; y < tilesMax.Z; y ++)
for (int32 y = tilesMin.Z; y < tilesMax.Z; y++)
{
for (int32 x = tilesMin.X; x < tilesMax.X; x ++)
for (int32 x = tilesMin.X; x < tilesMax.X; x++)
{
BoundingBox tileBounds;
if (GetNavMeshTileBounds(scene, x, y, tileSize, tileBounds))
@@ -695,7 +695,7 @@ void BuildWholeScene(NavigationScene* scene)
void BuildDirtyBounds(NavigationScene* scene, const BoundingBox& dirtyBounds)
{
const float tileSize = GetTileSize();
const auto navMesh = Navigation::GetNavMesh();
const auto navMesh = NavMeshRuntime::Get();
// Align dirty bounds to tile size
BoundingBox dirtyBoundsAligned;
@@ -739,9 +739,9 @@ void BuildDirtyBounds(NavigationScene* scene, const BoundingBox& dirtyBounds)
{
PROFILE_CPU_NAMED("StartBuildingTiles");
for (int32 y = tilesMin.Z; y < tilesMax.Z; y ++)
for (int32 y = tilesMin.Z; y < tilesMax.Z; y++)
{
for (int32 x = tilesMin.X; x < tilesMax.X; x ++)
for (int32 x = tilesMin.X; x < tilesMax.X; x++)
{
BoundingBox tileBounds;
if (GetNavMeshTileBounds(scene, x, y, tileSize, tileBounds))

View File

@@ -1,8 +1,8 @@
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
#include "NavMesh.h"
#include "Engine/Core/Log.h"
#include "NavMeshRuntime.h"
#include "NavigationScene.h"
#include "Engine/Core/Log.h"
#include "Engine/Profiler/ProfilerCPU.h"
#include "Engine/Threading/Threading.h"
#include <ThirdParty/recastnavigation/DetourNavMesh.h>
@@ -12,25 +12,25 @@
#define USE_DATA_LINK 0
#define USE_NAV_MESH_ALLOC 1
NavMesh::NavMesh()
NavMeshRuntime::NavMeshRuntime()
{
_navMesh = nullptr;
_navMeshQuery = dtAllocNavMeshQuery();
_tileSize = 0;
}
NavMesh::~NavMesh()
NavMeshRuntime::~NavMeshRuntime()
{
dtFreeNavMesh(_navMesh);
dtFreeNavMeshQuery(_navMeshQuery);
}
int32 NavMesh::GetTilesCapacity() const
int32 NavMeshRuntime::GetTilesCapacity() const
{
return _navMesh ? _navMesh->getMaxTiles() : 0;
}
void NavMesh::SetTileSize(float tileSize)
void NavMeshRuntime::SetTileSize(float tileSize)
{
ScopeLock lock(Locker);
@@ -49,7 +49,7 @@ void NavMesh::SetTileSize(float tileSize)
_tileSize = tileSize;
}
void NavMesh::EnsureCapacity(int32 tilesToAddCount)
void NavMeshRuntime::EnsureCapacity(int32 tilesToAddCount)
{
ScopeLock lock(Locker);
@@ -58,7 +58,7 @@ void NavMesh::EnsureCapacity(int32 tilesToAddCount)
if (newTilesCount <= capacity)
return;
PROFILE_CPU_NAMED("NavMesh.EnsureCapacity");
PROFILE_CPU_NAMED("NavMeshRuntime.EnsureCapacity");
// Navmesh tiles capacity growing rule
int32 newCapacity = 0;
@@ -132,7 +132,7 @@ void NavMesh::EnsureCapacity(int32 tilesToAddCount)
}
}
void NavMesh::AddTiles(NavigationScene* scene)
void NavMeshRuntime::AddTiles(NavigationScene* scene)
{
// Skip if no data
ASSERT(scene);
@@ -140,7 +140,7 @@ void NavMesh::AddTiles(NavigationScene* scene)
return;
auto& data = scene->Data;
PROFILE_CPU_NAMED("NavMesh.AddTiles");
PROFILE_CPU_NAMED("NavMeshRuntime.AddTiles");
ScopeLock lock(Locker);
@@ -168,12 +168,12 @@ void NavMesh::AddTiles(NavigationScene* scene)
}
}
void NavMesh::AddTile(NavigationScene* scene, NavMeshTileData& tileData)
void NavMeshRuntime::AddTile(NavigationScene* scene, NavMeshTileData& tileData)
{
ASSERT(scene);
auto& data = scene->Data;
PROFILE_CPU_NAMED("NavMesh.AddTile");
PROFILE_CPU_NAMED("NavMeshRuntime.AddTile");
ScopeLock lock(Locker);
@@ -198,17 +198,17 @@ void NavMesh::AddTile(NavigationScene* scene, NavMeshTileData& tileData)
AddTileInternal(scene, tileData);
}
bool IsTileFromScene(const NavMesh* navMesh, const NavMeshTile& tile, void* customData)
bool IsTileFromScene(const NavMeshRuntime* navMesh, const NavMeshTile& tile, void* customData)
{
return tile.Scene == (NavigationScene*)customData;
}
void NavMesh::RemoveTiles(NavigationScene* scene)
void NavMeshRuntime::RemoveTiles(NavigationScene* scene)
{
RemoveTiles(IsTileFromScene, scene);
}
void NavMesh::RemoveTile(int32 x, int32 y, int32 layer)
void NavMeshRuntime::RemoveTile(int32 x, int32 y, int32 layer)
{
ScopeLock lock(Locker);
@@ -216,7 +216,7 @@ void NavMesh::RemoveTile(int32 x, int32 y, int32 layer)
if (!_navMesh)
return;
PROFILE_CPU_NAMED("NavMesh.RemoveTile");
PROFILE_CPU_NAMED("NavMeshRuntime.RemoveTile");
const auto tileRef = _navMesh->getTileRefAt(x, y, layer);
if (tileRef == 0)
@@ -240,7 +240,7 @@ void NavMesh::RemoveTile(int32 x, int32 y, int32 layer)
}
}
void NavMesh::RemoveTiles(bool (* prediction)(const NavMesh* navMesh, const NavMeshTile& tile, void* customData), void* userData)
void NavMeshRuntime::RemoveTiles(bool (* prediction)(const NavMeshRuntime* navMesh, const NavMeshTile& tile, void* customData), void* userData)
{
ScopeLock lock(Locker);
@@ -249,7 +249,7 @@ void NavMesh::RemoveTiles(bool (* prediction)(const NavMesh* navMesh, const NavM
if (!_navMesh)
return;
PROFILE_CPU_NAMED("NavMesh.RemoveTiles");
PROFILE_CPU_NAMED("NavMeshRuntime.RemoveTiles");
for (int32 i = 0; i < _tiles.Count(); i++)
{
@@ -274,7 +274,7 @@ void NavMesh::RemoveTiles(bool (* prediction)(const NavMesh* navMesh, const NavM
}
}
void NavMesh::Dispose()
void NavMeshRuntime::Dispose()
{
if (_navMesh)
{
@@ -284,7 +284,7 @@ void NavMesh::Dispose()
_tiles.Resize(0);
}
void NavMesh::AddTileInternal(NavigationScene* scene, NavMeshTileData& tileData)
void NavMeshRuntime::AddTileInternal(NavigationScene* scene, NavMeshTileData& tileData)
{
// Check if that tile has been added to navmesh
NavMeshTile* tile = nullptr;

View File

@@ -21,8 +21,12 @@ public:
BytesContainer Data;
};
class FLAXENGINE_API NavMesh
class NavMeshRuntime
{
public:
static NavMeshRuntime* Get();
private:
dtNavMesh* _navMesh;
@@ -32,14 +36,13 @@ private:
public:
NavMesh();
~NavMesh();
NavMeshRuntime();
~NavMeshRuntime();
public:
/// <summary>
/// The NavMesh object locker.
/// The object locker.
/// </summary>
CriticalSection Locker;
@@ -110,7 +113,7 @@ public:
/// </summary>
/// <param name="prediction">The prediction callback, returns true for tiles to remove and false for tiles to preserve.</param>
/// <param name="userData">The user data passed to the callback method.</param>
void RemoveTiles(bool (*prediction)(const NavMesh* navMesh, const NavMeshTile& tile, void* customData), void* userData);
void RemoveTiles(bool (*prediction)(const NavMeshRuntime* navMesh, const NavMeshTile& tile, void* customData), void* userData);
/// <summary>
/// Releases the navmesh.

View File

@@ -1,11 +1,12 @@
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
#include "Navigation.h"
#include "NavMeshRuntime.h"
#include "NavMeshBuilder.h"
#include "Engine/Threading/Threading.h"
#include "Engine/Level/Scene/Scene.h"
#include "Engine/Engine/EngineService.h"
#include "NavMeshBuilder.h"
#include "NavMesh.h"
#include "Engine/Profiler/ProfilerCPU.h"
#include <ThirdParty/recastnavigation/RecastAlloc.h>
#include <ThirdParty/recastnavigation/DetourNavMesh.h>
#include <ThirdParty/recastnavigation/DetourNavMeshQuery.h>
@@ -13,7 +14,15 @@
#define DEFAULT_NAV_QUERY_EXTENT_HORIZONTAL 50.0f
#define DEFAULT_NAV_QUERY_EXTENT_VERTICAL 250.0f
NavMesh* _navMesh = nullptr;
namespace
{
NavMeshRuntime* _navMesh;
}
NavMeshRuntime* NavMeshRuntime::Get()
{
return ::_navMesh;
}
class NavigationService : public EngineService
{
@@ -36,11 +45,6 @@ public:
NavigationService NavigationServiceInstance;
NavMesh* Navigation::GetNavMesh()
{
return _navMesh;
}
void* dtAllocDefault(size_t size, dtAllocHint)
{
return Allocator::Allocate(size);
@@ -58,7 +62,7 @@ bool NavigationService::Init()
rcAllocSetCustom(rcAllocDefault, Allocator::Free);
// Create global nav mesh
_navMesh = New<NavMesh>();
_navMesh = New<NavMeshRuntime>();
return false;
}

View File

@@ -6,7 +6,6 @@
#include "Engine/Core/Math/Vector3.h"
class Scene;
class NavMesh;
#define NAV_MESH_PATH_MAX_SIZE 200
@@ -39,14 +38,6 @@ DECLARE_SCRIPTING_TYPE_MINIMAL(NavMeshHit);
API_CLASS(Static) class FLAXENGINE_API Navigation
{
DECLARE_SCRIPTING_TYPE_NO_SPAWN(Navigation);
public:
/// <summary>
/// Gets the navigation mesh (read-only). Use the other API to request data to use safe access to the navigation system.
/// </summary>
/// <returns>The navigation mesh.</returns>
static NavMesh* GetNavMesh();
public:
/// <summary>

View File

@@ -1,8 +1,8 @@
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
#include "NavigationScene.h"
#include "NavMesh.h"
#include "Navigation.h"
#include "NavMeshRuntime.h"
#include "NavMeshBoundsVolume.h"
#include "Engine/Profiler/ProfilerCPU.h"
#include "Engine/Level/Scene/Scene.h"
@@ -101,14 +101,14 @@ void NavigationScene::SaveNavMesh()
void NavigationScene::OnEnable()
{
auto navMesh = Navigation::GetNavMesh();
if (navMesh)
navMesh->AddTiles(this);
auto navMesh = NavMeshRuntime::Get();
CHECK(navMesh);
navMesh->AddTiles(this);
}
void NavigationScene::OnDisable()
{
auto navMesh = Navigation::GetNavMesh();
auto navMesh = NavMeshRuntime::Get();
if (navMesh)
navMesh->RemoveTiles(this);
}