1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-03-03 13:39:40 +00:00

Reuse dtNavMeshQuery

To avoid redundant allocations.
This commit is contained in:
elsid 2023-02-17 14:55:05 +01:00
parent 540ee5399c
commit 28f7a89530
No known key found for this signature in database
GPG key ID: 4DE04C198CBA7625
14 changed files with 73 additions and 88 deletions

View file

@ -74,7 +74,7 @@ namespace
mRecastMeshManager.setWorldspace(mWorldspace, nullptr); mRecastMeshManager.setWorldspace(mWorldspace, nullptr);
addHeightFieldPlane(mRecastMeshManager); addHeightFieldPlane(mRecastMeshManager);
AsyncNavMeshUpdater updater(mSettings, mRecastMeshManager, mOffMeshConnectionsManager, nullptr); AsyncNavMeshUpdater updater(mSettings, mRecastMeshManager, mOffMeshConnectionsManager, nullptr);
const auto navMeshCacheItem = std::make_shared<GuardedNavMeshCacheItem>(makeEmptyNavMesh(mSettings), 1); const auto navMeshCacheItem = std::make_shared<GuardedNavMeshCacheItem>(1, mSettings);
const std::map<TilePosition, ChangeType> changedTiles{ { TilePosition{ 0, 0 }, ChangeType::add } }; const std::map<TilePosition, ChangeType> changedTiles{ { TilePosition{ 0, 0 }, ChangeType::add } };
updater.post(mAgentBounds, navMeshCacheItem, mPlayerTile, mWorldspace, changedTiles); updater.post(mAgentBounds, navMeshCacheItem, mPlayerTile, mWorldspace, changedTiles);
updater.wait(WaitConditionType::allJobsDone, &mListener); updater.wait(WaitConditionType::allJobsDone, &mListener);
@ -86,7 +86,7 @@ namespace
mRecastMeshManager.setWorldspace(mWorldspace, nullptr); mRecastMeshManager.setWorldspace(mWorldspace, nullptr);
addHeightFieldPlane(mRecastMeshManager); addHeightFieldPlane(mRecastMeshManager);
AsyncNavMeshUpdater updater(mSettings, mRecastMeshManager, mOffMeshConnectionsManager, nullptr); AsyncNavMeshUpdater updater(mSettings, mRecastMeshManager, mOffMeshConnectionsManager, nullptr);
const auto navMeshCacheItem = std::make_shared<GuardedNavMeshCacheItem>(makeEmptyNavMesh(mSettings), 1); const auto navMeshCacheItem = std::make_shared<GuardedNavMeshCacheItem>(1, mSettings);
const std::map<TilePosition, ChangeType> changedTiles{ { TilePosition{ 0, 0 }, ChangeType::add } }; const std::map<TilePosition, ChangeType> changedTiles{ { TilePosition{ 0, 0 }, ChangeType::add } };
updater.post(mAgentBounds, navMeshCacheItem, mPlayerTile, mWorldspace, changedTiles); updater.post(mAgentBounds, navMeshCacheItem, mPlayerTile, mWorldspace, changedTiles);
updater.wait(WaitConditionType::allJobsDone, &mListener); updater.wait(WaitConditionType::allJobsDone, &mListener);
@ -109,7 +109,7 @@ namespace
mRecastMeshManager.setWorldspace(mWorldspace, nullptr); mRecastMeshManager.setWorldspace(mWorldspace, nullptr);
addHeightFieldPlane(mRecastMeshManager); addHeightFieldPlane(mRecastMeshManager);
AsyncNavMeshUpdater updater(mSettings, mRecastMeshManager, mOffMeshConnectionsManager, nullptr); AsyncNavMeshUpdater updater(mSettings, mRecastMeshManager, mOffMeshConnectionsManager, nullptr);
const auto navMeshCacheItem = std::make_shared<GuardedNavMeshCacheItem>(makeEmptyNavMesh(mSettings), 1); const auto navMeshCacheItem = std::make_shared<GuardedNavMeshCacheItem>(1, mSettings);
const std::map<TilePosition, ChangeType> changedTiles{ { TilePosition{ 0, 0 }, ChangeType::update } }; const std::map<TilePosition, ChangeType> changedTiles{ { TilePosition{ 0, 0 }, ChangeType::update } };
updater.post(mAgentBounds, navMeshCacheItem, mPlayerTile, mWorldspace, changedTiles); updater.post(mAgentBounds, navMeshCacheItem, mPlayerTile, mWorldspace, changedTiles);
updater.wait(WaitConditionType::allJobsDone, &mListener); updater.wait(WaitConditionType::allJobsDone, &mListener);
@ -135,7 +135,7 @@ namespace
auto db = std::make_unique<NavMeshDb>(":memory:", std::numeric_limits<std::uint64_t>::max()); auto db = std::make_unique<NavMeshDb>(":memory:", std::numeric_limits<std::uint64_t>::max());
NavMeshDb* const dbPtr = db.get(); NavMeshDb* const dbPtr = db.get();
AsyncNavMeshUpdater updater(mSettings, mRecastMeshManager, mOffMeshConnectionsManager, std::move(db)); AsyncNavMeshUpdater updater(mSettings, mRecastMeshManager, mOffMeshConnectionsManager, std::move(db));
const auto navMeshCacheItem = std::make_shared<GuardedNavMeshCacheItem>(makeEmptyNavMesh(mSettings), 1); const auto navMeshCacheItem = std::make_shared<GuardedNavMeshCacheItem>(1, mSettings);
const TilePosition tilePosition{ 0, 0 }; const TilePosition tilePosition{ 0, 0 };
const std::map<TilePosition, ChangeType> changedTiles{ { tilePosition, ChangeType::add } }; const std::map<TilePosition, ChangeType> changedTiles{ { tilePosition, ChangeType::add } };
updater.post(mAgentBounds, navMeshCacheItem, mPlayerTile, mWorldspace, changedTiles); updater.post(mAgentBounds, navMeshCacheItem, mPlayerTile, mWorldspace, changedTiles);
@ -162,7 +162,7 @@ namespace
NavMeshDb* const dbPtr = db.get(); NavMeshDb* const dbPtr = db.get();
mSettings.mWriteToNavMeshDb = false; mSettings.mWriteToNavMeshDb = false;
AsyncNavMeshUpdater updater(mSettings, mRecastMeshManager, mOffMeshConnectionsManager, std::move(db)); AsyncNavMeshUpdater updater(mSettings, mRecastMeshManager, mOffMeshConnectionsManager, std::move(db));
const auto navMeshCacheItem = std::make_shared<GuardedNavMeshCacheItem>(makeEmptyNavMesh(mSettings), 1); const auto navMeshCacheItem = std::make_shared<GuardedNavMeshCacheItem>(1, mSettings);
const TilePosition tilePosition{ 0, 0 }; const TilePosition tilePosition{ 0, 0 };
const std::map<TilePosition, ChangeType> changedTiles{ { tilePosition, ChangeType::add } }; const std::map<TilePosition, ChangeType> changedTiles{ { tilePosition, ChangeType::add } };
updater.post(mAgentBounds, navMeshCacheItem, mPlayerTile, mWorldspace, changedTiles); updater.post(mAgentBounds, navMeshCacheItem, mPlayerTile, mWorldspace, changedTiles);
@ -187,7 +187,7 @@ namespace
NavMeshDb* const dbPtr = db.get(); NavMeshDb* const dbPtr = db.get();
mSettings.mWriteToNavMeshDb = false; mSettings.mWriteToNavMeshDb = false;
AsyncNavMeshUpdater updater(mSettings, mRecastMeshManager, mOffMeshConnectionsManager, std::move(db)); AsyncNavMeshUpdater updater(mSettings, mRecastMeshManager, mOffMeshConnectionsManager, std::move(db));
const auto navMeshCacheItem = std::make_shared<GuardedNavMeshCacheItem>(makeEmptyNavMesh(mSettings), 1); const auto navMeshCacheItem = std::make_shared<GuardedNavMeshCacheItem>(1, mSettings);
const TilePosition tilePosition{ 0, 0 }; const TilePosition tilePosition{ 0, 0 };
const std::map<TilePosition, ChangeType> changedTiles{ { tilePosition, ChangeType::add } }; const std::map<TilePosition, ChangeType> changedTiles{ { tilePosition, ChangeType::add } };
updater.post(mAgentBounds, navMeshCacheItem, mPlayerTile, mWorldspace, changedTiles); updater.post(mAgentBounds, navMeshCacheItem, mPlayerTile, mWorldspace, changedTiles);
@ -207,7 +207,7 @@ namespace
mSettings.mMaxNavMeshTilesCacheSize = 0; mSettings.mMaxNavMeshTilesCacheSize = 0;
AsyncNavMeshUpdater updater(mSettings, mRecastMeshManager, mOffMeshConnectionsManager, AsyncNavMeshUpdater updater(mSettings, mRecastMeshManager, mOffMeshConnectionsManager,
std::make_unique<NavMeshDb>(":memory:", std::numeric_limits<std::uint64_t>::max())); std::make_unique<NavMeshDb>(":memory:", std::numeric_limits<std::uint64_t>::max()));
const auto navMeshCacheItem = std::make_shared<GuardedNavMeshCacheItem>(makeEmptyNavMesh(mSettings), 1); const auto navMeshCacheItem = std::make_shared<GuardedNavMeshCacheItem>(1, mSettings);
const std::map<TilePosition, ChangeType> changedTiles{ { TilePosition{ 0, 0 }, ChangeType::add } }; const std::map<TilePosition, ChangeType> changedTiles{ { TilePosition{ 0, 0 }, ChangeType::add } };
updater.post(mAgentBounds, navMeshCacheItem, mPlayerTile, mWorldspace, changedTiles); updater.post(mAgentBounds, navMeshCacheItem, mPlayerTile, mWorldspace, changedTiles);
updater.wait(WaitConditionType::allJobsDone, &mListener); updater.wait(WaitConditionType::allJobsDone, &mListener);
@ -236,7 +236,7 @@ namespace
mRecastMeshManager.setWorldspace(mWorldspace, nullptr); mRecastMeshManager.setWorldspace(mWorldspace, nullptr);
addHeightFieldPlane(mRecastMeshManager); addHeightFieldPlane(mRecastMeshManager);
AsyncNavMeshUpdater updater(mSettings, mRecastMeshManager, mOffMeshConnectionsManager, nullptr); AsyncNavMeshUpdater updater(mSettings, mRecastMeshManager, mOffMeshConnectionsManager, nullptr);
const auto navMeshCacheItem = std::make_shared<GuardedNavMeshCacheItem>(makeEmptyNavMesh(mSettings), 1); const auto navMeshCacheItem = std::make_shared<GuardedNavMeshCacheItem>(1, mSettings);
const std::map<TilePosition, ChangeType> changedTilesAdd{ { TilePosition{ 0, 0 }, ChangeType::add } }; const std::map<TilePosition, ChangeType> changedTilesAdd{ { TilePosition{ 0, 0 }, ChangeType::add } };
updater.post(mAgentBounds, navMeshCacheItem, mPlayerTile, mWorldspace, changedTilesAdd); updater.post(mAgentBounds, navMeshCacheItem, mPlayerTile, mWorldspace, changedTilesAdd);
updater.wait(WaitConditionType::allJobsDone, &mListener); updater.wait(WaitConditionType::allJobsDone, &mListener);
@ -258,7 +258,7 @@ namespace
auto db = std::make_unique<NavMeshDb>(":memory:", 4097); auto db = std::make_unique<NavMeshDb>(":memory:", 4097);
NavMeshDb* const dbPtr = db.get(); NavMeshDb* const dbPtr = db.get();
AsyncNavMeshUpdater updater(mSettings, mRecastMeshManager, mOffMeshConnectionsManager, std::move(db)); AsyncNavMeshUpdater updater(mSettings, mRecastMeshManager, mOffMeshConnectionsManager, std::move(db));
const auto navMeshCacheItem = std::make_shared<GuardedNavMeshCacheItem>(makeEmptyNavMesh(mSettings), 1); const auto navMeshCacheItem = std::make_shared<GuardedNavMeshCacheItem>(1, mSettings);
std::map<TilePosition, ChangeType> changedTiles; std::map<TilePosition, ChangeType> changedTiles;
for (int x = -5; x <= 5; ++x) for (int x = -5; x <= 5; ++x)
for (int y = -5; y <= 5; ++y) for (int y = -5; y <= 5; ++y)

