From 491a59b035c539a07f58d650732e58195e2d454c Mon Sep 17 00:00:00 2001 From: elsid Date: Mon, 25 Dec 2023 01:15:08 +0100 Subject: [PATCH 1/5] Remove unused getActiveGrid function --- components/terrain/viewdata.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/components/terrain/viewdata.hpp b/components/terrain/viewdata.hpp index b8b0b8a1f9..3014ba53f0 100644 --- a/components/terrain/viewdata.hpp +++ b/components/terrain/viewdata.hpp @@ -70,7 +70,6 @@ namespace Terrain mNodes.clear(); } } - const osg::Vec4i& getActiveGrid() const { return mActiveGrid; } unsigned int getWorldUpdateRevision() const { return mWorldUpdateRevision; } void setWorldUpdateRevision(int updateRevision) { mWorldUpdateRevision = updateRevision; } From d71b422615513020134f70f4bb914bae9fa17970 Mon Sep 17 00:00:00 2001 From: elsid Date: Sun, 29 Oct 2023 13:05:15 +0100 Subject: [PATCH 2/5] Convert PositionCellGrid into a struct --- apps/openmw/CMakeLists.txt | 1 + apps/openmw/mwworld/cellpreloader.cpp | 23 +++++++++++------------ apps/openmw/mwworld/cellpreloader.hpp | 9 +++------ apps/openmw/mwworld/positioncellgrid.hpp | 16 ++++++++++++++++ apps/openmw/mwworld/scene.cpp | 8 ++++---- apps/openmw/mwworld/scene.hpp | 3 +-- 6 files changed, 36 insertions(+), 24 deletions(-) create mode 100644 apps/openmw/mwworld/positioncellgrid.hpp diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index c71ad38665..b1d17b0a61 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -84,6 +84,7 @@ add_openmw_dir (mwworld store esmstore fallback actionrepair actionsoulgem livecellref actiondoor contentloader esmloader actiontrap cellreflist cellref weather projectilemanager cellpreloader datetimemanager groundcoverstore magiceffects cell ptrregistry + positioncellgrid ) add_openmw_dir (mwphysics diff --git a/apps/openmw/mwworld/cellpreloader.cpp b/apps/openmw/mwworld/cellpreloader.cpp index e08d576835..da2e19ae6c 100644 --- a/apps/openmw/mwworld/cellpreloader.cpp +++ b/apps/openmw/mwworld/cellpreloader.cpp @@ -29,15 +29,15 @@ namespace { template - bool contains(const std::vector& container, const Contained& contained, - float tolerance) + bool contains(const std::vector& container, const Contained& contained, float tolerance) { for (const auto& pos : contained) { bool found = false; for (const auto& pos2 : container) { - if ((pos.first - pos2.first).length2() < tolerance * tolerance && pos.second == pos2.second) + if ((pos.mPosition - pos2.mPosition).length2() < tolerance * tolerance + && pos.mCellBounds == pos2.mCellBounds) { found = true; break; @@ -52,7 +52,6 @@ namespace namespace MWWorld { - struct ListModelsVisitor { bool operator()(const MWWorld::ConstPtr& ptr) @@ -170,7 +169,7 @@ namespace MWWorld { public: TerrainPreloadItem(const std::vector>& views, Terrain::World* world, - const std::vector& preloadPositions) + const std::vector& preloadPositions) : mAbort(false) , mTerrainViews(views) , mWorld(world) @@ -183,8 +182,8 @@ namespace MWWorld for (unsigned int i = 0; i < mTerrainViews.size() && i < mPreloadPositions.size() && !mAbort; ++i) { mTerrainViews[i]->reset(); - mWorld->preload(mTerrainViews[i], mPreloadPositions[i].first, mPreloadPositions[i].second, mAbort, - mLoadingReporter); + mWorld->preload(mTerrainViews[i], mPreloadPositions[i].mPosition, mPreloadPositions[i].mCellBounds, + mAbort, mLoadingReporter); } mLoadingReporter.complete(); } @@ -197,7 +196,7 @@ namespace MWWorld std::atomic mAbort; std::vector> mTerrainViews; Terrain::World* mWorld; - std::vector mPreloadPositions; + std::vector mPreloadPositions; Loading::Reporter mLoadingReporter; }; @@ -375,7 +374,7 @@ namespace MWWorld mTerrainPreloadItem->wait(listener); } - void CellPreloader::abortTerrainPreloadExcept(const CellPreloader::PositionCellGrid* exceptPos) + void CellPreloader::abortTerrainPreloadExcept(const PositionCellGrid* exceptPos) { if (exceptPos && contains(mTerrainPreloadPositions, std::array{ *exceptPos }, Constants::CellSizeInUnits)) return; @@ -384,10 +383,10 @@ namespace MWWorld mTerrainPreloadItem->abort(); mTerrainPreloadItem->waitTillDone(); } - setTerrainPreloadPositions(std::vector()); + setTerrainPreloadPositions(std::vector()); } - void CellPreloader::setTerrainPreloadPositions(const std::vector& positions) + void CellPreloader::setTerrainPreloadPositions(const std::vector& positions) { if (positions.empty()) { @@ -417,7 +416,7 @@ namespace MWWorld } } - bool CellPreloader::isTerrainLoaded(const CellPreloader::PositionCellGrid& position, double referenceTime) const + bool CellPreloader::isTerrainLoaded(const PositionCellGrid& position, double referenceTime) const { return mLoadedTerrainTimestamp + mResourceSystem->getSceneManager()->getExpiryDelay() > referenceTime && contains(mLoadedTerrainPositions, std::array{ position }, Constants::CellSizeInUnits); diff --git a/apps/openmw/mwworld/cellpreloader.hpp b/apps/openmw/mwworld/cellpreloader.hpp index aa8f2c73be..f8b5c87c39 100644 --- a/apps/openmw/mwworld/cellpreloader.hpp +++ b/apps/openmw/mwworld/cellpreloader.hpp @@ -1,12 +1,10 @@ #ifndef OPENMW_MWWORLD_CELLPRELOADER_H #define OPENMW_MWWORLD_CELLPRELOADER_H -#include +#include "positioncellgrid.hpp" -#include +#include -#include -#include #include #include @@ -79,12 +77,11 @@ namespace MWWorld void setWorkQueue(osg::ref_ptr workQueue); - typedef std::pair PositionCellGrid; void setTerrainPreloadPositions(const std::vector& positions); void syncTerrainLoad(Loading::Listener& listener); void abortTerrainPreloadExcept(const PositionCellGrid* exceptPos); - bool isTerrainLoaded(const CellPreloader::PositionCellGrid& position, double referenceTime) const; + bool isTerrainLoaded(const PositionCellGrid& position, double referenceTime) const; void setTerrain(Terrain::World* terrain); void reportStats(unsigned int frameNumber, osg::Stats& stats) const; diff --git a/apps/openmw/mwworld/positioncellgrid.hpp b/apps/openmw/mwworld/positioncellgrid.hpp new file mode 100644 index 0000000000..cbb8e3300a --- /dev/null +++ b/apps/openmw/mwworld/positioncellgrid.hpp @@ -0,0 +1,16 @@ +#ifndef OPENMW_APPS_OPENMW_MWWORLD_POSITIONCELLGRID_H +#define OPENMW_APPS_OPENMW_MWWORLD_POSITIONCELLGRID_H + +#include +#include + +namespace MWWorld +{ + struct PositionCellGrid + { + osg::Vec3f mPosition; + osg::Vec4i mCellBounds; + }; +} + +#endif diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index 169e4bfd21..c918e2d78e 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -603,7 +603,7 @@ namespace MWWorld mPreloader->setTerrain(mRendering.getTerrain()); if (mRendering.pagingUnlockCache()) mPreloader->abortTerrainPreloadExcept(nullptr); - if (!mPreloader->isTerrainLoaded(std::make_pair(pos, newGrid), mRendering.getReferenceTime())) + if (!mPreloader->isTerrainLoaded(PositionCellGrid{ pos, newGrid }, mRendering.getReferenceTime())) preloadTerrain(pos, playerCellIndex.mWorldspace, true); mPagedRefs.clear(); mRendering.getPagedRefnums(newGrid, mPagedRefs); @@ -1093,8 +1093,8 @@ namespace MWWorld osg::Vec3f predictedPos = playerPos + moved / dt * mPredictionTime; if (mCurrentCell->isExterior()) - exteriorPositions.emplace_back( - predictedPos, gridCenterToBounds(getNewGridCenter(predictedPos, &mCurrentGridCenter))); + exteriorPositions.push_back(PositionCellGrid{ + predictedPos, gridCenterToBounds(getNewGridCenter(predictedPos, &mCurrentGridCenter)) }); mLastPlayerPos = playerPos; @@ -1305,7 +1305,7 @@ namespace MWWorld const ESM::ExteriorCellLocation cellIndex = ESM::positionToExteriorCellLocation(pos.x(), pos.y(), extWorldspace); preloadCellWithSurroundings(mWorld.getWorldModel().getExterior(cellIndex)); - exteriorPositions.emplace_back(pos, gridCenterToBounds(getNewGridCenter(pos))); + exteriorPositions.push_back(PositionCellGrid{ pos, gridCenterToBounds(getNewGridCenter(pos)) }); } } } diff --git a/apps/openmw/mwworld/scene.hpp b/apps/openmw/mwworld/scene.hpp index 91feff8746..f318deaa9f 100644 --- a/apps/openmw/mwworld/scene.hpp +++ b/apps/openmw/mwworld/scene.hpp @@ -5,6 +5,7 @@ #include #include +#include "positioncellgrid.hpp" #include "ptr.hpp" #include @@ -122,8 +123,6 @@ namespace MWWorld void requestChangeCellGrid(const osg::Vec3f& position, const osg::Vec2i& cell, bool changeEvent = true); - typedef std::pair PositionCellGrid; - void preloadCells(float dt); void preloadTeleportDoorDestinations(const osg::Vec3f& playerPos, const osg::Vec3f& predictedPos, std::vector& exteriorPositions); From ac891a5eb1c0a03fa9f26369c32a46185c430de0 Mon Sep 17 00:00:00 2001 From: elsid Date: Sun, 29 Oct 2023 13:31:03 +0100 Subject: [PATCH 3/5] Use algorithms to check if PositionCellGrid(s) is/are contained in a range --- apps/openmw/mwworld/cellpreloader.cpp | 43 +++++++++++++-------------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/apps/openmw/mwworld/cellpreloader.cpp b/apps/openmw/mwworld/cellpreloader.cpp index da2e19ae6c..4357f8ba57 100644 --- a/apps/openmw/mwworld/cellpreloader.cpp +++ b/apps/openmw/mwworld/cellpreloader.cpp @@ -1,8 +1,9 @@ #include "cellpreloader.hpp" -#include +#include #include #include +#include #include @@ -26,32 +27,28 @@ #include "cellstore.hpp" #include "class.hpp" -namespace +namespace MWWorld { - template - bool contains(const std::vector& container, const Contained& contained, float tolerance) + namespace { - for (const auto& pos : contained) + bool contains(std::span positions, const PositionCellGrid& contained, float tolerance) { - bool found = false; - for (const auto& pos2 : container) - { - if ((pos.mPosition - pos2.mPosition).length2() < tolerance * tolerance - && pos.mCellBounds == pos2.mCellBounds) - { - found = true; - break; - } - } - if (!found) - return false; + const float squaredTolerance = tolerance * tolerance; + const auto predicate = [&](const PositionCellGrid& v) { + return (contained.mPosition - v.mPosition).length2() < squaredTolerance + && contained.mCellBounds == v.mCellBounds; + }; + return std::ranges::any_of(positions, predicate); + } + + bool contains( + std::span container, std::span contained, float tolerance) + { + const auto predicate = [&](const PositionCellGrid& v) { return contains(container, v, tolerance); }; + return std::ranges::all_of(contained, predicate); } - return true; } -} -namespace MWWorld -{ struct ListModelsVisitor { bool operator()(const MWWorld::ConstPtr& ptr) @@ -376,7 +373,7 @@ namespace MWWorld void CellPreloader::abortTerrainPreloadExcept(const PositionCellGrid* exceptPos) { - if (exceptPos && contains(mTerrainPreloadPositions, std::array{ *exceptPos }, Constants::CellSizeInUnits)) + if (exceptPos != nullptr && contains(mTerrainPreloadPositions, *exceptPos, Constants::CellSizeInUnits)) return; if (mTerrainPreloadItem && !mTerrainPreloadItem->isDone()) { @@ -419,7 +416,7 @@ namespace MWWorld bool CellPreloader::isTerrainLoaded(const PositionCellGrid& position, double referenceTime) const { return mLoadedTerrainTimestamp + mResourceSystem->getSceneManager()->getExpiryDelay() > referenceTime - && contains(mLoadedTerrainPositions, std::array{ position }, Constants::CellSizeInUnits); + && contains(mLoadedTerrainPositions, position, Constants::CellSizeInUnits); } void CellPreloader::setTerrain(Terrain::World* terrain) From 7290ce81c04de5bbda719d02612d79b764017f76 Mon Sep 17 00:00:00 2001 From: elsid Date: Sun, 29 Oct 2023 13:38:20 +0100 Subject: [PATCH 4/5] Avoid allocating std::vector for a single element --- apps/openmw/mwworld/cellpreloader.cpp | 12 ++++++------ apps/openmw/mwworld/cellpreloader.hpp | 3 ++- apps/openmw/mwworld/scene.cpp | 9 ++++----- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/apps/openmw/mwworld/cellpreloader.cpp b/apps/openmw/mwworld/cellpreloader.cpp index 4357f8ba57..2881471b25 100644 --- a/apps/openmw/mwworld/cellpreloader.cpp +++ b/apps/openmw/mwworld/cellpreloader.cpp @@ -165,12 +165,12 @@ namespace MWWorld class TerrainPreloadItem : public SceneUtil::WorkItem { public: - TerrainPreloadItem(const std::vector>& views, Terrain::World* world, - const std::vector& preloadPositions) + explicit TerrainPreloadItem(const std::vector>& views, Terrain::World* world, + std::span preloadPositions) : mAbort(false) , mTerrainViews(views) , mWorld(world) - , mPreloadPositions(preloadPositions) + , mPreloadPositions(preloadPositions.begin(), preloadPositions.end()) { } @@ -380,10 +380,10 @@ namespace MWWorld mTerrainPreloadItem->abort(); mTerrainPreloadItem->waitTillDone(); } - setTerrainPreloadPositions(std::vector()); + setTerrainPreloadPositions({}); } - void CellPreloader::setTerrainPreloadPositions(const std::vector& positions) + void CellPreloader::setTerrainPreloadPositions(std::span positions) { if (positions.empty()) { @@ -404,7 +404,7 @@ namespace MWWorld mTerrainViews.emplace_back(mTerrain->createView()); } - mTerrainPreloadPositions = positions; + mTerrainPreloadPositions.assign(positions.begin(), positions.end()); if (!positions.empty()) { mTerrainPreloadItem = new TerrainPreloadItem(mTerrainViews, mTerrain, positions); diff --git a/apps/openmw/mwworld/cellpreloader.hpp b/apps/openmw/mwworld/cellpreloader.hpp index f8b5c87c39..405ba96a2e 100644 --- a/apps/openmw/mwworld/cellpreloader.hpp +++ b/apps/openmw/mwworld/cellpreloader.hpp @@ -8,6 +8,7 @@ #include #include +#include namespace osg { @@ -77,7 +78,7 @@ namespace MWWorld void setWorkQueue(osg::ref_ptr workQueue); - void setTerrainPreloadPositions(const std::vector& positions); + void setTerrainPreloadPositions(std::span positions); void syncTerrainLoad(Loading::Listener& listener); void abortTerrainPreloadExcept(const PositionCellGrid* exceptPos); diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index c918e2d78e..202b500fdd 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -1232,10 +1232,9 @@ namespace MWWorld void Scene::preloadTerrain(const osg::Vec3f& pos, ESM::RefId worldspace, bool sync) { ESM::ExteriorCellLocation cellPos = ESM::positionToExteriorCellLocation(pos.x(), pos.y(), worldspace); - std::vector vec; - vec.emplace_back(pos, gridCenterToBounds({ cellPos.mX, cellPos.mY })); - mPreloader->abortTerrainPreloadExcept(vec.data()); - mPreloader->setTerrainPreloadPositions(vec); + const PositionCellGrid position{ pos, gridCenterToBounds({ cellPos.mX, cellPos.mY }) }; + mPreloader->abortTerrainPreloadExcept(&position); + mPreloader->setTerrainPreloadPositions(std::span(&position, 1)); if (!sync) return; @@ -1249,7 +1248,7 @@ namespace MWWorld void Scene::reloadTerrain() { - mPreloader->setTerrainPreloadPositions(std::vector()); + mPreloader->setTerrainPreloadPositions({}); } struct ListFastTravelDestinationsVisitor From 6f70350f2fd4c8868abbebed1f896fe03fb28d2f Mon Sep 17 00:00:00 2001 From: elsid Date: Wed, 24 Apr 2024 01:47:10 +0200 Subject: [PATCH 5/5] Remove unused arguments from preload functions --- apps/openmw/mwworld/scene.cpp | 15 ++++++--------- apps/openmw/mwworld/scene.hpp | 7 +++---- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index 202b500fdd..5f585c1d26 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -1101,18 +1101,17 @@ namespace MWWorld if (mPreloadEnabled) { if (mPreloadDoors) - preloadTeleportDoorDestinations(playerPos, predictedPos, exteriorPositions); + preloadTeleportDoorDestinations(playerPos, predictedPos); if (mPreloadExteriorGrid) preloadExteriorGrid(playerPos, predictedPos); if (mPreloadFastTravel) - preloadFastTravelDestinations(playerPos, predictedPos, exteriorPositions); + preloadFastTravelDestinations(playerPos, exteriorPositions); } mPreloader->setTerrainPreloadPositions(exteriorPositions); } - void Scene::preloadTeleportDoorDestinations( - const osg::Vec3f& playerPos, const osg::Vec3f& predictedPos, std::vector& exteriorPositions) + void Scene::preloadTeleportDoorDestinations(const osg::Vec3f& playerPos, const osg::Vec3f& predictedPos) { std::vector teleportDoors; for (const MWWorld::CellStore* cellStore : mActiveCells) @@ -1281,12 +1280,10 @@ namespace MWWorld std::vector mList; }; - void Scene::preloadFastTravelDestinations(const osg::Vec3f& playerPos, const osg::Vec3f& /*predictedPos*/, - std::vector& exteriorPositions) // ignore predictedPos here since opening dialogue with - // travel service takes extra time + void Scene::preloadFastTravelDestinations( + const osg::Vec3f& playerPos, std::vector& exteriorPositions) { - const MWWorld::ConstPtr player = mWorld.getPlayerPtr(); - ListFastTravelDestinationsVisitor listVisitor(mPreloadDistance, player.getRefData().getPosition().asVec3()); + ListFastTravelDestinationsVisitor listVisitor(mPreloadDistance, playerPos); ESM::RefId extWorldspace = mWorld.getCurrentWorldspace(); for (MWWorld::CellStore* cellStore : mActiveCells) { diff --git a/apps/openmw/mwworld/scene.hpp b/apps/openmw/mwworld/scene.hpp index f318deaa9f..93d814ec51 100644 --- a/apps/openmw/mwworld/scene.hpp +++ b/apps/openmw/mwworld/scene.hpp @@ -124,11 +124,10 @@ namespace MWWorld void requestChangeCellGrid(const osg::Vec3f& position, const osg::Vec2i& cell, bool changeEvent = true); void preloadCells(float dt); - void preloadTeleportDoorDestinations(const osg::Vec3f& playerPos, const osg::Vec3f& predictedPos, - std::vector& exteriorPositions); + void preloadTeleportDoorDestinations(const osg::Vec3f& playerPos, const osg::Vec3f& predictedPos); void preloadExteriorGrid(const osg::Vec3f& playerPos, const osg::Vec3f& predictedPos); - void preloadFastTravelDestinations(const osg::Vec3f& playerPos, const osg::Vec3f& predictedPos, - std::vector& exteriorPositions); + void preloadFastTravelDestinations( + const osg::Vec3f& playerPos, std::vector& exteriorPositions); osg::Vec4i gridCenterToBounds(const osg::Vec2i& centerCell) const; osg::Vec2i getNewGridCenter(const osg::Vec3f& pos, const osg::Vec2i* currentGridCenter = nullptr) const;