2018-09-30 22:33:25 +00:00
|
|
|
#ifndef OPENMW_COMPONENTS_DETOURNAVIGATOR_NAVMESHTILESCACHE_H
|
|
|
|
#define OPENMW_COMPONENTS_DETOURNAVIGATOR_NAVMESHTILESCACHE_H
|
|
|
|
|
2021-07-13 22:03:10 +00:00
|
|
|
#include "preparednavmeshdata.hpp"
|
2018-09-30 22:33:25 +00:00
|
|
|
#include "recastmesh.hpp"
|
|
|
|
#include "tileposition.hpp"
|
|
|
|
|
|
|
|
#include <atomic>
|
|
|
|
#include <map>
|
|
|
|
#include <list>
|
|
|
|
#include <mutex>
|
2019-03-10 19:04:41 +00:00
|
|
|
#include <cassert>
|
2020-10-07 22:58:11 +00:00
|
|
|
#include <cstring>
|
|
|
|
#include <vector>
|
2018-09-30 22:33:25 +00:00
|
|
|
|
2019-03-17 17:18:53 +00:00
|
|
|
namespace osg
|
|
|
|
{
|
|
|
|
class Stats;
|
|
|
|
}
|
|
|
|
|
2018-09-30 22:33:25 +00:00
|
|
|
namespace DetourNavigator
|
|
|
|
{
|
2021-02-03 23:15:54 +00:00
|
|
|
struct RecastMeshData
|
|
|
|
{
|
|
|
|
std::vector<int> mIndices;
|
|
|
|
std::vector<float> mVertices;
|
|
|
|
std::vector<AreaType> mAreaTypes;
|
|
|
|
std::vector<RecastMesh::Water> mWater;
|
|
|
|
};
|
|
|
|
|
|
|
|
inline bool operator <(const RecastMeshData& lhs, const RecastMeshData& rhs)
|
|
|
|
{
|
|
|
|
return std::tie(lhs.mIndices, lhs.mVertices, lhs.mAreaTypes, lhs.mWater)
|
|
|
|
< std::tie(rhs.mIndices, rhs.mVertices, rhs.mAreaTypes, rhs.mWater);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool operator <(const RecastMeshData& lhs, const RecastMesh& rhs)
|
|
|
|
{
|
|
|
|
return std::tie(lhs.mIndices, lhs.mVertices, lhs.mAreaTypes, lhs.mWater)
|
|
|
|
< std::tie(rhs.getIndices(), rhs.getVertices(), rhs.getAreaTypes(), rhs.getWater());
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool operator <(const RecastMesh& lhs, const RecastMeshData& rhs)
|
|
|
|
{
|
|
|
|
return std::tie(lhs.getIndices(), lhs.getVertices(), lhs.getAreaTypes(), lhs.getWater())
|
|
|
|
< std::tie(rhs.mIndices, rhs.mVertices, rhs.mAreaTypes, rhs.mWater);
|
|
|
|
}
|
|
|
|
|
2018-09-30 22:33:25 +00:00
|
|
|
class NavMeshTilesCache
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
struct Item
|
|
|
|
{
|
|
|
|
std::atomic<std::int64_t> mUseCount;
|
|
|
|
osg::Vec3f mAgentHalfExtents;
|
|
|
|
TilePosition mChangedTile;
|
2021-07-13 22:03:10 +00:00
|
|
|
RecastMeshData mRecastMeshData;
|
|
|
|
std::unique_ptr<PreparedNavMeshData> mPreparedNavMeshData;
|
2021-02-03 23:15:54 +00:00
|
|
|
std::size_t mSize;
|
2018-09-30 22:33:25 +00:00
|
|
|
|
2021-07-13 22:03:10 +00:00
|
|
|
Item(const osg::Vec3f& agentHalfExtents, const TilePosition& changedTile,
|
|
|
|
RecastMeshData&& recastMeshData, std::size_t size)
|
2018-09-30 22:33:25 +00:00
|
|
|
: mUseCount(0)
|
|
|
|
, mAgentHalfExtents(agentHalfExtents)
|
|
|
|
, mChangedTile(changedTile)
|
2021-07-13 22:03:10 +00:00
|
|
|
, mRecastMeshData(std::move(recastMeshData))
|
2021-02-03 23:15:54 +00:00
|
|
|
, mSize(size)
|
2018-09-30 22:33:25 +00:00
|
|
|
{}
|
|
|
|
};
|
|
|
|
|
|
|
|
using ItemIterator = std::list<Item>::iterator;
|
|
|
|
|
|
|
|
class Value
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
Value()
|
|
|
|
: mOwner(nullptr), mIterator() {}
|
|
|
|
|
|
|
|
Value(NavMeshTilesCache& owner, ItemIterator iterator)
|
|
|
|
: mOwner(&owner), mIterator(iterator)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
Value(const Value& other) = delete;
|
|
|
|
|
|
|
|
Value(Value&& other)
|
|
|
|
: mOwner(other.mOwner), mIterator(other.mIterator)
|
|
|
|
{
|
2018-12-10 20:51:15 +00:00
|
|
|
other.mOwner = nullptr;
|
2018-09-30 22:33:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
~Value()
|
|
|
|
{
|
2018-12-10 20:51:15 +00:00
|
|
|
if (mOwner)
|
2018-09-30 22:33:25 +00:00
|
|
|
mOwner->releaseItem(mIterator);
|
|
|
|
}
|
|
|
|
|
|
|
|
Value& operator =(const Value& other) = delete;
|
|
|
|
|
|
|
|
Value& operator =(Value&& other)
|
|
|
|
{
|
2018-12-10 20:51:15 +00:00
|
|
|
if (mOwner)
|
2018-09-30 22:33:25 +00:00
|
|
|
mOwner->releaseItem(mIterator);
|
|
|
|
|
|
|
|
mOwner = other.mOwner;
|
|
|
|
mIterator = other.mIterator;
|
|
|
|
|
2018-12-10 20:51:15 +00:00
|
|
|
other.mOwner = nullptr;
|
2018-09-30 22:33:25 +00:00
|
|
|
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2021-07-13 22:03:10 +00:00
|
|
|
const PreparedNavMeshData& get() const
|
2018-09-30 22:33:25 +00:00
|
|
|
{
|
2021-07-13 22:03:10 +00:00
|
|
|
return *mIterator->mPreparedNavMeshData;
|
2018-09-30 22:33:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
operator bool() const
|
|
|
|
{
|
2018-12-10 20:51:15 +00:00
|
|
|
return mOwner;
|
2018-09-30 22:33:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
NavMeshTilesCache* mOwner;
|
|
|
|
ItemIterator mIterator;
|
|
|
|
};
|
|
|
|
|
2021-03-24 23:59:44 +00:00
|
|
|
struct Stats
|
|
|
|
{
|
|
|
|
std::size_t mNavMeshCacheSize;
|
|
|
|
std::size_t mUsedNavMeshTiles;
|
|
|
|
std::size_t mCachedNavMeshTiles;
|
|
|
|
std::size_t mHitCount;
|
|
|
|
std::size_t mGetCount;
|
|
|
|
};
|
|
|
|
|
2018-09-30 22:33:25 +00:00
|
|
|
NavMeshTilesCache(const std::size_t maxNavMeshDataSize);
|
|
|
|
|
|
|
|
Value get(const osg::Vec3f& agentHalfExtents, const TilePosition& changedTile,
|
2021-07-13 22:03:10 +00:00
|
|
|
const RecastMesh& recastMesh);
|
2018-09-30 22:33:25 +00:00
|
|
|
|
|
|
|
Value set(const osg::Vec3f& agentHalfExtents, const TilePosition& changedTile,
|
2021-07-13 22:03:10 +00:00
|
|
|
const RecastMesh& recastMesh, std::unique_ptr<PreparedNavMeshData>&& value);
|
2018-09-30 22:33:25 +00:00
|
|
|
|
2021-03-24 23:59:44 +00:00
|
|
|
Stats getStats() const;
|
|
|
|
|
2019-03-17 17:18:53 +00:00
|
|
|
void reportStats(unsigned int frameNumber, osg::Stats& stats) const;
|
|
|
|
|
2018-09-30 22:33:25 +00:00
|
|
|
private:
|
2019-03-17 17:18:53 +00:00
|
|
|
mutable std::mutex mMutex;
|
2018-09-30 22:33:25 +00:00
|
|
|
std::size_t mMaxNavMeshDataSize;
|
|
|
|
std::size_t mUsedNavMeshDataSize;
|
|
|
|
std::size_t mFreeNavMeshDataSize;
|
2021-02-03 23:18:25 +00:00
|
|
|
std::size_t mHitCount;
|
|
|
|
std::size_t mGetCount;
|
2018-09-30 22:33:25 +00:00
|
|
|
std::list<Item> mBusyItems;
|
|
|
|
std::list<Item> mFreeItems;
|
2021-07-13 22:03:10 +00:00
|
|
|
std::map<std::tuple<osg::Vec3f, TilePosition, std::reference_wrapper<const RecastMeshData>>, ItemIterator, std::less<>> mValues;
|
2018-09-30 22:33:25 +00:00
|
|
|
|
|
|
|
void removeLeastRecentlyUsed();
|
|
|
|
|
|
|
|
void acquireItemUnsafe(ItemIterator iterator);
|
|
|
|
|
|
|
|
void releaseItem(ItemIterator iterator);
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|