mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-27 21:35:24 +00:00
Remove tiles present on navmesh but outside desired area
This commit is contained in:
parent
61c69c5563
commit
d6f3d34f2f
@ -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…
x
Reference in New Issue
Block a user