1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-02-28 19:39:42 +00:00

Merge branch 'optimize_navmesh_related_mechanics' into 'master'

Optimize navmesh related mechanics

See merge request OpenMW/openmw!2742
This commit is contained in:
psi29a 2023-02-17 22:58:12 +00:00
commit 9487312fb8
18 changed files with 108 additions and 112 deletions

View file

@ -189,8 +189,17 @@ bool MWMechanics::AiPackage::pathTo(const MWWorld::Ptr& actor, const osg::Vec3f&
= getPointTolerance(actor.getClass().getMaxSpeed(actor), duration, world->getHalfExtents(actor));
static const bool smoothMovement = Settings::Manager::getBool("smooth movement", "Game");
mPathFinder.update(position, pointTolerance, DEFAULT_TOLERANCE,
/*shortenIfAlmostStraight=*/smoothMovement, actorCanMoveByZ, agentBounds, getNavigatorFlags(actor));
PathFinder::UpdateFlags updateFlags{};
if (actorCanMoveByZ)
updateFlags |= PathFinder::UpdateFlag_CanMoveByZ;
if (timerStatus == Misc::TimerStatus::Elapsed && smoothMovement)
updateFlags |= PathFinder::UpdateFlag_ShortenIfAlmostStraight;
if (timerStatus == Misc::TimerStatus::Elapsed)
updateFlags |= PathFinder::UpdateFlag_RemoveLoops;
mPathFinder.update(position, pointTolerance, DEFAULT_TOLERANCE, updateFlags, agentBounds, getNavigatorFlags(actor));
if (isDestReached || mPathFinder.checkPathCompleted()) // if path is finished
{

View file

@ -312,6 +312,13 @@ namespace MWMechanics
completeManualWalking(actor, storage);
}
if (storage.mState == AiWanderStorage::Wander_Walking && mUsePathgrid)
{
const auto agentBounds = MWBase::Environment::get().getWorld()->getPathfindingAgentBounds(actor);
mPathFinder.buildPathByNavMeshToNextPoint(
actor, agentBounds, getNavigatorFlags(actor), getAreaCosts(actor));
}
if (storage.mState == AiWanderStorage::Wander_MoveNow && storage.mCanWanderAlongPathGrid)
{
// Construct a new path if there isn't one
@ -560,13 +567,6 @@ namespace MWMechanics
void AiWander::evadeObstacles(const MWWorld::Ptr& actor, AiWanderStorage& storage)
{
if (mUsePathgrid)
{
const auto agentBounds = MWBase::Environment::get().getWorld()->getPathfindingAgentBounds(actor);
mPathFinder.buildPathByNavMeshToNextPoint(
actor, agentBounds, getNavigatorFlags(actor), getAreaCosts(actor));
}
if (mObstacleCheck.isEvading())
{
// first check if we're walking into a door

View file

@ -313,8 +313,7 @@ namespace MWMechanics
}
void PathFinder::update(const osg::Vec3f& position, float pointTolerance, float destinationTolerance,
bool shortenIfAlmostStraight, bool canMoveByZ, const DetourNavigator::AgentBounds& agentBounds,
const DetourNavigator::Flags flags)
UpdateFlags updateFlags, const DetourNavigator::AgentBounds& agentBounds, DetourNavigator::Flags pathFlags)
{
if (mPath.empty())
return;
@ -323,9 +322,9 @@ namespace MWMechanics
mPath.pop_front();
const IsValidShortcut isValidShortcut{ MWBase::Environment::get().getWorld()->getNavigator(), agentBounds,
flags };
pathFlags };
if (shortenIfAlmostStraight)
if ((updateFlags & UpdateFlag_ShortenIfAlmostStraight) != 0)
{
while (mPath.size() > 2 && isAlmostStraight(mPath[0], mPath[1], mPath[2], pointTolerance)
&& isValidShortcut(mPath[0], mPath[2]))
@ -335,7 +334,7 @@ namespace MWMechanics
mPath.pop_front();
}
if (mPath.size() > 1)
if ((updateFlags & UpdateFlag_RemoveLoops) != 0 && mPath.size() > 1)
{
std::size_t begin = 0;
for (std::size_t i = 1; i < mPath.size(); ++i)
@ -351,7 +350,7 @@ namespace MWMechanics
if (mPath.size() == 1)
{
float distSqr;
if (canMoveByZ)
if ((updateFlags & UpdateFlag_CanMoveByZ) != 0)
distSqr = (mPath.front() - position).length2();
else
distSqr = sqrDistanceIgnoreZ(mPath.front(), position);

View file

@ -82,11 +82,16 @@ namespace MWMechanics
class PathFinder
{
public:
PathFinder()
: mConstructed(false)
, mCell(nullptr)
using UpdateFlags = unsigned;
enum UpdateFlag : UpdateFlags
{
}
UpdateFlag_CanMoveByZ = 1 << 0,
UpdateFlag_ShortenIfAlmostStraight = 1 << 1,
UpdateFlag_RemoveLoops = 1 << 2,
};
PathFinder() = default;
void clearPath()
{
@ -121,8 +126,7 @@ namespace MWMechanics
/// Remove front point if exist and within tolerance
void update(const osg::Vec3f& position, float pointTolerance, float destinationTolerance,
bool shortenIfAlmostStraight, bool canMoveByZ, const DetourNavigator::AgentBounds& agentBounds,
const DetourNavigator::Flags flags);
UpdateFlags updateFlags, const DetourNavigator::AgentBounds& agentBounds, DetourNavigator::Flags pathFlags);
bool checkPathCompleted() const { return mConstructed && mPath.empty(); }
@ -201,10 +205,9 @@ namespace MWMechanics
}
private:
bool mConstructed;
bool mConstructed = false;
std::deque<osg::Vec3f> mPath;
const MWWorld::CellStore* mCell;
const MWWorld::CellStore* mCell = nullptr;
void buildPathByPathgridImpl(const osg::Vec3f& startPoint, const osg::Vec3f& endPoint,
const PathgridGraph& pathgridGraph, std::back_insert_iterator<std::deque<osg::Vec3f>> out);

View file

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

View file

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

View file

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

View file

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

View file

@ -13,7 +13,6 @@
#include "recastparams.hpp"
#include "settings.hpp"
#include "settingsutils.hpp"
#include "sharednavmesh.hpp"
#include "components/debug/debuglog.hpp"
@ -604,7 +603,7 @@ namespace DetourNavigator
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.
// There are 22 bits available for identifying a tile and a polygon.
@ -623,17 +622,10 @@ namespace DetourNavigator
params.maxTiles = 1 << tilesBits;
params.maxPolys = 1 << polysBits;
NavMeshPtr navMesh(dtAllocNavMesh(), &dtFreeNavMesh);
if (navMesh == nullptr)
throw NavigatorException("Failed to allocate navmesh");
const auto status = navMesh->init(&params);
const auto status = navMesh.init(&params);
if (!dtStatusSucceed(status))
throw NavigatorException("Failed to init navmesh");
return navMesh;
}
bool isSupportedAgentBounds(const RecastSettings& settings, const AgentBounds& agentBounds)

View file

@ -2,7 +2,6 @@
#define OPENMW_COMPONENTS_DETOURNAVIGATOR_MAKENAVMESH_H
#include "recastmesh.hpp"
#include "sharednavmesh.hpp"
#include "tileposition.hpp"
#include <memory>
@ -49,7 +48,7 @@ namespace DetourNavigator
const std::vector<OffMeshConnection>& offMeshConnections, const AgentBounds& agentBounds,
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);
}

