diff --git a/apps/opencs/view/render/cell.cpp b/apps/opencs/view/render/cell.cpp index 51279cac4..18614a85f 100644 --- a/apps/opencs/view/render/cell.cpp +++ b/apps/opencs/view/render/cell.cpp @@ -77,27 +77,55 @@ bool CSVRender::Cell::addObjects (int start, int end) void CSVRender::Cell::createLand() { + // Cell is deleted if (mDeleted) { - mTerrain.reset(); + unloadLand(); return; } + // Setup land if available const CSMWorld::IdCollection& land = mData.getLand(); int landIndex = land.searchId(mId); - if (landIndex != -1) + if (landIndex != -1 && !land.getRecord(mId).isDeleted()) { const ESM::Land& esmLand = land.getRecord(mId).get(); if (esmLand.getLandData (ESM::Land::DATA_VHGT)) { - mTerrain.reset(new Terrain::TerrainGrid(mCellNode, mCellNode, mData.getResourceSystem().get(), new TerrainStorage(mData), Mask_Terrain)); + if (mTerrain) + { + mTerrain->unloadCell(mCoordinates.getX(), mCoordinates.getY()); + mTerrain->clearAssociatedCaches(); + } + else + { + mTerrain.reset(new Terrain::TerrainGrid(mCellNode, mCellNode, + mData.getResourceSystem().get(), new TerrainStorage(mData), Mask_Terrain)); + } + mTerrain->loadCell(esmLand.mX, esmLand.mY); - mCellBorder.reset(new CellBorder(mCellNode, mCoordinates)); + if (!mCellBorder) + mCellBorder.reset(new CellBorder(mCellNode, mCoordinates)); + mCellBorder->buildShape(esmLand); + + return; } } + + // No land data + unloadLand(); +} + +void CSVRender::Cell::unloadLand() +{ + if (mTerrain) + mTerrain->unloadCell(mCoordinates.getX(), mCoordinates.getY()); + + if (mCellBorder) + mCellBorder.reset(); } CSVRender::Cell::Cell (CSMWorld::Data& data, osg::Group* rootNode, const std::string& id, diff --git a/apps/opencs/view/render/cell.hpp b/apps/opencs/view/render/cell.hpp index f6db475d7..6418ed249 100644 --- a/apps/opencs/view/render/cell.hpp +++ b/apps/opencs/view/render/cell.hpp @@ -73,6 +73,7 @@ namespace CSVRender bool addObjects (int start, int end); void createLand(); + void unloadLand(); public: diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index b224ac1c4..4a745195b 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -400,18 +400,21 @@ void CSVRender::PagedWorldspaceWidget::landTextureDataChanged (const QModelIndex { for (auto cellIt : mCells) cellIt.second->landTextureChanged(topLeft, bottomRight); + flagAsModified(); } void CSVRender::PagedWorldspaceWidget::landTextureAboutToBeRemoved (const QModelIndex& parent, int start, int end) { for (auto cellIt : mCells) cellIt.second->landTextureAboutToBeRemoved(parent, start, end); + flagAsModified(); } void CSVRender::PagedWorldspaceWidget::landTextureAdded (const QModelIndex& parent, int start, int end) { for (auto cellIt : mCells) cellIt.second->landTextureAdded(parent, start, end); + flagAsModified(); } diff --git a/components/terrain/world.cpp b/components/terrain/world.cpp index b7cc0ae01..22c65b62c 100644 --- a/components/terrain/world.cpp +++ b/components/terrain/world.cpp @@ -75,4 +75,10 @@ void World::updateTextureFiltering() mTextureManager->updateTextureFiltering(); } +void World::clearAssociatedCaches() +{ + mTextureManager->clearCache(); + mChunkManager->clearCache(); +} + } diff --git a/components/terrain/world.hpp b/components/terrain/world.hpp index d0576fbd3..e1c3828fc 100644 --- a/components/terrain/world.hpp +++ b/components/terrain/world.hpp @@ -63,6 +63,10 @@ namespace Terrain float getHeightAt (const osg::Vec3f& worldPos); + /// Clears the cached land and landtexture data. + /// @note Thread safe. + virtual void clearAssociatedCaches(); + /// Load a terrain cell at maximum LOD and store it in the View for later use. /// @note Thread safe. virtual void cacheCell(View* view, int x, int y) {}