Apply min distance only for not present tiles

To avoid waiting when navmesh update is triggered by transformed object for
already present tiles.
libera
elsid 4 years ago
parent d0ea9c482a
commit 59f89d22f8
No known key found for this signature in database
GPG Key ID: B845CB9FEE18AB40

@ -619,7 +619,7 @@ namespace MWWorld
if (changeEvent) if (changeEvent)
mCellChanged = true; mCellChanged = true;
mNavigator.wait(*loadingListener); mNavigator.wait(*loadingListener, DetourNavigator::WaitConditionType::requiredTilesPresent);
} }
void Scene::testExteriorCells() void Scene::testExteriorCells()
@ -848,7 +848,7 @@ namespace MWWorld
MWBase::Environment::get().getWindowManager()->changeCell(mCurrentCell); MWBase::Environment::get().getWindowManager()->changeCell(mCurrentCell);
mNavigator.wait(*loadingListener); mNavigator.wait(*loadingListener, DetourNavigator::WaitConditionType::requiredTilesPresent);
} }
void Scene::changeToExteriorCell (const ESM::Position& position, bool adjustPlayerPos, bool changeEvent) void Scene::changeToExteriorCell (const ESM::Position& position, bool adjustPlayerPos, bool changeEvent)

@ -127,7 +127,7 @@ namespace
mNavigator->addAgent(mAgentHalfExtents); mNavigator->addAgent(mAgentHalfExtents);
mNavigator->addObject(ObjectId(&shape), shape, btTransform::getIdentity()); mNavigator->addObject(ObjectId(&shape), shape, btTransform::getIdentity());
mNavigator->update(mPlayerPosition); mNavigator->update(mPlayerPosition);
mNavigator->wait(mListener); mNavigator->wait(mListener, WaitConditionType::requiredTilesPresent);
EXPECT_EQ(mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mAreaCosts, mOut), Status::Success); EXPECT_EQ(mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mAreaCosts, mOut), Status::Success);
@ -177,7 +177,7 @@ namespace
mNavigator->addAgent(mAgentHalfExtents); mNavigator->addAgent(mAgentHalfExtents);
mNavigator->addObject(ObjectId(&heightfieldShape), heightfieldShape, btTransform::getIdentity()); mNavigator->addObject(ObjectId(&heightfieldShape), heightfieldShape, btTransform::getIdentity());
mNavigator->update(mPlayerPosition); mNavigator->update(mPlayerPosition);
mNavigator->wait(mListener); mNavigator->wait(mListener, WaitConditionType::allJobsDone);
EXPECT_EQ(mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mAreaCosts, mOut), Status::Success); EXPECT_EQ(mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mAreaCosts, mOut), Status::Success);
@ -209,7 +209,7 @@ namespace
mNavigator->addObject(ObjectId(&compoundShape), compoundShape, btTransform::getIdentity()); mNavigator->addObject(ObjectId(&compoundShape), compoundShape, btTransform::getIdentity());
mNavigator->update(mPlayerPosition); mNavigator->update(mPlayerPosition);
mNavigator->wait(mListener); mNavigator->wait(mListener, WaitConditionType::allJobsDone);
mPath.clear(); mPath.clear();
mOut = std::back_inserter(mPath); mOut = std::back_inserter(mPath);
@ -262,7 +262,7 @@ namespace
mNavigator->addObject(ObjectId(&heightfieldShape), heightfieldShape, btTransform::getIdentity()); mNavigator->addObject(ObjectId(&heightfieldShape), heightfieldShape, btTransform::getIdentity());
mNavigator->addObject(ObjectId(&compoundShape), compoundShape, btTransform::getIdentity()); mNavigator->addObject(ObjectId(&compoundShape), compoundShape, btTransform::getIdentity());
mNavigator->update(mPlayerPosition); mNavigator->update(mPlayerPosition);
mNavigator->wait(mListener); mNavigator->wait(mListener, WaitConditionType::allJobsDone);
EXPECT_EQ(mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mAreaCosts, mOut), Status::Success); EXPECT_EQ(mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mAreaCosts, mOut), Status::Success);
@ -296,7 +296,7 @@ namespace
mNavigator->updateObject(ObjectId(&compoundShape), compoundShape, btTransform::getIdentity()); mNavigator->updateObject(ObjectId(&compoundShape), compoundShape, btTransform::getIdentity());
mNavigator->update(mPlayerPosition); mNavigator->update(mPlayerPosition);
mNavigator->wait(mListener); mNavigator->wait(mListener, WaitConditionType::allJobsDone);
mPath.clear(); mPath.clear();
mOut = std::back_inserter(mPath); mOut = std::back_inserter(mPath);
@ -355,7 +355,7 @@ namespace
mNavigator->addObject(ObjectId(&shape), shape, btTransform::getIdentity()); mNavigator->addObject(ObjectId(&shape), shape, btTransform::getIdentity());
mNavigator->addObject(ObjectId(&shape2), shape2, btTransform::getIdentity()); mNavigator->addObject(ObjectId(&shape2), shape2, btTransform::getIdentity());
mNavigator->update(mPlayerPosition); mNavigator->update(mPlayerPosition);
mNavigator->wait(mListener); mNavigator->wait(mListener, WaitConditionType::allJobsDone);
EXPECT_EQ(mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mAreaCosts, mOut), Status::Success); EXPECT_EQ(mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mAreaCosts, mOut), Status::Success);
@ -411,7 +411,7 @@ namespace
mNavigator->addAgent(mAgentHalfExtents); mNavigator->addAgent(mAgentHalfExtents);
mNavigator->addObject(ObjectId(&shape), ObjectShapes {shape, &shapeAvoid}, btTransform::getIdentity()); mNavigator->addObject(ObjectId(&shape), ObjectShapes {shape, &shapeAvoid}, btTransform::getIdentity());
mNavigator->update(mPlayerPosition); mNavigator->update(mPlayerPosition);
mNavigator->wait(mListener); mNavigator->wait(mListener, WaitConditionType::allJobsDone);
EXPECT_EQ(mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mAreaCosts, mOut), Status::Success); EXPECT_EQ(mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mAreaCosts, mOut), Status::Success);
@ -459,7 +459,7 @@ namespace
mNavigator->addWater(osg::Vec2i(0, 0), 128 * 4, 300, btTransform::getIdentity()); mNavigator->addWater(osg::Vec2i(0, 0), 128 * 4, 300, btTransform::getIdentity());
mNavigator->addObject(ObjectId(&shape), shape, btTransform::getIdentity()); mNavigator->addObject(ObjectId(&shape), shape, btTransform::getIdentity());
mNavigator->update(mPlayerPosition); mNavigator->update(mPlayerPosition);
mNavigator->wait(mListener); mNavigator->wait(mListener, WaitConditionType::allJobsDone);
mStart.x() = 0; mStart.x() = 0;
mStart.z() = 300; mStart.z() = 300;
@ -507,7 +507,7 @@ namespace
mNavigator->addWater(osg::Vec2i(0, 0), 128 * 4, -25, btTransform::getIdentity()); mNavigator->addWater(osg::Vec2i(0, 0), 128 * 4, -25, btTransform::getIdentity());
mNavigator->addObject(ObjectId(&shape), shape, btTransform::getIdentity()); mNavigator->addObject(ObjectId(&shape), shape, btTransform::getIdentity());
mNavigator->update(mPlayerPosition); mNavigator->update(mPlayerPosition);
mNavigator->wait(mListener); mNavigator->wait(mListener, WaitConditionType::allJobsDone);
mStart.x() = 0; mStart.x() = 0;
mEnd.x() = 0; mEnd.x() = 0;
@ -554,7 +554,7 @@ namespace
mNavigator->addObject(ObjectId(&shape), shape, btTransform::getIdentity()); mNavigator->addObject(ObjectId(&shape), shape, btTransform::getIdentity());
mNavigator->addWater(osg::Vec2i(0, 0), std::numeric_limits<int>::max(), -25, btTransform::getIdentity()); mNavigator->addWater(osg::Vec2i(0, 0), std::numeric_limits<int>::max(), -25, btTransform::getIdentity());
mNavigator->update(mPlayerPosition); mNavigator->update(mPlayerPosition);
mNavigator->wait(mListener); mNavigator->wait(mListener, WaitConditionType::allJobsDone);
mStart.x() = 0; mStart.x() = 0;
mEnd.x() = 0; mEnd.x() = 0;
@ -601,7 +601,7 @@ namespace
mNavigator->addWater(osg::Vec2i(0, 0), 128 * 4, -25, btTransform::getIdentity()); mNavigator->addWater(osg::Vec2i(0, 0), 128 * 4, -25, btTransform::getIdentity());
mNavigator->addObject(ObjectId(&shape), shape, btTransform::getIdentity()); mNavigator->addObject(ObjectId(&shape), shape, btTransform::getIdentity());
mNavigator->update(mPlayerPosition); mNavigator->update(mPlayerPosition);
mNavigator->wait(mListener); mNavigator->wait(mListener, WaitConditionType::allJobsDone);
mStart.x() = 0; mStart.x() = 0;
mEnd.x() = 0; mEnd.x() = 0;
@ -645,15 +645,15 @@ namespace
mNavigator->addAgent(mAgentHalfExtents); mNavigator->addAgent(mAgentHalfExtents);
mNavigator->addObject(ObjectId(&shape), shape, btTransform::getIdentity()); mNavigator->addObject(ObjectId(&shape), shape, btTransform::getIdentity());
mNavigator->update(mPlayerPosition); mNavigator->update(mPlayerPosition);
mNavigator->wait(mListener); mNavigator->wait(mListener, WaitConditionType::allJobsDone);
mNavigator->removeObject(ObjectId(&shape)); mNavigator->removeObject(ObjectId(&shape));
mNavigator->update(mPlayerPosition); mNavigator->update(mPlayerPosition);
mNavigator->wait(mListener); mNavigator->wait(mListener, WaitConditionType::allJobsDone);
mNavigator->addObject(ObjectId(&shape), shape, btTransform::getIdentity()); mNavigator->addObject(ObjectId(&shape), shape, btTransform::getIdentity());
mNavigator->update(mPlayerPosition); mNavigator->update(mPlayerPosition);
mNavigator->wait(mListener); mNavigator->wait(mListener, WaitConditionType::allJobsDone);
EXPECT_EQ(mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mAreaCosts, mOut), Status::Success); EXPECT_EQ(mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mAreaCosts, mOut), Status::Success);
@ -699,7 +699,7 @@ namespace
mNavigator->addAgent(mAgentHalfExtents); mNavigator->addAgent(mAgentHalfExtents);
mNavigator->addObject(ObjectId(&shape), shape, btTransform::getIdentity()); mNavigator->addObject(ObjectId(&shape), shape, btTransform::getIdentity());
mNavigator->update(mPlayerPosition); mNavigator->update(mPlayerPosition);
mNavigator->wait(mListener); mNavigator->wait(mListener, WaitConditionType::allJobsDone);
Misc::Rng::init(42); Misc::Rng::init(42);
@ -748,7 +748,7 @@ namespace
} }
mNavigator->update(mPlayerPosition); mNavigator->update(mPlayerPosition);
mNavigator->wait(mListener); mNavigator->wait(mListener, WaitConditionType::allJobsDone);
EXPECT_EQ(mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mAreaCosts, mOut), Status::Success); EXPECT_EQ(mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mAreaCosts, mOut), Status::Success);
@ -791,7 +791,7 @@ namespace
mNavigator->addObject(ObjectId(&shapes[i]), shapes[i], transform); mNavigator->addObject(ObjectId(&shapes[i]), shapes[i], transform);
} }
mNavigator->update(mPlayerPosition); mNavigator->update(mPlayerPosition);
mNavigator->wait(mListener); mNavigator->wait(mListener, WaitConditionType::allJobsDone);
const auto start = std::chrono::steady_clock::now(); const auto start = std::chrono::steady_clock::now();
for (std::size_t i = 0; i < shapes.size(); ++i) for (std::size_t i = 0; i < shapes.size(); ++i)
@ -800,7 +800,7 @@ namespace
mNavigator->updateObject(ObjectId(&shapes[i]), shapes[i], transform); mNavigator->updateObject(ObjectId(&shapes[i]), shapes[i], transform);
} }
mNavigator->update(mPlayerPosition); mNavigator->update(mPlayerPosition);
mNavigator->wait(mListener); mNavigator->wait(mListener, WaitConditionType::allJobsDone);
for (std::size_t i = 0; i < shapes.size(); ++i) for (std::size_t i = 0; i < shapes.size(); ++i)
{ {
@ -808,7 +808,7 @@ namespace
mNavigator->updateObject(ObjectId(&shapes[i]), shapes[i], transform); mNavigator->updateObject(ObjectId(&shapes[i]), shapes[i], transform);
} }
mNavigator->update(mPlayerPosition); mNavigator->update(mPlayerPosition);
mNavigator->wait(mListener); mNavigator->wait(mListener, WaitConditionType::allJobsDone);
const auto duration = std::chrono::steady_clock::now() - start; const auto duration = std::chrono::steady_clock::now() - start;
@ -831,7 +831,7 @@ namespace
mNavigator->addAgent(mAgentHalfExtents); mNavigator->addAgent(mAgentHalfExtents);
mNavigator->addObject(ObjectId(&shape), shape, btTransform::getIdentity()); mNavigator->addObject(ObjectId(&shape), shape, btTransform::getIdentity());
mNavigator->update(mPlayerPosition); mNavigator->update(mPlayerPosition);
mNavigator->wait(mListener); mNavigator->wait(mListener, WaitConditionType::allJobsDone);
const auto result = mNavigator->raycast(mAgentHalfExtents, mStart, mEnd, Flag_walk); const auto result = mNavigator->raycast(mAgentHalfExtents, mStart, mEnd, Flag_walk);
@ -862,7 +862,7 @@ namespace
mNavigator->addObject(ObjectId(&boderBoxShape), boderBoxShape, mNavigator->addObject(ObjectId(&boderBoxShape), boderBoxShape,
btTransform(btMatrix3x3::getIdentity(), oscillatingBoxShapePosition + btVector3(0, 0, 200))); btTransform(btMatrix3x3::getIdentity(), oscillatingBoxShapePosition + btVector3(0, 0, 200)));
mNavigator->update(mPlayerPosition); mNavigator->update(mPlayerPosition);
mNavigator->wait(mListener); mNavigator->wait(mListener, WaitConditionType::allJobsDone);
const auto navMeshes = mNavigator->getNavMeshes(); const auto navMeshes = mNavigator->getNavMeshes();
ASSERT_EQ(navMeshes.size(), 1); ASSERT_EQ(navMeshes.size(), 1);
@ -878,7 +878,7 @@ namespace
oscillatingBoxShapePosition); oscillatingBoxShapePosition);
mNavigator->updateObject(ObjectId(&oscillatingBoxShape), oscillatingBoxShape, transform); mNavigator->updateObject(ObjectId(&oscillatingBoxShape), oscillatingBoxShape, transform);
mNavigator->update(mPlayerPosition); mNavigator->update(mPlayerPosition);
mNavigator->wait(mListener); mNavigator->wait(mListener, WaitConditionType::allJobsDone);
} }
ASSERT_EQ(navMeshes.size(), 1); ASSERT_EQ(navMeshes.size(), 1);

