From 0c8a811ad5f4bf382155595fced2133612e6f009 Mon Sep 17 00:00:00 2001 From: elsid Date: Sat, 9 Oct 2021 18:36:37 +0200 Subject: [PATCH] Render only cached recast mesh To avoid waiting while recast mesh is generating. Remove redundant continue. --- apps/openmw/mwrender/recastmesh.cpp | 1 - .../cachedrecastmeshmanager.cpp | 35 ++++++++++++------- .../cachedrecastmeshmanager.hpp | 5 +++ components/detournavigator/navigator.hpp | 2 +- components/detournavigator/navigatorimpl.cpp | 2 +- components/detournavigator/navigatorimpl.hpp | 2 +- components/detournavigator/navigatorstub.hpp | 2 +- components/detournavigator/navmeshmanager.cpp | 7 ++-- components/detournavigator/navmeshmanager.hpp | 2 +- .../tilecachedrecastmeshmanager.cpp | 30 ++++++++++------ .../tilecachedrecastmeshmanager.hpp | 4 +++ 11 files changed, 59 insertions(+), 33 deletions(-) diff --git a/apps/openmw/mwrender/recastmesh.cpp b/apps/openmw/mwrender/recastmesh.cpp index 5afa78cd93..91035907e9 100644 --- a/apps/openmw/mwrender/recastmesh.cpp +++ b/apps/openmw/mwrender/recastmesh.cpp @@ -60,7 +60,6 @@ namespace MWRender it->second.mValue = group; it->second.mGeneration = tile->second->getGeneration(); it->second.mRevision = tile->second->getRevision(); - continue; } ++it; diff --git a/components/detournavigator/cachedrecastmeshmanager.cpp b/components/detournavigator/cachedrecastmeshmanager.cpp index 19b87aa820..d82310dc38 100644 --- a/components/detournavigator/cachedrecastmeshmanager.cpp +++ b/components/detournavigator/cachedrecastmeshmanager.cpp @@ -13,7 +13,7 @@ namespace DetourNavigator { if (!mImpl.addObject(id, shape, transform, areaType)) return false; - mCached.lock()->reset(); + mOutdatedCache = true; return true; } @@ -21,7 +21,7 @@ namespace DetourNavigator { if (!mImpl.updateObject(id, transform, areaType)) return false; - mCached.lock()->reset(); + mOutdatedCache = true; return true; } @@ -29,7 +29,7 @@ namespace DetourNavigator { auto object = mImpl.removeObject(id); if (object) - mCached.lock()->reset(); + mOutdatedCache = true; return object; } @@ -38,7 +38,7 @@ namespace DetourNavigator { if (!mImpl.addWater(cellPosition, cellSize, shift)) return false; - mCached.lock()->reset(); + mOutdatedCache = true; return true; } @@ -46,7 +46,7 @@ namespace DetourNavigator { const auto water = mImpl.removeWater(cellPosition); if (water) - mCached.lock()->reset(); + mOutdatedCache = true; return water; } @@ -55,7 +55,7 @@ namespace DetourNavigator { if (!mImpl.addHeightfield(cellPosition, cellSize, shift, shape)) return false; - mCached.lock()->reset(); + mOutdatedCache = true; return true; } @@ -63,18 +63,27 @@ namespace DetourNavigator { const auto cell = mImpl.removeHeightfield(cellPosition); if (cell) - mCached.lock()->reset(); + mOutdatedCache = true; return cell; } std::shared_ptr CachedRecastMeshManager::getMesh() { - std::shared_ptr cached = *mCached.lock(); - if (cached != nullptr) - return cached; - cached = mImpl.getMesh(); - *mCached.lock() = cached; - return cached; + bool outdated = true; + if (!mOutdatedCache.compare_exchange_strong(outdated, false)) + { + std::shared_ptr cached = getCachedMesh(); + if (cached != nullptr) + return cached; + } + std::shared_ptr mesh = mImpl.getMesh(); + *mCached.lock() = mesh; + return mesh; + } + + std::shared_ptr CachedRecastMeshManager::getCachedMesh() const + { + return *mCached.lockConst(); } bool CachedRecastMeshManager::isEmpty() const diff --git a/components/detournavigator/cachedrecastmeshmanager.hpp b/components/detournavigator/cachedrecastmeshmanager.hpp index b506f807fa..b1e2570b0a 100644 --- a/components/detournavigator/cachedrecastmeshmanager.hpp +++ b/components/detournavigator/cachedrecastmeshmanager.hpp @@ -7,6 +7,8 @@ #include +#include + namespace DetourNavigator { class CachedRecastMeshManager @@ -32,6 +34,8 @@ namespace DetourNavigator std::shared_ptr getMesh(); + std::shared_ptr getCachedMesh() const; + bool isEmpty() const; void reportNavMeshChange(const Version& recastMeshVersion, const Version& navMeshVersion); @@ -41,6 +45,7 @@ namespace DetourNavigator private: RecastMeshManager mImpl; Misc::ScopeGuarded> mCached; + std::atomic_bool mOutdatedCache {true}; }; } diff --git a/components/detournavigator/navigator.hpp b/components/detournavigator/navigator.hpp index d2e77892b9..265d69b6e1 100644 --- a/components/detournavigator/navigator.hpp +++ b/components/detournavigator/navigator.hpp @@ -236,7 +236,7 @@ namespace DetourNavigator std::optional raycast(const osg::Vec3f& agentHalfExtents, const osg::Vec3f& start, const osg::Vec3f& end, const Flags includeFlags) const; - virtual RecastMeshTiles getRecastMeshTiles() = 0; + virtual RecastMeshTiles getRecastMeshTiles() const = 0; virtual float getMaxNavmeshAreaRealRadius() const = 0; }; diff --git a/components/detournavigator/navigatorimpl.cpp b/components/detournavigator/navigatorimpl.cpp index 750901c73e..f29ae1bb95 100644 --- a/components/detournavigator/navigatorimpl.cpp +++ b/components/detournavigator/navigatorimpl.cpp @@ -187,7 +187,7 @@ namespace DetourNavigator mNavMeshManager.reportStats(frameNumber, stats); } - RecastMeshTiles NavigatorImpl::getRecastMeshTiles() + RecastMeshTiles NavigatorImpl::getRecastMeshTiles() const { return mNavMeshManager.getRecastMeshTiles(); } diff --git a/components/detournavigator/navigatorimpl.hpp b/components/detournavigator/navigatorimpl.hpp index cda6158958..8ed16b9a5b 100644 --- a/components/detournavigator/navigatorimpl.hpp +++ b/components/detournavigator/navigatorimpl.hpp @@ -60,7 +60,7 @@ namespace DetourNavigator void reportStats(unsigned int frameNumber, osg::Stats& stats) const override; - RecastMeshTiles getRecastMeshTiles() override; + RecastMeshTiles getRecastMeshTiles() const override; float getMaxNavmeshAreaRealRadius() const override; diff --git a/components/detournavigator/navigatorstub.hpp b/components/detournavigator/navigatorstub.hpp index 40de90f256..758519769b 100644 --- a/components/detournavigator/navigatorstub.hpp +++ b/components/detournavigator/navigatorstub.hpp @@ -94,7 +94,7 @@ namespace DetourNavigator void reportStats(unsigned int /*frameNumber*/, osg::Stats& /*stats*/) const override {} - RecastMeshTiles getRecastMeshTiles() override + RecastMeshTiles getRecastMeshTiles() const override { return {}; } diff --git a/components/detournavigator/navmeshmanager.cpp b/components/detournavigator/navmeshmanager.cpp index c378230845..362c6938c0 100644 --- a/components/detournavigator/navmeshmanager.cpp +++ b/components/detournavigator/navmeshmanager.cpp @@ -232,14 +232,15 @@ namespace DetourNavigator mAsyncNavMeshUpdater.reportStats(frameNumber, stats); } - RecastMeshTiles NavMeshManager::getRecastMeshTiles() + RecastMeshTiles NavMeshManager::getRecastMeshTiles() const { std::vector tiles; mRecastMeshManager.forEachTile( [&tiles] (const TilePosition& tile, const CachedRecastMeshManager&) { tiles.push_back(tile); }); RecastMeshTiles result; - std::transform(tiles.begin(), tiles.end(), std::inserter(result, result.end()), - [this] (const TilePosition& tile) { return std::make_pair(tile, mRecastMeshManager.getMesh(tile)); }); + for (const TilePosition& tile : tiles) + if (auto mesh = mRecastMeshManager.getCachedMesh(tile)) + result.emplace(tile, std::move(mesh)); return result; } diff --git a/components/detournavigator/navmeshmanager.hpp b/components/detournavigator/navmeshmanager.hpp index 76c9b1e0b9..b1496dc817 100644 --- a/components/detournavigator/navmeshmanager.hpp +++ b/components/detournavigator/navmeshmanager.hpp @@ -59,7 +59,7 @@ namespace DetourNavigator void reportStats(unsigned int frameNumber, osg::Stats& stats) const; - RecastMeshTiles getRecastMeshTiles(); + RecastMeshTiles getRecastMeshTiles() const; private: const Settings& mSettings; diff --git a/components/detournavigator/tilecachedrecastmeshmanager.cpp b/components/detournavigator/tilecachedrecastmeshmanager.cpp index 63d7e13f6b..d6e3e55005 100644 --- a/components/detournavigator/tilecachedrecastmeshmanager.cpp +++ b/components/detournavigator/tilecachedrecastmeshmanager.cpp @@ -192,17 +192,16 @@ namespace DetourNavigator std::shared_ptr TileCachedRecastMeshManager::getMesh(const TilePosition& tilePosition) const { - const auto manager = [&] () -> std::shared_ptr - { - const auto tiles = mTiles.lockConst(); - const auto it = tiles->find(tilePosition); - if (it == tiles->end()) - return nullptr; - return it->second; - } (); - if (manager == nullptr) - return nullptr; - return manager->getMesh(); + if (const auto manager = getManager(tilePosition)) + return manager->getMesh(); + return nullptr; + } + + std::shared_ptr TileCachedRecastMeshManager::getCachedMesh(const TilePosition& tilePosition) const + { + if (const auto manager = getManager(tilePosition)) + return manager->getCachedMesh(); + return nullptr; } std::size_t TileCachedRecastMeshManager::getRevision() const @@ -256,4 +255,13 @@ namespace DetourNavigator } return tileResult; } + + std::shared_ptr TileCachedRecastMeshManager::getManager(const TilePosition& tilePosition) const + { + const auto tiles = mTiles.lockConst(); + const auto it = tiles->find(tilePosition); + if (it == tiles->end()) + return nullptr; + return it->second; + } } diff --git a/components/detournavigator/tilecachedrecastmeshmanager.hpp b/components/detournavigator/tilecachedrecastmeshmanager.hpp index f6bc40d668..7b5480e006 100644 --- a/components/detournavigator/tilecachedrecastmeshmanager.hpp +++ b/components/detournavigator/tilecachedrecastmeshmanager.hpp @@ -88,6 +88,8 @@ namespace DetourNavigator std::shared_ptr getMesh(const TilePosition& tilePosition) const; + std::shared_ptr getCachedMesh(const TilePosition& tilePosition) const; + template void forEachTile(Function&& function) const { @@ -118,6 +120,8 @@ namespace DetourNavigator std::optional removeTile(const ObjectId id, const TilePosition& tilePosition, TilesMap& tiles); + + inline std::shared_ptr getManager(const TilePosition& tilePosition) const; }; }