Remove tiles present on navmesh but outside desired area

pull/3235/head
elsid 9 months ago
parent 61c69c5563
commit d6f3d34f2f
No known key found for this signature in database
GPG Key ID: 4DE04C198CBA7625

@ -1055,6 +1055,96 @@ namespace
} }
} }
TEST_P(DetourNavigatorUpdateTest, update_should_change_covered_area_when_player_moves_without_waiting_for_all)
{
Loading::Listener listener;
Settings settings = makeSettings();
settings.mMaxTilesNumber = 1;
settings.mWaitUntilMinDistanceToPlayer = 1;
NavigatorImpl navigator(settings, nullptr);
const AgentBounds agentBounds{ CollisionShapeType::Aabb, { 29, 29, 66 } };
ASSERT_TRUE(navigator.addAgent(agentBounds));
GetParam()(navigator);
{
auto updateGuard = navigator.makeUpdateGuard();
navigator.update(osg::Vec3f(3000, 3000, 0), updateGuard.get());
}
navigator.wait(WaitConditionType::requiredTilesPresent, &listener);
{
const auto navMesh = navigator.getNavMesh(agentBounds);
ASSERT_NE(navMesh, nullptr);
const TilePosition expectedTile(4, 4);
const auto usedTiles = getUsedTiles(*navMesh->lockConst());
EXPECT_THAT(usedTiles, Contains(expectedTile)) << usedTiles;
}
{
auto updateGuard = navigator.makeUpdateGuard();
navigator.update(osg::Vec3f(6000, 3000, 0), updateGuard.get());
}
navigator.wait(WaitConditionType::requiredTilesPresent, &listener);
{
const auto navMesh = navigator.getNavMesh(agentBounds);
ASSERT_NE(navMesh, nullptr);
const TilePosition expectedTile(8, 4);
const auto usedTiles = getUsedTiles(*navMesh->lockConst());
EXPECT_THAT(usedTiles, Contains(expectedTile)) << usedTiles;
}
}
TEST_P(DetourNavigatorUpdateTest, update_should_change_covered_area_when_player_moves_with_db)
{
Loading::Listener listener;
Settings settings = makeSettings();
settings.mMaxTilesNumber = 1;
settings.mWaitUntilMinDistanceToPlayer = 1;
NavigatorImpl navigator(settings, std::make_unique<NavMeshDb>(":memory:", settings.mMaxDbFileSize));
const AgentBounds agentBounds{ CollisionShapeType::Aabb, { 29, 29, 66 } };
ASSERT_TRUE(navigator.addAgent(agentBounds));
GetParam()(navigator);
{
auto updateGuard = navigator.makeUpdateGuard();
navigator.update(osg::Vec3f(3000, 3000, 0), updateGuard.get());
}
navigator.wait(WaitConditionType::requiredTilesPresent, &listener);
{
const auto navMesh = navigator.getNavMesh(agentBounds);
ASSERT_NE(navMesh, nullptr);
const TilePosition expectedTile(4, 4);
const auto usedTiles = getUsedTiles(*navMesh->lockConst());
EXPECT_THAT(usedTiles, Contains(expectedTile)) << usedTiles;
}
{
auto updateGuard = navigator.makeUpdateGuard();
navigator.update(osg::Vec3f(6000, 3000, 0), updateGuard.get());
}
navigator.wait(WaitConditionType::requiredTilesPresent, &listener);
{
const auto navMesh = navigator.getNavMesh(agentBounds);
ASSERT_NE(navMesh, nullptr);
const TilePosition expectedTile(8, 4);
const auto usedTiles = getUsedTiles(*navMesh->lockConst());
EXPECT_THAT(usedTiles, Contains(expectedTile)) << usedTiles;
}
}
struct AddHeightfieldSurface struct AddHeightfieldSurface
{ {
static constexpr std::size_t sSize = 65; static constexpr std::size_t sSize = 65;

@ -131,6 +131,15 @@ namespace DetourNavigator
function(position, tile.mVersion, *meshTile); function(position, tile.mVersion, *meshTile);
} }
template <class Function>
void forEachTilePosition(Function&& function) const
{
for (const auto& [position, tile] : mUsedTiles)
function(position);
for (const TilePosition& position : mEmptyTiles)
function(position);
}
private: private:
struct Tile struct Tile
{ {

@ -13,8 +13,6 @@
#include <DetourNavMesh.h> #include <DetourNavMesh.h>
#include <iterator>
namespace namespace
{ {
/// Safely reset shared_ptr with definite underlying object destrutor call. /// Safely reset shared_ptr with definite underlying object destrutor call.
@ -179,9 +177,9 @@ namespace DetourNavigator
{ {
std::map<osg::Vec2i, ChangeType> tilesToPost = changedTiles; std::map<osg::Vec2i, ChangeType> tilesToPost = changedTiles;
{ {
const int maxTiles = mSettings.mMaxTilesNumber;
const auto locked = cached->lockConst(); const auto locked = cached->lockConst();
const auto& navMesh = locked->getImpl(); const auto& navMesh = locked->getImpl();
const int maxTiles = mSettings.mMaxTilesNumber;
getTilesPositions(range, [&](const TilePosition& tile) { getTilesPositions(range, [&](const TilePosition& tile) {
if (changedTiles.find(tile) != changedTiles.end()) if (changedTiles.find(tile) != changedTiles.end())
return; return;
@ -192,6 +190,10 @@ namespace DetourNavigator
else if (!shouldAdd && presentInNavMesh) else if (!shouldAdd && presentInNavMesh)
tilesToPost.emplace(tile, ChangeType::mixed); tilesToPost.emplace(tile, ChangeType::mixed);
}); });
locked->forEachTilePosition([&](const TilePosition& tile) {
if (!shouldAddTile(tile, playerTile, maxTiles))
tilesToPost.emplace(tile, ChangeType::remove);
});
} }
mAsyncNavMeshUpdater.post(agentBounds, cached, playerTile, mWorldspace, tilesToPost); mAsyncNavMeshUpdater.post(agentBounds, cached, playerTile, mWorldspace, tilesToPost);
Log(Debug::Debug) << "Cache update posted for agent=" << agentBounds << " playerTile=" << playerTile Log(Debug::Debug) << "Cache update posted for agent=" << agentBounds << " playerTile=" << playerTile

Loading…
Cancel
Save