From 4549196b310d6bdc7f2797e19a5f69f34301d929 Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 9 Mar 2017 04:18:35 +0100 Subject: [PATCH] Use the new way of terrain preloading in CellPreloader/Scene --- apps/openmw/mwworld/cellpreloader.cpp | 51 +++++++++++++++++++++++++++ apps/openmw/mwworld/cellpreloader.hpp | 8 +++++ apps/openmw/mwworld/scene.cpp | 15 ++++++-- apps/openmw/mwworld/scene.hpp | 2 +- 4 files changed, 72 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwworld/cellpreloader.cpp b/apps/openmw/mwworld/cellpreloader.cpp index e45cf55bc..e633f5825 100644 --- a/apps/openmw/mwworld/cellpreloader.cpp +++ b/apps/openmw/mwworld/cellpreloader.cpp @@ -194,11 +194,22 @@ namespace MWWorld , mMaxCacheSize(0) , mPreloadInstances(true) , mLastResourceCacheUpdate(0.0) + , mTerrainView(NULL) { + mTerrainView = mTerrain->createView(); } CellPreloader::~CellPreloader() { + if (mTerrainPreloadItem) + { + mTerrainPreloadItem->waitTillDone(); + mTerrainPreloadItem = NULL; + } + + mTerrain->removeView(mTerrainView); + mTerrainView = NULL; + for (PreloadMap::iterator it = mPreloadCells.begin(); it != mPreloadCells.end();++it) it->second.mWorkItem->abort(); @@ -349,4 +360,44 @@ namespace MWWorld mUnrefQueue = unrefQueue; } + class TerrainPreloadItem : public SceneUtil::WorkItem + { + public: + TerrainPreloadItem(Terrain::View* view, Terrain::World* world, const std::vector& preloadPositions) + : mView(view) + , mWorld(world) + , mPreloadPositions(preloadPositions) + { + } + + virtual void doWork() + { + for (std::vector::const_iterator it = mPreloadPositions.begin(); it != mPreloadPositions.end(); ++it) + mWorld->preload(mView, *it); + + mView->reset(0); + } + + private: + Terrain::View* mView; + Terrain::World* mWorld; + std::vector mPreloadPositions; + }; + + void CellPreloader::setTerrainPreloadPositions(const std::vector &positions) + { + if (!mTerrainView) + return; + if (mTerrainPreloadItem && !mTerrainPreloadItem->isDone()) + return; + else if (positions == mTerrainPreloadPositions) + return; + else + { + mTerrainPreloadPositions = positions; + mTerrainPreloadItem = new TerrainPreloadItem(mTerrainView, mTerrain, positions); + mWorkQueue->addWorkItem(mTerrainPreloadItem); + } + } + } diff --git a/apps/openmw/mwworld/cellpreloader.hpp b/apps/openmw/mwworld/cellpreloader.hpp index ee73a4ea1..9bd062547 100644 --- a/apps/openmw/mwworld/cellpreloader.hpp +++ b/apps/openmw/mwworld/cellpreloader.hpp @@ -3,6 +3,7 @@ #include #include +#include #include namespace Resource @@ -14,6 +15,7 @@ namespace Resource namespace Terrain { class World; + class View; } namespace SceneUtil @@ -65,6 +67,8 @@ namespace MWWorld void setUnrefQueue(SceneUtil::UnrefQueue* unrefQueue); + void setTerrainPreloadPositions(const std::vector& positions); + private: Resource::ResourceSystem* mResourceSystem; Resource::BulletShapeManager* mBulletShapeManager; @@ -98,6 +102,10 @@ namespace MWWorld // Cells that are currently being preloaded, or have already finished preloading PreloadMap mPreloadCells; + + Terrain::View* mTerrainView; + std::vector mTerrainPreloadPositions; + osg::ref_ptr mTerrainPreloadItem; }; } diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index 41dcce1d9..a772abdc2 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -692,22 +692,29 @@ namespace MWWorld void Scene::preloadCells(float dt) { + std::vector exteriorPositions; + const MWWorld::ConstPtr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); osg::Vec3f playerPos = player.getRefData().getPosition().asVec3(); osg::Vec3f moved = playerPos - mLastPlayerPos; osg::Vec3f predictedPos = playerPos + moved / dt; + if (mCurrentCell->isExterior()) + exteriorPositions.push_back(predictedPos); + mLastPlayerPos = playerPos; if (mPreloadDoors) - preloadTeleportDoorDestinations(playerPos, predictedPos); + preloadTeleportDoorDestinations(playerPos, predictedPos, exteriorPositions); if (mPreloadExteriorGrid) preloadExteriorGrid(playerPos, predictedPos); if (mPreloadFastTravel) preloadFastTravelDestinations(playerPos, predictedPos); + + mPreloader->setTerrainPreloadPositions(exteriorPositions); } - void Scene::preloadTeleportDoorDestinations(const osg::Vec3f& playerPos, const osg::Vec3f& predictedPos) + void Scene::preloadTeleportDoorDestinations(const osg::Vec3f& playerPos, const osg::Vec3f& predictedPos, std::vector& exteriorPositions) { std::vector teleportDoors; for (CellStoreCollection::const_iterator iter (mActiveCells.begin()); @@ -739,9 +746,11 @@ namespace MWWorld preloadCell(MWBase::Environment::get().getWorld()->getInterior(door.getCellRef().getDestCell())); else { + osg::Vec3f pos = door.getCellRef().getDoorDest().asVec3(); int x,y; - MWBase::Environment::get().getWorld()->positionToIndex (door.getCellRef().getDoorDest().pos[0], door.getCellRef().getDoorDest().pos[1], x, y); + MWBase::Environment::get().getWorld()->positionToIndex (pos.x(), pos.y(), x, y); preloadCell(MWBase::Environment::get().getWorld()->getExterior(x,y), true); + exteriorPositions.push_back(pos); } } catch (std::exception& e) diff --git a/apps/openmw/mwworld/scene.hpp b/apps/openmw/mwworld/scene.hpp index 5f17f8d59..437279ff7 100644 --- a/apps/openmw/mwworld/scene.hpp +++ b/apps/openmw/mwworld/scene.hpp @@ -78,7 +78,7 @@ namespace MWWorld void getGridCenter(int& cellX, int& cellY); void preloadCells(float dt); - void preloadTeleportDoorDestinations(const osg::Vec3f& playerPos, const osg::Vec3f& predictedPos); + void preloadTeleportDoorDestinations(const osg::Vec3f& playerPos, const osg::Vec3f& predictedPos, std::vector& exteriorPositions); void preloadExteriorGrid(const osg::Vec3f& playerPos, const osg::Vec3f& predictedPos); void preloadFastTravelDestinations(const osg::Vec3f& playerPos, const osg::Vec3f& predictedPos);