1 #ifndef OPENMW_MWRENDER_OBJECTPAGING_H
2 #define OPENMW_MWRENDER_OBJECTPAGING_H
3 
4 #include <components/terrain/quadtreeworld.hpp>
5 #include <components/resource/resourcemanager.hpp>
6 #include <components/esm/loadcell.hpp>
7 
8 #include <mutex>
9 
10 namespace Resource
11 {
12     class SceneManager;
13 }
14 namespace MWWorld
15 {
16     class ESMStore;
17 }
18 
19 namespace MWRender
20 {
21 
22     typedef std::tuple<osg::Vec2f, float, bool> ChunkId; // Center, Size, ActiveGrid
23 
24     class ObjectPaging : public Resource::GenericResourceManager<ChunkId>, public Terrain::QuadTreeWorld::ChunkManager
25     {
26     public:
27         ObjectPaging(Resource::SceneManager* sceneManager);
28         ~ObjectPaging() = default;
29 
30         osg::ref_ptr<osg::Node> getChunk(float size, const osg::Vec2f& center, unsigned char lod, unsigned int lodFlags, bool activeGrid, const osg::Vec3f& viewPoint, bool compile) override;
31 
32         osg::ref_ptr<osg::Node> createChunk(float size, const osg::Vec2f& center, bool activeGrid, const osg::Vec3f& viewPoint, bool compile);
33 
34         unsigned int getNodeMask() override;
35 
36         /// @return true if view needs rebuild
37         bool enableObject(int type, const ESM::RefNum & refnum, const osg::Vec3f& pos, const osg::Vec2i& cell, bool enabled);
38 
39         /// @return true if view needs rebuild
40         bool blacklistObject(int type, const ESM::RefNum & refnum, const osg::Vec3f& pos, const osg::Vec2i& cell);
41 
42         void clear();
43 
44         /// Must be called after clear() before rendering starts.
45         /// @return true if view needs rebuild
46         bool unlockCache();
47 
48         void reportStats(unsigned int frameNumber, osg::Stats* stats) const override;
49 
50         void getPagedRefnums(const osg::Vec4i &activeGrid, std::set<ESM::RefNum> &out);
51 
52     private:
53         Resource::SceneManager* mSceneManager;
54         bool mActiveGrid;
55         bool mDebugBatches;
56         float mMergeFactor;
57         float mMinSize;
58         float mMinSizeMergeFactor;
59         float mMinSizeCostMultiplier;
60 
61         std::mutex mRefTrackerMutex;
62         struct RefTracker
63         {
64             std::set<ESM::RefNum> mDisabled;
65             std::set<ESM::RefNum> mBlacklist;
operator ==MWRender::ObjectPaging::RefTracker66             bool operator==(const RefTracker&other) const { return mDisabled == other.mDisabled && mBlacklist == other.mBlacklist; }
67         };
68         RefTracker mRefTracker;
69         RefTracker mRefTrackerNew;
70         bool mRefTrackerLocked;
71 
getRefTracker() const72         const RefTracker& getRefTracker() const { return mRefTracker; }
getWritableRefTracker()73         RefTracker& getWritableRefTracker() { return mRefTrackerLocked ? mRefTrackerNew : mRefTracker; }
74 
75         std::mutex mSizeCacheMutex;
76         typedef std::map<ESM::RefNum, float> SizeCache;
77         SizeCache mSizeCache;
78     };
79 
80     class RefnumMarker : public osg::Object
81     {
82     public:
RefnumMarker()83         RefnumMarker() : mNumVertices(0) { mRefnum.unset(); }
RefnumMarker(const RefnumMarker & copy,osg::CopyOp co)84         RefnumMarker(const RefnumMarker &copy, osg::CopyOp co) : mRefnum(copy.mRefnum), mNumVertices(copy.mNumVertices) {}
85         META_Object(MWRender, RefnumMarker)
86 
87         ESM::RefNum mRefnum;
88         unsigned int mNumVertices;
89     };
90 }
91 
92 #endif
93