Remove objects, water and heightfields when no longer required

This commit is contained in:
elsid 2022-02-01 21:48:06 +01:00
parent bb6b031afd
commit 542717394a
No known key found for this signature in database
GPG key ID: B845CB9FEE18AB40
3 changed files with 33 additions and 5 deletions

View file

@ -1132,4 +1132,16 @@ namespace
Vec3fEq(306, 56.66666412353515625, -2.6667339801788330078125) Vec3fEq(306, 56.66666412353515625, -2.6667339801788330078125)
)) << mPath; )) << mPath;
} }
TEST_F(DetourNavigatorNavigatorTest, only_one_water_per_cell_is_allowed)
{
const int cellSize1 = 100;
const float level1 = 1;
const int cellSize2 = 200;
const float level2 = 2;
mNavigator->addAgent(mAgentHalfExtents);
EXPECT_TRUE(mNavigator->addWater(mCellPosition, cellSize1, level1));
EXPECT_FALSE(mNavigator->addWater(mCellPosition, cellSize2, level2));
}
} }

View file

@ -63,7 +63,7 @@ namespace
EXPECT_TRUE(manager.addObject(ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground)); EXPECT_TRUE(manager.addObject(ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground));
} }
TEST_F(DetourNavigatorTileCachedRecastMeshManagerTest, add_object_for_existing_object_should_return_false) TEST_F(DetourNavigatorTileCachedRecastMeshManagerTest, add_object_for_existing_object_should_throw_exception)
{ {
TileCachedRecastMeshManager manager(mSettings); TileCachedRecastMeshManager manager(mSettings);
const btBoxShape boxShape(btVector3(20, 20, 100)); const btBoxShape boxShape(btVector3(20, 20, 100));
@ -225,7 +225,7 @@ namespace
const CollisionShape shape(mInstance, boxShape, mObjectTransform); const CollisionShape shape(mInstance, boxShape, mObjectTransform);
manager.addObject(ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground); manager.addObject(ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground);
const auto beforeAddRevision = manager.getRevision(); const auto beforeAddRevision = manager.getRevision();
manager.addObject(ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground); EXPECT_FALSE(manager.addObject(ObjectId(&boxShape), shape, btTransform::getIdentity(), AreaType::AreaType_ground));
EXPECT_EQ(manager.getRevision(), beforeAddRevision); EXPECT_EQ(manager.getRevision(), beforeAddRevision);
} }

View file

@ -33,6 +33,9 @@ namespace DetourNavigator
bool TileCachedRecastMeshManager::addObject(const ObjectId id, const CollisionShape& shape, bool TileCachedRecastMeshManager::addObject(const ObjectId id, const CollisionShape& shape,
const btTransform& transform, const AreaType areaType) const btTransform& transform, const AreaType areaType)
{ {
const auto it = mObjectsTilesPositions.find(id);
if (it != mObjectsTilesPositions.end())
return false;
std::vector<TilePosition> tilesPositions; std::vector<TilePosition> tilesPositions;
{ {
const std::lock_guard lock(mMutex); const std::lock_guard lock(mMutex);
@ -46,7 +49,7 @@ namespace DetourNavigator
if (tilesPositions.empty()) if (tilesPositions.empty())
return false; return false;
std::sort(tilesPositions.begin(), tilesPositions.end()); std::sort(tilesPositions.begin(), tilesPositions.end());
mObjectsTilesPositions.insert_or_assign(id, std::move(tilesPositions)); mObjectsTilesPositions.emplace_hint(it, id, std::move(tilesPositions));
++mRevision; ++mRevision;
return true; return true;
} }
@ -66,6 +69,7 @@ namespace DetourNavigator
result = removed; result = removed;
} }
} }
mObjectsTilesPositions.erase(object);
if (result) if (result)
++mRevision; ++mRevision;
return result; return result;
@ -73,7 +77,12 @@ namespace DetourNavigator
bool TileCachedRecastMeshManager::addWater(const osg::Vec2i& cellPosition, int cellSize, float level) bool TileCachedRecastMeshManager::addWater(const osg::Vec2i& cellPosition, int cellSize, float level)
{ {
auto& tilesPositions = mWaterTilesPositions[cellPosition]; const auto it = mWaterTilesPositions.find(cellPosition);
if (it != mWaterTilesPositions.end())
return false;
std::vector<TilePosition>& tilesPositions = mWaterTilesPositions.emplace_hint(
it, cellPosition, std::vector<TilePosition>())->second;
bool result = false; bool result = false;
@ -138,6 +147,7 @@ namespace DetourNavigator
if (tileResult && !result) if (tileResult && !result)
result = tileResult; result = tileResult;
} }
mWaterTilesPositions.erase(object);
if (result) if (result)
++mRevision; ++mRevision;
return result; return result;
@ -146,8 +156,13 @@ namespace DetourNavigator
bool TileCachedRecastMeshManager::addHeightfield(const osg::Vec2i& cellPosition, int cellSize, bool TileCachedRecastMeshManager::addHeightfield(const osg::Vec2i& cellPosition, int cellSize,
const HeightfieldShape& shape) const HeightfieldShape& shape)
{ {
const auto it = mHeightfieldTilesPositions.find(cellPosition);
if (it != mHeightfieldTilesPositions.end())
return false;
std::vector<TilePosition>& tilesPositions = mHeightfieldTilesPositions.emplace_hint(
it, cellPosition, std::vector<TilePosition>())->second;
const btVector3 shift = getHeightfieldShift(shape, cellPosition, cellSize); const btVector3 shift = getHeightfieldShift(shape, cellPosition, cellSize);
auto& tilesPositions = mHeightfieldTilesPositions[cellPosition];
bool result = false; bool result = false;
@ -196,6 +211,7 @@ namespace DetourNavigator
if (tileResult && !result) if (tileResult && !result)
result = tileResult; result = tileResult;
} }
mHeightfieldTilesPositions.erase(object);
if (result) if (result)
++mRevision; ++mRevision;
return result; return result;