@ -10,7 +10,9 @@
#include <osg/Stats> #include <osg/Stats>
#include <algorithm>
#include <numeric> #include <numeric>
#include <set>
namespace namespace
{ {
@ -23,11 +25,13 @@ namespace
} }
int getMinDistanceTo(const TilePosition& position, int maxDistance, int getMinDistanceTo(const TilePosition& position, int maxDistance,
const std::map<osg::Vec3f, std::set<TilePosition>>& tilesPerHalfExtents) const std::map<osg::Vec3f, std::set<TilePosition>>& tilesPerHalfExtents,
const std::set<std::tuple<osg::Vec3f, TilePosition>>& presentTiles)
{ {
int result = maxDistance; int result = maxDistance;
for (const auto& [halfExtents, tiles] : tilesPerHalfExtents) for (const auto& [halfExtents, tiles] : tilesPerHalfExtents)
for (const TilePosition& tile : tiles) for (const TilePosition& tile : tiles)
if (presentTiles.find(std::make_tuple(halfExtents, tile)) == presentTiles.end())
result = std::min(result, getManhattanDistance(position, tile)); result = std::min(result, getManhattanDistance(position, tile));
return result; return result;
} }
@ -142,7 +146,7 @@ namespace DetourNavigator
mHasJob.notify_all(); mHasJob.notify_all();
} }
void AsyncNavMeshUpdater::wait(Loading::Listener& listener) void AsyncNavMeshUpdater::wait(Loading::Listener& listener, WaitConditionType waitConditionType)
{ {
if (mSettings.get().mWaitUntilMinDistanceToPlayer == 0) if (mSettings.get().mWaitUntilMinDistanceToPlayer == 0)
return; return;
@ -150,15 +154,26 @@ namespace DetourNavigator
const std::size_t initialJobsLeft = getTotalJobs(); const std::size_t initialJobsLeft = getTotalJobs();
std::size_t maxProgress = initialJobsLeft + mThreads.size(); std::size_t maxProgress = initialJobsLeft + mThreads.size();
listener.setProgressRange(maxProgress); listener.setProgressRange(maxProgress);
const int minDistanceToPlayer = waitUntilJobsDone(initialJobsLeft, maxProgress, listener); switch (waitConditionType)
{
case WaitConditionType::requiredTilesPresent:
{
const int minDistanceToPlayer = waitUntilJobsDoneForNotPresentTiles(initialJobsLeft, maxProgress, listener);
if (minDistanceToPlayer < mSettings.get().mWaitUntilMinDistanceToPlayer) if (minDistanceToPlayer < mSettings.get().mWaitUntilMinDistanceToPlayer)
{ {
mProcessingTiles.wait(mProcessed, [] (const auto& v) { return v.empty(); }); mProcessingTiles.wait(mProcessed, [] (const auto& v) { return v.empty(); });
listener.setProgress(maxProgress); listener.setProgress(maxProgress);
} }
break;
}
case WaitConditionType::allJobsDone:
waitUntilAllJobsDone();
listener.setProgress(maxProgress);
break;
}
} }
int AsyncNavMeshUpdater::waitUntilJobsDone(const std::size_t initialJobsLeft, std::size_t& maxProgress, Loading::Listener& listener) int AsyncNavMeshUpdater::waitUntilJobsDoneForNotPresentTiles(const std::size_t initialJobsLeft, std::size_t& maxProgress, Loading::Listener& listener)
{ {
std::size_t prevJobsLeft = initialJobsLeft; std::size_t prevJobsLeft = initialJobsLeft;
std::size_t jobsDone = 0; std::size_t jobsDone = 0;
@ -174,9 +189,9 @@ namespace DetourNavigator
minDistanceToPlayer = 0; minDistanceToPlayer = 0;
return true; return true;
} }
minDistanceToPlayer = getMinDistanceTo(playerPosition, maxDistanceToPlayer, mPushed); minDistanceToPlayer = getMinDistanceTo(playerPosition, maxDistanceToPlayer, mPushed, mPresentTiles);
for (const auto& [threadId, queue] : mThreadsQueues) for (const auto& [threadId, queue] : mThreadsQueues)
minDistanceToPlayer = getMinDistanceTo(playerPosition, minDistanceToPlayer, queue.mPushed); minDistanceToPlayer = getMinDistanceTo(playerPosition, minDistanceToPlayer, queue.mPushed, mPresentTiles);
return minDistanceToPlayer >= maxDistanceToPlayer; return minDistanceToPlayer >= maxDistanceToPlayer;
}; };
std::unique_lock<std::mutex> lock(mMutex); std::unique_lock<std::mutex> lock(mMutex);
@ -199,6 +214,15 @@ namespace DetourNavigator
return minDistanceToPlayer; return minDistanceToPlayer;
} }
void AsyncNavMeshUpdater::waitUntilAllJobsDone()
{
{
std::unique_lock<std::mutex> lock(mMutex);
mDone.wait(lock, [this] { return mJobs.size() + getTotalThreadJobsUnsafe() == 0; });
}
mProcessingTiles.wait(mProcessed, [] (const auto& v) { return v.empty(); });
}
void AsyncNavMeshUpdater::reportStats(unsigned int frameNumber, osg::Stats& stats) const void AsyncNavMeshUpdater::reportStats(unsigned int frameNumber, osg::Stats& stats) const
{ {
std::size_t jobs = 0; std::size_t jobs = 0;
@ -273,6 +297,11 @@ namespace DetourNavigator
navMeshVersion); navMeshVersion);
} }
if (status == UpdateNavMeshStatus::removed || status == UpdateNavMeshStatus::lost)
mPresentTiles.erase(std::make_tuple(job.mAgentHalfExtents, job.mChangedTile));
else if (isSuccess(status) && status != UpdateNavMeshStatus::ignored)
mPresentTiles.insert(std::make_tuple(job.mAgentHalfExtents, job.mChangedTile));
const auto finish = std::chrono::steady_clock::now(); const auto finish = std::chrono::steady_clock::now();
writeDebugFiles(job, recastMesh.get()); writeDebugFiles(job, recastMesh.get());

