From abc51a8a17922850a086c48d077b8f17e7c5d8d7 Mon Sep 17 00:00:00 2001 From: elsid Date: Sun, 28 Oct 2018 14:59:12 +0300 Subject: [PATCH] Add settings option to set max number of polygons per navmesh tile --- apps/openmw/mwworld/worldimp.cpp | 1 + .../detournavigator/navigator.cpp | 1 + components/detournavigator/makenavmesh.cpp | 24 ++++++++++++++----- components/detournavigator/settings.hpp | 1 + files/settings-default.cfg | 5 ++++ 5 files changed, 26 insertions(+), 6 deletions(-) diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 93babf120..60c0395a0 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -211,6 +211,7 @@ namespace MWWorld navigatorSettings.mSwimHeightScale = mSwimHeightScale; navigatorSettings.mMaxEdgeLen = Settings::Manager::getInt("max edge len", "Navigator"); navigatorSettings.mMaxNavMeshQueryNodes = Settings::Manager::getInt("max nav mesh query nodes", "Navigator"); + navigatorSettings.mMaxPolys = Settings::Manager::getInt("max polygons per tile", "Navigator"); navigatorSettings.mMaxVertsPerPoly = Settings::Manager::getInt("max verts per poly", "Navigator"); navigatorSettings.mRegionMergeSize = Settings::Manager::getInt("region merge size", "Navigator"); navigatorSettings.mRegionMinSize = Settings::Manager::getInt("region min size", "Navigator"); diff --git a/apps/openmw_test_suite/detournavigator/navigator.cpp b/apps/openmw_test_suite/detournavigator/navigator.cpp index 7926e208d..febbc0387 100644 --- a/apps/openmw_test_suite/detournavigator/navigator.cpp +++ b/apps/openmw_test_suite/detournavigator/navigator.cpp @@ -60,6 +60,7 @@ namespace mSettings.mMaxPolygonPathSize = 1024; mSettings.mMaxSmoothPathSize = 1024; mSettings.mTrianglesPerChunk = 256; + mSettings.mMaxPolys = 4096; mNavigator.reset(new Navigator(mSettings)); } }; diff --git a/components/detournavigator/makenavmesh.cpp b/components/detournavigator/makenavmesh.cpp index 7f8a7b9d3..7072f2a23 100644 --- a/components/detournavigator/makenavmesh.cpp +++ b/components/detournavigator/makenavmesh.cpp @@ -456,6 +456,15 @@ namespace else return UpdateNavMeshStatus::ignore; } + + template + unsigned long getMinValuableBitsNumber(const T value) + { + unsigned long power = 0; + while (power < sizeof(T) * 8 && (static_cast(1) << power) < value) + ++power; + return power; + } } namespace DetourNavigator @@ -464,17 +473,20 @@ namespace DetourNavigator { // 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 auto tileBits = 10; - const auto polyBits = 22 - tileBits; - const auto maxTiles = 1 << tileBits; - const auto maxPolysPerTile = 1 << polyBits; + const int polysAndTilesBits = 22; + const auto polysBits = getMinValuableBitsNumber(settings.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.mTileSize * settings.mCellSize; params.tileHeight = settings.mTileSize * settings.mCellSize; - params.maxTiles = maxTiles; - params.maxPolys = maxPolysPerTile; + params.maxTiles = 1 << tilesBits; + params.maxPolys = 1 << polysBits; NavMeshPtr navMesh(dtAllocNavMesh(), &dtFreeNavMesh); const auto status = navMesh->init(¶ms); diff --git a/components/detournavigator/settings.hpp b/components/detournavigator/settings.hpp index f2eb2be24..3e537c2fb 100644 --- a/components/detournavigator/settings.hpp +++ b/components/detournavigator/settings.hpp @@ -23,6 +23,7 @@ namespace DetourNavigator int mBorderSize; int mMaxEdgeLen; int mMaxNavMeshQueryNodes; + int mMaxPolys; int mMaxVertsPerPoly; int mRegionMergeSize; int mRegionMinSize; diff --git a/files/settings-default.cfg b/files/settings-default.cfg index a76eaf1d6..d8f5faaa9 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -576,6 +576,11 @@ max edge len = 12 # Maximum number of search nodes. (0 < value <= 65535) max nav mesh query nodes = 2048 +# Maximum number of polygons per navmesh tile (value = 2^n, 0 < n < 22). Maximum number of navmesh tiles depends on +# this value. 22 bits is a limit to store both tile identifier and polygon identifier (tiles = 2^(22 - log2(polygons))). +# See recastnavigation for more details. +max polygons per tile = 4096 + # The maximum number of vertices allowed for polygons generated during the contour to polygon conversion process. (value >= 3) max verts per poly = 6