#ifndef OPENMW_MWRENDER_GROUNDCOVER_H #define OPENMW_MWRENDER_GROUNDCOVER_H #include <components/terrain/quadtreeworld.hpp> #include <components/resource/scenemanager.hpp> #include <components/sceneutil/statesetupdater.hpp> #include <components/esm/loadcell.hpp> namespace MWRender { class GroundcoverUpdater : public SceneUtil::StateSetUpdater { public: GroundcoverUpdater() : mWindSpeed(0.f) , mPlayerPos(osg::Vec3f()) { } void setWindSpeed(float windSpeed); void setPlayerPos(osg::Vec3f playerPos); protected: void setDefaults(osg::StateSet *stateset) override; void apply(osg::StateSet *stateset, osg::NodeVisitor *nv) override; private: float mWindSpeed; osg::Vec3f mPlayerPos; }; typedef std::tuple<osg::Vec2f, float, bool> ChunkId; // Center, Size, ActiveGrid class Groundcover : public Resource::GenericResourceManager<ChunkId>, public Terrain::QuadTreeWorld::ChunkManager { public: Groundcover(Resource::SceneManager* sceneManager, float density); ~Groundcover() = default; 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; unsigned int getNodeMask() override; void reportStats(unsigned int frameNumber, osg::Stats* stats) const override; struct GroundcoverEntry { ESM::Position mPos; float mScale; std::string mModel; GroundcoverEntry(const ESM::CellRef& ref, const std::string& model) { mPos = ref.mPos; mScale = ref.mScale; mModel = model; } }; private: Resource::SceneManager* mSceneManager; float mDensity; typedef std::map<std::string, std::vector<GroundcoverEntry>> InstanceMap; osg::ref_ptr<osg::Node> createChunk(InstanceMap& instances, const osg::Vec2f& center); void collectInstances(InstanceMap& instances, float size, const osg::Vec2f& center); }; } #endif