Preload the exterior cell grid

coverity_scan
scrawl 9 years ago
parent 49ecac4ced
commit 610257cd3a

@ -194,7 +194,7 @@ namespace MWWorld
void Scene::update (float duration, bool paused) void Scene::update (float duration, bool paused)
{ {
mPreloadTimer += duration; mPreloadTimer += duration;
if (mPreloadTimer > 1.f) if (mPreloadTimer > 0.5f)
{ {
preloadCells(); preloadCells();
mPreloadTimer = 0.f; mPreloadTimer = 0.f;
@ -313,7 +313,7 @@ namespace MWWorld
getGridCenter(cellX, cellY); getGridCenter(cellX, cellY);
float centerX, centerY; float centerX, centerY;
MWBase::Environment::get().getWorld()->indexToPosition(cellX, cellY, centerX, centerY, true); MWBase::Environment::get().getWorld()->indexToPosition(cellX, cellY, centerX, centerY, true);
const float maxDistance = 8192/2 + 1024; // 1/2 cell size + threshold const float maxDistance = 8192/2 + mCellLoadingThreshold; // 1/2 cell size + threshold
float distance = std::max(std::abs(centerX-pos.x()), std::abs(centerY-pos.y())); float distance = std::max(std::abs(centerX-pos.x()), std::abs(centerY-pos.y()));
if (distance > maxDistance) if (distance > maxDistance)
{ {
@ -447,6 +447,8 @@ namespace MWWorld
: mCurrentCell (0), mCellChanged (false), mPhysics(physics), mRendering(rendering) : mCurrentCell (0), mCellChanged (false), mPhysics(physics), mRendering(rendering)
, mPreloadTimer(0.f) , mPreloadTimer(0.f)
, mHalfGridSize(Settings::Manager::getInt("exterior cell load distance", "Cells")) , mHalfGridSize(Settings::Manager::getInt("exterior cell load distance", "Cells"))
, mCellLoadingThreshold(1024.f)
, mPreloadDistance(1000.f)
{ {
mPreloader.reset(new CellPreloader(rendering.getResourceSystem(), physics->getShapeManager())); mPreloader.reset(new CellPreloader(rendering.getResourceSystem(), physics->getShapeManager()));
} }
@ -612,6 +614,12 @@ namespace MWWorld
} }
void Scene::preloadCells() void Scene::preloadCells()
{
preloadTeleportDoorDestinations();
preloadExteriorGrid();
}
void Scene::preloadTeleportDoorDestinations()
{ {
std::vector<MWWorld::ConstPtr> teleportDoors; std::vector<MWWorld::ConstPtr> teleportDoors;
for (CellStoreCollection::const_iterator iter (mActiveCells.begin()); for (CellStoreCollection::const_iterator iter (mActiveCells.begin());
@ -630,14 +638,12 @@ namespace MWWorld
} }
const MWWorld::ConstPtr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); const MWWorld::ConstPtr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
const float preloadDist = 500.f;
for (std::vector<MWWorld::ConstPtr>::iterator it = teleportDoors.begin(); it != teleportDoors.end(); ++it) for (std::vector<MWWorld::ConstPtr>::iterator it = teleportDoors.begin(); it != teleportDoors.end(); ++it)
{ {
const MWWorld::ConstPtr& door = *it; const MWWorld::ConstPtr& door = *it;
float sqrDistToPlayer = (player.getRefData().getPosition().asVec3() - door.getRefData().getPosition().asVec3()).length2(); float sqrDistToPlayer = (player.getRefData().getPosition().asVec3() - door.getRefData().getPosition().asVec3()).length2();
if (sqrDistToPlayer < preloadDist*preloadDist) if (sqrDistToPlayer < mPreloadDistance*mPreloadDistance)
{ {
try try
{ {
@ -664,4 +670,41 @@ namespace MWWorld
} }
} }
} }
void Scene::preloadExteriorGrid()
{
if (!MWBase::Environment::get().getWorld()->isCellExterior())
return;
int halfGridSizePlusOne = mHalfGridSize + 1;
const MWWorld::ConstPtr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
osg::Vec3f playerPos = player.getRefData().getPosition().asVec3();
int cellX,cellY;
getGridCenter(cellX,cellY);
float centerX, centerY;
MWBase::Environment::get().getWorld()->indexToPosition(cellX, cellY, centerX, centerY, true);
for (int dx = -halfGridSizePlusOne; dx <= halfGridSizePlusOne; ++dx)
{
for (int dy = -halfGridSizePlusOne; dy <= halfGridSizePlusOne; ++dy)
{
if (dy != halfGridSizePlusOne && dy != -halfGridSizePlusOne && dx != halfGridSizePlusOne && dx != -halfGridSizePlusOne)
continue; // only care about the outer (not yet loaded) part of the grid
float thisCellCenterX, thisCellCenterY;
MWBase::Environment::get().getWorld()->indexToPosition(cellX+dx, cellY+dy, thisCellCenterX, thisCellCenterY, true);
float dist = std::max(std::abs(thisCellCenterX - playerPos.x()), std::abs(thisCellCenterY - playerPos.y()));
float loadDist = 8192/2 + 8192 - mCellLoadingThreshold + mPreloadDistance;
std::cout << cellX+dx << " " << cellY+dy << " dist " << dist << " need " << loadDist << std::endl;
if (dist < loadDist)
mPreloader->preload(MWBase::Environment::get().getWorld()->getExterior(cellX+dx, cellY+dy), mRendering.getReferenceTime());
}
}
}
} }

@ -60,6 +60,8 @@ namespace MWWorld
std::auto_ptr<CellPreloader> mPreloader; std::auto_ptr<CellPreloader> mPreloader;
float mPreloadTimer; float mPreloadTimer;
int mHalfGridSize; int mHalfGridSize;
float mCellLoadingThreshold;
float mPreloadDistance;
void insertCell (CellStore &cell, bool rescale, Loading::Listener* loadingListener); void insertCell (CellStore &cell, bool rescale, Loading::Listener* loadingListener);
@ -68,6 +70,10 @@ namespace MWWorld
void getGridCenter(int& cellX, int& cellY); void getGridCenter(int& cellX, int& cellY);
void preloadCells();
void preloadTeleportDoorDestinations();
void preloadExteriorGrid();
public: public:
Scene (MWRender::RenderingManager& rendering, MWPhysics::PhysicsSystem *physics); Scene (MWRender::RenderingManager& rendering, MWPhysics::PhysicsSystem *physics);
@ -114,8 +120,6 @@ namespace MWWorld
bool isCellActive(const CellStore &cell); bool isCellActive(const CellStore &cell);
Ptr searchPtrViaActorId (int actorId); Ptr searchPtrViaActorId (int actorId);
void preloadCells();
}; };
} }

Loading…
Cancel
Save