1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-01-30 03:15:32 +00:00

loadingscreen

Signed-off-by: Bret Curtis <psi29a@gmail.com>
This commit is contained in:
bzzt lost a hitlab login 2020-05-07 13:37:00 +00:00 committed by Bret Curtis
parent da92ad329b
commit ffbed7ee38
8 changed files with 88 additions and 12 deletions

View file

@ -174,6 +174,8 @@ namespace MWWorld
public:
TerrainPreloadItem(const std::vector<osg::ref_ptr<Terrain::View> >& views, Terrain::World* world, const std::vector<CellPreloader::PositionCellGrid>& preloadPositions)
: mAbort(false)
, mProgress(views.size())
, mProgressRange(0)
, mTerrainViews(views)
, mWorld(world)
, mPreloadPositions(preloadPositions)
@ -191,7 +193,7 @@ 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);
mWorld->preload(mTerrainViews[i], mPreloadPositions[i].first, mPreloadPositions[i].second, mAbort, mProgress[i], mProgressRange);
}
}
@ -200,8 +202,13 @@ namespace MWWorld
mAbort = true;
}
int getProgress() const { return !mProgress.empty() ? mProgress[0].load() : 0; }
int getProgressRange() const { return !mProgress.empty() && mProgress[0].load() ? mProgressRange : 0; }
private:
std::atomic<bool> mAbort;
std::vector<std::atomic<int>> mProgress;
int mProgressRange;
std::vector<osg::ref_ptr<Terrain::View> > mTerrainViews;
Terrain::World* mWorld;
std::vector<CellPreloader::PositionCellGrid> mPreloadPositions;
@ -328,9 +335,6 @@ namespace MWWorld
}
mPreloadCells.erase(found);
if (cell->isExterior() && mTerrainPreloadItem && mTerrainPreloadItem->isDone())
mTerrainPreloadItem->storeViews(0.0);
}
}
@ -415,6 +419,38 @@ namespace MWWorld
mUnrefQueue = unrefQueue;
}
bool CellPreloader::getTerrainPreloadInProgress(int& progress, int& progressRange, double timestamp)
{
if (!mTerrainPreloadItem)
return false;
else if (mTerrainPreloadItem->isDone())
{
mTerrainPreloadItem->storeViews(timestamp);
mTerrainPreloadItem = nullptr;
return false;
}
else
{
progress = mTerrainPreloadItem->getProgress();
progressRange = mTerrainPreloadItem->getProgressRange();
return !progress || progress < progressRange;
}
}
void CellPreloader::abortTerrainPreloadExcept(const osg::Vec3f& exceptPos)
{
if (mTerrainPreloadItem && !mTerrainPreloadItem->isDone())
{
const float resetThreshold = ESM::Land::REAL_SIZE;
for (auto pos : mTerrainPreloadPositions)
if ((pos.first-exceptPos).length2() < resetThreshold*resetThreshold)
return;
mTerrainPreloadItem->abort();
mTerrainPreloadItem->waitTillDone();
mTerrainPreloadItem = nullptr;
}
}
void CellPreloader::setTerrainPreloadPositions(const std::vector<CellPreloader::PositionCellGrid> &positions)
{
if (mTerrainPreloadItem && !mTerrainPreloadItem->isDone())
@ -436,8 +472,12 @@ namespace MWWorld
}
mTerrainPreloadPositions = positions;
mTerrainPreloadItem = new TerrainPreloadItem(mTerrainViews, mTerrain, positions);
mWorkQueue->addWorkItem(mTerrainPreloadItem);
if (!positions.empty())
{
mTerrainPreloadItem = new TerrainPreloadItem(mTerrainViews, mTerrain, positions);
mWorkQueue->addWorkItem(mTerrainPreloadItem);
}
}
}

View file

@ -72,6 +72,9 @@ namespace MWWorld
typedef std::pair<osg::Vec3f, osg::Vec4i> PositionCellGrid;
void setTerrainPreloadPositions(const std::vector<PositionCellGrid>& positions);
bool getTerrainPreloadInProgress(int& progress, int& progressRange, double timestamp);
void abortTerrainPreloadExcept(const osg::Vec3f& exceptPos);
private:
Resource::ResourceSystem* mResourceSystem;
Resource::BulletShapeManager* mBulletShapeManager;

View file

