From db8aaa74d6352168c74e39848d8294b8ae5cd590 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miloslav=20=C4=8C=C3=AD=C5=BE?= Date: Wed, 13 Jun 2018 01:48:31 +0200 Subject: [PATCH 1/8] Start cell border debug drawing --- apps/openmw/mwbase/world.hpp | 1 + apps/openmw/mwrender/renderingmanager.cpp | 13 +++- apps/openmw/mwrender/renderingmanager.hpp | 3 + apps/openmw/mwscript/docs/vmformat.txt | 3 +- apps/openmw/mwscript/miscextensions.cpp | 15 ++++ apps/openmw/mwworld/worldimp.cpp | 5 ++ apps/openmw/mwworld/worldimp.hpp | 1 + components/CMakeLists.txt | 2 +- components/compiler/extensions0.cpp | 2 + components/compiler/opcodes.hpp | 1 + components/terrain/cellborder.cpp | 91 +++++++++++++++++++++++ components/terrain/cellborder.hpp | 36 +++++++++ components/terrain/quadtreeworld.cpp | 4 +- components/terrain/quadtreeworld.hpp | 2 +- components/terrain/terraingrid.cpp | 10 ++- components/terrain/terraingrid.hpp | 7 +- components/terrain/world.cpp | 31 +++++++- components/terrain/world.hpp | 20 +++-- 18 files changed, 226 insertions(+), 21 deletions(-) create mode 100644 components/terrain/cellborder.cpp create mode 100644 components/terrain/cellborder.hpp diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 038535939..ef3063d83 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -120,6 +120,7 @@ namespace MWBase virtual bool toggleWater() = 0; virtual bool toggleWorld() = 0; + virtual bool toggleBorders() = 0; virtual void adjustSky() = 0; diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 4fbcdc4d5..6e5b06038 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -181,6 +181,7 @@ namespace MWRender , mNightEyeFactor(0.f) , mFieldOfViewOverride(0.f) , mFieldOfViewOverridden(false) + , mBorders(false) { resourceSystem->getSceneManager()->setParticleSystemMask(MWRender::Mask_ParticleSystem); resourceSystem->getSceneManager()->setShaderPath(resourcePath + "/shaders"); @@ -219,9 +220,10 @@ namespace MWRender Settings::Manager::getBool("auto use terrain specular maps", "Shaders")); if (distantTerrain) - mTerrain.reset(new Terrain::QuadTreeWorld(sceneRoot, mRootNode, mResourceSystem, mTerrainStorage, Mask_Terrain, Mask_PreCompile)); + mTerrain.reset(new Terrain::QuadTreeWorld(sceneRoot, mRootNode, mResourceSystem, mTerrainStorage, Mask_Terrain, Mask_PreCompile, Mask_Debug)); else - mTerrain.reset(new Terrain::TerrainGrid(sceneRoot, mRootNode, mResourceSystem, mTerrainStorage, Mask_Terrain, Mask_PreCompile)); + mTerrain.reset(new Terrain::TerrainGrid(sceneRoot, mRootNode, mResourceSystem, mTerrainStorage, Mask_Terrain, Mask_PreCompile, Mask_Debug)); + mTerrain->setDefaultViewer(mViewer->getCamera()); mCamera.reset(new Camera(mViewer->getCamera())); @@ -441,6 +443,13 @@ namespace MWRender { mSky->setEnabled(enabled); } + + bool RenderingManager::toggleBorders() + { + mBorders = !mBorders; + mTerrain->setBordersVisible(mBorders); + return mBorders; + } bool RenderingManager::toggleRenderMode(RenderMode mode) { diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index f0087e43d..56839adce 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -205,6 +205,8 @@ namespace MWRender LandManager* getLandManager() const; + bool toggleBorders(); + private: void updateProjectionMatrix(); void updateTextureFiltering(); @@ -257,6 +259,7 @@ namespace MWRender bool mFieldOfViewOverridden; float mFieldOfView; float mFirstPersonFieldOfView; + bool mBorders; void operator = (const RenderingManager&); RenderingManager(const RenderingManager&); diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt index e999097db..fed780be7 100644 --- a/apps/openmw/mwscript/docs/vmformat.txt +++ b/apps/openmw/mwscript/docs/vmformat.txt @@ -454,5 +454,6 @@ op 0x2000303: Fixme, explicit op 0x2000304: Show op 0x2000305: Show, explicit op 0x2000306: OnActivate, explicit +op 0x2000307: ToggleBorders, tb -opcodes 0x2000307-0x3ffffff unused +opcodes 0x2000308-0x3ffffff unused diff --git a/apps/openmw/mwscript/miscextensions.cpp b/apps/openmw/mwscript/miscextensions.cpp index 1067b5536..632d9e97c 100644 --- a/apps/openmw/mwscript/miscextensions.cpp +++ b/apps/openmw/mwscript/miscextensions.cpp @@ -254,6 +254,20 @@ namespace MWScript } }; + class OpToggleBorders : public Interpreter::Opcode0 + { + public: + + virtual void execute (Interpreter::Runtime& runtime) + { + bool enabled = + MWBase::Environment::get().getWorld()->toggleBorders(); + + runtime.getContext().report (enabled ? + "Border Rendering -> On" : "Border Rendering -> Off"); + } + }; + class OpTogglePathgrid : public Interpreter::Opcode0 { public: @@ -1374,6 +1388,7 @@ namespace MWScript interpreter.installSegment5 (Compiler::Misc::opcodeRemoveFromLevItem, new OpRemoveFromLevItem); interpreter.installSegment3 (Compiler::Misc::opcodeShowSceneGraph, new OpShowSceneGraph); interpreter.installSegment3 (Compiler::Misc::opcodeShowSceneGraphExplicit, new OpShowSceneGraph); + interpreter.installSegment5 (Compiler::Misc::opcodeToggleBorders, new OpToggleBorders); } } } diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 9c7fba9fa..af30b07d1 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1919,6 +1919,11 @@ namespace MWWorld return mRendering->toggleRenderMode(MWRender::Render_Scene); } + bool World::toggleBorders() + { + return mRendering->toggleBorders(); + } + void World::PCDropped (const Ptr& item) { std::string script = item.getClass().getScript(item); diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 7af7b2968..dc1ff4588 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -217,6 +217,7 @@ namespace MWWorld bool toggleWater() override; bool toggleWorld() override; + bool toggleBorders() override; void adjustSky() override; diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index a0b426a16..d74f11fc2 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -120,7 +120,7 @@ add_component_dir (translation ) add_component_dir (terrain - storage world buffercache defs terraingrid material terraindrawable texturemanager chunkmanager compositemaprenderer quadtreeworld quadtreenode viewdata + storage world buffercache defs terraingrid material terraindrawable texturemanager chunkmanager compositemaprenderer quadtreeworld quadtreenode viewdata cellborder ) add_component_dir (loadinglistener diff --git a/components/compiler/extensions0.cpp b/components/compiler/extensions0.cpp index cd5bf7ef7..7638d0f78 100644 --- a/components/compiler/extensions0.cpp +++ b/components/compiler/extensions0.cpp @@ -318,6 +318,8 @@ namespace Compiler extensions.registerInstruction ("removefromlevcreature", "ccl", opcodeRemoveFromLevCreature); extensions.registerInstruction ("addtolevitem", "ccl", opcodeAddToLevItem); extensions.registerInstruction ("removefromlevitem", "ccl", opcodeRemoveFromLevItem); + extensions.registerInstruction ("tb", "", opcodeToggleBorders); + extensions.registerInstruction ("toggleborders", "", opcodeToggleBorders); } } diff --git a/components/compiler/opcodes.hpp b/components/compiler/opcodes.hpp index 6a6552467..aef92b311 100644 --- a/components/compiler/opcodes.hpp +++ b/components/compiler/opcodes.hpp @@ -295,6 +295,7 @@ namespace Compiler const int opcodeRemoveFromLevItem = 0x20002fe; const int opcodeShowSceneGraph = 0x2002f; const int opcodeShowSceneGraphExplicit = 0x20030; + const int opcodeToggleBorders = 0x2000307; } namespace Sky diff --git a/components/terrain/cellborder.cpp b/components/terrain/cellborder.cpp new file mode 100644 index 000000000..b74e2e9be --- /dev/null +++ b/components/terrain/cellborder.cpp @@ -0,0 +1,91 @@ +#include "cellborder.hpp" + +#include +#include +#include + +#include "world.hpp" + +namespace MWRender +{ + +CellBorder::CellBorder(Terrain::World *world, osg::Group *root): + mWorld(world), + mRoot(root), + mBorderRoot(0) +{ +} + +void CellBorder::createCellBorderGeometry(int x, int y) +{ + const int cellSize = 8192; + const int borderSegments = 40; + const float offset = 10.0; + + osg::Vec3 cellCorner = osg::Vec3(x * cellSize,y * cellSize,0); + + osg::ref_ptr vertices = new osg::Vec3Array; + osg::ref_ptr colors = new osg::Vec4Array; + osg::ref_ptr normals = new osg::Vec3Array; + + normals->push_back(osg::Vec3(0.0f,-1.0f, 0.0f)); + + float borderStep = cellSize / ((float) borderSegments); + + for (int i = 0; i <= 2 * borderSegments; ++i) + { + osg::Vec3f pos = i < borderSegments ? + osg::Vec3(i * borderStep,0.0f,0.0f) : + osg::Vec3(cellSize,(i - borderSegments) * borderStep,0.0f); + + pos += cellCorner; + pos += osg::Vec3f(0,0,mWorld->getHeightAt(pos) + offset); + + vertices->push_back(pos); + + osg::Vec4f col = i % 2 == 0 ? + osg::Vec4f(0,0,0,1) : + osg::Vec4f(1,1,0,1); + + colors->push_back(col); + } + + osg::ref_ptr border = new osg::Geometry; + border->setVertexArray(vertices.get()); + border->setNormalArray(normals.get()); + border->setNormalBinding(osg::Geometry::BIND_OVERALL); + border->setColorArray(colors.get()); + border->setColorBinding(osg::Geometry::BIND_PER_VERTEX); + + border->addPrimitiveSet(new osg::DrawArrays(GL_LINE_STRIP,0,vertices->size())); + + osg::ref_ptr borderGeode = new osg::Geode; + borderGeode->addDrawable(border.get()); + + osg::StateSet *stateSet = borderGeode->getOrCreateStateSet(); + + osg::PolygonMode* polygonmode = new osg::PolygonMode; + polygonmode->setMode(osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::LINE); + stateSet->setAttributeAndModes(polygonmode,osg::StateAttribute::ON); + + mRoot->addChild(borderGeode); + + mBorderRoot = borderGeode; + + mCellBorderNodes[std::make_pair(x,y)] = borderGeode; +} + +void CellBorder::destroyCellBorderGeometry(int x, int y) +{ + CellGrid::iterator it = mCellBorderNodes.find(std::make_pair(x,y)); + + if (it == mCellBorderNodes.end()) + return; + + osg::ref_ptr borderNode = it->second; + mBorderRoot->removeChild(borderNode); + + mCellBorderNodes.erase(it); +} + +} diff --git a/components/terrain/cellborder.hpp b/components/terrain/cellborder.hpp new file mode 100644 index 000000000..6144f8c32 --- /dev/null +++ b/components/terrain/cellborder.hpp @@ -0,0 +1,36 @@ +#ifndef GAME_RENDER_CELLBORDER +#define GAME_RENDER_CELLBORDER + +#include +#include + +namespace Terrain +{ + class World; +} + +namespace MWRender +{ + /** + * @Brief Handles the debug cell borders. + */ + class CellBorder + { + public: + typedef std::map, osg::ref_ptr > CellGrid; + + CellBorder(Terrain::World *world, osg::Group *root); + + void createCellBorderGeometry(int x, int y); + void destroyCellBorderGeometry(int x, int y); + + protected: + Terrain::World *mWorld; + osg::Group *mRoot; + osg::Group *mBorderRoot; + + CellGrid mCellBorderNodes; + }; +} + +#endif diff --git a/components/terrain/quadtreeworld.cpp b/components/terrain/quadtreeworld.cpp index f31064805..f9bc7bb60 100644 --- a/components/terrain/quadtreeworld.cpp +++ b/components/terrain/quadtreeworld.cpp @@ -235,8 +235,8 @@ private: osg::ref_ptr mRootNode; }; -QuadTreeWorld::QuadTreeWorld(osg::Group *parent, osg::Group *compileRoot, Resource::ResourceSystem *resourceSystem, Storage *storage, int nodeMask, int preCompileMask) - : World(parent, compileRoot, resourceSystem, storage, nodeMask, preCompileMask) +QuadTreeWorld::QuadTreeWorld(osg::Group *parent, osg::Group *compileRoot, Resource::ResourceSystem *resourceSystem, Storage *storage, int nodeMask, int preCompileMask, int borderMask) + : World(parent, compileRoot, resourceSystem, storage, nodeMask, preCompileMask, borderMask) , mViewDataMap(new ViewDataMap) , mQuadTreeBuilt(false) { diff --git a/components/terrain/quadtreeworld.hpp b/components/terrain/quadtreeworld.hpp index ef33f158e..c166a9cb1 100644 --- a/components/terrain/quadtreeworld.hpp +++ b/components/terrain/quadtreeworld.hpp @@ -19,7 +19,7 @@ namespace Terrain class QuadTreeWorld : public Terrain::World { public: - QuadTreeWorld(osg::Group* parent, osg::Group* compileRoot, Resource::ResourceSystem* resourceSystem, Storage* storage, int nodeMask, int preCompileMask=~0); + QuadTreeWorld(osg::Group* parent, osg::Group* compileRoot, Resource::ResourceSystem* resourceSystem, Storage* storage, int nodeMask, int preCompileMask=~0, int borderMask=0); ~QuadTreeWorld(); void accept(osg::NodeVisitor& nv); diff --git a/components/terrain/terraingrid.cpp b/components/terrain/terraingrid.cpp index 466cddddc..f5ab6f64b 100644 --- a/components/terrain/terraingrid.cpp +++ b/components/terrain/terraingrid.cpp @@ -17,8 +17,8 @@ public: virtual void reset(unsigned int frame) {} }; -TerrainGrid::TerrainGrid(osg::Group* parent, osg::Group* compileRoot, Resource::ResourceSystem* resourceSystem, Storage* storage, int nodeMask, int preCompileMask) - : Terrain::World(parent, compileRoot, resourceSystem, storage, nodeMask, preCompileMask) +TerrainGrid::TerrainGrid(osg::Group* parent, osg::Group* compileRoot, Resource::ResourceSystem* resourceSystem, Storage* storage, int nodeMask, int preCompileMask, int borderMask) + : Terrain::World(parent, compileRoot, resourceSystem, storage, nodeMask, preCompileMask, borderMask) , mNumSplits(4) { } @@ -75,6 +75,8 @@ void TerrainGrid::loadCell(int x, int y) if (!terrainNode) return; // no terrain defined + Terrain::World::loadCell(x,y); + mTerrainRoot->addChild(terrainNode); mGrid[std::make_pair(x,y)] = terrainNode; @@ -82,7 +84,9 @@ void TerrainGrid::loadCell(int x, int y) void TerrainGrid::unloadCell(int x, int y) { - Grid::iterator it = mGrid.find(std::make_pair(x,y)); + World::unloadCell(x,y); + + MWRender::CellBorder::CellGrid::iterator it = mGrid.find(std::make_pair(x,y)); if (it == mGrid.end()) return; diff --git a/components/terrain/terraingrid.hpp b/components/terrain/terraingrid.hpp index 189fe7f63..f21dd39d3 100644 --- a/components/terrain/terraingrid.hpp +++ b/components/terrain/terraingrid.hpp @@ -7,6 +7,8 @@ #include "world.hpp" +#include "cellborder.hpp" + namespace Terrain { @@ -14,7 +16,7 @@ namespace Terrain class TerrainGrid : public Terrain::World { public: - TerrainGrid(osg::Group* parent, osg::Group* compileRoot, Resource::ResourceSystem* resourceSystem, Storage* storage, int nodeMask, int preCompileMask=~0); + TerrainGrid(osg::Group* parent, osg::Group* compileRoot, Resource::ResourceSystem* resourceSystem, Storage* storage, int nodeMask, int preCompileMask=~0, int borderMask=0); ~TerrainGrid(); virtual void cacheCell(View* view, int x, int y); @@ -33,8 +35,7 @@ namespace Terrain // split each ESM::Cell into mNumSplits*mNumSplits terrain chunks unsigned int mNumSplits; - typedef std::map, osg::ref_ptr > Grid; - Grid mGrid; + MWRender::CellBorder::CellGrid mGrid; }; } diff --git a/components/terrain/world.cpp b/components/terrain/world.cpp index 335bb496b..c08c02dc5 100644 --- a/components/terrain/world.cpp +++ b/components/terrain/world.cpp @@ -14,7 +14,7 @@ namespace Terrain { -World::World(osg::Group* parent, osg::Group* compileRoot, Resource::ResourceSystem* resourceSystem, Storage* storage, int nodeMask, int preCompileMask) +World::World(osg::Group* parent, osg::Group* compileRoot, Resource::ResourceSystem* resourceSystem, Storage* storage, int nodeMask, int preCompileMask, int borderMask) : mStorage(storage) , mParent(parent) , mResourceSystem(resourceSystem) @@ -28,6 +28,12 @@ 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()); @@ -39,7 +45,6 @@ World::World(osg::Group* parent, osg::Group* compileRoot, Resource::ResourceSyst compileRoot->addChild(compositeCam); - mCompositeMapRenderer = new CompositeMapRenderer; compositeCam->addChild(mCompositeMapRenderer); @@ -48,8 +53,30 @@ 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())); + mResourceSystem->addResourceManager(mChunkManager.get()); mResourceSystem->addResourceManager(mTextureManager.get()); + + setBordersVisible(false); +} + +void World::setBordersVisible(bool visible) +{ + if (visible) + mBorderRoot->setAllChildrenOn(); + else + mBorderRoot->setAllChildrenOff(); +} + +void World::loadCell(int x, int y) +{ + mCellBorder->createCellBorderGeometry(x,y); +} + +void World::unloadCell(int x, int y) +{ + mCellBorder->destroyCellBorderGeometry(x,y); } World::~World() diff --git a/components/terrain/world.hpp b/components/terrain/world.hpp index e1c3828fc..0d043c035 100644 --- a/components/terrain/world.hpp +++ b/components/terrain/world.hpp @@ -4,11 +4,14 @@ #include #include #include +#include #include #include "defs.hpp" +#include "cellborder.hpp" + namespace osg { class Group; @@ -54,7 +57,7 @@ namespace Terrain /// @param storage Storage instance to get terrain data from (heights, normals, colors, textures..) /// @param nodeMask mask for the terrain root /// @param preCompileMask mask for pre compiling textures - World(osg::Group* parent, osg::Group* compileRoot, Resource::ResourceSystem* resourceSystem, Storage* storage, int nodeMask, int preCompileMask); + World(osg::Group* parent, osg::Group* compileRoot, Resource::ResourceSystem* resourceSystem, Storage* storage, int nodeMask, int preCompileMask, int borderMask); virtual ~World(); /// Apply the scene manager's texture filtering settings to all cached textures. @@ -73,16 +76,16 @@ namespace Terrain /// Load the cell into the scene graph. /// @note Not thread safe. - /// @note May be ignored by derived implementations that don't organize the terrain into cells. - virtual void loadCell(int x, int y) {} + virtual void loadCell(int x, int y); /// Remove the cell from the scene graph. /// @note Not thread safe. - /// @note May be ignored by derived implementations that don't organize the terrain into cells. - virtual void unloadCell(int x, int y) {} + virtual void unloadCell(int x, int y); virtual void enable(bool enabled) {} + void setBordersVisible(bool visible); + /// Create a View to use with preload feature. The caller is responsible for deleting the view. /// @note Thread safe. virtual View* createView() { return NULL; } @@ -98,10 +101,14 @@ 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; @@ -110,8 +117,9 @@ namespace Terrain std::unique_ptr mTextureManager; std::unique_ptr mChunkManager; - }; + std::unique_ptr mCellBorder; + }; } #endif From 1fd5ad3e56ce9f3690569b95b3287a0d19be6bc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miloslav=20=C4=8C=C3=AD=C5=BE?= Date: Thu, 14 Jun 2018 01:01:22 +0200 Subject: [PATCH 2/8] Use REAL_SIZE constant --- components/terrain/cellborder.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/components/terrain/cellborder.cpp b/components/terrain/cellborder.cpp index b74e2e9be..31a162af7 100644 --- a/components/terrain/cellborder.cpp +++ b/components/terrain/cellborder.cpp @@ -5,6 +5,7 @@ #include #include "world.hpp" +#include "../esm/loadland.hpp" namespace MWRender { @@ -18,7 +19,7 @@ CellBorder::CellBorder(Terrain::World *world, osg::Group *root): 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; From 1b8d500c07892eda46219c63ebd324f38e9cd2ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miloslav=20=C4=8C=C3=AD=C5=BE?= Date: Thu, 14 Jun 2018 12:01:09 +0200 Subject: [PATCH 3/8] Make tb command work again --- components/terrain/cellborder.cpp | 13 ++++++++----- components/terrain/cellborder.hpp | 6 +++++- components/terrain/terraingrid.cpp | 24 ++++++++++++++++++++---- components/terrain/terraingrid.hpp | 6 +++++- components/terrain/world.cpp | 28 ---------------------------- components/terrain/world.hpp | 15 +++------------ 6 files changed, 41 insertions(+), 51 deletions(-) diff --git a/components/terrain/cellborder.cpp b/components/terrain/cellborder.cpp index 31a162af7..f9af60b75 100644 --- a/components/terrain/cellborder.cpp +++ b/components/terrain/cellborder.cpp @@ -12,8 +12,7 @@ namespace MWRender CellBorder::CellBorder(Terrain::World *world, osg::Group *root): mWorld(world), - mRoot(root), - mBorderRoot(0) + mRoot(root) { } @@ -71,8 +70,6 @@ void CellBorder::createCellBorderGeometry(int x, int y) mRoot->addChild(borderGeode); - mBorderRoot = borderGeode; - mCellBorderNodes[std::make_pair(x,y)] = borderGeode; } @@ -84,9 +81,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..a505aec9c 100644 --- a/components/terrain/cellborder.hpp +++ b/components/terrain/cellborder.hpp @@ -24,10 +24,14 @@ namespace MWRender 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; }; diff --git a/components/terrain/terraingrid.cpp b/components/terrain/terraingrid.cpp index f5ab6f64b..edd7de5da 100644 --- a/components/terrain/terraingrid.cpp +++ b/components/terrain/terraingrid.cpp @@ -19,8 +19,9 @@ public: TerrainGrid::TerrainGrid(osg::Group* parent, osg::Group* compileRoot, Resource::ResourceSystem* resourceSystem, Storage* storage, int nodeMask, int preCompileMask, int borderMask) : Terrain::World(parent, compileRoot, resourceSystem, storage, nodeMask, preCompileMask, borderMask) - , mNumSplits(4) + , mNumSplits(4), mBorderVisible(false) { + mCellBorder.reset(new MWRender::CellBorder(this,mTerrainRoot.get())); } TerrainGrid::~TerrainGrid() @@ -65,6 +66,19 @@ osg::ref_ptr TerrainGrid::buildTerrain (osg::Group* parent, float chu } } +void TerrainGrid::setBordersVisible(bool visible) +{ + mBorderVisible = visible; + + if (visible) + { + for (MWRender::CellBorder::CellGrid::iterator it = mGrid.begin(); it != mGrid.end(); ++it) + mCellBorder->createCellBorderGeometry(it->first.first,it->first.second); + } + else + mCellBorder->destroyCellBorderGeometry(); +} + void TerrainGrid::loadCell(int x, int y) { if (mGrid.find(std::make_pair(x, y)) != mGrid.end()) @@ -75,7 +89,8 @@ void TerrainGrid::loadCell(int x, int y) if (!terrainNode) return; // no terrain defined - Terrain::World::loadCell(x,y); + if (mBorderVisible) + mCellBorder->createCellBorderGeometry(x,y); mTerrainRoot->addChild(terrainNode); @@ -84,12 +99,13 @@ 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; + if (mBorderVisible) + mCellBorder->destroyCellBorderGeometry(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..164f09bd6 100644 --- a/components/terrain/terraingrid.hpp +++ b/components/terrain/terraingrid.hpp @@ -29,6 +29,7 @@ namespace Terrain View* createView(); + virtual void setBordersVisible(bool visible) override; private: osg::ref_ptr buildTerrain (osg::Group* parent, float chunkSize, const osg::Vec2f& chunkCenter); @@ -36,8 +37,11 @@ namespace Terrain unsigned int mNumSplits; MWRender::CellBorder::CellGrid mGrid; - }; + std::unique_ptr mCellBorder; + + bool mBorderVisible; + }; } #endif diff --git a/components/terrain/world.cpp b/components/terrain/world.cpp index d871d141b..b88e3f157 100644 --- a/components/terrain/world.cpp +++ b/components/terrain/world.cpp @@ -28,12 +28,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()); @@ -53,30 +47,8 @@ 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())); - mResourceSystem->addResourceManager(mChunkManager.get()); mResourceSystem->addResourceManager(mTextureManager.get()); - - setBordersVisible(false); -} - -void World::setBordersVisible(bool visible) -{ - if (visible) - mBorderRoot->setAllChildrenOn(); - else - mBorderRoot->setAllChildrenOff(); -} - -void World::loadCell(int x, int y) -{ - mCellBorder->createCellBorderGeometry(x,y); -} - -void World::unloadCell(int x, int y) -{ - mCellBorder->destroyCellBorderGeometry(x,y); } World::~World() diff --git a/components/terrain/world.hpp b/components/terrain/world.hpp index b847d08ab..77aa1ee28 100644 --- a/components/terrain/world.hpp +++ b/components/terrain/world.hpp @@ -4,14 +4,11 @@ #include #include #include -#include #include #include "defs.hpp" -#include "cellborder.hpp" - namespace osg { class Group; @@ -79,15 +76,15 @@ namespace Terrain /// Load the cell into the scene graph. /// @note Not thread safe. - virtual void loadCell(int x, int y); + virtual void loadCell(int x, int y) {} /// Remove the cell from the scene graph. /// @note Not thread safe. - virtual void unloadCell(int x, int y); + virtual void unloadCell(int x, int y) {} 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 +101,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; @@ -120,8 +113,6 @@ namespace Terrain std::unique_ptr mTextureManager; std::unique_ptr mChunkManager; - - std::unique_ptr mCellBorder; }; } From f18d57429e434505e3e428255cc46e2c6d245ef5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miloslav=20=C4=8C=C3=AD=C5=BE?= Date: Thu, 14 Jun 2018 12:27:22 +0200 Subject: [PATCH 4/8] Move cell border management to World --- components/terrain/terraingrid.cpp | 9 +++------ components/terrain/terraingrid.hpp | 6 ------ components/terrain/world.cpp | 22 ++++++++++++++++++++++ components/terrain/world.hpp | 11 ++++++++--- 4 files changed, 33 insertions(+), 15 deletions(-) diff --git a/components/terrain/terraingrid.cpp b/components/terrain/terraingrid.cpp index edd7de5da..6329accb2 100644 --- a/components/terrain/terraingrid.cpp +++ b/components/terrain/terraingrid.cpp @@ -19,9 +19,8 @@ public: TerrainGrid::TerrainGrid(osg::Group* parent, osg::Group* compileRoot, Resource::ResourceSystem* resourceSystem, Storage* storage, int nodeMask, int preCompileMask, int borderMask) : Terrain::World(parent, compileRoot, resourceSystem, storage, nodeMask, preCompileMask, borderMask) - , mNumSplits(4), mBorderVisible(false) + , mNumSplits(4) { - mCellBorder.reset(new MWRender::CellBorder(this,mTerrainRoot.get())); } TerrainGrid::~TerrainGrid() @@ -89,8 +88,7 @@ void TerrainGrid::loadCell(int x, int y) if (!terrainNode) return; // no terrain defined - if (mBorderVisible) - mCellBorder->createCellBorderGeometry(x,y); + TerrainGrid::World::loadCell(x,y); mTerrainRoot->addChild(terrainNode); @@ -103,8 +101,7 @@ void TerrainGrid::unloadCell(int x, int y) if (it == mGrid.end()) return; - if (mBorderVisible) - mCellBorder->destroyCellBorderGeometry(x,y); + 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 164f09bd6..0537dce42 100644 --- a/components/terrain/terraingrid.hpp +++ b/components/terrain/terraingrid.hpp @@ -7,8 +7,6 @@ #include "world.hpp" -#include "cellborder.hpp" - namespace Terrain { @@ -37,10 +35,6 @@ namespace Terrain unsigned int mNumSplits; MWRender::CellBorder::CellGrid mGrid; - - std::unique_ptr mCellBorder; - - bool mBorderVisible; }; } diff --git a/components/terrain/world.cpp b/components/terrain/world.cpp index b88e3f157..578131cc5 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); @@ -46,6 +47,7 @@ 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())); mResourceSystem->addResourceManager(mChunkManager.get()); mResourceSystem->addResourceManager(mTextureManager.get()); @@ -64,6 +66,26 @@ World::~World() delete mStorage; } +void World::setBordersVisible(bool visible) +{ + mBorderVisible = visible; + + if (!visible) + mCellBorder->destroyCellBorderGeometry(); +} + +void World::loadCell(int x, int y) +{ + if (mBorderVisible) + mCellBorder->createCellBorderGeometry(x,y); +} + +void World::unloadCell(int x, int y) +{ + if (mBorderVisible) + mCellBorder->destroyCellBorderGeometry(x,y); +} + void World::setTargetFrameRate(float rate) { mCompositeMapRenderer->setTargetFrameRate(rate); diff --git a/components/terrain/world.hpp b/components/terrain/world.hpp index 77aa1ee28..5ea0559df 100644 --- a/components/terrain/world.hpp +++ b/components/terrain/world.hpp @@ -8,6 +8,7 @@ #include #include "defs.hpp" +#include "cellborder.hpp" namespace osg { @@ -76,15 +77,15 @@ namespace Terrain /// Load the cell into the scene graph. /// @note Not thread safe. - virtual void loadCell(int x, int y) {} + virtual void loadCell(int x, int y); /// Remove the cell from the scene graph. /// @note Not thread safe. - virtual void unloadCell(int x, int y) {} + virtual void unloadCell(int x, int y); virtual void enable(bool enabled) {} - virtual 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. @@ -113,6 +114,10 @@ namespace Terrain std::unique_ptr mTextureManager; std::unique_ptr mChunkManager; + + std::unique_ptr mCellBorder; + + bool mBorderVisible; }; } From 414e6caafe9c8626a18d1b42975c454892e92572 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miloslav=20=C4=8C=C3=AD=C5=BE?= Date: Thu, 14 Jun 2018 13:14:38 +0200 Subject: [PATCH 5/8] Make tb work with distant terrain --- components/terrain/terraingrid.cpp | 13 ------------- components/terrain/terraingrid.hpp | 1 - components/terrain/world.cpp | 11 ++++++++++- components/terrain/world.hpp | 5 ++++- 4 files changed, 14 insertions(+), 16 deletions(-) diff --git a/components/terrain/terraingrid.cpp b/components/terrain/terraingrid.cpp index 6329accb2..74f683774 100644 --- a/components/terrain/terraingrid.cpp +++ b/components/terrain/terraingrid.cpp @@ -65,19 +65,6 @@ osg::ref_ptr TerrainGrid::buildTerrain (osg::Group* parent, float chu } } -void TerrainGrid::setBordersVisible(bool visible) -{ - mBorderVisible = visible; - - if (visible) - { - for (MWRender::CellBorder::CellGrid::iterator it = mGrid.begin(); it != mGrid.end(); ++it) - mCellBorder->createCellBorderGeometry(it->first.first,it->first.second); - } - else - mCellBorder->destroyCellBorderGeometry(); -} - void TerrainGrid::loadCell(int x, int y) { if (mGrid.find(std::make_pair(x, y)) != mGrid.end()) diff --git a/components/terrain/terraingrid.hpp b/components/terrain/terraingrid.hpp index 0537dce42..87e3b432c 100644 --- a/components/terrain/terraingrid.hpp +++ b/components/terrain/terraingrid.hpp @@ -27,7 +27,6 @@ namespace Terrain View* createView(); - virtual void setBordersVisible(bool visible) override; private: osg::ref_ptr buildTerrain (osg::Group* parent, float chunkSize, const osg::Vec2f& chunkCenter); diff --git a/components/terrain/world.cpp b/components/terrain/world.cpp index 578131cc5..f0f628561 100644 --- a/components/terrain/world.cpp +++ b/components/terrain/world.cpp @@ -70,7 +70,12 @@ void World::setBordersVisible(bool visible) { mBorderVisible = visible; - if (!visible) + if (visible) + { + for (std::set>::iterator it = mLoadedCells.begin(); it != mLoadedCells.end(); ++it) + mCellBorder->createCellBorderGeometry(it->first,it->second); + } + else mCellBorder->destroyCellBorderGeometry(); } @@ -78,12 +83,16 @@ void World::loadCell(int x, int y) { if (mBorderVisible) mCellBorder->createCellBorderGeometry(x,y); + + mLoadedCells.insert(std::pair(x,y)); } void World::unloadCell(int x, int y) { if (mBorderVisible) mCellBorder->destroyCellBorderGeometry(x,y); + + mLoadedCells.erase(std::pair(x,y)); } void World::setTargetFrameRate(float rate) diff --git a/components/terrain/world.hpp b/components/terrain/world.hpp index 5ea0559df..ae71693bd 100644 --- a/components/terrain/world.hpp +++ b/components/terrain/world.hpp @@ -6,6 +6,7 @@ #include #include +#include #include "defs.hpp" #include "cellborder.hpp" @@ -117,7 +118,9 @@ namespace Terrain std::unique_ptr mCellBorder; - bool mBorderVisible; + bool mBorderVisible; + + std::set> mLoadedCells; }; } From ab8de9fa14e0302f097c181196ff0db205406dfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miloslav=20=C4=8C=C3=AD=C5=BE?= Date: Thu, 14 Jun 2018 13:18:37 +0200 Subject: [PATCH 6/8] Set node mask to cell borders --- components/terrain/cellborder.cpp | 7 +++++-- components/terrain/cellborder.hpp | 3 ++- components/terrain/world.cpp | 2 +- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/components/terrain/cellborder.cpp b/components/terrain/cellborder.cpp index f9af60b75..d9e6d52fc 100644 --- a/components/terrain/cellborder.cpp +++ b/components/terrain/cellborder.cpp @@ -10,9 +10,10 @@ namespace MWRender { -CellBorder::CellBorder(Terrain::World *world, osg::Group *root): +CellBorder::CellBorder(Terrain::World *world, osg::Group *root, int borderMask): mWorld(world), - mRoot(root) + mRoot(root), + mBorderMask(borderMask) { } @@ -68,6 +69,8 @@ void CellBorder::createCellBorderGeometry(int x, int y) polygonmode->setMode(osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::LINE); stateSet->setAttributeAndModes(polygonmode,osg::StateAttribute::ON); + borderGeode->setNodeMask(mBorderMask); + mRoot->addChild(borderGeode); mCellBorderNodes[std::make_pair(x,y)] = borderGeode; diff --git a/components/terrain/cellborder.hpp b/components/terrain/cellborder.hpp index a505aec9c..0cbe7b899 100644 --- a/components/terrain/cellborder.hpp +++ b/components/terrain/cellborder.hpp @@ -19,7 +19,7 @@ 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); @@ -34,6 +34,7 @@ namespace MWRender osg::Group *mRoot; CellGrid mCellBorderNodes; + int mBorderMask; }; } diff --git a/components/terrain/world.cpp b/components/terrain/world.cpp index f0f628561..cc81dbef8 100644 --- a/components/terrain/world.cpp +++ b/components/terrain/world.cpp @@ -47,7 +47,7 @@ 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()); From 24078d4a72343d388b39438f1afdfeb19a43e741 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miloslav=20=C4=8C=C3=AD=C5=BE?= Date: Thu, 14 Jun 2018 13:22:12 +0200 Subject: [PATCH 7/8] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) 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 From 34f8eca7bd11271aad5fc5925128101f369eb39c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miloslav=20=C4=8C=C3=AD=C5=BE?= Date: Thu, 14 Jun 2018 13:43:32 +0200 Subject: [PATCH 8/8] Fix indent --- components/terrain/cellborder.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/terrain/cellborder.hpp b/components/terrain/cellborder.hpp index 0cbe7b899..530ea31ca 100644 --- a/components/terrain/cellborder.hpp +++ b/components/terrain/cellborder.hpp @@ -6,7 +6,7 @@ namespace Terrain { - class World; + class World; } namespace MWRender