diff --git a/apps/openmw/mwrender/objectpaging.cpp b/apps/openmw/mwrender/objectpaging.cpp index 20d69bcf11..53af609a71 100644 --- a/apps/openmw/mwrender/objectpaging.cpp +++ b/apps/openmw/mwrender/objectpaging.cpp @@ -1,6 +1,7 @@ #include "objectpaging.hpp" #include +#include #include #include @@ -276,7 +277,7 @@ namespace MWRender RefnumSet(){} RefnumSet(const RefnumSet& copy, const osg::CopyOp&) : mRefnums(copy.mRefnums) {} META_Object(MWRender, RefnumSet) - std::set mRefnums; + std::vector mRefnums; }; class AnalyzeVisitor : public osg::NodeVisitor @@ -554,7 +555,7 @@ namespace MWRender if (cnode->getNumChildrenRequiringUpdateTraversal() > 0 || SceneUtil::hasUserDescription(cnode, Constants::NightDayLabel) || SceneUtil::hasUserDescription(cnode, Constants::HerbalismLabel)) continue; else - refnumSet->mRefnums.insert(pair.first); + refnumSet->mRefnums.push_back(pair.first); } { @@ -727,6 +728,8 @@ namespace MWRender osg::UserDataContainer* udc = group->getOrCreateUserDataContainer(); if (activeGrid) { + std::sort(refnumSet->mRefnums.begin(), refnumSet->mRefnums.end()); + refnumSet->mRefnums.erase(std::unique(refnumSet->mRefnums.begin(), refnumSet->mRefnums.end()), refnumSet->mRefnums.end()); udc->addUserObject(refnumSet); group->addCullCallback(new SceneUtil::LightListCallback); } @@ -837,7 +840,7 @@ namespace MWRender struct GetRefnumsFunctor { - GetRefnumsFunctor(std::set& output) : mOutput(output) {} + GetRefnumsFunctor(std::vector& output) : mOutput(output) {} void operator()(MWRender::ChunkId chunkId, osg::Object* obj) { if (!std::get<2>(chunkId)) return; @@ -850,18 +853,20 @@ namespace MWRender { RefnumSet* refnums = dynamic_cast(udc->getUserObject(0)); if (!refnums) return; - mOutput.insert(refnums->mRefnums.begin(), refnums->mRefnums.end()); + mOutput.insert(mOutput.end(), refnums->mRefnums.begin(), refnums->mRefnums.end()); } } osg::Vec4i mActiveGrid; - std::set& mOutput; + std::vector& mOutput; }; - void ObjectPaging::getPagedRefnums(const osg::Vec4i &activeGrid, std::set &out) + void ObjectPaging::getPagedRefnums(const osg::Vec4i &activeGrid, std::vector& out) { GetRefnumsFunctor grf(out); grf.mActiveGrid = activeGrid; mCache->call(grf); + std::sort(out.begin(), out.end()); + out.erase(std::unique(out.begin(), out.end()), out.end()); } 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 940760ff6c..4820f150ab 100644 --- a/apps/openmw/mwrender/objectpaging.hpp +++ b/apps/openmw/mwrender/objectpaging.hpp @@ -47,7 +47,7 @@ namespace MWRender void reportStats(unsigned int frameNumber, osg::Stats* stats) const override; - void getPagedRefnums(const osg::Vec4i &activeGrid, std::set &out); + void getPagedRefnums(const osg::Vec4i &activeGrid, std::vector& out); private: Resource::SceneManager* mSceneManager; diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 8c39c13941..dcf66fc05b 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -1616,7 +1616,7 @@ namespace MWRender } return false; } - void RenderingManager::getPagedRefnums(const osg::Vec4i &activeGrid, std::set &out) + void RenderingManager::getPagedRefnums(const osg::Vec4i &activeGrid, std::vector& out) { if (mObjectPaging) mObjectPaging->getPagedRefnums(activeGrid, out); diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index 10b4872650..83dfd32287 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -250,7 +250,7 @@ namespace MWRender bool pagingEnableObject(int type, const MWWorld::ConstPtr& ptr, bool enabled); void pagingBlacklistObject(int type, const MWWorld::ConstPtr &ptr); bool pagingUnlockCache(); - void getPagedRefnums(const osg::Vec4i &activeGrid, std::set &out); + void getPagedRefnums(const osg::Vec4i &activeGrid, std::vector& out); void updateProjectionMatrix(); diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index 63c21d1a1b..e60be693e7 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -99,8 +99,8 @@ namespace return model; } - void addObject(const MWWorld::Ptr& ptr, const MWWorld::World& world, MWPhysics::PhysicsSystem& physics, - MWRender::RenderingManager& rendering, std::set& pagedRefs) + void addObject(const MWWorld::Ptr& ptr, const MWWorld::World& world, const std::vector& pagedRefs, + MWPhysics::PhysicsSystem& physics, MWRender::RenderingManager& rendering) { if (ptr.getRefData().getBaseNode() || physics.getActor(ptr)) { @@ -112,7 +112,7 @@ namespace const auto rotation = makeDirectNodeRotation(ptr); const ESM::RefNum& refnum = ptr.getCellRef().getRefNum(); - if (!refnum.hasContentFile() || pagedRefs.find(refnum) == pagedRefs.end()) + if (!refnum.hasContentFile() || !std::binary_search(pagedRefs.begin(), pagedRefs.end(), refnum)) ptr.getClass().insertObjectRendering(ptr, model, rendering); else ptr.getRefData().setBaseNode(new SceneUtil::PositionAttitudeTransform); // FIXME remove this when physics code is fixed not to depend on basenode @@ -255,6 +255,15 @@ namespace } return false; } + + bool removeFromSorted(const ESM::RefNum& refNum, std::vector& pagedRefs) + { + const auto it = std::lower_bound(pagedRefs.begin(), pagedRefs.end(), refNum); + if (it == pagedRefs.end() || *it != refNum) + return false; + pagedRefs.erase(it); + return true; + } } @@ -264,7 +273,7 @@ namespace MWWorld void Scene::removeFromPagedRefs(const Ptr &ptr) { const ESM::RefNum& refnum = ptr.getCellRef().getRefNum(); - if (refnum.hasContentFile() && mPagedRefs.erase(refnum)) + if (refnum.hasContentFile() && removeFromSorted(refnum, mPagedRefs)) { if (!ptr.getRefData().getBaseNode()) return; ptr.getClass().insertObjectRendering(ptr, getModel(ptr, mRendering.getResourceSystem()->getVFS()), mRendering); @@ -900,7 +909,7 @@ namespace MWWorld { InsertVisitor insertVisitor(cell, loadingListener); cell.forEach (insertVisitor); - insertVisitor.insert([&] (const MWWorld::Ptr& ptr) { addObject(ptr, mWorld, *mPhysics, mRendering, mPagedRefs); }); + insertVisitor.insert([&] (const MWWorld::Ptr& ptr) { addObject(ptr, mWorld, mPagedRefs, *mPhysics, mRendering); }); insertVisitor.insert([&] (const MWWorld::Ptr& ptr) { addObject(ptr, mWorld, *mPhysics, mNavigator); }); } @@ -908,7 +917,7 @@ namespace MWWorld { try { - addObject(ptr, mWorld, *mPhysics, mRendering, mPagedRefs); + addObject(ptr, mWorld, mPagedRefs, *mPhysics, mRendering); addObject(ptr, mWorld, *mPhysics, mNavigator); mWorld.scaleObject(ptr, ptr.getCellRef().getScale()); if (mCurrentCell != nullptr) diff --git a/apps/openmw/mwworld/scene.hpp b/apps/openmw/mwworld/scene.hpp index c504a2cf73..38e39e9450 100644 --- a/apps/openmw/mwworld/scene.hpp +++ b/apps/openmw/mwworld/scene.hpp @@ -104,7 +104,7 @@ namespace MWWorld osg::Vec3f mLastPlayerPos; - std::set mPagedRefs; + std::vector mPagedRefs; std::vector> mWorkItems;