#ifndef OPENMW_COMPONENTS_DETOURNAVIGATOR_RECASTMESHMANAGER_H #define OPENMW_COMPONENTS_DETOURNAVIGATOR_RECASTMESHMANAGER_H #include "oscillatingrecastmeshobject.hpp" #include "objectid.hpp" #include "version.hpp" #include "recastmesh.hpp" #include "heightfieldshape.hpp" #include <LinearMath/btTransform.h> #include <osg/Vec2i> #include <map> #include <optional> #include <memory> #include <variant> #include <tuple> #include <mutex> class btCollisionShape; namespace DetourNavigator { struct Settings; class RecastMesh; struct RemovedRecastMeshObject { std::reference_wrapper<const btCollisionShape> mShape; btTransform mTransform; }; class RecastMeshManager { public: RecastMeshManager(const Settings& settings, const TileBounds& bounds, std::size_t generation); bool addObject(const ObjectId id, const CollisionShape& shape, const btTransform& transform, const AreaType areaType); bool updateObject(const ObjectId id, const btTransform& transform, const AreaType areaType); std::optional<RemovedRecastMeshObject> removeObject(const ObjectId id); bool addWater(const osg::Vec2i& cellPosition, const int cellSize, const osg::Vec3f& shift); std::optional<Cell> removeWater(const osg::Vec2i& cellPosition); bool addHeightfield(const osg::Vec2i& cellPosition, int cellSize, const osg::Vec3f& shift, const HeightfieldShape& shape); std::optional<Cell> removeHeightfield(const osg::Vec2i& cellPosition); std::shared_ptr<RecastMesh> getMesh() const; bool isEmpty() const; void reportNavMeshChange(const Version& recastMeshVersion, const Version& navMeshVersion); Version getVersion() const; private: struct Report { std::size_t mRevision; Version mNavMeshVersion; }; struct Heightfield { Cell mCell; HeightfieldShape mShape; }; const Settings& mSettings; const std::size_t mGeneration; const TileBounds mTileBounds; mutable std::mutex mMutex; std::size_t mRevision = 0; std::map<ObjectId, OscillatingRecastMeshObject> mObjects; std::map<osg::Vec2i, Cell> mWater; std::map<osg::Vec2i, Heightfield> mHeightfields; std::optional<Report> mLastNavMeshReportedChange; std::optional<Report> mLastNavMeshReport; }; } #endif