Use the new way of terrain preloading in CellPreloader/Scene

0.6.1
scrawl 8 years ago
parent 4baa795152
commit 4549196b31

@ -194,11 +194,22 @@ namespace MWWorld
, mMaxCacheSize(0) , mMaxCacheSize(0)
, mPreloadInstances(true) , mPreloadInstances(true)
, mLastResourceCacheUpdate(0.0) , mLastResourceCacheUpdate(0.0)
, mTerrainView(NULL)
{ {
mTerrainView = mTerrain->createView();
} }
CellPreloader::~CellPreloader() CellPreloader::~CellPreloader()
{ {
if (mTerrainPreloadItem)
{
mTerrainPreloadItem->waitTillDone();
mTerrainPreloadItem = NULL;
}
mTerrain->removeView(mTerrainView);
mTerrainView = NULL;
for (PreloadMap::iterator it = mPreloadCells.begin(); it != mPreloadCells.end();++it) for (PreloadMap::iterator it = mPreloadCells.begin(); it != mPreloadCells.end();++it)
it->second.mWorkItem->abort(); it->second.mWorkItem->abort();
@ -349,4 +360,44 @@ namespace MWWorld
mUnrefQueue = unrefQueue; mUnrefQueue = unrefQueue;
} }
class TerrainPreloadItem : public SceneUtil::WorkItem
{
public:
TerrainPreloadItem(Terrain::View* view, Terrain::World* world, const std::vector<osg::Vec3f>& preloadPositions)
: mView(view)
, mWorld(world)
, mPreloadPositions(preloadPositions)
{
}
virtual void doWork()
{
for (std::vector<osg::Vec3f>::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<osg::Vec3f> mPreloadPositions;
};
void CellPreloader::setTerrainPreloadPositions(const std::vector<osg::Vec3f> &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);
}
}
} }

@ -3,6 +3,7 @@
#include <map> #include <map>
#include <osg/ref_ptr> #include <osg/ref_ptr>
#include <osg/Vec3f>
#include <components/sceneutil/workqueue.hpp> #include <components/sceneutil/workqueue.hpp>
namespace Resource namespace Resource
@ -14,6 +15,7 @@ namespace Resource
namespace Terrain namespace Terrain
{ {
class World; class World;
class View;
} }
namespace SceneUtil namespace SceneUtil
@ -65,6 +67,8 @@ namespace MWWorld
void setUnrefQueue(SceneUtil::UnrefQueue* unrefQueue); void setUnrefQueue(SceneUtil::UnrefQueue* unrefQueue);
void setTerrainPreloadPositions(const std::vector<osg::Vec3f>& positions);
private: private:
Resource::ResourceSystem* mResourceSystem; Resource::ResourceSystem* mResourceSystem;
Resource::BulletShapeManager* mBulletShapeManager; Resource::BulletShapeManager* mBulletShapeManager;
@ -98,6 +102,10 @@ namespace MWWorld
// Cells that are currently being preloaded, or have already finished preloading // Cells that are currently being preloaded, or have already finished preloading
PreloadMap mPreloadCells; PreloadMap mPreloadCells;
Terrain::View* mTerrainView;
std::vector<osg::Vec3f> mTerrainPreloadPositions;
osg::ref_ptr<SceneUtil::WorkItem> mTerrainPreloadItem;
}; };
} }

@ -692,22 +692,29 @@ namespace MWWorld
void Scene::preloadCells(float dt) void Scene::preloadCells(float dt)
{ {
std::vector<osg::Vec3f> exteriorPositions;
const MWWorld::ConstPtr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); const MWWorld::ConstPtr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
osg::Vec3f playerPos = player.getRefData().getPosition().asVec3(); osg::Vec3f playerPos = player.getRefData().getPosition().asVec3();
osg::Vec3f moved = playerPos - mLastPlayerPos; osg::Vec3f moved = playerPos - mLastPlayerPos;
osg::Vec3f predictedPos = playerPos + moved / dt; osg::Vec3f predictedPos = playerPos + moved / dt;
if (mCurrentCell->isExterior())
exteriorPositions.push_back(predictedPos);
mLastPlayerPos = playerPos; mLastPlayerPos = playerPos;
if (mPreloadDoors) if (mPreloadDoors)
preloadTeleportDoorDestinations(playerPos, predictedPos); preloadTeleportDoorDestinations(playerPos, predictedPos, exteriorPositions);
if (mPreloadExteriorGrid) if (mPreloadExteriorGrid)
preloadExteriorGrid(playerPos, predictedPos); preloadExteriorGrid(playerPos, predictedPos);
if (mPreloadFastTravel) if (mPreloadFastTravel)
preloadFastTravelDestinations(playerPos, predictedPos); 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<osg::Vec3f>& exteriorPositions)
{ {
std::vector<MWWorld::ConstPtr> teleportDoors; std::vector<MWWorld::ConstPtr> teleportDoors;
for (CellStoreCollection::const_iterator iter (mActiveCells.begin()); for (CellStoreCollection::const_iterator iter (mActiveCells.begin());
@ -739,9 +746,11 @@ namespace MWWorld
preloadCell(MWBase::Environment::get().getWorld()->getInterior(door.getCellRef().getDestCell())); preloadCell(MWBase::Environment::get().getWorld()->getInterior(door.getCellRef().getDestCell()));
else else
{ {
osg::Vec3f pos = door.getCellRef().getDoorDest().asVec3();
int x,y; 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); preloadCell(MWBase::Environment::get().getWorld()->getExterior(x,y), true);
exteriorPositions.push_back(pos);
} }
} }
catch (std::exception& e) catch (std::exception& e)

@ -78,7 +78,7 @@ namespace MWWorld
void getGridCenter(int& cellX, int& cellY); void getGridCenter(int& cellX, int& cellY);
void preloadCells(float dt); 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<osg::Vec3f>& exteriorPositions);
void preloadExteriorGrid(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); void preloadFastTravelDestinations(const osg::Vec3f& playerPos, const osg::Vec3f& predictedPos);

Loading…
Cancel
Save