mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-03 22:45:35 +00:00
Predict player movement when preloading cells to better handle moving at high speed
This commit is contained in:
parent
a46593fa74
commit
c68f662c9a
2 changed files with 27 additions and 17 deletions
|
@ -202,9 +202,9 @@ namespace MWWorld
|
||||||
if (mPreloadEnabled)
|
if (mPreloadEnabled)
|
||||||
{
|
{
|
||||||
mPreloadTimer += duration;
|
mPreloadTimer += duration;
|
||||||
if (mPreloadTimer > 0.25f)
|
if (mPreloadTimer > 0.1f)
|
||||||
{
|
{
|
||||||
preloadCells();
|
preloadCells(0.1f);
|
||||||
mPreloadTimer = 0.f;
|
mPreloadTimer = 0.f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -461,6 +461,8 @@ namespace MWWorld
|
||||||
mechMgr->watchActor(player);
|
mechMgr->watchActor(player);
|
||||||
|
|
||||||
MWBase::Environment::get().getWorld()->adjustSky();
|
MWBase::Environment::get().getWorld()->adjustSky();
|
||||||
|
|
||||||
|
mLastPlayerPos = pos.asVec3();
|
||||||
}
|
}
|
||||||
|
|
||||||
Scene::Scene (MWRender::RenderingManager& rendering, MWPhysics::PhysicsSystem *physics)
|
Scene::Scene (MWRender::RenderingManager& rendering, MWPhysics::PhysicsSystem *physics)
|
||||||
|
@ -648,17 +650,24 @@ namespace MWWorld
|
||||||
return Ptr();
|
return Ptr();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::preloadCells()
|
void Scene::preloadCells(float dt)
|
||||||
{
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
|
mLastPlayerPos = playerPos;
|
||||||
|
|
||||||
if (mPreloadDoors)
|
if (mPreloadDoors)
|
||||||
preloadTeleportDoorDestinations();
|
preloadTeleportDoorDestinations(playerPos, predictedPos);
|
||||||
if (mPreloadExteriorGrid)
|
if (mPreloadExteriorGrid)
|
||||||
preloadExteriorGrid();
|
preloadExteriorGrid(playerPos, predictedPos);
|
||||||
if (mPreloadFastTravel)
|
if (mPreloadFastTravel)
|
||||||
preloadFastTravelDestinations();
|
preloadFastTravelDestinations(playerPos, predictedPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::preloadTeleportDoorDestinations()
|
void Scene::preloadTeleportDoorDestinations(const osg::Vec3f& playerPos, const osg::Vec3f& predictedPos)
|
||||||
{
|
{
|
||||||
std::vector<MWWorld::ConstPtr> teleportDoors;
|
std::vector<MWWorld::ConstPtr> teleportDoors;
|
||||||
for (CellStoreCollection::const_iterator iter (mActiveCells.begin());
|
for (CellStoreCollection::const_iterator iter (mActiveCells.begin());
|
||||||
|
@ -676,11 +685,11 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const MWWorld::ConstPtr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
|
||||||
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 = (playerPos - door.getRefData().getPosition().asVec3()).length2();
|
||||||
|
sqrDistToPlayer = std::min(sqrDistToPlayer, (predictedPos - door.getRefData().getPosition().asVec3()).length2());
|
||||||
|
|
||||||
if (sqrDistToPlayer < mPreloadDistance*mPreloadDistance)
|
if (sqrDistToPlayer < mPreloadDistance*mPreloadDistance)
|
||||||
{
|
{
|
||||||
|
@ -703,15 +712,13 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::preloadExteriorGrid()
|
void Scene::preloadExteriorGrid(const osg::Vec3f& playerPos, const osg::Vec3f& predictedPos)
|
||||||
{
|
{
|
||||||
if (!MWBase::Environment::get().getWorld()->isCellExterior())
|
if (!MWBase::Environment::get().getWorld()->isCellExterior())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int halfGridSizePlusOne = mHalfGridSize + 1;
|
int halfGridSizePlusOne = mHalfGridSize + 1;
|
||||||
|
|
||||||
const MWWorld::ConstPtr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
|
||||||
osg::Vec3f playerPos = player.getRefData().getPosition().asVec3();
|
|
||||||
|
|
||||||
int cellX,cellY;
|
int cellX,cellY;
|
||||||
getGridCenter(cellX,cellY);
|
getGridCenter(cellX,cellY);
|
||||||
|
@ -730,6 +737,7 @@ namespace MWWorld
|
||||||
MWBase::Environment::get().getWorld()->indexToPosition(cellX+dx, cellY+dy, thisCellCenterX, thisCellCenterY, true);
|
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 dist = std::max(std::abs(thisCellCenterX - playerPos.x()), std::abs(thisCellCenterY - playerPos.y()));
|
||||||
|
dist = std::min(dist,std::max(std::abs(thisCellCenterX - predictedPos.x()), std::abs(thisCellCenterY - predictedPos.y())));
|
||||||
float loadDist = 8192/2 + 8192 - mCellLoadingThreshold + mPreloadDistance;
|
float loadDist = 8192/2 + 8192 - mCellLoadingThreshold + mPreloadDistance;
|
||||||
|
|
||||||
if (dist < loadDist)
|
if (dist < loadDist)
|
||||||
|
@ -789,7 +797,7 @@ namespace MWWorld
|
||||||
std::vector<ESM::Transport::Dest> mList;
|
std::vector<ESM::Transport::Dest> mList;
|
||||||
};
|
};
|
||||||
|
|
||||||
void Scene::preloadFastTravelDestinations()
|
void Scene::preloadFastTravelDestinations(const osg::Vec3f& playerPos, const osg::Vec3f& /*predictedPos*/) // ignore predictedPos here since opening dialogue with travel service takes extra time
|
||||||
{
|
{
|
||||||
const MWWorld::ConstPtr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
const MWWorld::ConstPtr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||||
ListFastTravelDestinationsVisitor listVisitor(mPreloadDistance, player.getRefData().getPosition().asVec3());
|
ListFastTravelDestinationsVisitor listVisitor(mPreloadDistance, player.getRefData().getPosition().asVec3());
|
||||||
|
|
|
@ -68,6 +68,8 @@ namespace MWWorld
|
||||||
bool mPreloadDoors;
|
bool mPreloadDoors;
|
||||||
bool mPreloadFastTravel;
|
bool mPreloadFastTravel;
|
||||||
|
|
||||||
|
osg::Vec3f mLastPlayerPos;
|
||||||
|
|
||||||
void insertCell (CellStore &cell, bool rescale, Loading::Listener* loadingListener);
|
void insertCell (CellStore &cell, bool rescale, Loading::Listener* loadingListener);
|
||||||
|
|
||||||
// Load and unload cells as necessary to create a cell grid with "X" and "Y" in the center
|
// Load and unload cells as necessary to create a cell grid with "X" and "Y" in the center
|
||||||
|
@ -75,10 +77,10 @@ namespace MWWorld
|
||||||
|
|
||||||
void getGridCenter(int& cellX, int& cellY);
|
void getGridCenter(int& cellX, int& cellY);
|
||||||
|
|
||||||
void preloadCells();
|
void preloadCells(float dt);
|
||||||
void preloadTeleportDoorDestinations();
|
void preloadTeleportDoorDestinations(const osg::Vec3f& playerPos, const osg::Vec3f& predictedPos);
|
||||||
void preloadExteriorGrid();
|
void preloadExteriorGrid(const osg::Vec3f& playerPos, const osg::Vec3f& predictedPos);
|
||||||
void preloadFastTravelDestinations();
|
void preloadFastTravelDestinations(const osg::Vec3f& playerPos, const osg::Vec3f& predictedPos);
|
||||||
|
|
||||||
void preloadCell(MWWorld::CellStore* cell, bool preloadSurrounding=false);
|
void preloadCell(MWWorld::CellStore* cell, bool preloadSurrounding=false);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue