Fix crash when resizing navmesh capacity with crowd created for that navmesh
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user