@ -849,15 +849,42 @@ namespace MWWorld
if (changeEvent)
MWBase::Environment::get().getWindowManager()->fadeScreenOut(0.5);
preloadTerrain(position.asVec3());
changeCellGrid(x, y, changeEvent);
CellStore* current = MWBase::Environment::get().getWorld()->getExterior(x, y);
changePlayerCell(current, position, adjustPlayerPos);
checkTerrainLoaded();
if (changeEvent)
MWBase::Environment::get().getWindowManager()->fadeScreenIn(0.5);
}
void Scene::checkTerrainLoaded()
{
Loading::Listener* loadingListener = MWBase::Environment::get().getWindowManager()->getLoadingScreen();
Loading::ScopedLoad load(loadingListener);
int progress = 0, initialProgress = -1, progressRange = 0;
while (mPreloader->getTerrainPreloadInProgress(progress, progressRange, mRendering.getReferenceTime()))
{
if (initialProgress == -1)
{
loadingListener->setLabel("#{sLoadingMessage4}");
initialProgress = progress;
}
if (progress)
{
loadingListener->setProgressRange(std::max(0, progressRange-initialProgress));
loadingListener->setProgress(progress-initialProgress);
}
else
loadingListener->setProgress(0);
OpenThreads::Thread::microSleep(5000);
}
}
CellStore* Scene::getCurrentCell ()
{
return mCurrentCell;
@ -1102,6 +1129,7 @@ namespace MWWorld
void Scene::preloadTerrain(const osg::Vec3f &pos)
{
mPreloader->abortTerrainPreloadExcept(pos);
std::vector<PositionCellGrid> vec;
vec.emplace_back(pos, gridCenterToBounds(getNewGridCenter(pos)));
mPreloader->setTerrainPreloadPositions(vec);

View file

@ -101,6 +101,8 @@ namespace MWWorld
void preloadExteriorGrid(const osg::Vec3f& playerPos, const osg::Vec3f& predictedPos);
void preloadFastTravelDestinations(const osg::Vec3f& playerPos, const osg::Vec3f& predictedPos, std::vector<PositionCellGrid>& exteriorPositions);
void checkTerrainLoaded();
osg::Vec4i gridCenterToBounds(const osg::Vec2i &centerCell) const;
osg::Vec2i getNewGridCenter(const osg::Vec3f &pos, const osg::Vec2i *currentGridCenter = nullptr) const;

View file

@ -243,7 +243,6 @@ namespace MWWorld
if (bypass && !mStartCell.empty())
{
ESM::Position pos;
if (findExteriorPosition (mStartCell, pos))
{
changeToExteriorCell (pos, true);
@ -384,9 +383,9 @@ namespace MWWorld
mPlayer->readRecord(reader, type);
if (getPlayerPtr().isInCell())
{
mWorldScene->preloadCell(getPlayerPtr().getCell(), true);
if (getPlayerPtr().getCell()->isExterior())
mWorldScene->preloadTerrain(getPlayerPtr().getRefData().getPosition().asVec3());
mWorldScene->preloadCell(getPlayerPtr().getCell(), true);
}
break;
default:

View file

@ -509,7 +509,7 @@ View* QuadTreeWorld::createView()
return new ViewData;
}
void QuadTreeWorld::preload(View *view, const osg::Vec3f &viewPoint, const osg::Vec4i &grid, std::atomic<bool> &abort)
void QuadTreeWorld::preload(View *view, const osg::Vec3f &viewPoint, const osg::Vec4i &grid, std::atomic<bool> &abort, std::atomic<int> &progress, int& progressTotal)
{
ensureQuadTreeBuilt();
@ -519,12 +519,16 @@ void QuadTreeWorld::preload(View *view, const osg::Vec3f &viewPoint, const osg::
DefaultLodCallback lodCallback(mLodFactor, MIN_SIZE, grid);
mRootNode->traverseNodes(vd, viewPoint, &lodCallback, mViewDistance);
const float cellWorldSize = mStorage->getCellWorldSize();
if (!progressTotal)
for (unsigned int i=0; i<vd->getNumEntries(); ++i)
progressTotal += vd->getEntry(i).mNode->getSize();
const float cellWorldSize = mStorage->getCellWorldSize();
for (unsigned int i=0; i<vd->getNumEntries() && !abort; ++i)
{
ViewData::Entry& entry = vd->getEntry(i);
loadRenderingNode(entry, vd, mVertexLodMod, cellWorldSize, grid, mChunkManagers, true);
progress += entry.mNode->getSize();
}
vd->markUnchanged();
}

View file

@ -38,7 +38,7 @@ namespace Terrain
virtual void unloadCell(int x, int y);
View* createView();
void preload(View* view, const osg::Vec3f& eyePoint, const osg::Vec4i &cellgrid, std::atomic<bool>& abort);
void preload(View* view, const osg::Vec3f& eyePoint, const osg::Vec4i &cellgrid, std::atomic<bool>& abort, std::atomic<int>& progress, int& progressRange);
void storeView(const View* view, double referenceTime);
void reportStats(unsigned int frameNumber, osg::Stats* stats);

View file

@ -147,7 +147,7 @@ namespace Terrain
/// @note Thread safe, as long as you do not attempt to load into the same view from multiple threads.
virtual void preload(View* view, const osg::Vec3f& viewPoint, const osg::Vec4i &cellgrid, std::atomic<bool>& abort) {}
virtual void preload(View* view, const osg::Vec3f& viewPoint, const osg::Vec4i &cellgrid, std::atomic<bool>& abort, std::atomic<int>& progress, int& progressRange) {}
/// Store a preloaded view into the cache with the intent that the next rendering traversal can use it.
/// @note Not thread safe.