Implement cell loading threshold (Fixes #1874)

The cell loading threshold (default: 1024 units) prevents exterior cell loading until the player has travelled part-way into the next cell. This gets rid of excessive cell loadings when walking along an exterior cell border.

Lower the maximum allowed view distance in options menu to accomodate. Change setting name so that old settings files are upgraded.
deque
scrawl 10 years ago
parent eda296f1e3
commit 7d36a202a8

@ -177,7 +177,7 @@ namespace MWBase
virtual void changeCell(MWWorld::CellStore* cell) = 0; virtual void changeCell(MWWorld::CellStore* cell) = 0;
///< change the active cell ///< change the active cell
virtual void setPlayerPos(const float x, const float y) = 0; virtual void setPlayerPos(int cellX, int cellY, const float x, const float y) = 0;
///< set player position in map space ///< set player position in map space
virtual void setPlayerDir(const float x, const float y) = 0; virtual void setPlayerDir(const float x, const float y) = 0;

@ -137,7 +137,7 @@ namespace MWBase
virtual MWWorld::LocalScripts& getLocalScripts() = 0; virtual MWWorld::LocalScripts& getLocalScripts() = 0;
virtual bool hasCellChanged() const = 0; virtual bool hasCellChanged() const = 0;
///< Has the player moved to a different cell, since the last frame? ///< Has the set of active cells changed, since the last frame?
virtual bool isCellExterior() const = 0; virtual bool isCellExterior() const = 0;

@ -159,8 +159,6 @@ namespace MWGui
, mLocalMap(NULL) , mLocalMap(NULL)
, mPrefix() , mPrefix()
, mChanged(true) , mChanged(true)
, mLastPositionX(0.0f)
, mLastPositionY(0.0f)
, mLastDirectionX(0.0f) , mLastDirectionX(0.0f)
, mLastDirectionY(0.0f) , mLastDirectionY(0.0f)
, mCompass(NULL) , mCompass(NULL)
@ -425,24 +423,24 @@ namespace MWGui
mLocalMap->getParent()->_updateChilds(); mLocalMap->getParent()->_updateChilds();
} }
void LocalMapBase::setPlayerPos(const float x, const float y) void LocalMapBase::setPlayerPos(int cellX, int cellY, const float nx, const float ny)
{ {
updateMagicMarkers(); updateMagicMarkers();
if (x == mLastPositionX && y == mLastPositionY)
return;
notifyPlayerUpdate (); notifyPlayerUpdate ();
MyGUI::IntSize size = mLocalMap->getCanvasSize(); MyGUI::IntPoint pos(widgetSize+nx*widgetSize-16, widgetSize+ny*widgetSize-16);
MyGUI::IntPoint middle = MyGUI::IntPoint((1/3.f + x/3.f)*size.width,(1/3.f + y/3.f)*size.height); pos.left += (cellX - mCurX) * widgetSize;
MyGUI::IntCoord viewsize = mLocalMap->getCoord(); pos.top -= (cellY - mCurY) * widgetSize;
MyGUI::IntPoint pos(0.5*viewsize.width - middle.left, 0.5*viewsize.height - middle.top);
mLocalMap->setViewOffset(pos);
mCompass->setPosition(MyGUI::IntPoint(widgetSize+x*widgetSize-16, widgetSize+y*widgetSize-16)); if (pos != mCompass->getPosition())
mLastPositionX = x; {
mLastPositionY = y; mCompass->setPosition(pos);
MyGUI::IntPoint middle (pos.left+16, pos.top+16);
MyGUI::IntCoord viewsize = mLocalMap->getCoord();
MyGUI::IntPoint viewOffset(0.5*viewsize.width - middle.left, 0.5*viewsize.height - middle.top);
mLocalMap->setViewOffset(viewOffset);
}
} }
void LocalMapBase::setPlayerDir(const float x, const float y) void LocalMapBase::setPlayerDir(const float x, const float y)

@ -75,7 +75,7 @@ namespace MWGui
void setCellPrefix(const std::string& prefix); void setCellPrefix(const std::string& prefix);
void setActiveCell(const int x, const int y, bool interior=false); void setActiveCell(const int x, const int y, bool interior=false);
void setPlayerDir(const float x, const float y); void setPlayerDir(const float x, const float y);
void setPlayerPos(const float x, const float y); void setPlayerPos(int cellX, int cellY, const float nx, const float ny);
void onFrame(float dt); void onFrame(float dt);
@ -129,8 +129,6 @@ namespace MWGui
float mMarkerUpdateTimer; float mMarkerUpdateTimer;
float mLastPositionX;
float mLastPositionY;
float mLastDirectionX; float mLastDirectionX;
float mLastDirectionY; float mLastDirectionY;
}; };

