mirror of
https://github.com/OpenMW/openmw.git
synced 2025-03-29 03:36:40 +00:00
Remove tiles present on navmesh but outside desired area
This commit is contained in:
parent
61c69c5563
commit
d6f3d34f2f
3 changed files with 104 additions and 3 deletions
|
@ -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…
Reference in a new issue