View file

@ -1,20 +1,15 @@
#include "findrandompointaroundcircle.hpp" #include "findrandompointaroundcircle.hpp"
#include "findsmoothpath.hpp" #include "findsmoothpath.hpp"
#include "settings.hpp"
#include <DetourNavMesh.h> #include <DetourNavMesh.h>
#include <DetourNavMeshQuery.h> #include <DetourNavMeshQuery.h>
namespace DetourNavigator namespace DetourNavigator
{ {
std::optional<osg::Vec3f> findRandomPointAroundCircle(const dtNavMesh& navMesh, const osg::Vec3f& halfExtents, std::optional<osg::Vec3f> findRandomPointAroundCircle(const dtNavMeshQuery& navMeshQuery,
const osg::Vec3f& start, const float maxRadius, const Flags includeFlags, const DetourSettings& settings, const osg::Vec3f& halfExtents, const osg::Vec3f& start, const float maxRadius, const Flags includeFlags,
float (*prng)()) float (*prng)())
{ {
dtNavMeshQuery navMeshQuery;
if (!initNavMeshQuery(navMeshQuery, navMesh, settings.mMaxNavMeshQueryNodes))
return std::optional<osg::Vec3f>();
dtQueryFilter queryFilter; dtQueryFilter queryFilter;
queryFilter.setIncludeFlags(includeFlags); queryFilter.setIncludeFlags(includeFlags);

View file

@ -6,14 +6,14 @@
#include <optional> #include <optional>
#include <osg/Vec3f> #include <osg/Vec3f>
class dtNavMesh; class dtNavMeshQuery;
namespace DetourNavigator namespace DetourNavigator
{ {
struct DetourSettings; struct DetourSettings;
std::optional<osg::Vec3f> findRandomPointAroundCircle(const dtNavMesh& navMesh, const osg::Vec3f& halfExtents, std::optional<osg::Vec3f> findRandomPointAroundCircle(const dtNavMeshQuery& navMeshQuery,
const osg::Vec3f& start, const float maxRadius, const Flags includeFlags, const DetourSettings& settings, const osg::Vec3f& halfExtents, const osg::Vec3f& start, const float maxRadius, const Flags includeFlags,
float (*prng)()); float (*prng)());
} }

View file

@ -252,14 +252,10 @@ namespace DetourNavigator
} }
template <class OutputIterator> template <class OutputIterator>
Status findSmoothPath(const dtNavMesh& navMesh, const osg::Vec3f& halfExtents, const float stepSize, Status findSmoothPath(const dtNavMesh& navMesh, const dtNavMeshQuery& navMeshQuery, const osg::Vec3f& halfExtents,
const osg::Vec3f& start, const osg::Vec3f& end, const Flags includeFlags, const AreaCosts& areaCosts, const float stepSize, const osg::Vec3f& start, const osg::Vec3f& end, const Flags includeFlags,
const Settings& settings, float endTolerance, OutputIterator out) const AreaCosts& areaCosts, const Settings& settings, float endTolerance, OutputIterator out)
{ {
dtNavMeshQuery navMeshQuery;
if (!initNavMeshQuery(navMeshQuery, navMesh, settings.mDetour.mMaxNavMeshQueryNodes))
return Status::InitNavMeshQueryFailed;
dtQueryFilter queryFilter; dtQueryFilter queryFilter;
queryFilter.setIncludeFlags(includeFlags); queryFilter.setIncludeFlags(includeFlags);
queryFilter.setAreaCost(AreaType_water, areaCosts.mWater); queryFilter.setAreaCost(AreaType_water, areaCosts.mWater);

View file

@ -13,7 +13,6 @@
#include "recastparams.hpp" #include "recastparams.hpp"
#include "settings.hpp" #include "settings.hpp"
#include "settingsutils.hpp" #include "settingsutils.hpp"
#include "sharednavmesh.hpp"
#include "components/debug/debuglog.hpp" #include "components/debug/debuglog.hpp"
@ -604,7 +603,7 @@ namespace DetourNavigator
return NavMeshData(navMeshData, navMeshDataSize); return NavMeshData(navMeshData, navMeshDataSize);
} }
NavMeshPtr makeEmptyNavMesh(const Settings& settings) void initEmptyNavMesh(const Settings& settings, dtNavMesh& navMesh)
{ {
// Max tiles and max polys affect how the tile IDs are caculated. // Max tiles and max polys affect how the tile IDs are caculated.
// There are 22 bits available for identifying a tile and a polygon. // There are 22 bits available for identifying a tile and a polygon.
@ -623,17 +622,10 @@ namespace DetourNavigator
params.maxTiles = 1 << tilesBits; params.maxTiles = 1 << tilesBits;
params.maxPolys = 1 << polysBits; params.maxPolys = 1 << polysBits;
NavMeshPtr navMesh(dtAllocNavMesh(), &dtFreeNavMesh); const auto status = navMesh.init(&params);
if (navMesh == nullptr)
throw NavigatorException("Failed to allocate navmesh");
const auto status = navMesh->init(&params);
if (!dtStatusSucceed(status)) if (!dtStatusSucceed(status))
throw NavigatorException("Failed to init navmesh"); throw NavigatorException("Failed to init navmesh");
return navMesh;
} }
bool isSupportedAgentBounds(const RecastSettings& settings, const AgentBounds& agentBounds) bool isSupportedAgentBounds(const RecastSettings& settings, const AgentBounds& agentBounds)

View file

@ -2,7 +2,6 @@
#define OPENMW_COMPONENTS_DETOURNAVIGATOR_MAKENAVMESH_H #define OPENMW_COMPONENTS_DETOURNAVIGATOR_MAKENAVMESH_H
#include "recastmesh.hpp" #include "recastmesh.hpp"
#include "sharednavmesh.hpp"
#include "tileposition.hpp" #include "tileposition.hpp"
#include <memory> #include <memory>
@ -49,7 +48,7 @@ namespace DetourNavigator
const std::vector<OffMeshConnection>& offMeshConnections, const AgentBounds& agentBounds, const std::vector<OffMeshConnection>& offMeshConnections, const AgentBounds& agentBounds,
const TilePosition& tile, const RecastSettings& settings); const TilePosition& tile, const RecastSettings& settings);
NavMeshPtr makeEmptyNavMesh(const Settings& settings); void initEmptyNavMesh(const Settings& settings, dtNavMesh& navMesh);
bool isSupportedAgentBounds(const RecastSettings& settings, const AgentBounds& agentBounds); bool isSupportedAgentBounds(const RecastSettings& settings, const AgentBounds& agentBounds);
} }

