mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-02-21 21:09:40 +00:00
Prioritise NavMesh jobs first to remove and last to add
When player move fast enough, tiles update for specific area square couldn't catch player move. Tiles to be removed are left in the queue with lower priority then tiles to be added which are nearest to player. This can lead to overflow for amount of tiles. So we try to do remove first. But we detect change type approximately using mixed change type, because even if we do it precise, change type could change while job is in queue.
This commit is contained in:
parent
b33a291a67
commit
c771986c56
4 changed files with 61 additions and 22 deletions
|
@ -9,16 +9,22 @@
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
using DetourNavigator::ChangeType;
|
||||||
using DetourNavigator::TilePosition;
|
using DetourNavigator::TilePosition;
|
||||||
|
|
||||||
int getDistance(const TilePosition& lhs, const TilePosition& rhs)
|
int getManhattanDistance(const TilePosition& lhs, const TilePosition& rhs)
|
||||||
{
|
{
|
||||||
return std::abs(lhs.x() - rhs.x()) + std::abs(lhs.y() - rhs.y());
|
return std::abs(lhs.x() - rhs.x()) + std::abs(lhs.y() - rhs.y());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<int, int> makePriority(const TilePosition& changedTile, const TilePosition& playerTile)
|
std::tuple<ChangeType, int, int> makePriority(const TilePosition& position, const ChangeType changeType,
|
||||||
|
const TilePosition& playerTile)
|
||||||
{
|
{
|
||||||
return std::make_pair(getDistance(changedTile, playerTile), getDistance(changedTile, TilePosition {0, 0}));
|
return std::make_tuple(
|
||||||
|
changeType,
|
||||||
|
getManhattanDistance(position, playerTile),
|
||||||
|
getManhattanDistance(position, TilePosition {0, 0})
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +66,7 @@ namespace DetourNavigator
|
||||||
|
|
||||||
void AsyncNavMeshUpdater::post(const osg::Vec3f& agentHalfExtents,
|
void AsyncNavMeshUpdater::post(const osg::Vec3f& agentHalfExtents,
|
||||||
const std::shared_ptr<NavMeshCacheItem>& navMeshCacheItem, const TilePosition& playerTile,
|
const std::shared_ptr<NavMeshCacheItem>& navMeshCacheItem, const TilePosition& playerTile,
|
||||||
const std::set<TilePosition>& changedTiles)
|
const std::map<TilePosition, ChangeType>& changedTiles)
|
||||||
{
|
{
|
||||||
log("post jobs playerTile=", playerTile);
|
log("post jobs playerTile=", playerTile);
|
||||||
|
|
||||||
|
@ -73,9 +79,9 @@ namespace DetourNavigator
|
||||||
|
|
||||||
for (const auto& changedTile : changedTiles)
|
for (const auto& changedTile : changedTiles)
|
||||||
{
|
{
|
||||||
if (mPushed[agentHalfExtents].insert(changedTile).second)
|
if (mPushed[agentHalfExtents].insert(changedTile.first).second)
|
||||||
mJobs.push(Job {agentHalfExtents, navMeshCacheItem, changedTile,
|
mJobs.push(Job {agentHalfExtents, navMeshCacheItem, changedTile.first,
|
||||||
makePriority(changedTile, playerTile)});
|
makePriority(changedTile.first, changedTile.second, playerTile)});
|
||||||
}
|
}
|
||||||
|
|
||||||
log("posted ", mJobs.size(), " jobs");
|
log("posted ", mJobs.size(), " jobs");
|
||||||
|
|
|
@ -22,6 +22,13 @@ class dtNavMesh;
|
||||||
|
|
||||||
namespace DetourNavigator
|
namespace DetourNavigator
|
||||||
{
|
{
|
||||||
|
enum class ChangeType
|
||||||
|
{
|
||||||
|
remove = 0,
|
||||||
|
mixed = 1,
|
||||||
|
add = 2,
|
||||||
|
};
|
||||||
|
|
||||||
class AsyncNavMeshUpdater
|
class AsyncNavMeshUpdater
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -29,7 +36,7 @@ namespace DetourNavigator
|
||||||
~AsyncNavMeshUpdater();
|
~AsyncNavMeshUpdater();
|
||||||
|
|
||||||
void post(const osg::Vec3f& agentHalfExtents, const std::shared_ptr<NavMeshCacheItem>& mNavMeshCacheItem,
|
void post(const osg::Vec3f& agentHalfExtents, const std::shared_ptr<NavMeshCacheItem>& mNavMeshCacheItem,
|
||||||
const TilePosition& playerTile, const std::set<TilePosition>& changedTiles);
|
const TilePosition& playerTile, const std::map<TilePosition, ChangeType>& changedTiles);
|
||||||
|
|
||||||
void wait();
|
void wait();
|
||||||
|
|
||||||
|
@ -39,7 +46,7 @@ namespace DetourNavigator
|
||||||
osg::Vec3f mAgentHalfExtents;
|
osg::Vec3f mAgentHalfExtents;
|
||||||
std::shared_ptr<NavMeshCacheItem> mNavMeshCacheItem;
|
std::shared_ptr<NavMeshCacheItem> mNavMeshCacheItem;
|
||||||
TilePosition mChangedTile;
|
TilePosition mChangedTile;
|
||||||
std::pair<int, int> mPriority;
|
std::tuple<ChangeType, int, int> mPriority;
|
||||||
|
|
||||||
friend inline bool operator <(const Job& lhs, const Job& rhs)
|
friend inline bool operator <(const Job& lhs, const Job& rhs)
|
||||||
{
|
{
|
||||||
|
|
|
@ -13,6 +13,16 @@
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
using DetourNavigator::ChangeType;
|
||||||
|
|
||||||
|
ChangeType addChangeType(const ChangeType current, const ChangeType add)
|
||||||
|
{
|
||||||
|
return current == add ? current : ChangeType::mixed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
namespace DetourNavigator
|
namespace DetourNavigator
|
||||||
{
|
{
|
||||||
NavMeshManager::NavMeshManager(const Settings& settings)
|
NavMeshManager::NavMeshManager(const Settings& settings)
|
||||||
|
@ -26,7 +36,7 @@ namespace DetourNavigator
|
||||||
{
|
{
|
||||||
if (!mRecastMeshManager.addObject(id, shape, transform))
|
if (!mRecastMeshManager.addObject(id, shape, transform))
|
||||||
return false;
|
return false;
|
||||||
addChangedTiles(shape, transform);
|
addChangedTiles(shape, transform, ChangeType::add);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +44,7 @@ namespace DetourNavigator
|
||||||
{
|
{
|
||||||
if (!mRecastMeshManager.updateObject(id, transform))
|
if (!mRecastMeshManager.updateObject(id, transform))
|
||||||
return false;
|
return false;
|
||||||
addChangedTiles(shape, transform);
|
addChangedTiles(shape, transform, ChangeType::mixed);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,7 +53,7 @@ namespace DetourNavigator
|
||||||
const auto object = mRecastMeshManager.removeObject(id);
|
const auto object = mRecastMeshManager.removeObject(id);
|
||||||
if (!object)
|
if (!object)
|
||||||
return false;
|
return false;
|
||||||
addChangedTiles(object->mShape, object->mTransform);
|
addChangedTiles(object->mShape, object->mTransform, ChangeType::remove);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,7 +82,7 @@ namespace DetourNavigator
|
||||||
return;
|
return;
|
||||||
mLastRecastMeshManagerRevision = mRecastMeshManager.getRevision();
|
mLastRecastMeshManagerRevision = mRecastMeshManager.getRevision();
|
||||||
mPlayerTile = playerTile;
|
mPlayerTile = playerTile;
|
||||||
std::set<TilePosition> tilesToPost;
|
std::map<TilePosition, ChangeType> tilesToPost;
|
||||||
const auto& cached = getCached(agentHalfExtents);
|
const auto& cached = getCached(agentHalfExtents);
|
||||||
const auto changedTiles = mChangedTiles.find(agentHalfExtents);
|
const auto changedTiles = mChangedTiles.find(agentHalfExtents);
|
||||||
{
|
{
|
||||||
|
@ -80,10 +90,16 @@ namespace DetourNavigator
|
||||||
if (changedTiles != mChangedTiles.end())
|
if (changedTiles != mChangedTiles.end())
|
||||||
{
|
{
|
||||||
for (const auto& tile : changedTiles->second)
|
for (const auto& tile : changedTiles->second)
|
||||||
if (locked->getTileAt(tile.x(), tile.y(), 0))
|
if (locked->getTileAt(tile.first.x(), tile.first.y(), 0))
|
||||||
tilesToPost.insert(tile);
|
{
|
||||||
|
auto tileToPost = tilesToPost.find(tile.first);
|
||||||
|
if (tileToPost == tilesToPost.end())
|
||||||
|
tilesToPost.insert(tile);
|
||||||
|
else
|
||||||
|
tileToPost->second = addChangeType(tileToPost->second, tile.second);
|
||||||
|
}
|
||||||
for (const auto& tile : tilesToPost)
|
for (const auto& tile : tilesToPost)
|
||||||
changedTiles->second.erase(tile);
|
changedTiles->second.erase(tile.first);
|
||||||
if (changedTiles->second.empty())
|
if (changedTiles->second.empty())
|
||||||
mChangedTiles.erase(changedTiles);
|
mChangedTiles.erase(changedTiles);
|
||||||
}
|
}
|
||||||
|
@ -94,8 +110,10 @@ namespace DetourNavigator
|
||||||
return;
|
return;
|
||||||
const auto shouldAdd = shouldAddTile(tile, playerTile, maxTiles);
|
const auto shouldAdd = shouldAddTile(tile, playerTile, maxTiles);
|
||||||
const auto presentInNavMesh = bool(locked->getTileAt(tile.x(), tile.y(), 0));
|
const auto presentInNavMesh = bool(locked->getTileAt(tile.x(), tile.y(), 0));
|
||||||
if ((shouldAdd && !presentInNavMesh) || (!shouldAdd && presentInNavMesh))
|
if (shouldAdd && !presentInNavMesh)
|
||||||
tilesToPost.insert(tile);
|
tilesToPost.insert(std::make_pair(tile, ChangeType::add));
|
||||||
|
else if (!shouldAdd && presentInNavMesh)
|
||||||
|
tilesToPost.insert(std::make_pair(tile, ChangeType::mixed));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
mAsyncNavMeshUpdater.post(agentHalfExtents, cached, playerTile, tilesToPost);
|
mAsyncNavMeshUpdater.post(agentHalfExtents, cached, playerTile, tilesToPost);
|
||||||
|
@ -120,12 +138,20 @@ namespace DetourNavigator
|
||||||
return mCache;
|
return mCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavMeshManager::addChangedTiles(const btCollisionShape& shape, const btTransform& transform)
|
void NavMeshManager::addChangedTiles(const btCollisionShape& shape, const btTransform& transform,
|
||||||
|
const ChangeType changeType)
|
||||||
{
|
{
|
||||||
getTilesPositions(shape, transform, mSettings, [&] (const TilePosition& v) {
|
getTilesPositions(shape, transform, mSettings, [&] (const TilePosition& v) {
|
||||||
for (const auto& cached : mCache)
|
for (const auto& cached : mCache)
|
||||||
if (cached.second)
|
if (cached.second)
|
||||||
mChangedTiles[cached.first].insert(v);
|
{
|
||||||
|
auto& tiles = mChangedTiles[cached.first];
|
||||||
|
auto tile = tiles.find(v);
|
||||||
|
if (tile == tiles.end())
|
||||||
|
tiles.insert(std::make_pair(v, changeType));
|
||||||
|
else
|
||||||
|
tile->second = addChangeType(tile->second, changeType);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,13 +45,13 @@ namespace DetourNavigator
|
||||||
const Settings& mSettings;
|
const Settings& mSettings;
|
||||||
TileCachedRecastMeshManager mRecastMeshManager;
|
TileCachedRecastMeshManager mRecastMeshManager;
|
||||||
std::map<osg::Vec3f, std::shared_ptr<NavMeshCacheItem>> mCache;
|
std::map<osg::Vec3f, std::shared_ptr<NavMeshCacheItem>> mCache;
|
||||||
std::map<osg::Vec3f, std::set<TilePosition>> mChangedTiles;
|
std::map<osg::Vec3f, std::map<TilePosition, ChangeType>> mChangedTiles;
|
||||||
AsyncNavMeshUpdater mAsyncNavMeshUpdater;
|
AsyncNavMeshUpdater mAsyncNavMeshUpdater;
|
||||||
std::size_t mGenerationCounter = 0;
|
std::size_t mGenerationCounter = 0;
|
||||||
boost::optional<TilePosition> mPlayerTile;
|
boost::optional<TilePosition> mPlayerTile;
|
||||||
std::size_t mLastRecastMeshManagerRevision = 0;
|
std::size_t mLastRecastMeshManagerRevision = 0;
|
||||||
|
|
||||||
void addChangedTiles(const btCollisionShape& shape, const btTransform& transform);
|
void addChangedTiles(const btCollisionShape& shape, const btTransform& transform, const ChangeType changeType);
|
||||||
|
|
||||||
const std::shared_ptr<NavMeshCacheItem>& getCached(const osg::Vec3f& agentHalfExtents) const;
|
const std::shared_ptr<NavMeshCacheItem>& getCached(const osg::Vec3f& agentHalfExtents) const;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue