From 0c6f1ff9dc2a0ec68ec2c2524861e9590f575685 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Thu, 3 Apr 2025 17:21:48 +0200 Subject: [PATCH] Optimize NavMesh to not allocate tile memory twice and add safelock to asset data --- Source/Engine/Content/Assets/RawDataAsset.cpp | 5 ++--- Source/Engine/Navigation/NavMesh.cpp | 1 + Source/Engine/Navigation/NavMeshData.cpp | 2 +- Source/Engine/Navigation/NavMeshData.h | 4 ++-- Source/Engine/Navigation/NavMeshRuntime.cpp | 9 +++++++-- 5 files changed, 13 insertions(+), 8 deletions(-) diff --git a/Source/Engine/Content/Assets/RawDataAsset.cpp b/Source/Engine/Content/Assets/RawDataAsset.cpp index 5c39683da..106fd5a1b 100644 --- a/Source/Engine/Content/Assets/RawDataAsset.cpp +++ b/Source/Engine/Content/Assets/RawDataAsset.cpp @@ -70,9 +70,8 @@ Asset::LoadResult RawDataAsset::load() if (chunk0 == nullptr || chunk0->IsMissing()) return LoadResult::MissingDataChunk; - Data.Clear(); - Data.EnsureCapacity(chunk0->Data.Length()); - Data.Add(chunk0->Data.Get(), chunk0->Data.Length()); + // TODO: swap memory alloc pointer to optimize this asset + Data.Set(chunk0->Data.Get(), chunk0->Data.Length()); return LoadResult::Ok; } diff --git a/Source/Engine/Navigation/NavMesh.cpp b/Source/Engine/Navigation/NavMesh.cpp index 7eb2b468a..772336ba3 100644 --- a/Source/Engine/Navigation/NavMesh.cpp +++ b/Source/Engine/Navigation/NavMesh.cpp @@ -104,6 +104,7 @@ void NavMesh::OnDataAssetLoaded() // Skip if already has data (prevent reloading navmesh on saving) if (Data.Tiles.HasItems()) return; + ScopeLock lock(DataAsset->Locker); // Remove added tiles if (_navMeshActive) diff --git a/Source/Engine/Navigation/NavMeshData.cpp b/Source/Engine/Navigation/NavMeshData.cpp index c6faccc1e..fc4332e3f 100644 --- a/Source/Engine/Navigation/NavMeshData.cpp +++ b/Source/Engine/Navigation/NavMeshData.cpp @@ -80,7 +80,7 @@ bool NavMeshData::Load(BytesContainer& data, bool copyData) tile.Layer = tileHeader->Layer; // Read tile data - const auto tileData = stream.Move(tileHeader->DataSize); + const auto* tileData = (const byte*)stream.Move(tileHeader->DataSize); if (copyData) tile.Data.Copy(tileData, tileHeader->DataSize); else diff --git a/Source/Engine/Navigation/NavMeshData.h b/Source/Engine/Navigation/NavMeshData.h index 651331074..0f2a2bb7d 100644 --- a/Source/Engine/Navigation/NavMeshData.h +++ b/Source/Engine/Navigation/NavMeshData.h @@ -7,13 +7,13 @@ class WriteStream; -struct NavMeshTileDataHeader +PACK_STRUCT(struct NavMeshTileDataHeader { int32 PosX; int32 PosY; int32 Layer; int32 DataSize; -}; +}); struct NavMeshTileData { diff --git a/Source/Engine/Navigation/NavMeshRuntime.cpp b/Source/Engine/Navigation/NavMeshRuntime.cpp index c4576aa53..fb42cf1ea 100644 --- a/Source/Engine/Navigation/NavMeshRuntime.cpp +++ b/Source/Engine/Navigation/NavMeshRuntime.cpp @@ -13,8 +13,7 @@ #define MAX_NODES 2048 #define USE_DATA_LINK 0 -#define USE_NAV_MESH_ALLOC 1 -// TODO: try not using USE_NAV_MESH_ALLOC +#define USE_NAV_MESH_ALLOC 0 namespace { @@ -367,6 +366,9 @@ void NavMeshRuntime::EnsureCapacity(int32 tilesToAddCount) if (dtStatusFailed(result)) { LOG(Warning, "Could not add tile ({2}x{3}, layer {4}) to navmesh {0} (error: {1})", Properties.Name, result & ~DT_FAILURE, tile.X, tile.Y, tile.Layer); +#if USE_NAV_MESH_ALLOC + dtFree(data); +#endif } } } @@ -672,5 +674,8 @@ void NavMeshRuntime::AddTileInternal(NavMesh* navMesh, NavMeshTileData& tileData if (dtStatusFailed(result)) { LOG(Warning, "Could not add tile ({2}x{3}, layer {4}) to navmesh {0} (error: {1})", Properties.Name, result & ~DT_FAILURE, tileData.PosX, tileData.PosY, tileData.Layer); +#if USE_NAV_MESH_ALLOC + dtFree(data); +#endif } }