View file

@ -11,11 +11,12 @@ namespace DetourNavigator
const auto navMesh = navigator.getNavMesh(agentBounds); const auto navMesh = navigator.getNavMesh(agentBounds);
if (!navMesh) if (!navMesh)
return std::nullopt; return std::nullopt;
const auto& settings = navigator.getSettings(); const Settings& settings = navigator.getSettings();
const auto result = DetourNavigator::findRandomPointAroundCircle(navMesh->lockConst()->getImpl(), const auto locked = navMesh->lock();
const auto result = DetourNavigator::findRandomPointAroundCircle(locked->getQuery(),
toNavMeshCoordinates(settings.mRecast, agentBounds.mHalfExtents), toNavMeshCoordinates(settings.mRecast, agentBounds.mHalfExtents),
toNavMeshCoordinates(settings.mRecast, start), toNavMeshCoordinates(settings.mRecast, maxRadius), toNavMeshCoordinates(settings.mRecast, start), toNavMeshCoordinates(settings.mRecast, maxRadius),
includeFlags, settings.mDetour, prng); includeFlags, prng);
if (!result) if (!result)
return std::nullopt; return std::nullopt;
return std::optional<osg::Vec3f>(fromNavMeshCoordinates(settings.mRecast, *result)); return std::optional<osg::Vec3f>(fromNavMeshCoordinates(settings.mRecast, *result));
@ -27,11 +28,11 @@ namespace DetourNavigator
const auto navMesh = navigator.getNavMesh(agentBounds); const auto navMesh = navigator.getNavMesh(agentBounds);
if (navMesh == nullptr) if (navMesh == nullptr)
return std::nullopt; return std::nullopt;
const auto& settings = navigator.getSettings(); const Settings& settings = navigator.getSettings();
const auto result = DetourNavigator::raycast(navMesh->lockConst()->getImpl(), const auto locked = navMesh->lock();
const auto result = DetourNavigator::raycast(locked->getQuery(),
toNavMeshCoordinates(settings.mRecast, agentBounds.mHalfExtents), toNavMeshCoordinates(settings.mRecast, agentBounds.mHalfExtents),
toNavMeshCoordinates(settings.mRecast, start), toNavMeshCoordinates(settings.mRecast, end), includeFlags, toNavMeshCoordinates(settings.mRecast, start), toNavMeshCoordinates(settings.mRecast, end), includeFlags);
settings.mDetour);
if (!result) if (!result)
return std::nullopt; return std::nullopt;
return fromNavMeshCoordinates(settings.mRecast, *result); return fromNavMeshCoordinates(settings.mRecast, *result);