View file

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

View file

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

View file

@ -1,12 +1,16 @@
#include "navmeshcacheitem.hpp"
#include "debug.hpp"
#include "makenavmesh.hpp"
#include "navmeshdata.hpp"
#include "navmeshtilescache.hpp"
#include "navmeshtileview.hpp"
#include "settings.hpp"
#include "tileposition.hpp"
#include <DetourNavMesh.h>
#include <ostream>
#include <sstream>
namespace
{
@ -66,18 +70,32 @@ namespace DetourNavigator
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(
const TilePosition& position, NavMeshTilesCache::Value&& cached, NavMeshData&& navMeshData)
{
const dtMeshTile* currentTile = getTile(*mImpl, position);
const dtMeshTile* currentTile = getTile(mImpl, position);
if (currentTile != nullptr
&& asNavMeshTileConstView(*currentTile) == asNavMeshTileConstView(navMeshData.mValue.get()))
{
return UpdateNavMeshStatus::ignored;
}
bool removed = ::removeTile(*mImpl, position);
bool removed = ::removeTile(mImpl, position);
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))
{
auto tile = mUsedTiles.find(position);
@ -111,7 +129,7 @@ namespace DetourNavigator
UpdateNavMeshStatus NavMeshCacheItem::removeTile(const TilePosition& position)
{
bool removed = ::removeTile(*mImpl, position);
bool removed = ::removeTile(mImpl, position);
removed = mEmptyTiles.erase(position) > 0 || removed;
if (removed)
{
@ -123,7 +141,7 @@ namespace DetourNavigator
UpdateNavMeshStatus NavMeshCacheItem::markAsEmpty(const TilePosition& position)
{
bool removed = ::removeTile(*mImpl, position);
bool removed = ::removeTile(mImpl, position);
removed = mEmptyTiles.insert(position).second || removed;
if (removed)
{

View file

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

View file

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

View file

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

View file

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