diff --git a/CHANGELOG.md b/CHANGELOG.md index f407a156e..4c7930f03 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ Bug #4429: [Windows] Error on build INSTALL.vcxproj project (debug) with cmake 3.7.2 Bug #4432: Guards behaviour is incorrect if they do not have AI packages Bug #4433: Guard behaviour is incorrect with Alarm = 0 + Feature #4256: Implement ToggleBorders (TB) console command Feature #4345: Add equivalents for the command line commands to Launcher Feature #4444: Per-group KF-animation files support diff --git a/components/terrain/cellborder.cpp b/components/terrain/cellborder.cpp index b74e2e9be..d9e6d52fc 100644 --- a/components/terrain/cellborder.cpp +++ b/components/terrain/cellborder.cpp @@ -5,20 +5,21 @@ #include #include "world.hpp" +#include "../esm/loadland.hpp" namespace MWRender { -CellBorder::CellBorder(Terrain::World *world, osg::Group *root): +CellBorder::CellBorder(Terrain::World *world, osg::Group *root, int borderMask): mWorld(world), mRoot(root), - mBorderRoot(0) + mBorderMask(borderMask) { } void CellBorder::createCellBorderGeometry(int x, int y) { - const int cellSize = 8192; + const int cellSize = ESM::Land::REAL_SIZE; const int borderSegments = 40; const float offset = 10.0; @@ -68,9 +69,9 @@ void CellBorder::createCellBorderGeometry(int x, int y) polygonmode->setMode(osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::LINE); stateSet->setAttributeAndModes(polygonmode,osg::StateAttribute::ON); - mRoot->addChild(borderGeode); + borderGeode->setNodeMask(mBorderMask); - mBorderRoot = borderGeode; + mRoot->addChild(borderGeode); mCellBorderNodes[std::make_pair(x,y)] = borderGeode; } @@ -83,9 +84,15 @@ void CellBorder::destroyCellBorderGeometry(int x, int y) return; osg::ref_ptr borderNode = it->second; - mBorderRoot->removeChild(borderNode); + mRoot->removeChild(borderNode); mCellBorderNodes.erase(it); } +void CellBorder::destroyCellBorderGeometry() +{ + for (CellGrid::iterator it = mCellBorderNodes.begin(); it != mCellBorderNodes.end(); ++it) + destroyCellBorderGeometry(it->first.first,it->first.second); +} + } diff --git a/components/terrain/cellborder.hpp b/components/terrain/cellborder.hpp index 6144f8c32..0cbe7b899 100644 --- a/components/terrain/cellborder.hpp +++ b/components/terrain/cellborder.hpp @@ -19,17 +19,22 @@ namespace MWRender public: typedef std::map, osg::ref_ptr > CellGrid; - CellBorder(Terrain::World *world, osg::Group *root); + CellBorder(Terrain::World *world, osg::Group *root, int borderMask); void createCellBorderGeometry(int x, int y); void destroyCellBorderGeometry(int x, int y); + /** + Destroys the geometry for all borders. + */ + void destroyCellBorderGeometry(); + protected: Terrain::World *mWorld; osg::Group *mRoot; - osg::Group *mBorderRoot; CellGrid mCellBorderNodes; + int mBorderMask; }; } diff --git a/components/terrain/terraingrid.cpp b/components/terrain/terraingrid.cpp index f5ab6f64b..74f683774 100644 --- a/components/terrain/terraingrid.cpp +++ b/components/terrain/terraingrid.cpp @@ -75,7 +75,7 @@ void TerrainGrid::loadCell(int x, int y) if (!terrainNode) return; // no terrain defined - Terrain::World::loadCell(x,y); + TerrainGrid::World::loadCell(x,y); mTerrainRoot->addChild(terrainNode); @@ -84,12 +84,12 @@ void TerrainGrid::loadCell(int x, int y) void TerrainGrid::unloadCell(int x, int y) { - World::unloadCell(x,y); - MWRender::CellBorder::CellGrid::iterator it = mGrid.find(std::make_pair(x,y)); if (it == mGrid.end()) return; + Terrain::World::unloadCell(x,y); + osg::ref_ptr terrainNode = it->second; mTerrainRoot->removeChild(terrainNode); diff --git a/components/terrain/terraingrid.hpp b/components/terrain/terraingrid.hpp index f21dd39d3..87e3b432c 100644 --- a/components/terrain/terraingrid.hpp +++ b/components/terrain/terraingrid.hpp @@ -7,8 +7,6 @@ #include "world.hpp" -#include "cellborder.hpp" - namespace Terrain { @@ -37,7 +35,6 @@ namespace Terrain MWRender::CellBorder::CellGrid mGrid; }; - } #endif diff --git a/components/terrain/world.cpp b/components/terrain/world.cpp index d871d141b..cc81dbef8 100644 --- a/components/terrain/world.cpp +++ b/components/terrain/world.cpp @@ -18,6 +18,7 @@ World::World(osg::Group* parent, osg::Group* compileRoot, Resource::ResourceSyst : mStorage(storage) , mParent(parent) , mResourceSystem(resourceSystem) + , mBorderVisible(false) { mTerrainRoot = new osg::Group; mTerrainRoot->setNodeMask(nodeMask); @@ -28,12 +29,6 @@ World::World(osg::Group* parent, osg::Group* compileRoot, Resource::ResourceSyst mTerrainRoot->setName("Terrain Root"); - mBorderRoot = new osg::Switch; - mBorderRoot->setName("Border Root"); - mBorderRoot->setNodeMask(borderMask); - - mTerrainRoot->addChild(mBorderRoot); - osg::ref_ptr compositeCam = new osg::Camera; compositeCam->setRenderOrder(osg::Camera::PRE_RENDER, -1); compositeCam->setProjectionMatrix(osg::Matrix::identity()); @@ -52,44 +47,52 @@ World::World(osg::Group* parent, osg::Group* compileRoot, Resource::ResourceSyst mTextureManager.reset(new TextureManager(mResourceSystem->getSceneManager())); mChunkManager.reset(new ChunkManager(mStorage, mResourceSystem->getSceneManager(), mTextureManager.get(), mCompositeMapRenderer)); - - mCellBorder.reset(new MWRender::CellBorder(this,mTerrainRoot.get())); + mCellBorder.reset(new MWRender::CellBorder(this,mTerrainRoot.get(),borderMask)); mResourceSystem->addResourceManager(mChunkManager.get()); mResourceSystem->addResourceManager(mTextureManager.get()); +} - setBordersVisible(false); +World::~World() +{ + mResourceSystem->removeResourceManager(mChunkManager.get()); + mResourceSystem->removeResourceManager(mTextureManager.get()); + + mParent->removeChild(mTerrainRoot); + + mCompositeMapCamera->removeChild(mCompositeMapRenderer); + mCompositeMapCamera->getParent(0)->removeChild(mCompositeMapCamera); + + delete mStorage; } void World::setBordersVisible(bool visible) { + mBorderVisible = visible; + if (visible) - mBorderRoot->setAllChildrenOn(); + { + for (std::set>::iterator it = mLoadedCells.begin(); it != mLoadedCells.end(); ++it) + mCellBorder->createCellBorderGeometry(it->first,it->second); + } else - mBorderRoot->setAllChildrenOff(); + mCellBorder->destroyCellBorderGeometry(); } void World::loadCell(int x, int y) { - mCellBorder->createCellBorderGeometry(x,y); -} + if (mBorderVisible) + mCellBorder->createCellBorderGeometry(x,y); -void World::unloadCell(int x, int y) -{ - mCellBorder->destroyCellBorderGeometry(x,y); + mLoadedCells.insert(std::pair(x,y)); } -World::~World() +void World::unloadCell(int x, int y) { - mResourceSystem->removeResourceManager(mChunkManager.get()); - mResourceSystem->removeResourceManager(mTextureManager.get()); - - mParent->removeChild(mTerrainRoot); + if (mBorderVisible) + mCellBorder->destroyCellBorderGeometry(x,y); - mCompositeMapCamera->removeChild(mCompositeMapRenderer); - mCompositeMapCamera->getParent(0)->removeChild(mCompositeMapCamera); - - delete mStorage; + mLoadedCells.erase(std::pair(x,y)); } void World::setTargetFrameRate(float rate) diff --git a/components/terrain/world.hpp b/components/terrain/world.hpp index b847d08ab..ae71693bd 100644 --- a/components/terrain/world.hpp +++ b/components/terrain/world.hpp @@ -4,12 +4,11 @@ #include #include #include -#include #include +#include #include "defs.hpp" - #include "cellborder.hpp" namespace osg @@ -87,7 +86,7 @@ namespace Terrain virtual void enable(bool enabled) {} - void setBordersVisible(bool visible); + virtual void setBordersVisible(bool visible); /// Create a View to use with preload feature. The caller is responsible for deleting the view. /// @note Thread safe. @@ -104,14 +103,10 @@ namespace Terrain Storage* getStorage() { return mStorage; } protected: - void createCellBorderGeometry(int x, int y); - void destroyCellBorderGeometry(int x, int y); - Storage* mStorage; osg::ref_ptr mParent; osg::ref_ptr mTerrainRoot; - osg::ref_ptr mBorderRoot; osg::ref_ptr mCompositeMapCamera; osg::ref_ptr mCompositeMapRenderer; @@ -122,6 +117,10 @@ namespace Terrain std::unique_ptr mChunkManager; std::unique_ptr mCellBorder; + + bool mBorderVisible; + + std::set> mLoadedCells; }; }