mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-03-11 19:13:29 +00:00
Use memcpy to create navmesh key
Implementation with memcpy is ~13 times faster.
This commit is contained in:
parent
f637dc38bd
commit
7591d45008
@ -9,42 +9,32 @@ namespace DetourNavigator
|
||||
{
|
||||
namespace
|
||||
{
|
||||
inline std::string makeNavMeshKey(const RecastMesh& recastMesh,
|
||||
inline std::vector<unsigned char> makeNavMeshKey(const RecastMesh& recastMesh,
|
||||
const std::vector<OffMeshConnection>& offMeshConnections)
|
||||
{
|
||||
std::string result;
|
||||
result.reserve(
|
||||
recastMesh.getIndices().size() * sizeof(int)
|
||||
+ recastMesh.getVertices().size() * sizeof(float)
|
||||
+ recastMesh.getAreaTypes().size() * sizeof(AreaType)
|
||||
+ recastMesh.getWater().size() * sizeof(RecastMesh::Water)
|
||||
+ offMeshConnections.size() * sizeof(OffMeshConnection)
|
||||
);
|
||||
std::copy(
|
||||
reinterpret_cast<const char*>(recastMesh.getIndices().data()),
|
||||
reinterpret_cast<const char*>(recastMesh.getIndices().data() + recastMesh.getIndices().size()),
|
||||
std::back_inserter(result)
|
||||
);
|
||||
std::copy(
|
||||
reinterpret_cast<const char*>(recastMesh.getVertices().data()),
|
||||
reinterpret_cast<const char*>(recastMesh.getVertices().data() + recastMesh.getVertices().size()),
|
||||
std::back_inserter(result)
|
||||
);
|
||||
std::copy(
|
||||
reinterpret_cast<const char*>(recastMesh.getAreaTypes().data()),
|
||||
reinterpret_cast<const char*>(recastMesh.getAreaTypes().data() + recastMesh.getAreaTypes().size()),
|
||||
std::back_inserter(result)
|
||||
);
|
||||
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)
|
||||
);
|
||||
const std::size_t indicesSize = recastMesh.getIndices().size() * sizeof(int);
|
||||
const std::size_t verticesSize = recastMesh.getVertices().size() * sizeof(float);
|
||||
const std::size_t areaTypesSize = recastMesh.getAreaTypes().size() * sizeof(AreaType);
|
||||
const std::size_t waterSize = recastMesh.getWater().size() * sizeof(RecastMesh::Water);
|
||||
const std::size_t offMeshConnectionsSize = offMeshConnections.size() * sizeof(OffMeshConnection);
|
||||
|
||||
std::vector<unsigned char> result(indicesSize + verticesSize + areaTypesSize + waterSize + offMeshConnectionsSize);
|
||||
unsigned char* dst = result.data();
|
||||
|
||||
std::memcpy(dst, recastMesh.getIndices().data(), indicesSize);
|
||||
dst += indicesSize;
|
||||
|
||||
std::memcpy(dst, recastMesh.getVertices().data(), verticesSize);
|
||||
dst += verticesSize;
|
||||
|
||||
std::memcpy(dst, recastMesh.getAreaTypes().data(), areaTypesSize);
|
||||
dst += areaTypesSize;
|
||||
|
||||
std::memcpy(dst, recastMesh.getWater().data(), waterSize);
|
||||
dst += waterSize;
|
||||
|
||||
std::memcpy(dst, offMeshConnections.data(), offMeshConnectionsSize);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@ -189,8 +179,8 @@ namespace DetourNavigator
|
||||
{
|
||||
struct CompareBytes
|
||||
{
|
||||
const char* mRhsIt;
|
||||
const char* mRhsEnd;
|
||||
const unsigned char* mRhsIt;
|
||||
const unsigned char* const mRhsEnd;
|
||||
|
||||
template <class T>
|
||||
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()};
|
||||
|
||||
|
@ -11,6 +11,8 @@
|
||||
#include <list>
|
||||
#include <mutex>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
|
||||
namespace osg
|
||||
{
|
||||
@ -33,10 +35,10 @@ namespace DetourNavigator
|
||||
std::atomic<std::int64_t> mUseCount;
|
||||
osg::Vec3f mAgentHalfExtents;
|
||||
TilePosition mChangedTile;
|
||||
std::string mNavMeshKey;
|
||||
std::vector<unsigned char> mNavMeshKey;
|
||||
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)
|
||||
, mAgentHalfExtents(agentHalfExtents)
|
||||
, mChangedTile(changedTile)
|
||||
@ -120,19 +122,32 @@ namespace DetourNavigator
|
||||
|
||||
virtual ~KeyView() = default;
|
||||
|
||||
KeyView(const std::string& value)
|
||||
KeyView(const std::vector<unsigned char>& value)
|
||||
: mValue(&value) {}
|
||||
|
||||
const std::string& getValue() const
|
||||
const std::vector<unsigned char>& getValue() const
|
||||
{
|
||||
assert(mValue);
|
||||
return *mValue;
|
||||
}
|
||||
|
||||
virtual int compare(const std::string& other) const
|
||||
virtual int compare(const std::vector<unsigned char>& other) const
|
||||
{
|
||||
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
|
||||
@ -147,7 +162,7 @@ namespace DetourNavigator
|
||||
}
|
||||
|
||||
private:
|
||||
const std::string* mValue = nullptr;
|
||||
const std::vector<unsigned char>* mValue = nullptr;
|
||||
};
|
||||
|
||||
class RecastMeshKeyView : public KeyView
|
||||
@ -156,7 +171,7 @@ namespace DetourNavigator
|
||||
RecastMeshKeyView(const RecastMesh& recastMesh, const std::vector<OffMeshConnection>& 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
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user