@ -880,9 +880,6 @@ namespace MWGui
mMap->addVisitedLocation ("#{sCell=" + name + "}", cell->getCell()->getGridX (), cell->getCell()->getGridY ()); mMap->addVisitedLocation ("#{sCell=" + name + "}", cell->getCell()->getGridX (), cell->getCell()->getGridY ());
mMap->cellExplored (cell->getCell()->getGridX(), cell->getCell()->getGridY()); mMap->cellExplored (cell->getCell()->getGridX(), cell->getCell()->getGridY());
mMap->setCellPrefix("Cell");
mHud->setCellPrefix("Cell");
} }
else else
{ {
@ -900,14 +897,20 @@ namespace MWGui
void WindowManager::setActiveMap(int x, int y, bool interior) void WindowManager::setActiveMap(int x, int y, bool interior)
{ {
if (!interior)
{
mMap->setCellPrefix("Cell");
mHud->setCellPrefix("Cell");
}
mMap->setActiveCell(x,y, interior); mMap->setActiveCell(x,y, interior);
mHud->setActiveCell(x,y, interior); mHud->setActiveCell(x,y, interior);
} }
void WindowManager::setPlayerPos(const float x, const float y) void WindowManager::setPlayerPos(int cellX, int cellY, const float x, const float y)
{ {
mMap->setPlayerPos(x,y); mMap->setPlayerPos(cellX, cellY, x, y);
mHud->setPlayerPos(x,y); mHud->setPlayerPos(cellX, cellY, x, y);
} }
void WindowManager::setPlayerDir(const float x, const float y) void WindowManager::setPlayerDir(const float x, const float y)

@ -183,7 +183,7 @@ namespace MWGui
virtual void updateSkillArea(); ///< update display of skills, factions, birth sign, reputation and bounty virtual void updateSkillArea(); ///< update display of skills, factions, birth sign, reputation and bounty
virtual void changeCell(MWWorld::CellStore* cell); ///< change the active cell virtual void changeCell(MWWorld::CellStore* cell); ///< change the active cell
virtual void setPlayerPos(const float x, const float y); ///< set player position in map space virtual void setPlayerPos(int cellX, int cellY, const float x, const float y); ///< set player position in map space
virtual void setPlayerDir(const float x, const float y); ///< set player view direction in map space virtual void setPlayerDir(const float x, const float y); ///< set player view direction in map space
virtual void setFocusObject(const MWWorld::Ptr& focus); virtual void setFocusObject(const MWWorld::Ptr& focus);

@ -25,7 +25,7 @@ using namespace MWRender;
using namespace Ogre; using namespace Ogre;
LocalMap::LocalMap(OEngine::Render::OgreRenderer* rend, MWRender::RenderingManager* rendering) : LocalMap::LocalMap(OEngine::Render::OgreRenderer* rend, MWRender::RenderingManager* rendering) :
mInterior(false), mCellX(0), mCellY(0) mInterior(false)
{ {
mRendering = rend; mRendering = rend;
mRenderingManager = rendering; mRenderingManager = rendering;
@ -522,10 +522,9 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Quaterni
{ {
x = std::ceil(pos.x / sSize)-1; x = std::ceil(pos.x / sSize)-1;
y = std::ceil(pos.y / sSize)-1; y = std::ceil(pos.y / sSize)-1;
mCellX = x;
mCellY = y;
} }
MWBase::Environment::get().getWindowManager()->setActiveMap(x,y,mInterior); else
MWBase::Environment::get().getWindowManager()->setActiveMap(x,y,mInterior);
// convert from world coordinates to texture UV coordinates // convert from world coordinates to texture UV coordinates
std::string texBaseName; std::string texBaseName;
@ -540,7 +539,7 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Quaterni
texBaseName = mInteriorName + "_"; texBaseName = mInteriorName + "_";
} }
MWBase::Environment::get().getWindowManager()->setPlayerPos(u, v); MWBase::Environment::get().getWindowManager()->setPlayerPos(x, y, u, v);
MWBase::Environment::get().getWindowManager()->setPlayerDir(playerdirection.x, playerdirection.y); MWBase::Environment::get().getWindowManager()->setPlayerDir(playerdirection.x, playerdirection.y);
// explore radius (squared) // explore radius (squared)

@ -134,7 +134,6 @@ namespace MWRender
Ogre::RenderTarget* mRenderTarget; Ogre::RenderTarget* mRenderTarget;
bool mInterior; bool mInterior;
int mCellX, mCellY;
Ogre::AxisAlignedBox mBounds; Ogre::AxisAlignedBox mBounds;
std::string mInteriorName; std::string mInteriorName;
}; };

