|
|
|
@ -25,8 +25,6 @@ namespace
|
|
|
|
|
{
|
|
|
|
|
using namespace DetourNavigator;
|
|
|
|
|
|
|
|
|
|
static const int doNotTransferOwnership = 0;
|
|
|
|
|
|
|
|
|
|
void initPolyMeshDetail(rcPolyMeshDetail& value)
|
|
|
|
|
{
|
|
|
|
|
value.meshes = nullptr;
|
|
|
|
@ -441,56 +439,7 @@ namespace
|
|
|
|
|
return NavMeshData(navMeshData, navMeshDataSize);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class UpdateNavMeshStatusBuilder
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
UpdateNavMeshStatusBuilder() = default;
|
|
|
|
|
|
|
|
|
|
UpdateNavMeshStatusBuilder removed(bool value)
|
|
|
|
|
{
|
|
|
|
|
if (value)
|
|
|
|
|
set(UpdateNavMeshStatus::removed);
|
|
|
|
|
else
|
|
|
|
|
unset(UpdateNavMeshStatus::removed);
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
UpdateNavMeshStatusBuilder added(bool value)
|
|
|
|
|
{
|
|
|
|
|
if (value)
|
|
|
|
|
set(UpdateNavMeshStatus::added);
|
|
|
|
|
else
|
|
|
|
|
unset(UpdateNavMeshStatus::added);
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
UpdateNavMeshStatusBuilder failed(bool value)
|
|
|
|
|
{
|
|
|
|
|
if (value)
|
|
|
|
|
set(UpdateNavMeshStatus::failed);
|
|
|
|
|
else
|
|
|
|
|
unset(UpdateNavMeshStatus::failed);
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
UpdateNavMeshStatus getResult() const
|
|
|
|
|
{
|
|
|
|
|
return mResult;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
UpdateNavMeshStatus mResult = UpdateNavMeshStatus::ignored;
|
|
|
|
|
|
|
|
|
|
void set(UpdateNavMeshStatus value)
|
|
|
|
|
{
|
|
|
|
|
mResult = static_cast<UpdateNavMeshStatus>(static_cast<unsigned>(mResult) | static_cast<unsigned>(value));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void unset(UpdateNavMeshStatus value)
|
|
|
|
|
{
|
|
|
|
|
mResult = static_cast<UpdateNavMeshStatus>(static_cast<unsigned>(mResult) & ~static_cast<unsigned>(value));
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template <class T>
|
|
|
|
|
unsigned long getMinValuableBitsNumber(const T value)
|
|
|
|
@ -500,49 +449,6 @@ namespace
|
|
|
|
|
++power;
|
|
|
|
|
return power;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dtStatus addTile(dtNavMesh& navMesh, const NavMeshData& navMeshData)
|
|
|
|
|
{
|
|
|
|
|
const dtTileRef lastRef = 0;
|
|
|
|
|
dtTileRef* const result = nullptr;
|
|
|
|
|
return navMesh.addTile(navMeshData.mValue.get(), navMeshData.mSize,
|
|
|
|
|
doNotTransferOwnership, lastRef, result);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dtStatus addTile(dtNavMesh& navMesh, const NavMeshTilesCache::Value& cachedNavMeshData)
|
|
|
|
|
{
|
|
|
|
|
const dtTileRef lastRef = 0;
|
|
|
|
|
dtTileRef* const result = nullptr;
|
|
|
|
|
return navMesh.addTile(cachedNavMeshData.get().mValue, cachedNavMeshData.get().mSize,
|
|
|
|
|
doNotTransferOwnership, lastRef, result);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <class T>
|
|
|
|
|
UpdateNavMeshStatus replaceTile(const SharedNavMeshCacheItem& navMeshCacheItem,
|
|
|
|
|
const TilePosition& changedTile, T&& navMeshData)
|
|
|
|
|
{
|
|
|
|
|
const auto locked = navMeshCacheItem->lock();
|
|
|
|
|
auto& navMesh = locked->getValue();
|
|
|
|
|
const int layer = 0;
|
|
|
|
|
const auto tileRef = navMesh.getTileRefAt(changedTile.x(), changedTile.y(), layer);
|
|
|
|
|
unsigned char** const data = nullptr;
|
|
|
|
|
int* const dataSize = nullptr;
|
|
|
|
|
const auto removed = dtStatusSucceed(navMesh.removeTile(tileRef, data, dataSize));
|
|
|
|
|
const auto addStatus = addTile(navMesh, navMeshData);
|
|
|
|
|
|
|
|
|
|
if (dtStatusSucceed(addStatus))
|
|
|
|
|
{
|
|
|
|
|
locked->setUsedTile(changedTile, std::forward<T>(navMeshData));
|
|
|
|
|
return UpdateNavMeshStatusBuilder().added(true).removed(removed).getResult();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (removed)
|
|
|
|
|
locked->removeUsedTile(changedTile);
|
|
|
|
|
log("failed to add tile with status=", WriteDtStatus {addStatus});
|
|
|
|
|
return UpdateNavMeshStatusBuilder().removed(removed).failed((addStatus & DT_OUT_OF_MEMORY) != 0).getResult();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
namespace DetourNavigator
|
|
|
|
@ -591,26 +497,13 @@ namespace DetourNavigator
|
|
|
|
|
" playerTile=", playerTile,
|
|
|
|
|
" changedTileDistance=", getDistance(changedTile, playerTile));
|
|
|
|
|
|
|
|
|
|
const auto params = *navMeshCacheItem->lockConst()->getValue().getParams();
|
|
|
|
|
const auto params = *navMeshCacheItem->lockConst()->getImpl().getParams();
|
|
|
|
|
const osg::Vec3f origin(params.orig[0], params.orig[1], params.orig[2]);
|
|
|
|
|
|
|
|
|
|
const auto x = changedTile.x();
|
|
|
|
|
const auto y = changedTile.y();
|
|
|
|
|
|
|
|
|
|
const auto removeTile = [&] {
|
|
|
|
|
const auto locked = navMeshCacheItem->lock();
|
|
|
|
|
auto& navMesh = locked->getValue();
|
|
|
|
|
const auto tileRef = navMesh.getTileRefAt(x, y, 0);
|
|
|
|
|
const auto removed = dtStatusSucceed(navMesh.removeTile(tileRef, nullptr, nullptr));
|
|
|
|
|
if (removed)
|
|
|
|
|
locked->removeUsedTile(changedTile);
|
|
|
|
|
return UpdateNavMeshStatusBuilder().removed(removed).getResult();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (!recastMesh)
|
|
|
|
|
{
|
|
|
|
|
log("ignore add tile: recastMesh is null");
|
|
|
|
|
return removeTile();
|
|
|
|
|
return navMeshCacheItem->lock()->removeTile(changedTile);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
auto recastMeshBounds = recastMesh->getBounds();
|
|
|
|
@ -625,13 +518,13 @@ namespace DetourNavigator
|
|
|
|
|
if (isEmpty(recastMeshBounds))
|
|
|
|
|
{
|
|
|
|
|
log("ignore add tile: recastMesh is empty");
|
|
|
|
|
return removeTile();
|
|
|
|
|
return navMeshCacheItem->lock()->removeTile(changedTile);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!shouldAddTile(changedTile, playerTile, std::min(settings.mMaxTilesNumber, params.maxTiles)))
|
|
|
|
|
{
|
|
|
|
|
log("ignore add tile: too far from player");
|
|
|
|
|
return removeTile();
|
|
|
|
|
return navMeshCacheItem->lock()->removeTile(changedTile);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
auto cachedNavMeshData = navMeshTilesCache.get(agentHalfExtents, changedTile, *recastMesh, offMeshConnections);
|
|
|
|
@ -648,7 +541,7 @@ namespace DetourNavigator
|
|
|
|
|
if (!navMeshData.mValue)
|
|
|
|
|
{
|
|
|
|
|
log("ignore add tile: NavMeshData is null");
|
|
|
|
|
return removeTile();
|
|
|
|
|
return navMeshCacheItem->lock()->removeTile(changedTile);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
@ -665,10 +558,10 @@ namespace DetourNavigator
|
|
|
|
|
if (!cachedNavMeshData)
|
|
|
|
|
{
|
|
|
|
|
log("cache overflow");
|
|
|
|
|
return replaceTile(navMeshCacheItem, changedTile, std::move(navMeshData));
|
|
|
|
|
return navMeshCacheItem->lock()->updateTile(changedTile, std::move(navMeshData));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return replaceTile(navMeshCacheItem, changedTile, std::move(cachedNavMeshData));
|
|
|
|
|
return navMeshCacheItem->lock()->updateTile(changedTile, std::move(cachedNavMeshData));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|