Merge pull request #3011 from elsid/navmesh_fixes

Navmesh fixes
pull/593/head
Bret Curtis 4 years ago committed by GitHub
commit 11c938b176
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -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…
Cancel
Save