mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-21 11:53:51 +00:00
commit
11c938b176
5 changed files with 82 additions and 50 deletions
|
@ -38,8 +38,14 @@ namespace DetourNavigator
|
||||||
return stream << "failed";
|
return stream << "failed";
|
||||||
case UpdateNavMeshStatus::lost:
|
case UpdateNavMeshStatus::lost:
|
||||||
return stream << "lost";
|
return stream << "lost";
|
||||||
|
case UpdateNavMeshStatus::cached:
|
||||||
|
return stream << "cached";
|
||||||
|
case UpdateNavMeshStatus::unchanged:
|
||||||
|
return stream << "unchanged";
|
||||||
|
case UpdateNavMeshStatus::restored:
|
||||||
|
return stream << "restored";
|
||||||
}
|
}
|
||||||
return stream << "unknown";
|
return stream << "unknown(" << static_cast<unsigned>(value) << ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
AsyncNavMeshUpdater::AsyncNavMeshUpdater(const Settings& settings, TileCachedRecastMeshManager& recastMeshManager,
|
AsyncNavMeshUpdater::AsyncNavMeshUpdater(const Settings& settings, TileCachedRecastMeshManager& recastMeshManager,
|
||||||
|
|
|
@ -559,6 +559,7 @@ namespace DetourNavigator
|
||||||
}
|
}
|
||||||
|
|
||||||
auto cachedNavMeshData = navMeshTilesCache.get(agentHalfExtents, changedTile, *recastMesh, offMeshConnections);
|
auto cachedNavMeshData = navMeshTilesCache.get(agentHalfExtents, changedTile, *recastMesh, offMeshConnections);
|
||||||
|
bool cached = static_cast<bool>(cachedNavMeshData);
|
||||||
|
|
||||||
if (!cachedNavMeshData)
|
if (!cachedNavMeshData)
|
||||||
{
|
{
|
||||||
|
@ -584,6 +585,7 @@ namespace DetourNavigator
|
||||||
{
|
{
|
||||||
cachedNavMeshData = navMeshTilesCache.get(agentHalfExtents, changedTile, *recastMesh,
|
cachedNavMeshData = navMeshTilesCache.get(agentHalfExtents, changedTile, *recastMesh,
|
||||||
offMeshConnections);
|
offMeshConnections);
|
||||||
|
cached = static_cast<bool>(cachedNavMeshData);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cachedNavMeshData)
|
if (!cachedNavMeshData)
|
||||||
|
@ -593,6 +595,8 @@ namespace DetourNavigator
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return navMeshCacheItem->lock()->updateTile(changedTile, std::move(cachedNavMeshData));
|
const auto updateStatus = navMeshCacheItem->lock()->updateTile(changedTile, std::move(cachedNavMeshData));
|
||||||
|
|
||||||
|
return UpdateNavMeshStatusBuilder(updateStatus).cached(cached).getResult();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,9 @@ namespace DetourNavigator
|
||||||
replaced = removed | added,
|
replaced = removed | added,
|
||||||
failed = 1 << 2,
|
failed = 1 << 2,
|
||||||
lost = removed | failed,
|
lost = removed | failed,
|
||||||
|
cached = 1 << 3,
|
||||||
|
unchanged = replaced | cached,
|
||||||
|
restored = added | cached,
|
||||||
};
|
};
|
||||||
|
|
||||||
inline bool isSuccess(UpdateNavMeshStatus value)
|
inline bool isSuccess(UpdateNavMeshStatus value)
|
||||||
|
@ -34,6 +37,9 @@ namespace DetourNavigator
|
||||||
public:
|
public:
|
||||||
UpdateNavMeshStatusBuilder() = default;
|
UpdateNavMeshStatusBuilder() = default;
|
||||||
|
|
||||||
|
explicit UpdateNavMeshStatusBuilder(UpdateNavMeshStatus value)
|
||||||
|
: mResult(value) {}
|
||||||
|
|
||||||
UpdateNavMeshStatusBuilder removed(bool value)
|
UpdateNavMeshStatusBuilder removed(bool value)
|
||||||
{
|
{
|
||||||
if (value)
|
if (value)
|
||||||
|
@ -61,6 +67,15 @@ namespace DetourNavigator
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UpdateNavMeshStatusBuilder cached(bool value)
|
||||||
|
{
|
||||||
|
if (value)
|
||||||
|
set(UpdateNavMeshStatus::cached);
|
||||||
|
else
|
||||||
|
unset(UpdateNavMeshStatus::cached);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
UpdateNavMeshStatus getResult() const
|
UpdateNavMeshStatus getResult() const
|
||||||
{
|
{
|
||||||
return mResult;
|
return mResult;
|
||||||
|
@ -143,7 +158,7 @@ namespace DetourNavigator
|
||||||
|
|
||||||
UpdateNavMeshStatus removeTile(const TilePosition& position)
|
UpdateNavMeshStatus removeTile(const TilePosition& position)
|
||||||
{
|
{
|
||||||
const auto removed = dtStatusSucceed(removeTileImpl(position));
|
const auto removed = removeTileImpl(position);
|
||||||
if (removed)
|
if (removed)
|
||||||
removeUsedTile(position);
|
removeUsedTile(position);
|
||||||
return UpdateNavMeshStatusBuilder().removed(removed).getResult();
|
return UpdateNavMeshStatusBuilder().removed(removed).getResult();
|
||||||
|
@ -181,13 +196,15 @@ namespace DetourNavigator
|
||||||
return mImpl->addTile(data, size, doNotTransferOwnership, lastRef, result);
|
return mImpl->addTile(data, size, doNotTransferOwnership, lastRef, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
dtStatus removeTileImpl(const TilePosition& position)
|
bool removeTileImpl(const TilePosition& position)
|
||||||
{
|
{
|
||||||
const int layer = 0;
|
const int layer = 0;
|
||||||
const auto tileRef = mImpl->getTileRefAt(position.x(), position.y(), layer);
|
const auto tileRef = mImpl->getTileRefAt(position.x(), position.y(), layer);
|
||||||
|
if (tileRef == 0)
|
||||||
|
return false;
|
||||||
unsigned char** const data = nullptr;
|
unsigned char** const data = nullptr;
|
||||||
int* const dataSize = nullptr;
|
int* const dataSize = nullptr;
|
||||||
return mImpl->removeTile(tileRef, data, dataSize);
|
return dtStatusSucceed(mImpl->removeTile(tileRef, data, dataSize));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -9,42 +9,32 @@ namespace DetourNavigator
|
||||||
{
|
{
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
inline std::string makeNavMeshKey(const RecastMesh& recastMesh,
|
inline std::vector<unsigned char> makeNavMeshKey(const RecastMesh& recastMesh,
|
||||||
const std::vector<OffMeshConnection>& offMeshConnections)
|
const std::vector<OffMeshConnection>& offMeshConnections)
|
||||||
{
|
{
|
||||||
std::string result;
|
const std::size_t indicesSize = recastMesh.getIndices().size() * sizeof(int);
|
||||||
result.reserve(
|
const std::size_t verticesSize = recastMesh.getVertices().size() * sizeof(float);
|
||||||
recastMesh.getIndices().size() * sizeof(int)
|
const std::size_t areaTypesSize = recastMesh.getAreaTypes().size() * sizeof(AreaType);
|
||||||
+ recastMesh.getVertices().size() * sizeof(float)
|
const std::size_t waterSize = recastMesh.getWater().size() * sizeof(RecastMesh::Water);
|
||||||
+ recastMesh.getAreaTypes().size() * sizeof(AreaType)
|
const std::size_t offMeshConnectionsSize = offMeshConnections.size() * sizeof(OffMeshConnection);
|
||||||
+ recastMesh.getWater().size() * sizeof(RecastMesh::Water)
|
|
||||||
+ offMeshConnections.size() * sizeof(OffMeshConnection)
|
std::vector<unsigned char> result(indicesSize + verticesSize + areaTypesSize + waterSize + offMeshConnectionsSize);
|
||||||
);
|
unsigned char* dst = result.data();
|
||||||
std::copy(
|
|
||||||
reinterpret_cast<const char*>(recastMesh.getIndices().data()),
|
std::memcpy(dst, recastMesh.getIndices().data(), indicesSize);
|
||||||
reinterpret_cast<const char*>(recastMesh.getIndices().data() + recastMesh.getIndices().size()),
|
dst += indicesSize;
|
||||||
std::back_inserter(result)
|
|
||||||
);
|
std::memcpy(dst, recastMesh.getVertices().data(), verticesSize);
|
||||||
std::copy(
|
dst += verticesSize;
|
||||||
reinterpret_cast<const char*>(recastMesh.getVertices().data()),
|
|
||||||
reinterpret_cast<const char*>(recastMesh.getVertices().data() + recastMesh.getVertices().size()),
|
std::memcpy(dst, recastMesh.getAreaTypes().data(), areaTypesSize);
|
||||||
std::back_inserter(result)
|
dst += areaTypesSize;
|
||||||
);
|
|
||||||
std::copy(
|
std::memcpy(dst, recastMesh.getWater().data(), waterSize);
|
||||||
reinterpret_cast<const char*>(recastMesh.getAreaTypes().data()),
|
dst += waterSize;
|
||||||
reinterpret_cast<const char*>(recastMesh.getAreaTypes().data() + recastMesh.getAreaTypes().size()),
|
|
||||||
std::back_inserter(result)
|
std::memcpy(dst, offMeshConnections.data(), offMeshConnectionsSize);
|
||||||
);
|
|
||||||
std::copy(
|
|
||||||
reinterpret_cast<const char*>(recastMesh.getWater().data()),
|
|
||||||
reinterpret_cast<const char*>(recastMesh.getWater().data() + recastMesh.getWater().size()),
|
|
||||||
std::back_inserter(result)
|
|
||||||
);
|
|
||||||
std::copy(
|
|
||||||
reinterpret_cast<const char*>(offMeshConnections.data()),
|
|
||||||
reinterpret_cast<const char*>(offMeshConnections.data() + offMeshConnections.size()),
|
|
||||||
std::back_inserter(result)
|
|
||||||
);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -189,8 +179,8 @@ namespace DetourNavigator
|
||||||
{
|
{
|
||||||
struct CompareBytes
|
struct CompareBytes
|
||||||
{
|
{
|
||||||
const char* mRhsIt;
|
const unsigned char* mRhsIt;
|
||||||
const char* mRhsEnd;
|
const unsigned char* const mRhsEnd;
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
int operator ()(const std::vector<T>& lhs)
|
int operator ()(const std::vector<T>& lhs)
|
||||||
|
@ -225,7 +215,7 @@ namespace DetourNavigator
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
int NavMeshTilesCache::RecastMeshKeyView::compare(const std::string& other) const
|
int NavMeshTilesCache::RecastMeshKeyView::compare(const std::vector<unsigned char>& other) const
|
||||||
{
|
{
|
||||||
CompareBytes compareBytes {other.data(), other.data() + other.size()};
|
CompareBytes compareBytes {other.data(), other.data() + other.size()};
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <cstring>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace osg
|
namespace osg
|
||||||
{
|
{
|
||||||
|
@ -33,10 +35,10 @@ namespace DetourNavigator
|
||||||
std::atomic<std::int64_t> mUseCount;
|
std::atomic<std::int64_t> mUseCount;
|
||||||
osg::Vec3f mAgentHalfExtents;
|
osg::Vec3f mAgentHalfExtents;
|
||||||
TilePosition mChangedTile;
|
TilePosition mChangedTile;
|
||||||
std::string mNavMeshKey;
|
std::vector<unsigned char> mNavMeshKey;
|
||||||
NavMeshData mNavMeshData;
|
NavMeshData mNavMeshData;
|
||||||
|
|
||||||
Item(const osg::Vec3f& agentHalfExtents, const TilePosition& changedTile, std::string navMeshKey)
|
Item(const osg::Vec3f& agentHalfExtents, const TilePosition& changedTile, std::vector<unsigned char>&& navMeshKey)
|
||||||
: mUseCount(0)
|
: mUseCount(0)
|
||||||
, mAgentHalfExtents(agentHalfExtents)
|
, mAgentHalfExtents(agentHalfExtents)
|
||||||
, mChangedTile(changedTile)
|
, mChangedTile(changedTile)
|
||||||
|
@ -120,19 +122,32 @@ namespace DetourNavigator
|
||||||
|
|
||||||
virtual ~KeyView() = default;
|
virtual ~KeyView() = default;
|
||||||
|
|
||||||
KeyView(const std::string& value)
|
KeyView(const std::vector<unsigned char>& value)
|
||||||
: mValue(&value) {}
|
: mValue(&value) {}
|
||||||
|
|
||||||
const std::string& getValue() const
|
const std::vector<unsigned char>& getValue() const
|
||||||
{
|
{
|
||||||
assert(mValue);
|
assert(mValue);
|
||||||
return *mValue;
|
return *mValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual int compare(const std::string& other) const
|
virtual int compare(const std::vector<unsigned char>& other) const
|
||||||
{
|
{
|
||||||
assert(mValue);
|
assert(mValue);
|
||||||
return mValue->compare(other);
|
|
||||||
|
const auto valueSize = mValue->size();
|
||||||
|
const auto otherSize = other.size();
|
||||||
|
|
||||||
|
if (const auto result = std::memcmp(mValue->data(), other.data(), std::min(valueSize, otherSize)))
|
||||||
|
return result;
|
||||||
|
|
||||||
|
if (valueSize < otherSize)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (valueSize > otherSize)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool isLess(const KeyView& other) const
|
virtual bool isLess(const KeyView& other) const
|
||||||
|
@ -147,7 +162,7 @@ namespace DetourNavigator
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const std::string* mValue = nullptr;
|
const std::vector<unsigned char>* mValue = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
class RecastMeshKeyView : public KeyView
|
class RecastMeshKeyView : public KeyView
|
||||||
|
@ -156,7 +171,7 @@ namespace DetourNavigator
|
||||||
RecastMeshKeyView(const RecastMesh& recastMesh, const std::vector<OffMeshConnection>& offMeshConnections)
|
RecastMeshKeyView(const RecastMesh& recastMesh, const std::vector<OffMeshConnection>& offMeshConnections)
|
||||||
: mRecastMesh(recastMesh), mOffMeshConnections(offMeshConnections) {}
|
: mRecastMesh(recastMesh), mOffMeshConnections(offMeshConnections) {}
|
||||||
|
|
||||||
int compare(const std::string& other) const override;
|
int compare(const std::vector<unsigned char>& other) const override;
|
||||||
|
|
||||||
bool isLess(const KeyView& other) const override
|
bool isLess(const KeyView& other) const override
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue