Refactor local map updates

We don't need the delay any more because the rendering itself is part of the normal rendering traversal - so it's delayed anyway.

Don't request maps that we're not actually using (i.e. with cell grid sizes higher than the default 3, we were rendering more maps than the map window could show).
coverity_scan
scrawl 9 years ago
parent 300379617e
commit bd655c20fd

@ -176,7 +176,7 @@ namespace MWBase
virtual void updateSkillArea() = 0; virtual void updateSkillArea() = 0;
///< update display of skills, factions, birth sign, reputation and bounty ///< update display of skills, factions, birth sign, reputation and bounty
virtual void changeCell(MWWorld::CellStore* cell) = 0; virtual void changeCell(const MWWorld::CellStore* cell) = 0;
///< change the active cell ///< change the active cell
virtual void setFocusObject(const MWWorld::Ptr& focus) = 0; virtual void setFocusObject(const MWWorld::Ptr& focus) = 0;
@ -354,7 +354,6 @@ namespace MWBase
virtual std::string correctBookartPath(const std::string& path, int width, int height) = 0; virtual std::string correctBookartPath(const std::string& path, int width, int height) = 0;
virtual std::string correctTexturePath(const std::string& path) = 0; virtual std::string correctTexturePath(const std::string& path) = 0;
virtual void requestMap(std::set<MWWorld::CellStore*> cells) = 0;
virtual void removeCell(MWWorld::CellStore* cell) = 0; virtual void removeCell(MWWorld::CellStore* cell) = 0;
virtual void writeFog(MWWorld::CellStore* cell) = 0; virtual void writeFog(MWWorld::CellStore* cell) = 0;
}; };

