diff --git a/components/detournavigator/asyncnavmeshupdater.cpp b/components/detournavigator/asyncnavmeshupdater.cpp index 900d699420..cc3156a6c8 100644 --- a/components/detournavigator/asyncnavmeshupdater.cpp +++ b/components/detournavigator/asyncnavmeshupdater.cpp @@ -91,10 +91,7 @@ namespace DetourNavigator const auto recastMesh = getRecastMesh(); - updateNavMesh(job.mAgentHalfExtents, *recastMesh, job.mChangedTile, mSettings, - job.mNavMeshCacheItem->mValue); - - ++job.mNavMeshCacheItem->mNavMeshRevision; + updateNavMesh(job.mAgentHalfExtents, *recastMesh, job.mChangedTile, mSettings, *job.mNavMeshCacheItem); const auto finish = std::chrono::steady_clock::now(); diff --git a/components/detournavigator/asyncnavmeshupdater.hpp b/components/detournavigator/asyncnavmeshupdater.hpp index 649fa9ffb0..7ffa8f5f06 100644 --- a/components/detournavigator/asyncnavmeshupdater.hpp +++ b/components/detournavigator/asyncnavmeshupdater.hpp @@ -1,8 +1,8 @@ #ifndef OPENMW_COMPONENTS_DETOURNAVIGATOR_ASYNCNAVMESHUPDATER_H #define OPENMW_COMPONENTS_DETOURNAVIGATOR_ASYNCNAVMESHUPDATER_H +#include "navmeshcacheitem.hpp" #include "recastmesh.hpp" -#include "sharednavmesh.hpp" #include "tileposition.hpp" #include @@ -22,16 +22,6 @@ class dtNavMesh; namespace DetourNavigator { - struct NavMeshCacheItem - { - SharedNavMesh mValue; - std::size_t mRecastMeshRevision; - std::atomic_size_t mNavMeshRevision; - - NavMeshCacheItem(const NavMeshPtr& value, std::size_t revision) - : mValue(value), mRecastMeshRevision(revision), mNavMeshRevision(0) {} - }; - class AsyncNavMeshUpdater { public: diff --git a/components/detournavigator/makenavmesh.cpp b/components/detournavigator/makenavmesh.cpp index 2d5d4c2429..a1c6d732a0 100644 --- a/components/detournavigator/makenavmesh.cpp +++ b/components/detournavigator/makenavmesh.cpp @@ -214,6 +214,23 @@ namespace return NavMeshData(navMeshData, navMeshDataSize); } + + struct AutoIncrementRevision + { + std::atomic_size_t& mNavMeshRevision; + bool mNavMeshChanged; + + AutoIncrementRevision(std::atomic_size_t& navMeshRevision) + : mNavMeshRevision(navMeshRevision) + , mNavMeshChanged(false) + {} + + ~AutoIncrementRevision() + { + if (mNavMeshChanged) + ++mNavMeshRevision; + } + }; } namespace DetourNavigator @@ -241,7 +258,7 @@ namespace DetourNavigator } void updateNavMesh(const osg::Vec3f& agentHalfExtents, const RecastMesh& recastMesh, - const TilePosition& changedTile, const Settings& settings, SharedNavMesh& navMesh) + const TilePosition& changedTile, const Settings& settings, NavMeshCacheItem& navMeshCacheItem) { log("update NavMesh with mutiple tiles:", " agentHeight=", std::setprecision(std::numeric_limits::max_exponent10), @@ -255,15 +272,19 @@ namespace DetourNavigator const auto& boundsMin = recastMesh.getBoundsMin(); const auto& boundsMax = recastMesh.getBoundsMax(); + auto& navMesh = navMeshCacheItem.mValue; const auto& params = *navMesh.lock()->getParams(); const osg::Vec3f origin(params.orig[0], params.orig[1], params.orig[2]); const auto x = changedTile.x(); const auto y = changedTile.y(); + AutoIncrementRevision incRev(navMeshCacheItem.mNavMeshRevision); + { const auto locked = navMesh.lock(); - locked->removeTile(locked->getTileRefAt(x, y, 0), nullptr, nullptr); + incRev.mNavMeshChanged = dtStatusSucceed(locked->removeTile(locked->getTileRefAt(x, y, 0), + nullptr, nullptr)); } const auto tileBounds = makeTileBounds(settings, changedTile); @@ -274,10 +295,17 @@ namespace DetourNavigator tileBorderMin, tileBorderMax, settings); if (!navMeshData.mValue) + { + log("ignore add tile: NavMeshData is null"); return; + } - OPENMW_CHECK_DT_STATUS(navMesh.lock()->addTile(navMeshData.mValue.get(), navMeshData.mSize, - DT_TILE_FREE_DATA, 0, 0)); + const auto status = navMesh.lock()->addTile(navMeshData.mValue.get(), navMeshData.mSize, + DT_TILE_FREE_DATA, 0, 0); + if (dtStatusSucceed(status)) + incRev.mNavMeshChanged = true; + else + log("failed to add tile with status=", WriteDtStatus {status}); navMeshData.mValue.release(); } } diff --git a/components/detournavigator/makenavmesh.hpp b/components/detournavigator/makenavmesh.hpp index 60ad2acf7d..03c3e63625 100644 --- a/components/detournavigator/makenavmesh.hpp +++ b/components/detournavigator/makenavmesh.hpp @@ -2,6 +2,7 @@ #define OPENMW_COMPONENTS_DETOURNAVIGATOR_MAKENAVMESH_H #include "settings.hpp" +#include "navmeshcacheitem.hpp" #include "tileposition.hpp" #include @@ -22,7 +23,7 @@ namespace DetourNavigator NavMeshPtr makeEmptyNavMesh(const Settings& settings); void updateNavMesh(const osg::Vec3f& agentHalfExtents, const RecastMesh& recastMesh, - const TilePosition& changedTile, const Settings& settings, SharedNavMesh& navMesh); + const TilePosition& changedTile, const Settings& settings, NavMeshCacheItem& navMeshCacheItem); } #endif diff --git a/components/detournavigator/navmeshcacheitem.hpp b/components/detournavigator/navmeshcacheitem.hpp new file mode 100644 index 0000000000..4c73fd05d1 --- /dev/null +++ b/components/detournavigator/navmeshcacheitem.hpp @@ -0,0 +1,21 @@ +#ifndef OPENMW_COMPONENTS_DETOURNAVIGATOR_NAVMESHCACHEITEM_H +#define OPENMW_COMPONENTS_DETOURNAVIGATOR_NAVMESHCACHEITEM_H + +#include "sharednavmesh.hpp" + +#include + +namespace DetourNavigator +{ + struct NavMeshCacheItem + { + SharedNavMesh mValue; + std::size_t mRecastMeshRevision; + std::atomic_size_t mNavMeshRevision; + + NavMeshCacheItem(const NavMeshPtr& value, std::size_t revision) + : mValue(value), mRecastMeshRevision(revision), mNavMeshRevision(0) {} + }; +} + +#endif