mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-20 13:53:53 +00:00
beeb882ea8
To reduce cache size and make it more flexible. Adding off mesh connections to the navmesh is the last step of navmesh generation and it's very fast comparing to other steps (microseconds vs milliseconds). Having less cache size makes get and set operations almost 2x times faster that also have an order of microseconds. So in total there is no performance impact.
138 lines
3.6 KiB
C++
138 lines
3.6 KiB
C++
#ifndef OPENMW_COMPONENTS_DETOURNAVIGATOR_NAVMESHCACHEITEM_H
|
|
#define OPENMW_COMPONENTS_DETOURNAVIGATOR_NAVMESHCACHEITEM_H
|
|
|
|
#include "sharednavmesh.hpp"
|
|
#include "tileposition.hpp"
|
|
#include "navmeshtilescache.hpp"
|
|
#include "dtstatus.hpp"
|
|
#include "navmeshdata.hpp"
|
|
|
|
#include <components/misc/guarded.hpp>
|
|
|
|
#include <map>
|
|
|
|
struct dtMeshTile;
|
|
|
|
namespace DetourNavigator
|
|
{
|
|
enum class UpdateNavMeshStatus : unsigned
|
|
{
|
|
ignored = 0,
|
|
removed = 1 << 0,
|
|
added = 1 << 1,
|
|
replaced = removed | added,
|
|
failed = 1 << 2,
|
|
lost = removed | failed,
|
|
cached = 1 << 3,
|
|
unchanged = replaced | cached,
|
|
restored = added | cached,
|
|
};
|
|
|
|
inline bool isSuccess(UpdateNavMeshStatus value)
|
|
{
|
|
return (static_cast<unsigned>(value) & static_cast<unsigned>(UpdateNavMeshStatus::failed)) == 0;
|
|
}
|
|
|
|
class UpdateNavMeshStatusBuilder
|
|
{
|
|
public:
|
|
UpdateNavMeshStatusBuilder() = default;
|
|
|
|
explicit UpdateNavMeshStatusBuilder(UpdateNavMeshStatus value)
|
|
: mResult(value) {}
|
|
|
|
UpdateNavMeshStatusBuilder removed(bool value)
|
|
{
|
|
if (value)
|
|
set(UpdateNavMeshStatus::removed);
|
|
else
|
|
unset(UpdateNavMeshStatus::removed);
|
|
return *this;
|
|
}
|
|
|
|
UpdateNavMeshStatusBuilder added(bool value)
|
|
{
|
|
if (value)
|
|
set(UpdateNavMeshStatus::added);
|
|
else
|
|
unset(UpdateNavMeshStatus::added);
|
|
return *this;
|
|
}
|
|
|
|
UpdateNavMeshStatusBuilder failed(bool value)
|
|
{
|
|
if (value)
|
|
set(UpdateNavMeshStatus::failed);
|
|
else
|
|
unset(UpdateNavMeshStatus::failed);
|
|
return *this;
|
|
}
|
|
|
|
UpdateNavMeshStatusBuilder cached(bool value)
|
|
{
|
|
if (value)
|
|
set(UpdateNavMeshStatus::cached);
|
|
else
|
|
unset(UpdateNavMeshStatus::cached);
|
|
return *this;
|
|
}
|
|
|
|
UpdateNavMeshStatus getResult() const
|
|
{
|
|
return mResult;
|
|
}
|
|
|
|
private:
|
|
UpdateNavMeshStatus mResult = UpdateNavMeshStatus::ignored;
|
|
|
|
void set(UpdateNavMeshStatus value)
|
|
{
|
|
mResult = static_cast<UpdateNavMeshStatus>(static_cast<unsigned>(mResult) | static_cast<unsigned>(value));
|
|
}
|
|
|
|
void unset(UpdateNavMeshStatus value)
|
|
{
|
|
mResult = static_cast<UpdateNavMeshStatus>(static_cast<unsigned>(mResult) & ~static_cast<unsigned>(value));
|
|
}
|
|
};
|
|
|
|
class NavMeshCacheItem
|
|
{
|
|
public:
|
|
NavMeshCacheItem(const NavMeshPtr& impl, std::size_t generation)
|
|
: mImpl(impl), mGeneration(generation), mNavMeshRevision(0)
|
|
{
|
|
}
|
|
|
|
const dtNavMesh& getImpl() const
|
|
{
|
|
return *mImpl;
|
|
}
|
|
|
|
std::size_t getGeneration() const
|
|
{
|
|
return mGeneration;
|
|
}
|
|
|
|
std::size_t getNavMeshRevision() const
|
|
{
|
|
return mNavMeshRevision;
|
|
}
|
|
|
|
UpdateNavMeshStatus updateTile(const TilePosition& position, NavMeshTilesCache::Value&& cached,
|
|
NavMeshData&& navMeshData);
|
|
|
|
UpdateNavMeshStatus removeTile(const TilePosition& position);
|
|
|
|
private:
|
|
NavMeshPtr mImpl;
|
|
std::size_t mGeneration;
|
|
std::size_t mNavMeshRevision;
|
|
std::map<TilePosition, std::pair<NavMeshTilesCache::Value, NavMeshData>> mUsedTiles;
|
|
};
|
|
|
|
using GuardedNavMeshCacheItem = Misc::ScopeGuarded<NavMeshCacheItem>;
|
|
using SharedNavMeshCacheItem = std::shared_ptr<GuardedNavMeshCacheItem>;
|
|
}
|
|
|
|
#endif
|