mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-02-27 18:41:05 +00:00
Avoid the terrain sync completely in most cases (#3103)
We can take elsid's commit 605cb8d further by avoiding the terrain sync completely in most cases. Currently in changeCellGrid we wait for a new preloading task to ensure the getPagedRefnums for the new active cells have been filled in by object paging. This is usually not necessary because we have already completed a preload in the past containing these active cells. With this PR we remember what we preloaded and skip the terrain sync if it is not needed.
This commit is contained in:
parent
c658acc2b3
commit
f62adab43a
@ -21,6 +21,29 @@
|
||||
#include "cellstore.hpp"
|
||||
#include "class.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
template <class Contained>
|
||||
bool contains(const std::vector<MWWorld::CellPreloader::PositionCellGrid>& container,
|
||||
const Contained& contained, float tolerance=1.f)
|
||||
{
|
||||
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)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
namespace MWWorld
|
||||
{
|
||||
|
||||
@ -224,6 +247,7 @@ namespace MWWorld
|
||||
, mPreloadInstances(true)
|
||||
, mLastResourceCacheUpdate(0.0)
|
||||
, mStoreViewsFailCount(0)
|
||||
, mLoadedTerrainTimestamp(0.0)
|
||||
{
|
||||
}
|
||||
|
||||
@ -369,7 +393,11 @@ namespace MWWorld
|
||||
setTerrainPreloadPositions(std::vector<PositionCellGrid>());
|
||||
}
|
||||
else
|
||||
{
|
||||
mStoreViewsFailCount = 0;
|
||||
mLoadedTerrainPositions = mTerrainPreloadPositions;
|
||||
mLoadedTerrainTimestamp = timestamp;
|
||||
}
|
||||
mTerrainPreloadItem = nullptr;
|
||||
}
|
||||
}
|
||||
@ -436,10 +464,8 @@ namespace MWWorld
|
||||
|
||||
void CellPreloader::abortTerrainPreloadExcept(const CellPreloader::PositionCellGrid *exceptPos)
|
||||
{
|
||||
const float resetThreshold = ESM::Land::REAL_SIZE;
|
||||
for (const auto& pos : mTerrainPreloadPositions)
|
||||
if (exceptPos && (pos.first-exceptPos->first).length2() < resetThreshold*resetThreshold && pos.second == exceptPos->second)
|
||||
return;
|
||||
if (exceptPos && contains(mTerrainPreloadPositions, std::array {*exceptPos}, ESM::Land::REAL_SIZE))
|
||||
return;
|
||||
if (mTerrainPreloadItem && !mTerrainPreloadItem->isDone())
|
||||
{
|
||||
mTerrainPreloadItem->abort();
|
||||
@ -448,28 +474,13 @@ namespace MWWorld
|
||||
setTerrainPreloadPositions(std::vector<CellPreloader::PositionCellGrid>());
|
||||
}
|
||||
|
||||
bool contains(const std::vector<CellPreloader::PositionCellGrid>& container, const std::vector<CellPreloader::PositionCellGrid>& contained)
|
||||
{
|
||||
for (const auto& pos : contained)
|
||||
{
|
||||
bool found = false;
|
||||
for (const auto& pos2 : container)
|
||||
{
|
||||
if ((pos.first-pos2.first).length2() < 1 && pos.second == pos2.second)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void CellPreloader::setTerrainPreloadPositions(const std::vector<CellPreloader::PositionCellGrid> &positions)
|
||||
{
|
||||
if (positions.empty())
|
||||
{
|
||||
mTerrainPreloadPositions.clear();
|
||||
mLoadedTerrainPositions.clear();
|
||||
}
|
||||
else if (contains(mTerrainPreloadPositions, positions))
|
||||
return;
|
||||
if (mTerrainPreloadItem && !mTerrainPreloadItem->isDone())
|
||||
@ -496,5 +507,10 @@ namespace MWWorld
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CellPreloader::isTerrainLoaded(const CellPreloader::PositionCellGrid &position, double referenceTime) const
|
||||
{
|
||||
return mLoadedTerrainTimestamp + mResourceSystem->getSceneManager()->getExpiryDelay() > referenceTime && contains(mLoadedTerrainPositions, std::array {position}, ESM::Land::REAL_SIZE);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -79,6 +79,7 @@ namespace MWWorld
|
||||
|
||||
bool syncTerrainLoad(const std::vector<CellPreloader::PositionCellGrid> &positions, double timestamp, Loading::Listener& listener);
|
||||
void abortTerrainPreloadExcept(const PositionCellGrid *exceptPos);
|
||||
bool isTerrainLoaded(const CellPreloader::PositionCellGrid &position, double referenceTime) const;
|
||||
|
||||
private:
|
||||
Resource::ResourceSystem* mResourceSystem;
|
||||
@ -119,6 +120,9 @@ namespace MWWorld
|
||||
std::vector<PositionCellGrid> mTerrainPreloadPositions;
|
||||
osg::ref_ptr<TerrainPreloadItem> mTerrainPreloadItem;
|
||||
osg::ref_ptr<SceneUtil::WorkItem> mUpdateCacheItem;
|
||||
|
||||
std::vector<PositionCellGrid> mLoadedTerrainPositions;
|
||||
double mLoadedTerrainTimestamp;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -628,7 +628,10 @@ namespace MWWorld
|
||||
osg::Vec4i newGrid = gridCenterToBounds(mCurrentGridCenter);
|
||||
mRendering.setActiveGrid(newGrid);
|
||||
|
||||
preloadTerrain(pos, true);
|
||||
if (mRendering.pagingUnlockCache())
|
||||
mPreloader->abortTerrainPreloadExcept(nullptr);
|
||||
if (!mPreloader->isTerrainLoaded(std::make_pair(pos, newGrid), mRendering.getReferenceTime()))
|
||||
preloadTerrain(pos, true);
|
||||
mPagedRefs.clear();
|
||||
mRendering.getPagedRefnums(newGrid, mPagedRefs);
|
||||
|
||||
@ -1241,10 +1244,7 @@ namespace MWWorld
|
||||
{
|
||||
std::vector<PositionCellGrid> vec;
|
||||
vec.emplace_back(pos, gridCenterToBounds(getNewGridCenter(pos)));
|
||||
if (sync && mRendering.pagingUnlockCache())
|
||||
mPreloader->abortTerrainPreloadExcept(nullptr);
|
||||
else
|
||||
mPreloader->abortTerrainPreloadExcept(&vec[0]);
|
||||
mPreloader->abortTerrainPreloadExcept(&vec[0]);
|
||||
mPreloader->setTerrainPreloadPositions(vec);
|
||||
if (!sync) return;
|
||||
|
||||
|
@ -59,6 +59,7 @@ namespace Resource
|
||||
|
||||
/// How long to keep objects in cache after no longer being referenced.
|
||||
void setExpiryDelay (double expiryDelay) override { mExpiryDelay = expiryDelay; }
|
||||
float getExpiryDelay() const { return mExpiryDelay; }
|
||||
|
||||
const VFS::Manager* getVFS() const { return mVFS; }
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user