From 98a0819d523e1cf7ba40ac8df279e2579896e284 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Mocquillon?= Date: Thu, 29 Jul 2021 15:33:58 +0200 Subject: [PATCH 1/4] Debug terrain chunks --- components/terrain/cellborder.cpp | 19 +++++++++++++------ components/terrain/cellborder.hpp | 3 +++ components/terrain/chunkmanager.cpp | 18 +++++++++++++++++- components/terrain/chunkmanager.hpp | 1 + components/terrain/quadtreeworld.cpp | 2 +- .../reference/modding/settings/terrain.rst | 9 +++++++++ files/settings-default.cfg | 3 +++ 7 files changed, 47 insertions(+), 8 deletions(-) diff --git a/components/terrain/cellborder.cpp b/components/terrain/cellborder.cpp index c34ed9ab0a..e391036902 100644 --- a/components/terrain/cellborder.cpp +++ b/components/terrain/cellborder.cpp @@ -9,6 +9,7 @@ #include "../esm/loadland.hpp" #include +#include namespace Terrain { @@ -21,13 +22,14 @@ CellBorder::CellBorder(Terrain::World *world, osg::Group *root, int borderMask, { } -void CellBorder::createCellBorderGeometry(int x, int y) +osg::ref_ptr CellBorder::createBorderGeometry(float x, float y, float size, Terrain::Storage* terrain, Resource::SceneManager* sceneManager, int mask) { const int cellSize = ESM::Land::REAL_SIZE; const int borderSegments = 40; const float offset = 10.0; osg::Vec3 cellCorner = osg::Vec3(x * cellSize,y * cellSize,0); + size *= cellSize; osg::ref_ptr vertices = new osg::Vec3Array; osg::ref_ptr colors = new osg::Vec4Array; @@ -35,16 +37,16 @@ void CellBorder::createCellBorderGeometry(int x, int y) normals->push_back(osg::Vec3(0.0f,-1.0f, 0.0f)); - float borderStep = cellSize / ((float) borderSegments); + float borderStep = size / ((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); + osg::Vec3(size, (i - borderSegments) * borderStep,0.0f); pos += cellCorner; - pos += osg::Vec3f(0,0,mWorld->getHeightAt(pos) + offset); + pos += osg::Vec3f(0,0, terrain->getHeightAt(pos) + offset); vertices->push_back(pos); @@ -76,10 +78,15 @@ void CellBorder::createCellBorderGeometry(int x, int y) polygonmode->setMode(osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::LINE); stateSet->setAttributeAndModes(polygonmode,osg::StateAttribute::ON); - mSceneManager->recreateShaders(borderGeode, "debug"); + sceneManager->recreateShaders(borderGeode, "debug"); + borderGeode->setNodeMask(mask); - borderGeode->setNodeMask(mBorderMask); + return borderGeode; +} +void CellBorder::createCellBorderGeometry(int x, int y) +{ + auto borderGeode = createBorderGeometry(x, y, 1.f, mWorld->getStorage(), mSceneManager, mBorderMask); mRoot->addChild(borderGeode); mCellBorderNodes[std::make_pair(x,y)] = borderGeode; diff --git a/components/terrain/cellborder.hpp b/components/terrain/cellborder.hpp index ee8fd72593..d72241e3dc 100644 --- a/components/terrain/cellborder.hpp +++ b/components/terrain/cellborder.hpp @@ -11,6 +11,7 @@ namespace Resource namespace Terrain { + class Storage; class World; /** @@ -31,6 +32,8 @@ namespace Terrain */ void destroyCellBorderGeometry(); + static osg::ref_ptr createBorderGeometry(float x, float y, float size, Storage* terrain, Resource::SceneManager* sceneManager, int mask); + protected: Terrain::World *mWorld; Resource::SceneManager* mSceneManager; diff --git a/components/terrain/chunkmanager.cpp b/components/terrain/chunkmanager.cpp index 8809a75bb9..53b743c03a 100644 --- a/components/terrain/chunkmanager.cpp +++ b/components/terrain/chunkmanager.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include @@ -12,12 +13,14 @@ #include #include +#include #include "terraindrawable.hpp" #include "material.hpp" #include "storage.hpp" #include "texturemanager.hpp" #include "compositemaprenderer.hpp" +#include namespace Terrain { @@ -32,6 +35,7 @@ ChunkManager::ChunkManager(Storage *storage, Resource::SceneManager *sceneMgr, T , mCompositeMapSize(512) , mCompositeMapLevel(1.f) , mMaxCompGeometrySize(1.f) + , mDebugChunks(Settings::Manager::getBool("debug chunks", "Terrain")) { mMultiPassRoot = new osg::StateSet; mMultiPassRoot->setRenderingHint(osg::StateSet::OPAQUE_BIN); @@ -234,7 +238,19 @@ osg::ref_ptr ChunkManager::createChunk(float chunkSize, const osg::Ve } geometry->setNodeMask(mNodeMask); - return geometry; + osg::ref_ptr result(new osg::Group); + result->addChild(geometry); + if (mDebugChunks) + { + auto chunkBorder = CellBorder::createBorderGeometry(chunkCenter.x() - chunkSize / 2.f, chunkCenter.y() - chunkSize / 2.f, chunkSize, mStorage, mSceneManager, getNodeMask()); + osg::Vec3f center = { chunkCenter.x(), chunkCenter.y(), 0 }; + osg::ref_ptr trans = new osg::MatrixTransform(osg::Matrixf::translate(-center*Constants::CellSizeInUnits)); + trans->setDataVariance(osg::Object::STATIC); + trans->addChild(chunkBorder); + result->addChild(trans); + } + + return result; } } diff --git a/components/terrain/chunkmanager.hpp b/components/terrain/chunkmanager.hpp index 9b7dbf3ee1..4e030e018c 100644 --- a/components/terrain/chunkmanager.hpp +++ b/components/terrain/chunkmanager.hpp @@ -72,6 +72,7 @@ namespace Terrain unsigned int mCompositeMapSize; float mCompositeMapLevel; float mMaxCompGeometrySize; + bool mDebugChunks = false; }; } diff --git a/components/terrain/quadtreeworld.cpp b/components/terrain/quadtreeworld.cpp index 6a228a75af..ca28e1cc05 100644 --- a/components/terrain/quadtreeworld.cpp +++ b/components/terrain/quadtreeworld.cpp @@ -367,7 +367,7 @@ void updateWaterCullingView(HeightCullCallback* callback, ViewData* vd, osgUtil: for (unsigned int i=0; igetNumEntries(); ++i) { ViewData::Entry& entry = vd->getEntry(i); - osg::BoundingBox bb = static_cast(entry.mRenderingNode->asGroup()->getChild(0))->getWaterBoundingBox(); + osg::BoundingBox bb = static_cast(entry.mRenderingNode->asGroup()->getChild(0)->asGroup()->getChild(0))->getWaterBoundingBox(); if (!bb.valid()) continue; osg::Vec3f ofs (entry.mNode->getCenter().x()*cellworldsize, entry.mNode->getCenter().y()*cellworldsize, 0.f); diff --git a/docs/source/reference/modding/settings/terrain.rst b/docs/source/reference/modding/settings/terrain.rst index e6018a8655..80c085f4c9 100644 --- a/docs/source/reference/modding/settings/terrain.rst +++ b/docs/source/reference/modding/settings/terrain.rst @@ -100,6 +100,15 @@ max composite geometry size Controls the maximum size of simple composite geometry chunk in cell units. With small values there will more draw calls and small textures, but higher values create more overdraw (not every texture layer is used everywhere). +debug chunks +------------ + +:Type: boolean +:Range: True/False +:Default: False + +This debug setting allows you to see the borders of each chunks of the world by drawing lines arround them (as with toggleborder). + object paging ------------- diff --git a/files/settings-default.cfg b/files/settings-default.cfg index 7f57ba529d..08039f5fbe 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -139,6 +139,9 @@ composite map resolution = 512 # Controls the maximum size of composite geometry, should be >= 1.0. With low values there will be many small chunks, with high values - lesser count of bigger chunks. max composite geometry size = 4.0 +# Draw lines arround chunks. +debug chunks = false + # Use object paging for non active cells object paging = true From 4b7d0bba53cb3d4f84da72b53828afce9ce6e80e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Mocquillon?= Date: Mon, 6 Sep 2021 21:10:03 +0200 Subject: [PATCH 2/4] Avoid adding redundant osg;;Group in non debug mode --- components/terrain/chunkmanager.cpp | 7 ++++--- components/terrain/quadtreeworld.cpp | 11 ++++++++--- components/terrain/quadtreeworld.hpp | 1 + 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/components/terrain/chunkmanager.cpp b/components/terrain/chunkmanager.cpp index 53b743c03a..1f3279e5c5 100644 --- a/components/terrain/chunkmanager.cpp +++ b/components/terrain/chunkmanager.cpp @@ -238,19 +238,20 @@ osg::ref_ptr ChunkManager::createChunk(float chunkSize, const osg::Ve } geometry->setNodeMask(mNodeMask); - osg::ref_ptr result(new osg::Group); - result->addChild(geometry); if (mDebugChunks) { + osg::ref_ptr result(new osg::Group); + result->addChild(geometry); auto chunkBorder = CellBorder::createBorderGeometry(chunkCenter.x() - chunkSize / 2.f, chunkCenter.y() - chunkSize / 2.f, chunkSize, mStorage, mSceneManager, getNodeMask()); osg::Vec3f center = { chunkCenter.x(), chunkCenter.y(), 0 }; osg::ref_ptr trans = new osg::MatrixTransform(osg::Matrixf::translate(-center*Constants::CellSizeInUnits)); trans->setDataVariance(osg::Object::STATIC); trans->addChild(chunkBorder); result->addChild(trans); + return result; } - return result; + return geometry; } } diff --git a/components/terrain/quadtreeworld.cpp b/components/terrain/quadtreeworld.cpp index ca28e1cc05..bbf212942e 100644 --- a/components/terrain/quadtreeworld.cpp +++ b/components/terrain/quadtreeworld.cpp @@ -252,6 +252,7 @@ QuadTreeWorld::QuadTreeWorld(osg::Group *parent, osg::Group *compileRoot, Resour , mVertexLodMod(vertexLodMod) , mViewDistance(std::numeric_limits::max()) , mMinSize(1/8.f) + , mDebugTerrainChunks(Settings::Manager::getBool("debug chunks", "Terrain")) { mChunkManager->setCompositeMapSize(compMapResolution); mChunkManager->setCompositeMapLevel(compMapLevel); @@ -351,7 +352,7 @@ void loadRenderingNode(ViewData::Entry& entry, ViewData* vd, int vertexLodMod, f } } -void updateWaterCullingView(HeightCullCallback* callback, ViewData* vd, osgUtil::CullVisitor* cv, float cellworldsize, bool outofworld) +void updateWaterCullingView(HeightCullCallback* callback, ViewData* vd, osgUtil::CullVisitor* cv, float cellworldsize, bool outofworld, bool debugTerrainChunk) { if (!(cv->getTraversalMask() & callback->getCullMask())) return; @@ -367,7 +368,11 @@ void updateWaterCullingView(HeightCullCallback* callback, ViewData* vd, osgUtil: for (unsigned int i=0; igetNumEntries(); ++i) { ViewData::Entry& entry = vd->getEntry(i); - osg::BoundingBox bb = static_cast(entry.mRenderingNode->asGroup()->getChild(0)->asGroup()->getChild(0))->getWaterBoundingBox(); + osg::BoundingBox bb; + if(debugTerrainChunk) + bb = static_cast(entry.mRenderingNode->asGroup()->getChild(0)->asGroup()->getChild(0))->getWaterBoundingBox(); + else + bb = static_cast(entry.mRenderingNode->asGroup()->getChild(0))->getWaterBoundingBox(); if (!bb.valid()) continue; osg::Vec3f ofs (entry.mNode->getCenter().x()*cellworldsize, entry.mNode->getCenter().y()*cellworldsize, 0.f); @@ -443,7 +448,7 @@ void QuadTreeWorld::accept(osg::NodeVisitor &nv) } if (mHeightCullCallback && isCullVisitor) - updateWaterCullingView(mHeightCullCallback, vd, static_cast(&nv), mStorage->getCellWorldSize(), !isGridEmpty()); + updateWaterCullingView(mHeightCullCallback, vd, static_cast(&nv), mStorage->getCellWorldSize(), !isGridEmpty(), mDebugTerrainChunks); vd->markUnchanged(); diff --git a/components/terrain/quadtreeworld.hpp b/components/terrain/quadtreeworld.hpp index 3dd96a0b84..f7cbf8097a 100644 --- a/components/terrain/quadtreeworld.hpp +++ b/components/terrain/quadtreeworld.hpp @@ -72,6 +72,7 @@ namespace Terrain int mVertexLodMod; float mViewDistance; float mMinSize; + bool mDebugTerrainChunks; }; } From 080c909c285a3719f1804517ab831005fc47131d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Mocquillon?= Date: Wed, 8 Sep 2021 19:59:53 +0200 Subject: [PATCH 3/4] Merge the 'debug chunks' and 'object paging debug batches' settings into a single one --- apps/openmw/mwrender/objectpaging.cpp | 2 +- docs/source/reference/modding/settings/terrain.rst | 14 ++++---------- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/apps/openmw/mwrender/objectpaging.cpp b/apps/openmw/mwrender/objectpaging.cpp index 907631436f..376c517d59 100644 --- a/apps/openmw/mwrender/objectpaging.cpp +++ b/apps/openmw/mwrender/objectpaging.cpp @@ -390,7 +390,7 @@ namespace MWRender , mRefTrackerLocked(false) { mActiveGrid = Settings::Manager::getBool("object paging active grid", "Terrain"); - mDebugBatches = Settings::Manager::getBool("object paging debug batches", "Terrain"); + mDebugBatches = Settings::Manager::getBool("debug chunks", "Terrain"); mMergeFactor = Settings::Manager::getFloat("object paging merge factor", "Terrain"); mMinSize = Settings::Manager::getFloat("object paging min size", "Terrain"); mMinSizeMergeFactor = Settings::Manager::getFloat("object paging min size merge factor", "Terrain"); diff --git a/docs/source/reference/modding/settings/terrain.rst b/docs/source/reference/modding/settings/terrain.rst index 80c085f4c9..752260fd48 100644 --- a/docs/source/reference/modding/settings/terrain.rst +++ b/docs/source/reference/modding/settings/terrain.rst @@ -107,7 +107,10 @@ debug chunks :Range: True/False :Default: False -This debug setting allows you to see the borders of each chunks of the world by drawing lines arround them (as with toggleborder). +This debug setting allows you to see the borders of each chunks of the world by drawing lines arround them (as with toggleborder). +If object paging is set to true then this debug setting will allows you to see what objects have been merged in the scene +by making them colored randomly. + object paging ------------- @@ -203,12 +206,3 @@ object paging min size cost multiplier This setting adjusts the calculated cost of merging an object used in the mentioned functionality. The larger this value is, the less expensive objects can be before they are discarded. See the formula above to figure out the math. - -object paging debug batches ---------------------------- -:Type: boolean -:Range: True/False -:Default: False - -This debug setting allows you to see what objects have been merged in the scene -by making them colored randomly. From d7352ded36f05330df2c392b06edc3411a762eee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Mocquillon?= Date: Sat, 11 Sep 2021 08:25:41 +0200 Subject: [PATCH 4/4] Add configurable color and offset --- components/terrain/cellborder.cpp | 6 +++--- components/terrain/cellborder.hpp | 2 +- components/terrain/chunkmanager.cpp | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/components/terrain/cellborder.cpp b/components/terrain/cellborder.cpp index e391036902..280a55faca 100644 --- a/components/terrain/cellborder.cpp +++ b/components/terrain/cellborder.cpp @@ -22,11 +22,11 @@ CellBorder::CellBorder(Terrain::World *world, osg::Group *root, int borderMask, { } -osg::ref_ptr CellBorder::createBorderGeometry(float x, float y, float size, Terrain::Storage* terrain, Resource::SceneManager* sceneManager, int mask) +osg::ref_ptr CellBorder::createBorderGeometry(float x, float y, float size, Terrain::Storage* terrain, Resource::SceneManager* sceneManager, int mask, + float offset, osg::Vec4f color) { const int cellSize = ESM::Land::REAL_SIZE; const int borderSegments = 40; - const float offset = 10.0; osg::Vec3 cellCorner = osg::Vec3(x * cellSize,y * cellSize,0); size *= cellSize; @@ -52,7 +52,7 @@ osg::ref_ptr CellBorder::createBorderGeometry(float x, float y, floa osg::Vec4f col = i % 2 == 0 ? osg::Vec4f(0,0,0,1) : - osg::Vec4f(1,1,0,1); + color; colors->push_back(col); } diff --git a/components/terrain/cellborder.hpp b/components/terrain/cellborder.hpp index d72241e3dc..785c441b86 100644 --- a/components/terrain/cellborder.hpp +++ b/components/terrain/cellborder.hpp @@ -32,7 +32,7 @@ namespace Terrain */ void destroyCellBorderGeometry(); - static osg::ref_ptr createBorderGeometry(float x, float y, float size, Storage* terrain, Resource::SceneManager* sceneManager, int mask); + static osg::ref_ptr createBorderGeometry(float x, float y, float size, Storage* terrain, Resource::SceneManager* sceneManager, int mask, float offset = 10.0, osg::Vec4f color = { 1,1,0,0 }); protected: Terrain::World *mWorld; diff --git a/components/terrain/chunkmanager.cpp b/components/terrain/chunkmanager.cpp index 1f3279e5c5..7a6d4fdb0a 100644 --- a/components/terrain/chunkmanager.cpp +++ b/components/terrain/chunkmanager.cpp @@ -242,7 +242,7 @@ osg::ref_ptr ChunkManager::createChunk(float chunkSize, const osg::Ve { osg::ref_ptr result(new osg::Group); result->addChild(geometry); - auto chunkBorder = CellBorder::createBorderGeometry(chunkCenter.x() - chunkSize / 2.f, chunkCenter.y() - chunkSize / 2.f, chunkSize, mStorage, mSceneManager, getNodeMask()); + auto chunkBorder = CellBorder::createBorderGeometry(chunkCenter.x() - chunkSize / 2.f, chunkCenter.y() - chunkSize / 2.f, chunkSize, mStorage, mSceneManager, getNodeMask(), 5.f, { 1, 0, 0, 0 }); osg::Vec3f center = { chunkCenter.x(), chunkCenter.y(), 0 }; osg::ref_ptr trans = new osg::MatrixTransform(osg::Matrixf::translate(-center*Constants::CellSizeInUnits)); trans->setDataVariance(osg::Object::STATIC);