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
{
static constexpr std::size_t sSize = 65;

@ -131,6 +131,15 @@ namespace DetourNavigator
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:
struct Tile
{

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

Loading…
Cancel
Save