@ -499,7 +499,7 @@ bool RenderingManager::toggleRenderMode(int mode)
} }
} }
void RenderingManager::configureFog(MWWorld::CellStore &mCell) void RenderingManager::configureFog(const MWWorld::CellStore &mCell)
{ {
Ogre::ColourValue color; Ogre::ColourValue color;
color.setAsABGR (mCell.getCell()->mAmbi.mFog); color.setAsABGR (mCell.getCell()->mAmbi.mFog);
@ -510,7 +510,7 @@ void RenderingManager::configureFog(MWWorld::CellStore &mCell)
void RenderingManager::configureFog(const float density, const Ogre::ColourValue& colour) void RenderingManager::configureFog(const float density, const Ogre::ColourValue& colour)
{ {
mFogColour = colour; mFogColour = colour;
float max = Settings::Manager::getFloat("max viewing distance", "Viewing distance"); float max = Settings::Manager::getFloat("viewing distance", "Viewing distance");
if (density == 0) if (density == 0)
{ {
@ -742,7 +742,7 @@ void RenderingManager::processChangedSettings(const Settings::CategorySettingVec
{ {
setMenuTransparency(Settings::Manager::getFloat("menu transparency", "GUI")); setMenuTransparency(Settings::Manager::getFloat("menu transparency", "GUI"));
} }
else if (it->second == "max viewing distance" && it->first == "Viewing distance") else if (it->second == "viewing distance" && it->first == "Viewing distance")
{ {
if (!MWBase::Environment::get().getWorld()->isCellExterior() && !MWBase::Environment::get().getWorld()->isCellQuasiExterior() if (!MWBase::Environment::get().getWorld()->isCellExterior() && !MWBase::Environment::get().getWorld()->isCellQuasiExterior()
&& MWBase::Environment::get().getWorld()->getPlayerPtr().mCell) && MWBase::Environment::get().getWorld()->getPlayerPtr().mCell)

@ -183,7 +183,7 @@ public:
///< request the local map for a cell ///< request the local map for a cell
/// configure fog according to cell /// configure fog according to cell
void configureFog(MWWorld::CellStore &mCell); void configureFog(const MWWorld::CellStore &mCell);
/// configure fog manually /// configure fog manually
void configureFog(const float density, const Ogre::ColourValue& colour); void configureFog(const float density, const Ogre::ColourValue& colour);

@ -5,7 +5,7 @@
#include <components/nif/niffile.hpp> #include <components/nif/niffile.hpp>
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp" /// FIXME #include "../mwbase/world.hpp"
#include "../mwbase/soundmanager.hpp" #include "../mwbase/soundmanager.hpp"
#include "../mwbase/mechanicsmanager.hpp" #include "../mwbase/mechanicsmanager.hpp"
#include "../mwbase/windowmanager.hpp" #include "../mwbase/windowmanager.hpp"
@ -117,6 +117,28 @@ namespace MWWorld
} }
} }
void Scene::getGridCenter(int &cellX, int &cellY)
{
int maxX = std::numeric_limits<int>().min();
int maxY = std::numeric_limits<int>().min();
int minX = std::numeric_limits<int>().max();
int minY = std::numeric_limits<int>().max();
CellStoreCollection::iterator iter = mActiveCells.begin();
while (iter!=mActiveCells.end())
{
assert ((*iter)->getCell()->isExterior());
int x = (*iter)->getCell()->getGridX();
int y = (*iter)->getCell()->getGridY();
maxX = std::max(x, maxX);
maxY = std::max(y, maxY);
minX = std::min(x, minX);
minY = std::min(y, minY);
++iter;
}
cellX = (minX + maxX) / 2;
cellY = (minY + maxY) / 2;
}
void Scene::update (float duration, bool paused) void Scene::update (float duration, bool paused)
{ {
if (mNeedMapUpdate) if (mNeedMapUpdate)
@ -126,6 +148,13 @@ namespace MWWorld
for (CellStoreCollection::iterator active = mActiveCells.begin(); active!=mActiveCells.end(); ++active) for (CellStoreCollection::iterator active = mActiveCells.begin(); active!=mActiveCells.end(); ++active)
mRendering.requestMap(*active); mRendering.requestMap(*active);
mNeedMapUpdate = false; mNeedMapUpdate = false;
if (mCurrentCell->isExterior())
{
int cellX, cellY;
getGridCenter(cellX, cellY);
MWBase::Environment::get().getWindowManager()->setActiveMap(cellX,cellY,false);
}
} }
mRendering.update (duration, paused); mRendering.update (duration, paused);
@ -213,41 +242,6 @@ namespace MWWorld
MWBase::Environment::get().getWorld()->getLocalScripts().addCell (cell); MWBase::Environment::get().getWorld()->getLocalScripts().addCell (cell);
} }
void Scene::playerCellChange(CellStore *cell, const ESM::Position& pos, bool adjustPlayerPos)
{
MWBase::World *world = MWBase::Environment::get().getWorld();
MWWorld::Ptr old = world->getPlayerPtr();
world->getPlayer().setCell(cell);
MWWorld::Ptr player = world->getPlayerPtr();
mRendering.updatePlayerPtr(player);
if (adjustPlayerPos) {
world->moveObject(player, pos.pos[0], pos.pos[1], pos.pos[2]);
float x = Ogre::Radian(pos.rot[0]).valueDegrees();
float y = Ogre::Radian(pos.rot[1]).valueDegrees();
float z = Ogre::Radian(pos.rot[2]).valueDegrees();
world->rotateObject(player, x, y, z);
player.getClass().adjustPosition(player, true);
}
MWBase::MechanicsManager *mechMgr =
MWBase::Environment::get().getMechanicsManager();
mechMgr->updateCell(old, player);
mechMgr->watchActor(player);
mRendering.updateTerrain();
// Delay the map update until scripts have been given a chance to run.
// If we don't do this, objects that should be disabled will still appear on the map.
mNeedMapUpdate = true;
MWBase::Environment::get().getWindowManager()->changeCell(mCurrentCell);
}
void Scene::changeToVoid() void Scene::changeToVoid()
{ {
CellStoreCollection::iterator active = mActiveCells.begin(); CellStoreCollection::iterator active = mActiveCells.begin();
@ -257,7 +251,28 @@ namespace MWWorld
mCurrentCell = NULL; mCurrentCell = NULL;
} }
void Scene::changeCell (int X, int Y, const ESM::Position& position, bool adjustPlayerPos) void Scene::playerMoved(const Ogre::Vector3 &pos)
{
if (!mCurrentCell || !mCurrentCell->isExterior())
return;
// figure out the center of the current cell grid (*not* necessarily mCurrentCell, which is the cell the player is in)
int cellX, cellY;
getGridCenter(cellX, cellY);
float centerX, centerY;
MWBase::Environment::get().getWorld()->indexToPosition(cellX, cellY, centerX, centerY, true);
const float maxDistance = 8192/2 + 1024; // 1/2 cell size + threshold
float distance = std::max(std::abs(centerX-pos.x), std::abs(centerY-pos.y));
if (distance > maxDistance)
{
int newX, newY;
MWBase::Environment::get().getWorld()->positionToIndex(pos.x, pos.y, newX, newY);
changeCellGrid(newX, newY);
mRendering.updateTerrain();
}
}
void Scene::changeCellGrid (int X, int Y)
{ {
Loading::Listener* loadingListener = MWBase::Environment::get().getWindowManager()->getLoadingScreen(); Loading::Listener* loadingListener = MWBase::Environment::get().getWindowManager()->getLoadingScreen();
Loading::ScopedLoad load(loadingListener); Loading::ScopedLoad load(loadingListener);
@ -286,6 +301,7 @@ namespace MWWorld
int refsToLoad = 0; int refsToLoad = 0;
// get the number of refs to load // get the number of refs to load
for (int x=X-1; x<=X+1; ++x) for (int x=X-1; x<=X+1; ++x)
{
for (int y=Y-1; y<=Y+1; ++y) for (int y=Y-1; y<=Y+1; ++y)
{ {
CellStoreCollection::iterator iter = mActiveCells.begin(); CellStoreCollection::iterator iter = mActiveCells.begin();
@ -304,11 +320,13 @@ namespace MWWorld
if (iter==mActiveCells.end()) if (iter==mActiveCells.end())
refsToLoad += MWBase::Environment::get().getWorld()->getExterior(x, y)->count(); refsToLoad += MWBase::Environment::get().getWorld()->getExterior(x, y)->count();
} }
}
loadingListener->setProgressRange(refsToLoad); loadingListener->setProgressRange(refsToLoad);
// Load cells // Load cells
for (int x=X-1; x<=X+1; ++x) for (int x=X-1; x<=X+1; ++x)
{
for (int y=Y-1; y<=Y+1; ++y) for (int y=Y-1; y<=Y+1; ++y)
{ {
CellStoreCollection::iterator iter = mActiveCells.begin(); CellStoreCollection::iterator iter = mActiveCells.begin();
@ -331,32 +349,47 @@ namespace MWWorld
loadCell (cell, loadingListener); loadCell (cell, loadingListener);
} }
} }
}
// find current cell CellStore* current = MWBase::Environment::get().getWorld()->getExterior(X,Y);
CellStoreCollection::iterator iter = mActiveCells.begin(); MWBase::Environment::get().getWindowManager()->changeCell(current);
while (iter!=mActiveCells.end()) mCellChanged = true;
{
assert ((*iter)->getCell()->isExterior());
if (X==(*iter)->getCell()->getGridX() && // Delay the map update until scripts have been given a chance to run.
Y==(*iter)->getCell()->getGridY()) // If we don't do this, objects that should be disabled will still appear on the map.
break; mNeedMapUpdate = true;
}
++iter; void Scene::changePlayerCell(CellStore *cell, const ESM::Position &pos, bool adjustPlayerPos)
} {
mCurrentCell = cell;
assert (iter!=mActiveCells.end()); MWBase::World *world = MWBase::Environment::get().getWorld();
MWWorld::Ptr old = world->getPlayerPtr();
world->getPlayer().setCell(cell);
mCurrentCell = *iter; MWWorld::Ptr player = world->getPlayerPtr();
mRendering.updatePlayerPtr(player);
// adjust player if (adjustPlayerPos) {
playerCellChange (mCurrentCell, position, adjustPlayerPos); world->moveObject(player, pos.pos[0], pos.pos[1], pos.pos[2]);
// Sky system float x = Ogre::Radian(pos.rot[0]).valueDegrees();
MWBase::Environment::get().getWorld()->adjustSky(); float y = Ogre::Radian(pos.rot[1]).valueDegrees();
float z = Ogre::Radian(pos.rot[2]).valueDegrees();
world->rotateObject(player, x, y, z);
mCellChanged = true; player.getClass().adjustPosition(player, true);
}
MWBase::MechanicsManager *mechMgr =
MWBase::Environment::get().getMechanicsManager();
mechMgr->updateCell(old, player);
mechMgr->watchActor(player);
MWBase::Environment::get().getWorld()->adjustSky();
} }
//We need the ogre renderer and a scene node. //We need the ogre renderer and a scene node.
@ -427,33 +460,39 @@ namespace MWWorld
// Load cell. // Load cell.
std::cout << "cellName: " << cell->getCell()->mName << std::endl; std::cout << "cellName: " << cell->getCell()->mName << std::endl;
//Loading Interior loading text
loadCell (cell, loadingListener); loadCell (cell, loadingListener);
mCurrentCell = cell; changePlayerCell(cell, position, true);
// adjust fog // adjust fog
mRendering.configureFog(*mCurrentCell); mRendering.configureFog(*mCurrentCell);
// adjust player
playerCellChange (mCurrentCell, position);
// Sky system // Sky system
MWBase::Environment::get().getWorld()->adjustSky(); MWBase::Environment::get().getWorld()->adjustSky();
mCellChanged = true; mCellChanged = true;
MWBase::Environment::get().getWindowManager()->fadeScreenIn(0.5); MWBase::Environment::get().getWindowManager()->fadeScreenIn(0.5);
MWBase::Environment::get().getWindowManager()->changeCell(mCurrentCell);
// Delay the map update until scripts have been given a chance to run.
// If we don't do this, objects that should be disabled will still appear on the map.
mNeedMapUpdate = true;
} }
void Scene::changeToExteriorCell (const ESM::Position& position) void Scene::changeToExteriorCell (const ESM::Position& position, bool adjustPlayerPos)
{ {
int x = 0; int x = 0;
int y = 0; int y = 0;
MWBase::Environment::get().getWorld()->positionToIndex (position.pos[0], position.pos[1], x, y); MWBase::Environment::get().getWorld()->positionToIndex (position.pos[0], position.pos[1], x, y);
changeCell (x, y, position, true); changeCellGrid(x, y);
CellStore* current = MWBase::Environment::get().getWorld()->getExterior(x, y);
changePlayerCell(current, position, adjustPlayerPos);
mRendering.updateTerrain();
} }
CellStore* Scene::getCurrentCell () CellStore* Scene::getCurrentCell ()

