From 17637c65759fd93008672dc1704dd0dd05783fea Mon Sep 17 00:00:00 2001 From: bzzt lost a hitlab login Date: Fri, 8 May 2020 13:37:00 +0000 Subject: [PATCH] pagerebuild on disable Signed-off-by: Bret Curtis --- apps/openmw/mwrender/objectpaging.cpp | 47 ++++++++++++++++++++--- apps/openmw/mwrender/objectpaging.hpp | 4 +- apps/openmw/mwrender/renderingmanager.cpp | 6 +-- apps/openmw/mwrender/renderingmanager.hpp | 2 +- apps/openmw/mwworld/worldimp.cpp | 10 ++++- components/resource/objectcache.hpp | 4 +- components/terrain/quadtreeworld.cpp | 7 ++++ components/terrain/quadtreeworld.hpp | 1 + components/terrain/texturemanager.cpp | 2 +- components/terrain/viewdata.cpp | 20 ++++++++++ components/terrain/viewdata.hpp | 2 + components/terrain/world.hpp | 2 + 12 files changed, 91 insertions(+), 16 deletions(-) diff --git a/apps/openmw/mwrender/objectpaging.cpp b/apps/openmw/mwrender/objectpaging.cpp index d30bd7a63..eb71f0993 100644 --- a/apps/openmw/mwrender/objectpaging.cpp +++ b/apps/openmw/mwrender/objectpaging.cpp @@ -576,17 +576,52 @@ namespace MWRender return Mask_Static; } - void ObjectPaging::enableObject(const ESM::RefNum & refnum, bool enabled) + struct ClearCacheFunctor { - OpenThreads::ScopedLock lock(mDisabledMutex); - if (enabled) mDisabled.erase(refnum); - else mDisabled.insert(refnum); + void operator()(MWRender::ChunkId id, osg::Object* obj) + { + if (intersects(id, mPosition)) + mToClear.insert(id); + } + bool intersects(ChunkId id, osg::Vec3f pos) + { + pos /= ESM::Land::REAL_SIZE; + osg::Vec2f center = std::get<0>(id); + float halfSize = std::get<1>(id)/2; + return pos.x() >= center.x()-halfSize && pos.y() >= center.y()-halfSize && pos.x() <= center.x()+halfSize && pos.y() <= center.y()+halfSize; + } + osg::Vec3f mPosition; + std::set mToClear; + }; + + bool ObjectPaging::enableObject(int type, const ESM::RefNum & refnum, const osg::Vec3f& pos, bool enabled) + { + if (!typeFilter(type, false)) + return false; + + { + OpenThreads::ScopedLock lock(mDisabledMutex); + if (enabled && !mDisabled.erase(refnum)) return false; + if (!enabled && !mDisabled.insert(refnum).second) return false; + } + + ClearCacheFunctor ccf; + ccf.mPosition = pos; + mCache->call(ccf); + for (auto chunk : ccf.mToClear) + mCache->removeFromObjectCache(chunk); + return true; } void ObjectPaging::clear() { - OpenThreads::ScopedLock lock(mDisabledMutex); - mDisabled.clear(); + { + OpenThreads::ScopedLock lock(mDisabledMutex); + if (mDisabled.empty()) + return; + mDisabled.clear(); + } + mCache->clear(); } void ObjectPaging::reportStats(unsigned int frameNumber, osg::Stats *stats) const diff --git a/apps/openmw/mwrender/objectpaging.hpp b/apps/openmw/mwrender/objectpaging.hpp index 57121ae76..93423f21e 100644 --- a/apps/openmw/mwrender/objectpaging.hpp +++ b/apps/openmw/mwrender/objectpaging.hpp @@ -33,7 +33,9 @@ namespace MWRender virtual unsigned int getNodeMask() override; - void enableObject(const ESM::RefNum & refnum, bool enabled); + /// @return true if something changed + bool enableObject(int type, const ESM::RefNum & refnum, const osg::Vec3f& pos, bool enabled); + void clear(); void reportStats(unsigned int frameNumber, osg::Stats* stats) const override; diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index a545e0674..9d435a612 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -1481,9 +1481,9 @@ namespace MWRender { mTerrain->setActiveGrid(grid); } - void RenderingManager::pagingEnableObject(const ESM::RefNum & refnum, bool enabled) + void RenderingManager::pagingEnableObject(int type, const MWWorld::ConstPtr& ptr, bool enabled) { - if (mObjectPaging) - mObjectPaging->enableObject(refnum, enabled); + if (mObjectPaging && mObjectPaging->enableObject(type, ptr.getCellRef().getRefNum(), ptr.getRefData().getPosition().asVec3(), enabled)) + mTerrain->clearCachedViews(ptr.getRefData().getPosition().asVec3()); } } diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index 6bf122232..36df09202 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -241,7 +241,7 @@ namespace MWRender void setActiveGrid(const osg::Vec4i &grid); - void pagingEnableObject(const ESM::RefNum & refnum, bool enabled); + void pagingEnableObject(int type, const MWWorld::ConstPtr& ptr, bool enabled); private: void updateProjectionMatrix(); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 5f4f9d1cd..fdb54fb75 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -815,7 +815,10 @@ namespace MWWorld mWorldScene->addObjectToScene (reference); if (reference.getCellRef().getRefNum().hasContentFile()) - mRendering->pagingEnableObject(reference.getCellRef().getRefNum(), true); + { + int type = mStore.find(Misc::StringUtils::lowerCase(reference.getCellRef().getRefId())); + mRendering->pagingEnableObject(type, reference, true); + } } } @@ -853,7 +856,10 @@ namespace MWWorld reference.getRefData().disable(); if (reference.getCellRef().getRefNum().hasContentFile()) - mRendering->pagingEnableObject(reference.getCellRef().getRefNum(), false); + { + int type = mStore.find(Misc::StringUtils::lowerCase(reference.getCellRef().getRefId())); + mRendering->pagingEnableObject(type, reference, false); + } if(mWorldScene->getActiveCells().find (reference.getCell())!=mWorldScene->getActiveCells().end() && reference.getRefData().getCount()) mWorldScene->removeObjectFromScene (reference); diff --git a/components/resource/objectcache.hpp b/components/resource/objectcache.hpp index cfd41f19c..24d7d04a9 100644 --- a/components/resource/objectcache.hpp +++ b/components/resource/objectcache.hpp @@ -161,13 +161,13 @@ class GenericObjectCache : public osg::Referenced } } - /** call operator()(osg::Object*) for each object in the cache. */ + /** call operator()(KeyType, osg::Object*) for each object in the cache. */ template void call(Functor& f) { OpenThreads::ScopedLock lock(_objectCacheMutex); for (typename ObjectCacheMap::iterator it = _objectCache.begin(); it != _objectCache.end(); ++it) - f(it->second.first.get()); + f(it->first, it->second.first.get()); } /** Get the number of objects in the cache. */ diff --git a/components/terrain/quadtreeworld.cpp b/components/terrain/quadtreeworld.cpp index cdb9e6191..92bd09bd0 100644 --- a/components/terrain/quadtreeworld.cpp +++ b/components/terrain/quadtreeworld.cpp @@ -574,4 +574,11 @@ void QuadTreeWorld::addChunkManager(QuadTreeWorld::ChunkManager* m) mTerrainRoot->setNodeMask(mTerrainRoot->getNodeMask()|m->getNodeMask()); } +void QuadTreeWorld::clearCachedViews(const osg::Vec3f &pos) +{ +//mViewDataMap->clear(); + osg::Vec3 pos_ = pos / mStorage->getCellWorldSize(); + mViewDataMap->clearCachedViews(pos_); +} + } diff --git a/components/terrain/quadtreeworld.hpp b/components/terrain/quadtreeworld.hpp index 97fcd004d..7c01f5c27 100644 --- a/components/terrain/quadtreeworld.hpp +++ b/components/terrain/quadtreeworld.hpp @@ -40,6 +40,7 @@ namespace Terrain View* createView(); void preload(View* view, const osg::Vec3f& eyePoint, const osg::Vec4i &cellgrid, std::atomic& abort, std::atomic& progress, int& progressRange); void storeView(const View* view, double referenceTime); + void clearCachedViews(const osg::Vec3f& pos) override; void reportStats(unsigned int frameNumber, osg::Stats* stats); diff --git a/components/terrain/texturemanager.cpp b/components/terrain/texturemanager.cpp index b901fa159..c28b13f1d 100644 --- a/components/terrain/texturemanager.cpp +++ b/components/terrain/texturemanager.cpp @@ -25,7 +25,7 @@ struct UpdateTextureFilteringFunctor } Resource::SceneManager* mSceneManager; - void operator()(osg::Object* obj) + void operator()(std::string, osg::Object* obj) { mSceneManager->applyFilterSettings(static_cast(obj)); } diff --git a/components/terrain/viewdata.cpp b/components/terrain/viewdata.cpp index 6399425a4..e5e856cad 100644 --- a/components/terrain/viewdata.cpp +++ b/components/terrain/viewdata.cpp @@ -1,5 +1,7 @@ #include "viewdata.hpp" +#include "quadtreenode.hpp" + namespace Terrain { @@ -99,6 +101,18 @@ bool ViewData::contains(QuadTreeNode *node) return false; } +bool intersects(const osg::Vec2f& center, float halfSize, osg::Vec3f pos) +{ + return (pos.x() >= center.x()-halfSize && pos.y() >= center.y()-halfSize && pos.x() <= center.x()+halfSize && pos.y() <= center.y()+halfSize); +} + +void ViewData::clearCache(const osg::Vec3f &cellPos) +{ + for (Entry& entry : mEntries) + if (entry.mNode && intersects(entry.mNode->getCenter(), entry.mNode->getSize()/2.f, cellPos)) + entry.mRenderingNode = nullptr; +} + ViewData::Entry::Entry() : mNode(nullptr) , mLodFlags(0) @@ -188,6 +202,12 @@ void ViewDataMap::clearUnusedViews(double referenceTime) } } +void ViewDataMap::clearCachedViews(const osg::Vec3f &cellPos) +{ + for (auto pair : mViews) + pair.second->clearCache(cellPos); +} + void ViewDataMap::clear() { mViews.clear(); diff --git a/components/terrain/viewdata.hpp b/components/terrain/viewdata.hpp index 87b45f57b..f21f56ae1 100644 --- a/components/terrain/viewdata.hpp +++ b/components/terrain/viewdata.hpp @@ -24,6 +24,7 @@ namespace Terrain void reset(); void clear(); + void clearCache(const osg::Vec3f &cellPos); bool contains(QuadTreeNode* node); @@ -84,6 +85,7 @@ namespace Terrain ViewData* createOrReuseView(); void clearUnusedViews(double referenceTime); + void clearCachedViews(const osg::Vec3f &cellPos); void clear(); diff --git a/components/terrain/world.hpp b/components/terrain/world.hpp index dba79994a..4ad4e5f0a 100644 --- a/components/terrain/world.hpp +++ b/components/terrain/world.hpp @@ -153,6 +153,8 @@ namespace Terrain /// @note Not thread safe. virtual void storeView(const View* view, double referenceTime) {} + virtual void clearCachedViews(const osg::Vec3f& pos) {} + virtual void reportStats(unsigned int frameNumber, osg::Stats* stats) {} virtual void setViewDistance(float distance) {}