View file

@ -35,8 +35,9 @@ namespace DetourNavigator
const auto navMesh = navigator.getNavMesh(agentBounds); const auto navMesh = navigator.getNavMesh(agentBounds);
if (navMesh == nullptr) if (navMesh == nullptr)
return Status::NavMeshNotFound; return Status::NavMeshNotFound;
const auto settings = navigator.getSettings(); const Settings& settings = navigator.getSettings();
return findSmoothPath(navMesh->lockConst()->getImpl(), const auto locked = navMesh->lock();
return findSmoothPath(locked->getImpl(), locked->getQuery(),
toNavMeshCoordinates(settings.mRecast, agentBounds.mHalfExtents), toNavMeshCoordinates(settings.mRecast, agentBounds.mHalfExtents),
toNavMeshCoordinates(settings.mRecast, stepSize), toNavMeshCoordinates(settings.mRecast, start), toNavMeshCoordinates(settings.mRecast, stepSize), toNavMeshCoordinates(settings.mRecast, start),
toNavMeshCoordinates(settings.mRecast, end), includeFlags, areaCosts, settings, endTolerance, out); toNavMeshCoordinates(settings.mRecast, end), includeFlags, areaCosts, settings, endTolerance, out);

View file

@ -1,12 +1,16 @@
#include "navmeshcacheitem.hpp" #include "navmeshcacheitem.hpp"
#include "debug.hpp"
#include "makenavmesh.hpp"
#include "navmeshdata.hpp" #include "navmeshdata.hpp"
#include "navmeshtilescache.hpp" #include "navmeshtilescache.hpp"
#include "navmeshtileview.hpp" #include "navmeshtileview.hpp"
#include "settings.hpp"
#include "tileposition.hpp" #include "tileposition.hpp"
#include <DetourNavMesh.h> #include <DetourNavMesh.h>
#include <ostream> #include <ostream>
#include <sstream>
namespace namespace
{ {
@ -66,18 +70,32 @@ namespace DetourNavigator
return navMesh.getTileAt(position.x(), position.y(), layer); return navMesh.getTileAt(position.x(), position.y(), layer);
} }
NavMeshCacheItem::NavMeshCacheItem(std::size_t generation, const Settings& settings)
: mVersion{ generation, 0 }
{
initEmptyNavMesh(settings, mImpl);
if (const dtStatus status = mQuery.init(&mImpl, settings.mDetour.mMaxNavMeshQueryNodes);
!dtStatusSucceed(status))
{
std::ostringstream error;
error << "Failed to init navmesh query: " << WriteDtStatus{ status };
throw std::runtime_error(error.str());
}
}
UpdateNavMeshStatus NavMeshCacheItem::updateTile( UpdateNavMeshStatus NavMeshCacheItem::updateTile(
const TilePosition& position, NavMeshTilesCache::Value&& cached, NavMeshData&& navMeshData) const TilePosition& position, NavMeshTilesCache::Value&& cached, NavMeshData&& navMeshData)
{ {
const dtMeshTile* currentTile = getTile(*mImpl, position); const dtMeshTile* currentTile = getTile(mImpl, position);
if (currentTile != nullptr if (currentTile != nullptr
&& asNavMeshTileConstView(*currentTile) == asNavMeshTileConstView(navMeshData.mValue.get())) && asNavMeshTileConstView(*currentTile) == asNavMeshTileConstView(navMeshData.mValue.get()))
{ {
return UpdateNavMeshStatus::ignored; return UpdateNavMeshStatus::ignored;
} }
bool removed = ::removeTile(*mImpl, position); bool removed = ::removeTile(mImpl, position);
removed = mEmptyTiles.erase(position) > 0 || removed; removed = mEmptyTiles.erase(position) > 0 || removed;
const auto addStatus = addTile(*mImpl, navMeshData.mValue.get(), navMeshData.mSize); const auto addStatus = addTile(mImpl, navMeshData.mValue.get(), navMeshData.mSize);
if (dtStatusSucceed(addStatus)) if (dtStatusSucceed(addStatus))
{ {
auto tile = mUsedTiles.find(position); auto tile = mUsedTiles.find(position);
@ -111,7 +129,7 @@ namespace DetourNavigator
UpdateNavMeshStatus NavMeshCacheItem::removeTile(const TilePosition& position) UpdateNavMeshStatus NavMeshCacheItem::removeTile(const TilePosition& position)
{ {
bool removed = ::removeTile(*mImpl, position); bool removed = ::removeTile(mImpl, position);
removed = mEmptyTiles.erase(position) > 0 || removed; removed = mEmptyTiles.erase(position) > 0 || removed;
if (removed) if (removed)
{ {
@ -123,7 +141,7 @@ namespace DetourNavigator
UpdateNavMeshStatus NavMeshCacheItem::markAsEmpty(const TilePosition& position) UpdateNavMeshStatus NavMeshCacheItem::markAsEmpty(const TilePosition& position)
{ {
bool removed = ::removeTile(*mImpl, position); bool removed = ::removeTile(mImpl, position);
removed = mEmptyTiles.insert(position).second || removed; removed = mEmptyTiles.insert(position).second || removed;
if (removed) if (removed)
{ {

View file

@ -3,10 +3,12 @@
#include "navmeshdata.hpp" #include "navmeshdata.hpp"
#include "navmeshtilescache.hpp" #include "navmeshtilescache.hpp"
#include "sharednavmesh.hpp"
#include "tileposition.hpp" #include "tileposition.hpp"
#include "version.hpp" #include "version.hpp"
#include <DetourNavMesh.h>
#include <DetourNavMeshQuery.h>
#include <iosfwd> #include <iosfwd>
#include <map> #include <map>
#include <set> #include <set>
@ -15,6 +17,8 @@ struct dtMeshTile;
namespace DetourNavigator namespace DetourNavigator
{ {
struct Settings;
enum class UpdateNavMeshStatus : unsigned enum class UpdateNavMeshStatus : unsigned
{ {
ignored = 0, ignored = 0,
@ -102,13 +106,11 @@ namespace DetourNavigator
class NavMeshCacheItem class NavMeshCacheItem
{ {
public: public:
NavMeshCacheItem(const NavMeshPtr& impl, std::size_t generation) explicit NavMeshCacheItem(std::size_t generation, const Settings& settings);
: mImpl(impl)
, mVersion{ generation, 0 }
{
}
const dtNavMesh& getImpl() const { return *mImpl; } const dtNavMesh& getImpl() const { return mImpl; }
dtNavMeshQuery& getQuery() { return mQuery; }
const Version& getVersion() const { return mVersion; } const Version& getVersion() const { return mVersion; }
@ -125,7 +127,7 @@ namespace DetourNavigator
void forEachUsedTile(Function&& function) const void forEachUsedTile(Function&& function) const
{ {
for (const auto& [position, tile] : mUsedTiles) for (const auto& [position, tile] : mUsedTiles)
if (const dtMeshTile* meshTile = getTile(*mImpl, position)) if (const dtMeshTile* meshTile = getTile(mImpl, position))
function(position, tile.mVersion, *meshTile); function(position, tile.mVersion, *meshTile);
} }
@ -137,8 +139,9 @@ namespace DetourNavigator
NavMeshData mData; NavMeshData mData;
}; };
NavMeshPtr mImpl;
Version mVersion; Version mVersion;
dtNavMesh mImpl;
dtNavMeshQuery mQuery;
std::map<TilePosition, Tile> mUsedTiles; std::map<TilePosition, Tile> mUsedTiles;
std::set<TilePosition> mEmptyTiles; std::set<TilePosition> mEmptyTiles;
}; };

View file

@ -69,7 +69,7 @@ namespace DetourNavigator
return; return;
mRecastMeshManager.setWorldspace(worldspace, getImpl(guard)); mRecastMeshManager.setWorldspace(worldspace, getImpl(guard));
for (auto& [agent, cache] : mCache) for (auto& [agent, cache] : mCache)
cache = std::make_shared<GuardedNavMeshCacheItem>(makeEmptyNavMesh(mSettings), ++mGenerationCounter); cache = std::make_shared<GuardedNavMeshCacheItem>(++mGenerationCounter, mSettings);
mWorldspace = worldspace; mWorldspace = worldspace;
} }
@ -123,8 +123,7 @@ namespace DetourNavigator
auto cached = mCache.find(agentBounds); auto cached = mCache.find(agentBounds);
if (cached != mCache.end()) if (cached != mCache.end())
return; return;
mCache.insert(std::make_pair( mCache.emplace(agentBounds, std::make_shared<GuardedNavMeshCacheItem>(++mGenerationCounter, mSettings));
agentBounds, std::make_shared<GuardedNavMeshCacheItem>(makeEmptyNavMesh(mSettings), ++mGenerationCounter)));
mPlayerTile.reset(); mPlayerTile.reset();
Log(Debug::Debug) << "cache add for agent=" << agentBounds; Log(Debug::Debug) << "cache add for agent=" << agentBounds;
} }

View file

@ -1,6 +1,4 @@
#include "raycast.hpp" #include "raycast.hpp"
#include "findsmoothpath.hpp"
#include "settings.hpp"
#include <DetourNavMesh.h> #include <DetourNavMesh.h>
#include <DetourNavMeshQuery.h> #include <DetourNavMeshQuery.h>
@ -9,13 +7,9 @@
namespace DetourNavigator namespace DetourNavigator
{ {
std::optional<osg::Vec3f> raycast(const dtNavMesh& navMesh, const osg::Vec3f& halfExtents, const osg::Vec3f& start, std::optional<osg::Vec3f> raycast(const dtNavMeshQuery& navMeshQuery, const osg::Vec3f& halfExtents,
const osg::Vec3f& end, const Flags includeFlags, const DetourSettings& settings) const osg::Vec3f& start, const osg::Vec3f& end, const Flags includeFlags)
{ {
dtNavMeshQuery navMeshQuery;
if (!initNavMeshQuery(navMeshQuery, navMesh, settings.mMaxNavMeshQueryNodes))
return {};
dtQueryFilter queryFilter; dtQueryFilter queryFilter;
queryFilter.setIncludeFlags(includeFlags); queryFilter.setIncludeFlags(includeFlags);

View file

@ -6,14 +6,14 @@
#include <optional> #include <optional>
#include <osg/Vec3f> #include <osg/Vec3f>
class dtNavMesh; class dtNavMeshQuery;
namespace DetourNavigator namespace DetourNavigator
{ {
struct DetourSettings; struct DetourSettings;
std::optional<osg::Vec3f> raycast(const dtNavMesh& navMesh, const osg::Vec3f& halfExtents, const osg::Vec3f& start, std::optional<osg::Vec3f> raycast(const dtNavMeshQuery& navMeshQuery, const osg::Vec3f& halfExtents,
const osg::Vec3f& end, const Flags includeFlags, const DetourSettings& settings); const osg::Vec3f& start, const osg::Vec3f& end, const Flags includeFlags);
} }
#endif #endif

View file

@ -1,13 +0,0 @@
#ifndef OPENMW_COMPONENTS_DETOURNAVIGATOR_SHAREDNAVMESH_H
#define OPENMW_COMPONENTS_DETOURNAVIGATOR_SHAREDNAVMESH_H
#include <memory>
class dtNavMesh;
namespace DetourNavigator
{
using NavMeshPtr = std::shared_ptr<dtNavMesh>;
}
#endif