Fix crash when resizing navmesh capacity with crowd created for that navmesh

This commit is contained in:
Wojtek Figat
2023-12-18 21:45:27 +01:00
parent bc2e130281
commit 8a94e053a8
3 changed files with 30 additions and 24 deletions

View File

@@ -36,7 +36,7 @@ NavMeshRuntime::NavMeshRuntime(const NavMeshProperties& properties)
NavMeshRuntime::~NavMeshRuntime()
{
dtFreeNavMesh(_navMesh);
Dispose();
dtFreeNavMeshQuery(_navMeshQuery);
}
@@ -336,9 +336,7 @@ void NavMeshRuntime::SetTileSize(float tileSize)
// Dispose the existing mesh (its invalid)
if (_navMesh)
{
dtFreeNavMesh(_navMesh);
_navMesh = nullptr;
_tiles.Clear();
Dispose();
}
_tileSize = tileSize;
@@ -363,14 +361,9 @@ void NavMeshRuntime::EnsureCapacity(int32 tilesToAddCount)
// Ensure to have size assigned
ASSERT(_tileSize != 0);
// Fre previous data (if any)
if (_navMesh)
{
dtFreeNavMesh(_navMesh);
}
// Allocate new navmesh
_navMesh = dtAllocNavMesh();
// Allocate navmesh and initialize the default query
if (!_navMesh)
_navMesh = dtAllocNavMesh();
if (dtStatusFailed(_navMeshQuery->init(_navMesh, MAX_NODES)))
{
LOG(Error, "Failed to initialize navmesh {0}.", Properties.Name);
@@ -517,7 +510,7 @@ void NavMeshRuntime::RemoveTile(int32 x, int32 y, int32 layer)
}
}
void NavMeshRuntime::RemoveTiles(bool (* prediction)(const NavMeshRuntime* 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);
ASSERT(prediction);

View File

@@ -208,21 +208,13 @@ dtNavMesh::dtNavMesh() :
dtNavMesh::~dtNavMesh()
{
for (int i = 0; i < m_maxTiles; ++i)
{
if (m_tiles[i].flags & DT_TILE_FREE_DATA)
{
dtFree(m_tiles[i].data);
m_tiles[i].data = 0;
m_tiles[i].dataSize = 0;
}
}
dtFree(m_posLookup);
dtFree(m_tiles);
purge();
}
dtStatus dtNavMesh::init(const dtNavMeshParams* params)
{
if (m_tiles)
purge();
memcpy(&m_params, params, sizeof(dtNavMeshParams));
dtVcopy(m_orig, params->orig);
m_tileWidth = params->tileWidth;
@@ -1178,6 +1170,24 @@ int dtNavMesh::getMaxTiles() const
return m_maxTiles;
}
void dtNavMesh::purge()
{
for (int i = 0; i < m_maxTiles; ++i)
{
if (m_tiles[i].flags & DT_TILE_FREE_DATA)
{
dtFree(m_tiles[i].data);
m_tiles[i].data = 0;
m_tiles[i].dataSize = 0;
}
}
m_maxTiles = 0;
dtFree(m_posLookup);
m_posLookup = 0;
dtFree(m_tiles);
m_tiles = 0;
}
dtMeshTile* dtNavMesh::getTile(int i)
{
return &m_tiles[i];

View File

@@ -613,6 +613,9 @@ private:
dtNavMesh(const dtNavMesh&);
dtNavMesh& operator=(const dtNavMesh&);
/// Clears all tiles from memory. Can be called before init to rebuild navigation mesh with different parameters.
void purge();
/// Returns pointer to tile in the tile array.
dtMeshTile* getTile(int i);