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;
///< 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
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 correctTexturePath(const std::string& path) = 0;
virtual void requestMap(std::set<MWWorld::CellStore*> cells) = 0;
virtual void removeCell(MWWorld::CellStore* cell) = 0;
virtual void writeFog(MWWorld::CellStore* cell) = 0;
};

@ -454,6 +454,26 @@ namespace MWGui
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()
{
// Redraw children in proper order

@ -23,6 +23,11 @@ namespace ESM
class ESMWriter;
}
namespace MWWorld
{
class CellStore;
}
namespace Loading
{
class Listener;
@ -67,6 +72,7 @@ namespace MWGui
void setCellPrefix(const std::string& prefix);
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 setPlayerPos(int cellX, int cellY, const float nx, const float ny);

@ -926,7 +926,7 @@ namespace MWGui
if (!mLocalMapRender)
return;
MWWorld::Ptr player = MWMechanics::getPlayer();
MWWorld::ConstPtr player = MWMechanics::getPlayer();
osg::Vec3f playerPosition = player.getRefData().getPosition().asVec3();
osg::Quat playerOrientation (-player.getRefData().getPosition().rot[2], osg::Vec3(0,0,1));
@ -938,10 +938,9 @@ namespace MWGui
if (!player.getCell()->isExterior())
{
mMap->setActiveCell(x, y, true);
mHud->setActiveCell(x, y, true);
setActiveMap(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->setPlayerPos(x, y, u, v);
@ -1007,8 +1006,10 @@ namespace MWGui
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);
mMap->setCellName( name );
@ -1020,6 +1021,8 @@ namespace MWGui
mMap->addVisitedLocation (name, cell->getCell()->getGridX (), cell->getCell()->getGridY ());
mMap->cellExplored (cell->getCell()->getGridX(), cell->getCell()->getGridY());
setActiveMap(cell->getCell()->getGridX(), cell->getCell()->getGridY(), false);
}
else
{
@ -1032,6 +1035,8 @@ namespace MWGui
else
MWBase::Environment::get().getWorld()->getPlayer().setLastKnownExteriorPosition(worldPos);
mMap->setGlobalMapPlayerPosition(worldPos.x(), worldPos.y());
setActiveMap(0, 0, true);
}
}
@ -2078,11 +2083,6 @@ namespace MWGui
tex->unlock();
}
void WindowManager::requestMap(std::set<MWWorld::CellStore*> cells)
{
mLocalMapRender->requestMap(cells);
}
void WindowManager::removeCell(MWWorld::CellStore *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 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 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 correctTexturePath(const std::string& path);
void requestMap(std::set<MWWorld::CellStore*> cells);
void removeCell(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;
}
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())
requestExteriorMap(cell);
else
@ -296,7 +296,7 @@ void LocalMap::cleanupCameras()
mCamerasPendingRemoval.clear();
}
void LocalMap::requestExteriorMap(MWWorld::CellStore* cell)
void LocalMap::requestExteriorMap(const MWWorld::CellStore* cell)
{
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;
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
// be covered by the map anymore.
// The following code detects this, and discards the CellStore's fog state if it needs to.
bool cellHasValidFog = false;
if (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))
{
// Nuke it
cell->setFog(NULL);
cellHasValidFog = false;
}
else
{
// Looks sane, use it
mBounds = osg::BoundingBox(newMin, newMax);
mAngle = fog->mNorthMarkerAngle;
cellHasValidFog = true;
}
}
@ -434,7 +436,7 @@ void LocalMap::requestInteriorMap(MWWorld::CellStore* cell)
MapSegment& segment = mSegments[std::make_pair(x,y)];
if (!segment.mFogOfWarImage)
{
if (!cell->getFog())
if (!cellHasValidFog)
segment.initFogOfWar();
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.
*/
void requestMap (std::set<MWWorld::CellStore*> cells);
void requestMap (std::set<const MWWorld::CellStore*> cells);
/**
* Remove map and fog textures for the given cell.
@ -146,8 +146,8 @@ namespace MWRender
float mAngle;
const osg::Vec2f rotatePoint(const osg::Vec2f& point, const osg::Vec2f& center, const float angle);
void requestExteriorMap(MWWorld::CellStore* cell);
void requestInteriorMap(MWWorld::CellStore* cell);
void requestExteriorMap(const 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);
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)
{
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);
}
@ -410,10 +389,6 @@ namespace MWWorld
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();
}
@ -449,7 +424,7 @@ namespace MWWorld
}
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);
// 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();
}

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

Loading…
Cancel
Save