@ -60,11 +60,13 @@ namespace MWWorld
bool mNeedMapUpdate; bool mNeedMapUpdate;
void playerCellChange (CellStore *cell, const ESM::Position& position,
bool adjustPlayerPos = true);
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
void changeCellGrid (int X, int Y);
void getGridCenter(int& cellX, int& cellY);
public: public:
Scene (MWRender::RenderingManager& rendering, PhysicsSystem *physics); Scene (MWRender::RenderingManager& rendering, PhysicsSystem *physics);
@ -75,19 +77,21 @@ namespace MWWorld
void loadCell (CellStore *cell, Loading::Listener* loadingListener); void loadCell (CellStore *cell, Loading::Listener* loadingListener);
void changeCell (int X, int Y, const ESM::Position& position, bool adjustPlayerPos); void playerMoved (const Ogre::Vector3& pos);
void changePlayerCell (CellStore* newCell, const ESM::Position& position, bool adjustPlayerPos);
CellStore* getCurrentCell (); CellStore *getCurrentCell();
const CellStoreCollection& getActiveCells () const; const CellStoreCollection& getActiveCells () const;
bool hasCellChanged() const; bool hasCellChanged() const;
///< Has the player moved to a different cell, since the last frame? ///< Has the set of active cells changed, since the last frame?
void changeToInteriorCell (const std::string& cellName, const ESM::Position& position); void changeToInteriorCell (const std::string& cellName, const ESM::Position& position);
///< Move to interior cell. ///< Move to interior cell.
void changeToExteriorCell (const ESM::Position& position); void changeToExteriorCell (const ESM::Position& position, bool adjustPlayerPos);
///< Move to exterior cell. ///< Move to exterior cell.
void changeToVoid(); void changeToVoid();

