diff --git a/apps/openmw/mwbase/windowmanager.hpp b/apps/openmw/mwbase/windowmanager.hpp index f364ada7a..2d4c0e2ca 100644 --- a/apps/openmw/mwbase/windowmanager.hpp +++ b/apps/openmw/mwbase/windowmanager.hpp @@ -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 cells) = 0; virtual void removeCell(MWWorld::CellStore* cell) = 0; virtual void writeFog(MWWorld::CellStore* cell) = 0; }; diff --git a/apps/openmw/mwgui/mapwindow.cpp b/apps/openmw/mwgui/mapwindow.cpp index 89f4d8cf3..469564d9d 100644 --- a/apps/openmw/mwgui/mapwindow.cpp +++ b/apps/openmw/mwgui/mapwindow.cpp @@ -454,6 +454,26 @@ namespace MWGui updateCustomMarkers(); } + void LocalMapBase::requestMapRender(const MWWorld::CellStore *cell) + { + std::set 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 diff --git a/apps/openmw/mwgui/mapwindow.hpp b/apps/openmw/mwgui/mapwindow.hpp index 227a9e3f9..96fd3c994 100644 --- a/apps/openmw/mwgui/mapwindow.hpp +++ b/apps/openmw/mwgui/mapwindow.hpp @@ -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); diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index f151bee80..90c0494f6 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -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 cells) - { - mLocalMapRender->requestMap(cells); - } - void WindowManager::removeCell(MWWorld::CellStore *cell) { mLocalMapRender->removeCell(cell); diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index 6edb4660c..3cdba8a87 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -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 cells); void removeCell(MWWorld::CellStore* cell); void writeFog(MWWorld::CellStore* cell); diff --git a/apps/openmw/mwrender/localmap.cpp b/apps/openmw/mwrender/localmap.cpp index 200f484b5..4efcf5d1b 100644 --- a/apps/openmw/mwrender/localmap.cpp +++ b/apps/openmw/mwrender/localmap.cpp @@ -229,11 +229,11 @@ void LocalMap::setupRenderToTexture(osg::ref_ptr camera, int x, int segment.mMapTexture = texture; } -void LocalMap::requestMap(std::set cells) +void LocalMap::requestMap(std::set cells) { - for (std::set::iterator it = cells.begin(); it != cells.end(); ++it) + for (std::set::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 { diff --git a/apps/openmw/mwrender/localmap.hpp b/apps/openmw/mwrender/localmap.hpp index 59165013d..52f570b0b 100644 --- a/apps/openmw/mwrender/localmap.hpp +++ b/apps/openmw/mwrender/localmap.hpp @@ -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 cells); + void requestMap (std::set 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 createOrthographicCamera(float left, float top, float width, float height, const osg::Vec3d& upVector, float zmin, float zmax); void setupRenderToTexture(osg::ref_ptr camera, int x, int y); diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index 15b3c057b..dc93c3b1d 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -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 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(); } diff --git a/apps/openmw/mwworld/scene.hpp b/apps/openmw/mwworld/scene.hpp index 439c8d72c..c6de3ebdf 100644 --- a/apps/openmw/mwworld/scene.hpp +++ b/apps/openmw/mwworld/scene.hpp @@ -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