mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-15 15:19:55 +00:00
ed73d130f9
Use LRU modification to hold currently used items. Use RecastMesh binary data for item key. Store original pointer of btCollisionShape in user pointer to make available it as an identifier within all duplicates. Use pointer to heights data array for btHeightfieldTerrainShape.
127 lines
3.5 KiB
C++
127 lines
3.5 KiB
C++
#ifndef OPENMW_COMPONENTS_DETOURNAVIGATOR_NAVMESHTILESCACHE_H
|
|
#define OPENMW_COMPONENTS_DETOURNAVIGATOR_NAVMESHTILESCACHE_H
|
|
|
|
#include "offmeshconnection.hpp"
|
|
#include "navmeshdata.hpp"
|
|
#include "recastmesh.hpp"
|
|
#include "tileposition.hpp"
|
|
|
|
#include <atomic>
|
|
#include <map>
|
|
#include <list>
|
|
#include <mutex>
|
|
|
|
namespace DetourNavigator
|
|
{
|
|
struct NavMeshDataRef
|
|
{
|
|
unsigned char* mValue;
|
|
int mSize;
|
|
};
|
|
|
|
class NavMeshTilesCache
|
|
{
|
|
public:
|
|
struct Item
|
|
{
|
|
std::atomic<std::int64_t> mUseCount;
|
|
osg::Vec3f mAgentHalfExtents;
|
|
TilePosition mChangedTile;
|
|
std::string mNavMeshKey;
|
|
NavMeshData mNavMeshData;
|
|
|
|
Item(const osg::Vec3f& agentHalfExtents, const TilePosition& changedTile, std::string navMeshKey)
|
|
: mUseCount(0)
|
|
, mAgentHalfExtents(agentHalfExtents)
|
|
, mChangedTile(changedTile)
|
|
, mNavMeshKey(std::move(navMeshKey))
|
|
{}
|
|
};
|
|
|
|
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)
|
|
{
|
|
other.mIterator = ItemIterator();
|
|
}
|
|
|
|
~Value()
|
|
{
|
|
if (mIterator != ItemIterator())
|
|
mOwner->releaseItem(mIterator);
|
|
}
|
|
|
|
Value& operator =(const Value& other) = delete;
|
|
|
|
Value& operator =(Value&& other)
|
|
{
|
|
if (mIterator == other.mIterator)
|
|
return *this;
|
|
|
|
if (mIterator != ItemIterator())
|
|
mOwner->releaseItem(mIterator);
|
|
|
|
mOwner = other.mOwner;
|
|
mIterator = other.mIterator;
|
|
|
|
other.mIterator = ItemIterator();
|
|
|
|
return *this;
|
|
}
|
|
|
|
NavMeshDataRef get() const
|
|
{
|
|
return NavMeshDataRef {mIterator->mNavMeshData.mValue.get(), mIterator->mNavMeshData.mSize};
|
|
}
|
|
|
|
operator bool() const
|
|
{
|
|
return mIterator != ItemIterator();
|
|
}
|
|
|
|
private:
|
|
NavMeshTilesCache* mOwner;
|
|
ItemIterator mIterator;
|
|
};
|
|
|
|
NavMeshTilesCache(const std::size_t maxNavMeshDataSize);
|
|
|
|
Value get(const osg::Vec3f& agentHalfExtents, const TilePosition& changedTile,
|
|
const RecastMesh& recastMesh, const std::vector<OffMeshConnection>& offMeshConnections);
|
|
|
|
Value set(const osg::Vec3f& agentHalfExtents, const TilePosition& changedTile,
|
|
const RecastMesh& recastMesh, const std::vector<OffMeshConnection>& offMeshConnections,
|
|
NavMeshData value);
|
|
|
|
private:
|
|
std::mutex mMutex;
|
|
std::size_t mMaxNavMeshDataSize;
|
|
std::size_t mUsedNavMeshDataSize;
|
|
std::size_t mFreeNavMeshDataSize;
|
|
std::list<Item> mBusyItems;
|
|
std::list<Item> mFreeItems;
|
|
std::map<osg::Vec3f, std::map<TilePosition, std::map<std::string, ItemIterator>>> mValues;
|
|
|
|
void removeLeastRecentlyUsed();
|
|
|
|
void acquireItemUnsafe(ItemIterator iterator);
|
|
|
|
void releaseItem(ItemIterator iterator);
|
|
};
|
|
}
|
|
|
|
#endif
|