@ -241,7 +241,7 @@ namespace MWWorld
pos.rot[0] = 0; pos.rot[0] = 0;
pos.rot[1] = 0; pos.rot[1] = 0;
pos.rot[2] = 0; pos.rot[2] = 0;
mWorldScene->changeToExteriorCell(pos); mWorldScene->changeToExteriorCell(pos, true);
} }
} }
@ -920,7 +920,7 @@ namespace MWWorld
mRendering->notifyWorldSpaceChanged(); mRendering->notifyWorldSpaceChanged();
} }
removeContainerScripts(getPlayerPtr()); removeContainerScripts(getPlayerPtr());
mWorldScene->changeToExteriorCell(position); mWorldScene->changeToExteriorCell(position, true);
addContainerScripts(getPlayerPtr(), getPlayerPtr().getCell()); addContainerScripts(getPlayerPtr(), getPlayerPtr().getCell());
} }
@ -1057,9 +1057,10 @@ namespace MWWorld
changeToInteriorCell(Misc::StringUtils::lowerCase(newCell->getCell()->mName), pos); changeToInteriorCell(Misc::StringUtils::lowerCase(newCell->getCell()->mName), pos);
else else
{ {
int cellX = newCell->getCell()->getGridX(); if (mWorldScene->isCellActive(*newCell))
int cellY = newCell->getCell()->getGridY(); mWorldScene->changePlayerCell(newCell, pos, false);
mWorldScene->changeCell(cellX, cellY, pos, false); else
mWorldScene->changeToExteriorCell(pos, false);
} }
addContainerScripts (getPlayerPtr(), newCell); addContainerScripts (getPlayerPtr(), newCell);
} }
@ -1120,6 +1121,10 @@ namespace MWWorld
mRendering->moveObject(ptr, vec); mRendering->moveObject(ptr, vec);
mPhysics->moveObject (ptr); mPhysics->moveObject (ptr);
} }
if (isPlayer)
{
mWorldScene->playerMoved (vec);
}
} }
bool World::moveObjectImp(const Ptr& ptr, float x, float y, float z) bool World::moveObjectImp(const Ptr& ptr, float x, float y, float z)
@ -1565,7 +1570,7 @@ namespace MWWorld
bool World::isCellExterior() const bool World::isCellExterior() const
{ {
CellStore *currentCell = mWorldScene->getCurrentCell(); const CellStore *currentCell = mWorldScene->getCurrentCell();
if (currentCell) if (currentCell)
{ {
return currentCell->getCell()->isExterior(); return currentCell->getCell()->isExterior();
@ -1575,7 +1580,7 @@ namespace MWWorld
bool World::isCellQuasiExterior() const bool World::isCellQuasiExterior() const
{ {
CellStore *currentCell = mWorldScene->getCurrentCell(); const CellStore *currentCell = mWorldScene->getCurrentCell();
if (currentCell) if (currentCell)
{ {
if (!(currentCell->getCell()->mData.mFlags & ESM::Cell::QuasiEx)) if (!(currentCell->getCell()->mData.mFlags & ESM::Cell::QuasiEx))

@ -198,7 +198,7 @@ namespace MWWorld
virtual LocalScripts& getLocalScripts(); virtual LocalScripts& getLocalScripts();
virtual bool hasCellChanged() const; virtual bool hasCellChanged() const;
///< Has the player moved to a different cell, since the last frame? ///< Has the set of active cells changed, since the last frame?
virtual bool isCellExterior() const; virtual bool isCellExterior() const;

@ -2,8 +2,7 @@
<MyGUI type="Layout"> <MyGUI type="Layout">
<Widget type="Window" skin="MW_Window" position="0 0 400 400" layer="Console" name="_Main"> <Widget type="Window" skin="MW_Window" position="0 0 400 400" layer="Console" name="_Main">
<Property key="Caption" value="#{sConsoleTitle}"/> <Property key="Caption" value="#{sConsoleTitle}"/>
<Property key="MinSize" value="400 245"/> <Property key="MinSize" value="40 40"/>
<Property key="MaxSize" value="2000 2000"/>
<Property key="Visible" value="false"/> <Property key="Visible" value="false"/>
<!-- Log window --> <!-- Log window -->

@ -346,10 +346,10 @@
<Property key="Page" value="300"/> <Property key="Page" value="300"/>
<UserString key="SettingType" value="Slider"/> <UserString key="SettingType" value="Slider"/>
<UserString key="SettingCategory" value="Viewing distance"/> <UserString key="SettingCategory" value="Viewing distance"/>
<UserString key="SettingName" value="max viewing distance"/> <UserString key="SettingName" value="viewing distance"/>
<UserString key="SettingValueType" value="Float"/> <UserString key="SettingValueType" value="Float"/>
<UserString key="SettingMin" value="2000"/> <UserString key="SettingMin" value="2000"/>
<UserString key="SettingMax" value="5600"/> <UserString key="SettingMax" value="4600"/>
</Widget> </Widget>
<Widget type="TextBox" skin="SandText" position="4 178 332 18" align="Left Top"> <Widget type="TextBox" skin="SandText" position="4 178 332 18" align="Left Top">
<Property key="Caption" value="#{sNear}"/> <Property key="Caption" value="#{sNear}"/>

@ -122,8 +122,12 @@ small object size = 250
# Rendering distance for small objects # Rendering distance for small objects
small object distance = 3500 small object distance = 3500
# Max viewing distance at clear weather conditions # Viewing distance at normal weather conditions
max viewing distance = 5600 # The maximum distance with no pop-in will be: (see RenderingManager::configureFog)
# viewing distance / minimum weather fog depth (.69) * view frustum factor <= cell size (8192) - loading threshold (1024)
# view frustum factor takes into account that the view frustum end is a plane, so at the edges of the screen you can see further than you should be able to.
# exact factor would depend on FOV
viewing distance = 4600
# Distance at which fog starts (proportional to viewing distance) # Distance at which fog starts (proportional to viewing distance)
fog start factor = 0.5 fog start factor = 0.5

Loading…
Cancel
Save