@ -6,6 +6,7 @@
#include "tilecachedrecastmeshmanager.hpp" #include "tilecachedrecastmeshmanager.hpp"
#include "tileposition.hpp" #include "tileposition.hpp"
#include "navmeshtilescache.hpp" #include "navmeshtilescache.hpp"
#include "waitconditiontype.hpp"
#include <osg/Vec3f> #include <osg/Vec3f>
@ -61,7 +62,7 @@ namespace DetourNavigator
void post(const osg::Vec3f& agentHalfExtents, const SharedNavMeshCacheItem& mNavMeshCacheItem, void post(const osg::Vec3f& agentHalfExtents, const SharedNavMeshCacheItem& mNavMeshCacheItem,
const TilePosition& playerTile, const std::map<TilePosition, ChangeType>& changedTiles); const TilePosition& playerTile, const std::map<TilePosition, ChangeType>& changedTiles);
void wait(Loading::Listener& listener); void wait(Loading::Listener& listener, WaitConditionType waitConditionType);
void reportStats(unsigned int frameNumber, osg::Stats& stats) const; void reportStats(unsigned int frameNumber, osg::Stats& stats) const;
@ -114,6 +115,7 @@ namespace DetourNavigator
NavMeshTilesCache mNavMeshTilesCache; NavMeshTilesCache mNavMeshTilesCache;
Misc::ScopeGuarded<std::map<osg::Vec3f, std::map<TilePosition, std::thread::id>>> mProcessingTiles; Misc::ScopeGuarded<std::map<osg::Vec3f, std::map<TilePosition, std::thread::id>>> mProcessingTiles;
std::map<osg::Vec3f, std::map<TilePosition, std::chrono::steady_clock::time_point>> mLastUpdates; std::map<osg::Vec3f, std::map<TilePosition, std::chrono::steady_clock::time_point>> mLastUpdates;
std::set<std::tuple<osg::Vec3f, TilePosition>> mPresentTiles;
std::map<std::thread::id, Queue> mThreadsQueues; std::map<std::thread::id, Queue> mThreadsQueues;
std::vector<std::thread> mThreads; std::vector<std::thread> mThreads;
@ -143,7 +145,9 @@ namespace DetourNavigator
void cleanupLastUpdates(); void cleanupLastUpdates();
int waitUntilJobsDone(const std::size_t initialJobsLeft, std::size_t& maxJobsLeft, Loading::Listener& listener); int waitUntilJobsDoneForNotPresentTiles(const std::size_t initialJobsLeft, std::size_t& maxJobsLeft, Loading::Listener& listener);
void waitUntilAllJobsDone();
}; };
} }

