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:
parent
da92ad329b
commit
ffbed7ee38
8 changed files with 88 additions and 12 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 ¢erCell) const;
|
||||
osg::Vec2i getNewGridCenter(const osg::Vec3f &pos, const osg::Vec2i *currentGridCenter = nullptr) const;
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in a new issue