diff --git a/apps/openmw/mwrender/terrainstorage.cpp b/apps/openmw/mwrender/terrainstorage.cpp index 7894a8393..528ce70ea 100644 --- a/apps/openmw/mwrender/terrainstorage.cpp +++ b/apps/openmw/mwrender/terrainstorage.cpp @@ -22,6 +22,15 @@ namespace MWRender mResourceSystem->removeResourceManager(mLandManager.get()); } + bool TerrainStorage::hasData(int cellX, int cellY) + { + const MWWorld::ESMStore &esmStore = + MWBase::Environment::get().getWorld()->getStore(); + + const ESM::Land* land = esmStore.get().search(cellX, cellY); + return land != nullptr; + } + void TerrainStorage::getBounds(float& minX, float& maxX, float& minY, float& maxY) { minX = 0, minY = 0, maxX = 0, maxY = 0; diff --git a/apps/openmw/mwrender/terrainstorage.hpp b/apps/openmw/mwrender/terrainstorage.hpp index 6f716e752..cae56d3aa 100644 --- a/apps/openmw/mwrender/terrainstorage.hpp +++ b/apps/openmw/mwrender/terrainstorage.hpp @@ -23,6 +23,8 @@ namespace MWRender virtual osg::ref_ptr getLand (int cellX, int cellY); virtual const ESM::LandTexture* getLandTexture(int index, short plugin); + virtual bool hasData(int cellX, int cellY) override; + /// Get bounds of the whole terrain in cell units virtual void getBounds(float& minX, float& maxX, float& minY, float& maxY); diff --git a/components/terrain/quadtreeworld.cpp b/components/terrain/quadtreeworld.cpp index efe0dd58a..cf877142a 100644 --- a/components/terrain/quadtreeworld.cpp +++ b/components/terrain/quadtreeworld.cpp @@ -184,6 +184,11 @@ public: return node; } + // Do not add child nodes for default cells without data. + // size = 1 means that the single shape covers the whole cell. + if (node->getSize() == 1 && !mStorage->hasData(center.x()-0.5, center.y()-0.5)) + return node; + if (node->getSize() <= mMinSize) { // We arrived at a leaf diff --git a/components/terrain/storage.hpp b/components/terrain/storage.hpp index ebac1148c..3bc20aa59 100644 --- a/components/terrain/storage.hpp +++ b/components/terrain/storage.hpp @@ -28,6 +28,14 @@ namespace Terrain /// Get bounds of the whole terrain in cell units virtual void getBounds(float& minX, float& maxX, float& minY, float& maxY) = 0; + /// Return true if there is land data for this cell + /// May be overriden for a faster implementation + virtual bool hasData(int cellX, int cellY) + { + float dummy; + return getMinMaxHeights(1, osg::Vec2f(cellX+0.5, cellY+0.5), dummy, dummy); + } + /// Get the minimum and maximum heights of a terrain region. /// @note Will only be called for chunks with size = minBatchSize, i.e. leafs of the quad tree. /// Larger chunks can simply merge AABB of children.