@ -7,6 +7,7 @@
#include "objectid.hpp" #include "objectid.hpp"
#include "navmeshcacheitem.hpp" #include "navmeshcacheitem.hpp"
#include "recastmeshtiles.hpp" #include "recastmeshtiles.hpp"
#include "waitconditiontype.hpp"
namespace ESM namespace ESM
{ {
@ -165,9 +166,10 @@ namespace DetourNavigator
virtual void setUpdatesEnabled(bool enabled) = 0; virtual void setUpdatesEnabled(bool enabled) = 0;
/** /**
* @brief wait locks thread until all tiles are updated from last update call. * @brief wait locks thread until tiles are updated from last update call based on passed condition type.
* @param waitConditionType defines when waiting will stop
*/ */
virtual void wait(Loading::Listener& listener) = 0; virtual void wait(Loading::Listener& listener, WaitConditionType waitConditionType) = 0;
/** /**
* @brief findPath fills output iterator with points of scene surfaces to be used for actor to walk through. * @brief findPath fills output iterator with points of scene surfaces to be used for actor to walk through.

@ -153,9 +153,9 @@ namespace DetourNavigator
mUpdatesEnabled = enabled; mUpdatesEnabled = enabled;
} }
void NavigatorImpl::wait(Loading::Listener& listener) void NavigatorImpl::wait(Loading::Listener& listener, WaitConditionType waitConditionType)
{ {
mNavMeshManager.wait(listener); mNavMeshManager.wait(listener, waitConditionType);
} }
SharedNavMeshCacheItem NavigatorImpl::getNavMesh(const osg::Vec3f& agentHalfExtents) const SharedNavMeshCacheItem NavigatorImpl::getNavMesh(const osg::Vec3f& agentHalfExtents) const

@ -48,7 +48,7 @@ namespace DetourNavigator
void setUpdatesEnabled(bool enabled) override; void setUpdatesEnabled(bool enabled) override;
void wait(Loading::Listener& listener) override; void wait(Loading::Listener& listener, WaitConditionType waitConditionType) override;
SharedNavMeshCacheItem getNavMesh(const osg::Vec3f& agentHalfExtents) const override; SharedNavMeshCacheItem getNavMesh(const osg::Vec3f& agentHalfExtents) const override;

@ -73,7 +73,7 @@ namespace DetourNavigator
void setUpdatesEnabled(bool /*enabled*/) override {} void setUpdatesEnabled(bool /*enabled*/) override {}
void wait(Loading::Listener& /*listener*/) override {} void wait(Loading::Listener& /*listener*/, WaitConditionType /*waitConditionType*/) override {}
SharedNavMeshCacheItem getNavMesh(const osg::Vec3f& /*agentHalfExtents*/) const override SharedNavMeshCacheItem getNavMesh(const osg::Vec3f& /*agentHalfExtents*/) const override
{ {

@ -5,6 +5,7 @@
#include "makenavmesh.hpp" #include "makenavmesh.hpp"
#include "navmeshcacheitem.hpp" #include "navmeshcacheitem.hpp"
#include "settings.hpp" #include "settings.hpp"
#include "waitconditiontype.hpp"
#include <components/debug/debuglog.hpp> #include <components/debug/debuglog.hpp>
@ -190,9 +191,9 @@ namespace DetourNavigator
" recastMeshManagerRevision=" << lastRevision; " recastMeshManagerRevision=" << lastRevision;
} }
void NavMeshManager::wait(Loading::Listener& listener) void NavMeshManager::wait(Loading::Listener& listener, WaitConditionType waitConditionType)
{ {
mAsyncNavMeshUpdater.wait(listener); mAsyncNavMeshUpdater.wait(listener, waitConditionType);
} }
SharedNavMeshCacheItem NavMeshManager::getNavMesh(const osg::Vec3f& agentHalfExtents) const SharedNavMeshCacheItem NavMeshManager::getNavMesh(const osg::Vec3f& agentHalfExtents) const

@ -6,6 +6,7 @@
#include "offmeshconnectionsmanager.hpp" #include "offmeshconnectionsmanager.hpp"
#include "sharednavmesh.hpp" #include "sharednavmesh.hpp"
#include "recastmeshtiles.hpp" #include "recastmeshtiles.hpp"
#include "waitconditiontype.hpp"
#include <BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h> #include <BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h>
@ -45,7 +46,7 @@ namespace DetourNavigator
void update(osg::Vec3f playerPosition, const osg::Vec3f& agentHalfExtents); void update(osg::Vec3f playerPosition, const osg::Vec3f& agentHalfExtents);
void wait(Loading::Listener& listener); void wait(Loading::Listener& listener, WaitConditionType waitConditionType);
SharedNavMeshCacheItem getNavMesh(const osg::Vec3f& agentHalfExtents) const; SharedNavMeshCacheItem getNavMesh(const osg::Vec3f& agentHalfExtents) const;

@ -0,0 +1,13 @@
#ifndef OPENMW_COMPONENTS_DETOURNAVIGATOR_WAITCONDITIONTYPE_H
#define OPENMW_COMPONENTS_DETOURNAVIGATOR_WAITCONDITIONTYPE_H
namespace DetourNavigator
{
enum class WaitConditionType
{
requiredTilesPresent,
allJobsDone,
};
}
#endif
Loading…
Cancel
Save