mirror of
https://github.com/OpenMW/openmw.git
synced 2025-05-09 20:11:25 +00:00
Wait until navmesh is generated for interior cells
Add special loading progress bar. It should be fast enough to not keep loading screen for noticably long but will provide better pathfinding for actors inside interior cells.
This commit is contained in:
parent
3618eabaf0
commit
f169f8e6f0
11 changed files with 99 additions and 38 deletions
|
@ -847,6 +847,8 @@ namespace MWWorld
|
||||||
MWBase::Environment::get().getWindowManager()->fadeScreenIn(0.5);
|
MWBase::Environment::get().getWindowManager()->fadeScreenIn(0.5);
|
||||||
|
|
||||||
MWBase::Environment::get().getWindowManager()->changeCell(mCurrentCell);
|
MWBase::Environment::get().getWindowManager()->changeCell(mCurrentCell);
|
||||||
|
|
||||||
|
mNavigator.wait(*loadingListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::changeToExteriorCell (const ESM::Position& position, bool adjustPlayerPos, bool changeEvent)
|
void Scene::changeToExteriorCell (const ESM::Position& position, bool adjustPlayerPos, bool changeEvent)
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <components/detournavigator/navigatorimpl.hpp>
|
#include <components/detournavigator/navigatorimpl.hpp>
|
||||||
#include <components/detournavigator/exceptions.hpp>
|
#include <components/detournavigator/exceptions.hpp>
|
||||||
#include <components/misc/rng.hpp>
|
#include <components/misc/rng.hpp>
|
||||||
|
#include <components/loadinglistener/loadinglistener.hpp>
|
||||||
|
|
||||||
#include <BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h>
|
#include <BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h>
|
||||||
#include <BulletCollision/CollisionShapes/btBoxShape.h>
|
#include <BulletCollision/CollisionShapes/btBoxShape.h>
|
||||||
|
@ -35,6 +36,7 @@ namespace
|
||||||
std::back_insert_iterator<std::deque<osg::Vec3f>> mOut;
|
std::back_insert_iterator<std::deque<osg::Vec3f>> mOut;
|
||||||
float mStepSize;
|
float mStepSize;
|
||||||
AreaCosts mAreaCosts;
|
AreaCosts mAreaCosts;
|
||||||
|
Loading::Listener mListener;
|
||||||
|
|
||||||
DetourNavigatorNavigatorTest()
|
DetourNavigatorNavigatorTest()
|
||||||
: mPlayerPosition(0, 0, 0)
|
: mPlayerPosition(0, 0, 0)
|
||||||
|
@ -124,7 +126,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();
|
mNavigator->wait(mListener);
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
|
@ -174,7 +176,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();
|
mNavigator->wait(mListener);
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
|
@ -206,7 +208,7 @@ namespace
|
||||||
|
|
||||||
mNavigator->addObject(ObjectId(&compoundShape), compoundShape, btTransform::getIdentity());
|
mNavigator->addObject(ObjectId(&compoundShape), compoundShape, btTransform::getIdentity());
|
||||||
mNavigator->update(mPlayerPosition);
|
mNavigator->update(mPlayerPosition);
|
||||||
mNavigator->wait();
|
mNavigator->wait(mListener);
|
||||||
|
|
||||||
mPath.clear();
|
mPath.clear();
|
||||||
mOut = std::back_inserter(mPath);
|
mOut = std::back_inserter(mPath);
|
||||||
|
@ -259,7 +261,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();
|
mNavigator->wait(mListener);
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
|
@ -293,7 +295,7 @@ namespace
|
||||||
|
|
||||||
mNavigator->updateObject(ObjectId(&compoundShape), compoundShape, btTransform::getIdentity());
|
mNavigator->updateObject(ObjectId(&compoundShape), compoundShape, btTransform::getIdentity());
|
||||||
mNavigator->update(mPlayerPosition);
|
mNavigator->update(mPlayerPosition);
|
||||||
mNavigator->wait();
|
mNavigator->wait(mListener);
|
||||||
|
|
||||||
mPath.clear();
|
mPath.clear();
|
||||||
mOut = std::back_inserter(mPath);
|
mOut = std::back_inserter(mPath);
|
||||||
|
@ -352,7 +354,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();
|
mNavigator->wait(mListener);
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
|
@ -408,7 +410,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();
|
mNavigator->wait(mListener);
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
|
@ -456,7 +458,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();
|
mNavigator->wait(mListener);
|
||||||
|
|
||||||
mStart.x() = 0;
|
mStart.x() = 0;
|
||||||
mStart.z() = 300;
|
mStart.z() = 300;
|
||||||
|
@ -504,7 +506,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();
|
mNavigator->wait(mListener);
|
||||||
|
|
||||||
mStart.x() = 0;
|
mStart.x() = 0;
|
||||||
mEnd.x() = 0;
|
mEnd.x() = 0;
|
||||||
|
@ -551,7 +553,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();
|
mNavigator->wait(mListener);
|
||||||
|
|
||||||
mStart.x() = 0;
|
mStart.x() = 0;
|
||||||
mEnd.x() = 0;
|
mEnd.x() = 0;
|
||||||
|
@ -598,7 +600,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();
|
mNavigator->wait(mListener);
|
||||||
|
|
||||||
mStart.x() = 0;
|
mStart.x() = 0;
|
||||||
mEnd.x() = 0;
|
mEnd.x() = 0;
|
||||||
|
@ -642,15 +644,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();
|
mNavigator->wait(mListener);
|
||||||
|
|
||||||
mNavigator->removeObject(ObjectId(&shape));
|
mNavigator->removeObject(ObjectId(&shape));
|
||||||
mNavigator->update(mPlayerPosition);
|
mNavigator->update(mPlayerPosition);
|
||||||
mNavigator->wait();
|
mNavigator->wait(mListener);
|
||||||
|
|
||||||
mNavigator->addObject(ObjectId(&shape), shape, btTransform::getIdentity());
|
mNavigator->addObject(ObjectId(&shape), shape, btTransform::getIdentity());
|
||||||
mNavigator->update(mPlayerPosition);
|
mNavigator->update(mPlayerPosition);
|
||||||
mNavigator->wait();
|
mNavigator->wait(mListener);
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
|
@ -696,7 +698,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();
|
mNavigator->wait(mListener);
|
||||||
|
|
||||||
Misc::Rng::init(42);
|
Misc::Rng::init(42);
|
||||||
|
|
||||||
|
@ -745,7 +747,7 @@ namespace
|
||||||
}
|
}
|
||||||
|
|
||||||
mNavigator->update(mPlayerPosition);
|
mNavigator->update(mPlayerPosition);
|
||||||
mNavigator->wait();
|
mNavigator->wait(mListener);
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
|
@ -788,7 +790,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();
|
mNavigator->wait(mListener);
|
||||||
|
|
||||||
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)
|
||||||
|
@ -797,7 +799,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();
|
mNavigator->wait(mListener);
|
||||||
|
|
||||||
for (std::size_t i = 0; i < shapes.size(); ++i)
|
for (std::size_t i = 0; i < shapes.size(); ++i)
|
||||||
{
|
{
|
||||||
|
@ -805,7 +807,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();
|
mNavigator->wait(mListener);
|
||||||
|
|
||||||
const auto duration = std::chrono::steady_clock::now() - start;
|
const auto duration = std::chrono::steady_clock::now() - start;
|
||||||
|
|
||||||
|
@ -828,7 +830,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();
|
mNavigator->wait(mListener);
|
||||||
|
|
||||||
const auto result = mNavigator->raycast(mAgentHalfExtents, mStart, mEnd, Flag_walk);
|
const auto result = mNavigator->raycast(mAgentHalfExtents, mStart, mEnd, Flag_walk);
|
||||||
|
|
||||||
|
@ -859,7 +861,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();
|
mNavigator->wait(mListener);
|
||||||
|
|
||||||
const auto navMeshes = mNavigator->getNavMeshes();
|
const auto navMeshes = mNavigator->getNavMeshes();
|
||||||
ASSERT_EQ(navMeshes.size(), 1);
|
ASSERT_EQ(navMeshes.size(), 1);
|
||||||
|
@ -875,7 +877,7 @@ namespace
|
||||||
oscillatingBoxShapePosition);
|
oscillatingBoxShapePosition);
|
||||||
mNavigator->updateObject(ObjectId(&oscillatingBoxShape), oscillatingBoxShape, transform);
|
mNavigator->updateObject(ObjectId(&oscillatingBoxShape), oscillatingBoxShape, transform);
|
||||||
mNavigator->update(mPlayerPosition);
|
mNavigator->update(mPlayerPosition);
|
||||||
mNavigator->wait();
|
mNavigator->wait(mListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT_EQ(navMeshes.size(), 1);
|
ASSERT_EQ(navMeshes.size(), 1);
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include <components/debug/debuglog.hpp>
|
#include <components/debug/debuglog.hpp>
|
||||||
#include <components/misc/thread.hpp>
|
#include <components/misc/thread.hpp>
|
||||||
|
#include <components/loadinglistener/loadinglistener.hpp>
|
||||||
|
|
||||||
#include <osg/Stats>
|
#include <osg/Stats>
|
||||||
|
|
||||||
|
@ -111,13 +112,44 @@ namespace DetourNavigator
|
||||||
mHasJob.notify_all();
|
mHasJob.notify_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AsyncNavMeshUpdater::wait()
|
void AsyncNavMeshUpdater::wait(Loading::Listener& listener)
|
||||||
{
|
{
|
||||||
{
|
listener.setLabel("Building navigation mesh");
|
||||||
std::unique_lock<std::mutex> lock(mMutex);
|
const std::size_t initialJobsLeft = getTotalJobs();
|
||||||
mDone.wait(lock, [&] { return mJobs.empty() && getTotalThreadJobsUnsafe() == 0; });
|
std::size_t maxProgress = initialJobsLeft + mThreads.size();
|
||||||
}
|
listener.setProgressRange(maxProgress);
|
||||||
|
waitUntilJobsDone(initialJobsLeft, maxProgress, listener);
|
||||||
mProcessingTiles.wait(mProcessed, [] (const auto& v) { return v.empty(); });
|
mProcessingTiles.wait(mProcessed, [] (const auto& v) { return v.empty(); });
|
||||||
|
listener.setProgress(maxProgress);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AsyncNavMeshUpdater::waitUntilJobsDone(const std::size_t initialJobsLeft, std::size_t& maxProgress, Loading::Listener& listener)
|
||||||
|
{
|
||||||
|
std::size_t prevJobsLeft = initialJobsLeft;
|
||||||
|
std::size_t jobsDone = 0;
|
||||||
|
std::size_t jobsLeft = 0;
|
||||||
|
const auto isDone = [&]
|
||||||
|
{
|
||||||
|
jobsLeft = mJobs.size() + getTotalThreadJobsUnsafe();
|
||||||
|
return jobsLeft == 0;
|
||||||
|
};
|
||||||
|
std::unique_lock<std::mutex> lock(mMutex);
|
||||||
|
while (!mDone.wait_for(lock, std::chrono::milliseconds(250), isDone))
|
||||||
|
{
|
||||||
|
if (maxProgress < jobsLeft)
|
||||||
|
{
|
||||||
|
maxProgress = jobsLeft + mThreads.size();
|
||||||
|
listener.setProgressRange(maxProgress);
|
||||||
|
listener.setProgress(jobsDone);
|
||||||
|
}
|
||||||
|
else if (jobsLeft < prevJobsLeft)
|
||||||
|
{
|
||||||
|
const std::size_t newJobsDone = prevJobsLeft - jobsLeft;
|
||||||
|
jobsDone += newJobsDone;
|
||||||
|
prevJobsLeft = jobsLeft;
|
||||||
|
listener.increaseProgress(newJobsDone);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AsyncNavMeshUpdater::reportStats(unsigned int frameNumber, osg::Stats& stats) const
|
void AsyncNavMeshUpdater::reportStats(unsigned int frameNumber, osg::Stats& stats) const
|
||||||
|
@ -381,6 +413,12 @@ namespace DetourNavigator
|
||||||
mProcessed.notify_all();
|
mProcessed.notify_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::size_t AsyncNavMeshUpdater::getTotalJobs() const
|
||||||
|
{
|
||||||
|
const std::scoped_lock lock(mMutex);
|
||||||
|
return mJobs.size() + getTotalThreadJobsUnsafe();
|
||||||
|
}
|
||||||
|
|
||||||
std::size_t AsyncNavMeshUpdater::getTotalThreadJobsUnsafe() const
|
std::size_t AsyncNavMeshUpdater::getTotalThreadJobsUnsafe() const
|
||||||
{
|
{
|
||||||
return std::accumulate(mThreadsQueues.begin(), mThreadsQueues.end(), std::size_t(0),
|
return std::accumulate(mThreadsQueues.begin(), mThreadsQueues.end(), std::size_t(0),
|
||||||
|
|
|
@ -20,6 +20,11 @@
|
||||||
|
|
||||||
class dtNavMesh;
|
class dtNavMesh;
|
||||||
|
|
||||||
|
namespace Loading
|
||||||
|
{
|
||||||
|
class Listener;
|
||||||
|
}
|
||||||
|
|
||||||
namespace DetourNavigator
|
namespace DetourNavigator
|
||||||
{
|
{
|
||||||
enum class ChangeType
|
enum class ChangeType
|
||||||
|
@ -55,7 +60,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();
|
void wait(Loading::Listener& listener);
|
||||||
|
|
||||||
void reportStats(unsigned int frameNumber, osg::Stats& stats) const;
|
void reportStats(unsigned int frameNumber, osg::Stats& stats) const;
|
||||||
|
|
||||||
|
@ -131,9 +136,13 @@ namespace DetourNavigator
|
||||||
|
|
||||||
void unlockTile(const osg::Vec3f& agentHalfExtents, const TilePosition& changedTile);
|
void unlockTile(const osg::Vec3f& agentHalfExtents, const TilePosition& changedTile);
|
||||||
|
|
||||||
|
inline std::size_t getTotalJobs() const;
|
||||||
|
|
||||||
inline std::size_t getTotalThreadJobsUnsafe() const;
|
inline std::size_t getTotalThreadJobsUnsafe() const;
|
||||||
|
|
||||||
void cleanupLastUpdates();
|
void cleanupLastUpdates();
|
||||||
|
|
||||||
|
void waitUntilJobsDone(const std::size_t initialJobsLeft, std::size_t& maxJobsLeft, Loading::Listener& listener);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,11 @@ namespace ESM
|
||||||
struct Pathgrid;
|
struct Pathgrid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace Loading
|
||||||
|
{
|
||||||
|
class Listener;
|
||||||
|
}
|
||||||
|
|
||||||
namespace DetourNavigator
|
namespace DetourNavigator
|
||||||
{
|
{
|
||||||
struct ObjectShapes
|
struct ObjectShapes
|
||||||
|
@ -162,7 +167,7 @@ namespace DetourNavigator
|
||||||
/**
|
/**
|
||||||
* @brief wait locks thread until all tiles are updated from last update call.
|
* @brief wait locks thread until all tiles are updated from last update call.
|
||||||
*/
|
*/
|
||||||
virtual void wait() = 0;
|
virtual void wait(Loading::Listener& listener) = 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()
|
void NavigatorImpl::wait(Loading::Listener& listener)
|
||||||
{
|
{
|
||||||
mNavMeshManager.wait();
|
mNavMeshManager.wait(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
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() override;
|
void wait(Loading::Listener& listener) override;
|
||||||
|
|
||||||
SharedNavMeshCacheItem getNavMesh(const osg::Vec3f& agentHalfExtents) const override;
|
SharedNavMeshCacheItem getNavMesh(const osg::Vec3f& agentHalfExtents) const override;
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,11 @@
|
||||||
|
|
||||||
#include "navigator.hpp"
|
#include "navigator.hpp"
|
||||||
|
|
||||||
|
namespace Loading
|
||||||
|
{
|
||||||
|
class Listener;
|
||||||
|
}
|
||||||
|
|
||||||
namespace DetourNavigator
|
namespace DetourNavigator
|
||||||
{
|
{
|
||||||
class NavigatorStub final : public Navigator
|
class NavigatorStub final : public Navigator
|
||||||
|
@ -68,7 +73,7 @@ namespace DetourNavigator
|
||||||
|
|
||||||
void setUpdatesEnabled(bool /*enabled*/) override {}
|
void setUpdatesEnabled(bool /*enabled*/) override {}
|
||||||
|
|
||||||
void wait() override {}
|
void wait(Loading::Listener& /*listener*/) override {}
|
||||||
|
|
||||||
SharedNavMeshCacheItem getNavMesh(const osg::Vec3f& /*agentHalfExtents*/) const override
|
SharedNavMeshCacheItem getNavMesh(const osg::Vec3f& /*agentHalfExtents*/) const override
|
||||||
{
|
{
|
||||||
|
|
|
@ -188,9 +188,9 @@ namespace DetourNavigator
|
||||||
" recastMeshManagerRevision=" << lastRevision;
|
" recastMeshManagerRevision=" << lastRevision;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavMeshManager::wait()
|
void NavMeshManager::wait(Loading::Listener& listener)
|
||||||
{
|
{
|
||||||
mAsyncNavMeshUpdater.wait();
|
mAsyncNavMeshUpdater.wait(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedNavMeshCacheItem NavMeshManager::getNavMesh(const osg::Vec3f& agentHalfExtents) const
|
SharedNavMeshCacheItem NavMeshManager::getNavMesh(const osg::Vec3f& agentHalfExtents) const
|
||||||
|
|
|
@ -45,7 +45,7 @@ namespace DetourNavigator
|
||||||
|
|
||||||
void update(osg::Vec3f playerPosition, const osg::Vec3f& agentHalfExtents);
|
void update(osg::Vec3f playerPosition, const osg::Vec3f& agentHalfExtents);
|
||||||
|
|
||||||
void wait();
|
void wait(Loading::Listener& listener);
|
||||||
|
|
||||||
SharedNavMeshCacheItem getNavMesh(const osg::Vec3f& agentHalfExtents) const;
|
SharedNavMeshCacheItem getNavMesh(const osg::Vec3f& agentHalfExtents) const;
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,7 @@ namespace Misc
|
||||||
return Locked<T>(mMutex, mValue);
|
return Locked<T>(mMutex, mValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
Locked<const T> lockConst()
|
Locked<const T> lockConst() const
|
||||||
{
|
{
|
||||||
return Locked<const T>(mMutex, mValue);
|
return Locked<const T>(mMutex, mValue);
|
||||||
}
|
}
|
||||||
|
@ -88,7 +88,7 @@ namespace Misc
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::mutex mMutex;
|
mutable std::mutex mMutex;
|
||||||
T mValue;
|
T mValue;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue