mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-08 09:37:53 +00:00
c771986c56
When player move fast enough, tiles update for specific area square couldn't catch player move. Tiles to be removed are left in the queue with lower priority then tiles to be added which are nearest to player. This can lead to overflow for amount of tiles. So we try to do remove first. But we detect change type approximately using mixed change type, because even if we do it precise, change type could change while job is in queue.
94 lines
2.5 KiB
C++
94 lines
2.5 KiB
C++
#ifndef OPENMW_COMPONENTS_DETOURNAVIGATOR_ASYNCNAVMESHUPDATER_H
|
|
#define OPENMW_COMPONENTS_DETOURNAVIGATOR_ASYNCNAVMESHUPDATER_H
|
|
|
|
#include "navmeshcacheitem.hpp"
|
|
#include "tilecachedrecastmeshmanager.hpp"
|
|
#include "tileposition.hpp"
|
|
|
|
#include <osg/Vec3f>
|
|
|
|
#include <boost/optional.hpp>
|
|
|
|
#include <atomic>
|
|
#include <chrono>
|
|
#include <condition_variable>
|
|
#include <memory>
|
|
#include <mutex>
|
|
#include <queue>
|
|
#include <set>
|
|
#include <thread>
|
|
|
|
class dtNavMesh;
|
|
|
|
namespace DetourNavigator
|
|
{
|
|
enum class ChangeType
|
|
{
|
|
remove = 0,
|
|
mixed = 1,
|
|
add = 2,
|
|
};
|
|
|
|
class AsyncNavMeshUpdater
|
|
{
|
|
public:
|
|
AsyncNavMeshUpdater(const Settings& settings, TileCachedRecastMeshManager& recastMeshManager);
|
|
~AsyncNavMeshUpdater();
|
|
|
|
void post(const osg::Vec3f& agentHalfExtents, const std::shared_ptr<NavMeshCacheItem>& mNavMeshCacheItem,
|
|
const TilePosition& playerTile, const std::map<TilePosition, ChangeType>& changedTiles);
|
|
|
|
void wait();
|
|
|
|
private:
|
|
struct Job
|
|
{
|
|
osg::Vec3f mAgentHalfExtents;
|
|
std::shared_ptr<NavMeshCacheItem> mNavMeshCacheItem;
|
|
TilePosition mChangedTile;
|
|
std::tuple<ChangeType, int, int> mPriority;
|
|
|
|
friend inline bool operator <(const Job& lhs, const Job& rhs)
|
|
{
|
|
return lhs.mPriority > rhs.mPriority;
|
|
}
|
|
};
|
|
|
|
using Jobs = std::priority_queue<Job, std::deque<Job>>;
|
|
|
|
std::reference_wrapper<const Settings> mSettings;
|
|
std::reference_wrapper<TileCachedRecastMeshManager> mRecastMeshManager;
|
|
std::atomic_bool mShouldStop;
|
|
std::mutex mMutex;
|
|
std::condition_variable mHasJob;
|
|
std::condition_variable mDone;
|
|
Jobs mJobs;
|
|
std::map<osg::Vec3f, std::set<TilePosition>> mPushed;
|
|
std::mutex mPlayerTileMutex;
|
|
TilePosition mPlayerTile;
|
|
std::mutex mFirstStartMutex;
|
|
boost::optional<std::chrono::steady_clock::time_point> mFirstStart;
|
|
std::thread mThread;
|
|
|
|
void process() throw();
|
|
|
|
void processJob(const Job& job);
|
|
|
|
boost::optional<Job> getNextJob();
|
|
|
|
void notifyHasJob();
|
|
|
|
void writeDebugFiles(const Job& job, const RecastMesh* recastMesh) const;
|
|
|
|
std::chrono::steady_clock::time_point getFirstStart();
|
|
|
|
void setFirstStart(const std::chrono::steady_clock::time_point& value);
|
|
|
|
TilePosition getPlayerTile();
|
|
|
|
void setPlayerTile(const TilePosition& value);
|
|
};
|
|
}
|
|
|
|
#endif
|