@ -454,6 +454,26 @@ namespace MWGui
updateCustomMarkers(); updateCustomMarkers();
} }
void LocalMapBase::requestMapRender(const MWWorld::CellStore *cell)
{
std::set<const MWWorld::CellStore*> cells;
if (!cell->isExterior())
cells.insert(cell);
else
{
for (int dX=-1; dX<2; ++dX)
{
for (int dY=-1; dY<2; ++dY)
{
const MWWorld::CellStore* gridCell = MWBase::Environment::get().getWorld()->getExterior (cell->getCell()->getGridX()+dX, cell->getCell()->getGridY()+dY);
cells.insert(gridCell);
}
}
}
mLocalMapRender->requestMap(cells);
}
void LocalMapBase::redraw() void LocalMapBase::redraw()
{ {
// Redraw children in proper order // Redraw children in proper order

@ -23,6 +23,11 @@ namespace ESM
class ESMWriter; class ESMWriter;
} }
namespace MWWorld
{
class CellStore;
}
namespace Loading namespace Loading
{ {
class Listener; class Listener;
@ -67,6 +72,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 requestMapRender(const MWWorld::CellStore* cell);
void setPlayerDir(const float x, const float y); void setPlayerDir(const float x, const float y);
void setPlayerPos(int cellX, int cellY, const float nx, const float ny); void setPlayerPos(int cellX, int cellY, const float nx, const float ny);

@ -926,7 +926,7 @@ namespace MWGui
if (!mLocalMapRender) if (!mLocalMapRender)
return; return;
MWWorld::Ptr player = MWMechanics::getPlayer(); MWWorld::ConstPtr player = MWMechanics::getPlayer();
osg::Vec3f playerPosition = player.getRefData().getPosition().asVec3(); osg::Vec3f playerPosition = player.getRefData().getPosition().asVec3();
osg::Quat playerOrientation (-player.getRefData().getPosition().rot[2], osg::Vec3(0,0,1)); osg::Quat playerOrientation (-player.getRefData().getPosition().rot[2], osg::Vec3(0,0,1));
@ -938,10 +938,9 @@ namespace MWGui
if (!player.getCell()->isExterior()) if (!player.getCell()->isExterior())
{ {
mMap->setActiveCell(x, y, true); setActiveMap(x, y, true);
mHud->setActiveCell(x, y, true);
} }
// else: need to know the current grid center, call setActiveCell from MWWorld::Scene // else: need to know the current grid center, call setActiveMap from changeCell
mMap->setPlayerDir(playerdirection.x(), playerdirection.y()); mMap->setPlayerDir(playerdirection.x(), playerdirection.y());
mMap->setPlayerPos(x, y, u, v); mMap->setPlayerPos(x, y, u, v);
@ -1007,8 +1006,10 @@ namespace MWGui
mDebugWindow->onFrame(frameDuration); mDebugWindow->onFrame(frameDuration);
} }
void WindowManager::changeCell(MWWorld::CellStore* cell) void WindowManager::changeCell(const MWWorld::CellStore* cell)
{ {
mMap->requestMapRender(cell);
std::string name = MWBase::Environment::get().getWorld()->getCellName (cell); std::string name = MWBase::Environment::get().getWorld()->getCellName (cell);
mMap->setCellName( name ); mMap->setCellName( name );
@ -1020,6 +1021,8 @@ namespace MWGui
mMap->addVisitedLocation (name, cell->getCell()->getGridX (), cell->getCell()->getGridY ()); mMap->addVisitedLocation (name, cell->getCell()->getGridX (), cell->getCell()->getGridY ());
mMap->cellExplored (cell->getCell()->getGridX(), cell->getCell()->getGridY()); mMap->cellExplored (cell->getCell()->getGridX(), cell->getCell()->getGridY());
setActiveMap(cell->getCell()->getGridX(), cell->getCell()->getGridY(), false);
} }
else else
{ {
@ -1032,6 +1035,8 @@ namespace MWGui
else else
MWBase::Environment::get().getWorld()->getPlayer().setLastKnownExteriorPosition(worldPos); MWBase::Environment::get().getWorld()->getPlayer().setLastKnownExteriorPosition(worldPos);
mMap->setGlobalMapPlayerPosition(worldPos.x(), worldPos.y()); mMap->setGlobalMapPlayerPosition(worldPos.x(), worldPos.y());
setActiveMap(0, 0, true);
} }
} }
@ -2078,11 +2083,6 @@ namespace MWGui
tex->unlock(); tex->unlock();
} }
void WindowManager::requestMap(std::set<MWWorld::CellStore*> cells)
{
mLocalMapRender->requestMap(cells);
}
void WindowManager::removeCell(MWWorld::CellStore *cell) void WindowManager::removeCell(MWWorld::CellStore *cell)
{ {
mLocalMapRender->removeCell(cell); mLocalMapRender->removeCell(cell);

@ -204,7 +204,7 @@ namespace MWGui
virtual void configureSkills (const SkillList& major, const SkillList& minor); ///< configure skill groups, each set contains the skill ID for that group. virtual void configureSkills (const SkillList& major, const SkillList& minor); ///< configure skill groups, each set contains the skill ID for that group.
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(const MWWorld::CellStore* cell); ///< change the active cell
virtual void setFocusObject(const MWWorld::Ptr& focus); virtual void setFocusObject(const MWWorld::Ptr& focus);
virtual void setFocusObjectScreenCoords(float min_x, float min_y, float max_x, float max_y); virtual void setFocusObjectScreenCoords(float min_x, float min_y, float max_x, float max_y);
@ -375,7 +375,6 @@ namespace MWGui
virtual std::string correctBookartPath(const std::string& path, int width, int height); virtual std::string correctBookartPath(const std::string& path, int width, int height);
virtual std::string correctTexturePath(const std::string& path); virtual std::string correctTexturePath(const std::string& path);
void requestMap(std::set<MWWorld::CellStore*> cells);
void removeCell(MWWorld::CellStore* cell); void removeCell(MWWorld::CellStore* cell);
void writeFog(MWWorld::CellStore* cell); void writeFog(MWWorld::CellStore* cell);

@ -229,11 +229,11 @@ void LocalMap::setupRenderToTexture(osg::ref_ptr<osg::Camera> camera, int x, int
segment.mMapTexture = texture; segment.mMapTexture = texture;
} }
void LocalMap::requestMap(std::set<MWWorld::CellStore*> cells) void LocalMap::requestMap(std::set<const MWWorld::CellStore*> cells)
{ {
for (std::set<MWWorld::CellStore*>::iterator it = cells.begin(); it != cells.end(); ++it) for (std::set<const MWWorld::CellStore*>::iterator it = cells.begin(); it != cells.end(); ++it)
{ {
MWWorld::CellStore* cell = *it; const MWWorld::CellStore* cell = *it;
if (cell->isExterior()) if (cell->isExterior())
requestExteriorMap(cell); requestExteriorMap(cell);
else else
@ -296,7 +296,7 @@ void LocalMap::cleanupCameras()
mCamerasPendingRemoval.clear(); mCamerasPendingRemoval.clear();
} }
void LocalMap::requestExteriorMap(MWWorld::CellStore* cell) void LocalMap::requestExteriorMap(const MWWorld::CellStore* cell)
{ {
mInterior = false; mInterior = false;
@ -321,7 +321,7 @@ void LocalMap::requestExteriorMap(MWWorld::CellStore* cell)
} }
} }
void LocalMap::requestInteriorMap(MWWorld::CellStore* cell) void LocalMap::requestInteriorMap(const MWWorld::CellStore* cell)
{ {
osg::ComputeBoundsVisitor computeBoundsVisitor; osg::ComputeBoundsVisitor computeBoundsVisitor;
computeBoundsVisitor.setTraversalMask(Mask_Scene|Mask_Terrain); computeBoundsVisitor.setTraversalMask(Mask_Scene|Mask_Terrain);
@ -375,6 +375,7 @@ void LocalMap::requestInteriorMap(MWWorld::CellStore* cell)
// If they changed by too much (for bounds, < padding is considered acceptable) then parts of the interior might not // If they changed by too much (for bounds, < padding is considered acceptable) then parts of the interior might not
// be covered by the map anymore. // be covered by the map anymore.
// The following code detects this, and discards the CellStore's fog state if it needs to. // The following code detects this, and discards the CellStore's fog state if it needs to.
bool cellHasValidFog = false;
if (cell->getFog()) if (cell->getFog())
{ {
ESM::FogState* fog = cell->getFog(); ESM::FogState* fog = cell->getFog();
@ -390,13 +391,14 @@ void LocalMap::requestInteriorMap(MWWorld::CellStore* cell)
|| std::abs(mAngle - fog->mNorthMarkerAngle) > osg::DegreesToRadians(5.f)) || std::abs(mAngle - fog->mNorthMarkerAngle) > osg::DegreesToRadians(5.f))
{ {
// Nuke it // Nuke it
cell->setFog(NULL); cellHasValidFog = false;
} }
else else
{ {
// Looks sane, use it // Looks sane, use it
mBounds = osg::BoundingBox(newMin, newMax); mBounds = osg::BoundingBox(newMin, newMax);
mAngle = fog->mNorthMarkerAngle; mAngle = fog->mNorthMarkerAngle;
cellHasValidFog = true;
} }
} }
@ -434,7 +436,7 @@ void LocalMap::requestInteriorMap(MWWorld::CellStore* cell)
MapSegment& segment = mSegments[std::make_pair(x,y)]; MapSegment& segment = mSegments[std::make_pair(x,y)];
if (!segment.mFogOfWarImage) if (!segment.mFogOfWarImage)
{ {
if (!cell->getFog()) if (!cellHasValidFog)
segment.initFogOfWar(); segment.initFogOfWar();
else else
{ {

@ -52,7 +52,7 @@ namespace MWRender
/** /**
* Request a map render for the given cells. Render textures will be immediately created and can be retrieved with the getMapTexture function. * Request a map render for the given cells. Render textures will be immediately created and can be retrieved with the getMapTexture function.
*/ */
void requestMap (std::set<MWWorld::CellStore*> cells); void requestMap (std::set<const MWWorld::CellStore*> cells);
/** /**
* Remove map and fog textures for the given cell. * Remove map and fog textures for the given cell.
@ -146,8 +146,8 @@ namespace MWRender
float mAngle; float mAngle;
const osg::Vec2f rotatePoint(const osg::Vec2f& point, const osg::Vec2f& center, const float angle); const osg::Vec2f rotatePoint(const osg::Vec2f& point, const osg::Vec2f& center, const float angle);
void requestExteriorMap(MWWorld::CellStore* cell); void requestExteriorMap(const MWWorld::CellStore* cell);
void requestInteriorMap(MWWorld::CellStore* cell); void requestInteriorMap(const MWWorld::CellStore* cell);
osg::ref_ptr<osg::Camera> createOrthographicCamera(float left, float top, float width, float height, const osg::Vec3d& upVector, float zmin, float zmax); osg::ref_ptr<osg::Camera> createOrthographicCamera(float left, float top, float width, float height, const osg::Vec3d& upVector, float zmin, float zmax);
void setupRenderToTexture(osg::ref_ptr<osg::Camera> camera, int x, int y); void setupRenderToTexture(osg::ref_ptr<osg::Camera> camera, int x, int y);

@ -179,27 +179,6 @@ namespace MWWorld
void Scene::update (float duration, bool paused) void Scene::update (float duration, bool paused)
{ {
if (mNeedMapUpdate)
{
// Note: exterior cell maps must be updated, even if they were visited before, because the set of surrounding cells might be different
// (and objects in a different cell can "bleed" into another cells map if they cross the border)
std::set<MWWorld::CellStore*> cellsToUpdate;
for (CellStoreCollection::iterator active = mActiveCells.begin(); active!=mActiveCells.end(); ++active)
{
cellsToUpdate.insert(*active);
}
MWBase::Environment::get().getWindowManager()->requestMap(cellsToUpdate);
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);
} }
@ -410,10 +389,6 @@ namespace MWWorld
mCellChanged = true; mCellChanged = true;
// 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;
mRendering.getResourceSystem()->clearCache(); mRendering.getResourceSystem()->clearCache();
} }
@ -449,7 +424,7 @@ namespace MWWorld
} }
Scene::Scene (MWRender::RenderingManager& rendering, MWPhysics::PhysicsSystem *physics) Scene::Scene (MWRender::RenderingManager& rendering, MWPhysics::PhysicsSystem *physics)
: mCurrentCell (0), mCellChanged (false), mPhysics(physics), mRendering(rendering), mNeedMapUpdate(false) : mCurrentCell (0), mCellChanged (false), mPhysics(physics), mRendering(rendering)
{ {
} }
@ -527,10 +502,6 @@ namespace MWWorld
MWBase::Environment::get().getWindowManager()->changeCell(mCurrentCell); 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;
mRendering.getResourceSystem()->clearCache(); mRendering.getResourceSystem()->clearCache();
} }

@ -58,8 +58,6 @@ namespace MWWorld
MWPhysics::PhysicsSystem *mPhysics; MWPhysics::PhysicsSystem *mPhysics;
MWRender::RenderingManager& mRendering; MWRender::RenderingManager& mRendering;
bool mNeedMapUpdate;
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

Loading…
Cancel
Save