From a1438f65feccb3e7b2c58b2af99be86891b13bcc Mon Sep 17 00:00:00 2001 From: elsid Date: Sat, 30 Mar 2024 02:09:55 +0100 Subject: [PATCH] Set proper max tiles on initializing navmesh settings --- .../detournavigator/asyncnavmeshupdater.cpp | 11 +- components/detournavigator/makenavmesh.cpp | 26 +---- components/detournavigator/navmeshmanager.cpp | 2 +- components/detournavigator/settings.cpp | 103 +++++++++++++----- components/detournavigator/settings.hpp | 4 - files/settings-default.cfg | 2 +- 6 files changed, 81 insertions(+), 67 deletions(-) diff --git a/components/detournavigator/asyncnavmeshupdater.cpp b/components/detournavigator/asyncnavmeshupdater.cpp index 03f6062788..1ea7b63429 100644 --- a/components/detournavigator/asyncnavmeshupdater.cpp +++ b/components/detournavigator/asyncnavmeshupdater.cpp @@ -180,13 +180,10 @@ namespace DetourNavigator if (!playerTileChanged && changedTiles.empty()) return; - const int maxTiles - = std::min(mSettings.get().mMaxTilesNumber, navMeshCacheItem->lockConst()->getImpl().getParams()->maxTiles); - std::unique_lock lock(mMutex); if (playerTileChanged) - updateJobs(mWaiting, playerTile, maxTiles); + updateJobs(mWaiting, playerTile, mSettings.get().mMaxTilesNumber); for (const auto& [changedTile, changeType] : changedTiles) { @@ -221,7 +218,7 @@ namespace DetourNavigator lock.unlock(); if (playerTileChanged && mDbWorker != nullptr) - mDbWorker->updateJobs(playerTile, maxTiles); + mDbWorker->updateJobs(playerTile, mSettings.get().mMaxTilesNumber); } void AsyncNavMeshUpdater::wait(WaitConditionType waitConditionType, Loading::Listener* listener) @@ -376,10 +373,8 @@ namespace DetourNavigator return JobStatus::Done; const auto playerTile = *mPlayerTile.lockConst(); - const int maxTiles - = std::min(mSettings.get().mMaxTilesNumber, navMeshCacheItem->lockConst()->getImpl().getParams()->maxTiles); - if (!shouldAddTile(job.mChangedTile, playerTile, maxTiles)) + if (!shouldAddTile(job.mChangedTile, playerTile, mSettings.get().mMaxTilesNumber)) { Log(Debug::Debug) << "Ignore add tile by job " << job.mId << ": too far from player"; navMeshCacheItem->lock()->removeTile(job.mChangedTile); diff --git a/components/detournavigator/makenavmesh.cpp b/components/detournavigator/makenavmesh.cpp index d35ecf499d..e143bf1837 100644 --- a/components/detournavigator/makenavmesh.cpp +++ b/components/detournavigator/makenavmesh.cpp @@ -480,15 +480,6 @@ namespace DetourNavigator return true; } - template - unsigned long getMinValuableBitsNumber(const T value) - { - unsigned long power = 0; - while (power < sizeof(T) * 8 && (static_cast(1) << power) < value) - ++power; - return power; - } - std::pair getBoundsByZ( const RecastMesh& recastMesh, float agentHalfExtentsZ, const RecastSettings& settings) { @@ -528,10 +519,7 @@ namespace DetourNavigator return { minZ, maxZ }; } } -} // namespace DetourNavigator -namespace DetourNavigator -{ std::unique_ptr prepareNavMeshTileData(const RecastMesh& recastMesh, std::string_view worldspace, const TilePosition& tilePosition, const AgentBounds& agentBounds, const RecastSettings& settings) @@ -621,22 +609,12 @@ namespace DetourNavigator void initEmptyNavMesh(const Settings& settings, dtNavMesh& navMesh) { - // Max tiles and max polys affect how the tile IDs are caculated. - // There are 22 bits available for identifying a tile and a polygon. - const int polysAndTilesBits = 22; - const auto polysBits = getMinValuableBitsNumber(settings.mDetour.mMaxPolys); - - if (polysBits >= polysAndTilesBits) - throw InvalidArgument("Too many polygons per tile"); - - const auto tilesBits = polysAndTilesBits - polysBits; - dtNavMeshParams params; std::fill_n(params.orig, 3, 0.0f); params.tileWidth = settings.mRecast.mTileSize * settings.mRecast.mCellSize; params.tileHeight = settings.mRecast.mTileSize * settings.mRecast.mCellSize; - params.maxTiles = 1 << tilesBits; - params.maxPolys = 1 << polysBits; + params.maxTiles = settings.mMaxTilesNumber; + params.maxPolys = settings.mDetour.mMaxPolys; const auto status = navMesh.init(¶ms); diff --git a/components/detournavigator/navmeshmanager.cpp b/components/detournavigator/navmeshmanager.cpp index f4a82b850f..e6f831bb6e 100644 --- a/components/detournavigator/navmeshmanager.cpp +++ b/components/detournavigator/navmeshmanager.cpp @@ -181,7 +181,7 @@ namespace DetourNavigator { const auto locked = cached->lockConst(); const auto& navMesh = locked->getImpl(); - const auto maxTiles = std::min(mSettings.mMaxTilesNumber, navMesh.getParams()->maxTiles); + const int maxTiles = mSettings.mMaxTilesNumber; getTilesPositions(range, [&](const TilePosition& tile) { if (changedTiles.find(tile) != changedTiles.end()) return; diff --git a/components/detournavigator/settings.cpp b/components/detournavigator/settings.cpp index 0470c629e5..5e555050f7 100644 --- a/components/detournavigator/settings.cpp +++ b/components/detournavigator/settings.cpp @@ -3,41 +3,81 @@ #include #include +#include +#include +#include + namespace DetourNavigator { - RecastSettings makeRecastSettingsFromSettingsManager() + namespace { - RecastSettings result; - - result.mBorderSize = ::Settings::navigator().mBorderSize; - result.mCellHeight = ::Settings::navigator().mCellHeight; - result.mCellSize = ::Settings::navigator().mCellSize; - result.mDetailSampleDist = ::Settings::navigator().mDetailSampleDist; - result.mDetailSampleMaxError = ::Settings::navigator().mDetailSampleMaxError; - result.mMaxClimb = Constants::sStepSizeUp; - result.mMaxSimplificationError = ::Settings::navigator().mMaxSimplificationError; - result.mMaxSlope = Constants::sMaxSlope; - result.mRecastScaleFactor = ::Settings::navigator().mRecastScaleFactor; - result.mSwimHeightScale = 0; - result.mMaxEdgeLen = ::Settings::navigator().mMaxEdgeLen; - result.mMaxVertsPerPoly = ::Settings::navigator().mMaxVertsPerPoly; - result.mRegionMergeArea = ::Settings::navigator().mRegionMergeArea; - result.mRegionMinArea = ::Settings::navigator().mRegionMinArea; - result.mTileSize = ::Settings::navigator().mTileSize; + struct NavMeshLimits + { + int mMaxTiles; + int mMaxPolys; + }; - return result; - } + template + unsigned long getMinValuableBitsNumber(const T value) + { + unsigned long power = 0; + while (power < sizeof(T) * 8 && (static_cast(1) << power) < value) + ++power; + return power; + } - DetourSettings makeDetourSettingsFromSettingsManager() - { - DetourSettings result; + NavMeshLimits getNavMeshTileLimits(const DetourSettings& settings) + { + // Max tiles and max polys affect how the tile IDs are caculated. + // There are 22 bits available for identifying a tile and a polygon. + constexpr int polysAndTilesBits = 22; + const unsigned long polysBits = getMinValuableBitsNumber(settings.mMaxPolys); - result.mMaxNavMeshQueryNodes = ::Settings::navigator().mMaxNavMeshQueryNodes; - result.mMaxPolys = ::Settings::navigator().mMaxPolygonsPerTile; - result.mMaxPolygonPathSize = ::Settings::navigator().mMaxPolygonPathSize; - result.mMaxSmoothPathSize = ::Settings::navigator().mMaxSmoothPathSize; + if (polysBits >= polysAndTilesBits) + throw std::invalid_argument("Too many polygons per tile: " + std::to_string(settings.mMaxPolys)); - return result; + const unsigned long tilesBits = polysAndTilesBits - polysBits; + + return NavMeshLimits{ + .mMaxTiles = static_cast(1 << tilesBits), + .mMaxPolys = static_cast(1 << polysBits), + }; + } + + RecastSettings makeRecastSettingsFromSettingsManager() + { + RecastSettings result; + + result.mBorderSize = ::Settings::navigator().mBorderSize; + result.mCellHeight = ::Settings::navigator().mCellHeight; + result.mCellSize = ::Settings::navigator().mCellSize; + result.mDetailSampleDist = ::Settings::navigator().mDetailSampleDist; + result.mDetailSampleMaxError = ::Settings::navigator().mDetailSampleMaxError; + result.mMaxClimb = Constants::sStepSizeUp; + result.mMaxSimplificationError = ::Settings::navigator().mMaxSimplificationError; + result.mMaxSlope = Constants::sMaxSlope; + result.mRecastScaleFactor = ::Settings::navigator().mRecastScaleFactor; + result.mSwimHeightScale = 0; + result.mMaxEdgeLen = ::Settings::navigator().mMaxEdgeLen; + result.mMaxVertsPerPoly = ::Settings::navigator().mMaxVertsPerPoly; + result.mRegionMergeArea = ::Settings::navigator().mRegionMergeArea; + result.mRegionMinArea = ::Settings::navigator().mRegionMinArea; + result.mTileSize = ::Settings::navigator().mTileSize; + + return result; + } + + DetourSettings makeDetourSettingsFromSettingsManager() + { + DetourSettings result; + + result.mMaxNavMeshQueryNodes = ::Settings::navigator().mMaxNavMeshQueryNodes; + result.mMaxPolys = ::Settings::navigator().mMaxPolygonsPerTile; + result.mMaxPolygonPathSize = ::Settings::navigator().mMaxPolygonPathSize; + result.mMaxSmoothPathSize = ::Settings::navigator().mMaxSmoothPathSize; + + return result; + } } Settings makeSettingsFromSettingsManager() @@ -46,7 +86,12 @@ namespace DetourNavigator result.mRecast = makeRecastSettingsFromSettingsManager(); result.mDetour = makeDetourSettingsFromSettingsManager(); - result.mMaxTilesNumber = ::Settings::navigator().mMaxTilesNumber; + + const NavMeshLimits limits = getNavMeshTileLimits(result.mDetour); + + result.mDetour.mMaxPolys = limits.mMaxPolys; + + result.mMaxTilesNumber = std::min(limits.mMaxTiles, ::Settings::navigator().mMaxTilesNumber.get()); result.mWaitUntilMinDistanceToPlayer = ::Settings::navigator().mWaitUntilMinDistanceToPlayer; result.mAsyncNavMeshUpdaterThreads = ::Settings::navigator().mAsyncNavMeshUpdaterThreads; result.mMaxNavMeshTilesCacheSize = ::Settings::navigator().mMaxNavMeshTilesCacheSize; diff --git a/components/detournavigator/settings.hpp b/components/detournavigator/settings.hpp index 45bcf15dbf..1d1f6f5847 100644 --- a/components/detournavigator/settings.hpp +++ b/components/detournavigator/settings.hpp @@ -55,10 +55,6 @@ namespace DetourNavigator inline constexpr std::int64_t navMeshFormatVersion = 2; - RecastSettings makeRecastSettingsFromSettingsManager(); - - DetourSettings makeDetourSettingsFromSettingsManager(); - Settings makeSettingsFromSettingsManager(); } diff --git a/files/settings-default.cfg b/files/settings-default.cfg index 73331867a7..2f236bf55a 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -981,7 +981,7 @@ enable agents paths render = false enable recast mesh render = false # Max number of navmesh tiles (value >= 0) -max tiles number = 512 +max tiles number = 1024 # Min time duration for the same tile update in milliseconds (value >= 0) min update interval ms = 250