2018-04-15 22:07:18 +00:00
|
|
|
#ifndef OPENMW_COMPONENTS_DETOURNAVIGATOR_TILECACHEDRECASTMESHMANAGER_H
|
|
|
|
#define OPENMW_COMPONENTS_DETOURNAVIGATOR_TILECACHEDRECASTMESHMANAGER_H
|
|
|
|
|
2022-08-26 18:33:34 +00:00
|
|
|
#include "areatype.hpp"
|
2022-02-01 00:21:47 +00:00
|
|
|
#include "changetype.hpp"
|
2018-04-15 22:07:18 +00:00
|
|
|
#include "commulativeaabb.hpp"
|
2020-02-25 02:38:39 +00:00
|
|
|
#include "gettilespositions.hpp"
|
2021-07-14 18:57:52 +00:00
|
|
|
#include "heightfieldshape.hpp"
|
2022-08-26 18:33:34 +00:00
|
|
|
#include "objectid.hpp"
|
|
|
|
#include "recastmesh.hpp"
|
|
|
|
#include "recastmeshobject.hpp"
|
2022-08-28 14:43:43 +00:00
|
|
|
#include "tileposition.hpp"
|
2023-04-20 23:45:21 +00:00
|
|
|
#include "updateguard.hpp"
|
2022-08-28 14:43:43 +00:00
|
|
|
#include "version.hpp"
|
2018-04-15 22:07:18 +00:00
|
|
|
|
2022-08-28 14:43:43 +00:00
|
|
|
#include <boost/geometry/geometries/box.hpp>
|
|
|
|
#include <boost/geometry/geometries/point.hpp>
|
|
|
|
#include <boost/geometry/index/rtree.hpp>
|
|
|
|
|
2023-04-21 00:13:40 +00:00
|
|
|
#include <LinearMath/btTransform.h>
|
|
|
|
|
|
|
|
#include <osg/Vec2i>
|
|
|
|
|
2018-04-15 22:07:18 +00:00
|
|
|
#include <map>
|
2023-04-21 00:13:40 +00:00
|
|
|
#include <memory>
|
2018-04-15 22:07:18 +00:00
|
|
|
#include <mutex>
|
2022-08-28 14:43:43 +00:00
|
|
|
#include <optional>
|
2023-04-21 00:13:40 +00:00
|
|
|
#include <unordered_map>
|
2018-04-15 22:07:18 +00:00
|
|
|
|
|
|
|
namespace DetourNavigator
|
|
|
|
{
|
2022-08-26 18:33:34 +00:00
|
|
|
class RecastMesh;
|
2024-05-19 18:03:34 +00:00
|
|
|
struct TileCachedRecastMeshManagerStats;
|
2022-08-26 18:33:34 +00:00
|
|
|
|
2018-04-15 22:07:18 +00:00
|
|
|
class TileCachedRecastMeshManager
|
|
|
|
{
|
|
|
|
public:
|
2021-11-06 12:46:43 +00:00
|
|
|
explicit TileCachedRecastMeshManager(const RecastSettings& settings);
|
2018-04-15 22:07:18 +00:00
|
|
|
|
2023-04-20 23:45:21 +00:00
|
|
|
ScopedUpdateGuard makeUpdateGuard()
|
|
|
|
{
|
|
|
|
mMutex.lock();
|
|
|
|
return ScopedUpdateGuard(&mUpdateGuard);
|
|
|
|
}
|
|
|
|
|
2023-01-15 02:24:37 +00:00
|
|
|
void setRange(const TilesPositionsRange& range, const UpdateGuard* guard);
|
2022-02-01 00:21:47 +00:00
|
|
|
|
2023-01-15 02:24:37 +00:00
|
|
|
TilesPositionsRange getLimitedObjectsRange() const;
|
2021-07-09 20:51:42 +00:00
|
|
|
|
2024-05-19 12:26:28 +00:00
|
|
|
void setWorldspace(ESM::RefId worldspace, const UpdateGuard* guard);
|
2021-07-09 20:51:42 +00:00
|
|
|
|
2022-09-05 07:23:14 +00:00
|
|
|
bool addObject(ObjectId id, const CollisionShape& shape, const btTransform& transform, AreaType areaType,
|
|
|
|
const UpdateGuard* guard);
|
2018-04-15 22:07:18 +00:00
|
|
|
|
2022-09-05 07:23:14 +00:00
|
|
|
bool updateObject(ObjectId id, const btTransform& transform, AreaType areaType, const UpdateGuard* guard);
|
2018-05-26 14:44:25 +00:00
|
|
|
|
2022-09-05 07:23:14 +00:00
|
|
|
void removeObject(ObjectId id, const UpdateGuard* guard);
|
2018-04-15 22:07:18 +00:00
|
|
|
|
2022-09-05 07:23:14 +00:00
|
|
|
void addWater(const osg::Vec2i& cellPosition, int cellSize, float level, const UpdateGuard* guard);
|
2018-07-20 19:11:34 +00:00
|
|
|
|
2022-09-05 07:23:14 +00:00
|
|
|
void removeWater(const osg::Vec2i& cellPosition, const UpdateGuard* guard);
|
2018-07-20 19:11:34 +00:00
|
|
|
|
2022-09-05 07:23:14 +00:00
|
|
|
void addHeightfield(
|
|
|
|
const osg::Vec2i& cellPosition, int cellSize, const HeightfieldShape& shape, const UpdateGuard* guard);
|
2021-07-14 18:57:52 +00:00
|
|
|
|
2022-09-05 07:23:14 +00:00
|
|
|
void removeHeightfield(const osg::Vec2i& cellPosition, const UpdateGuard* guard);
|
2021-07-14 18:57:52 +00:00
|
|
|
|
2024-05-19 12:26:28 +00:00
|
|
|
std::shared_ptr<RecastMesh> getMesh(ESM::RefId worldspace, const TilePosition& tilePosition);
|
2018-04-15 22:07:18 +00:00
|
|
|
|
2024-05-19 12:26:28 +00:00
|
|
|
std::shared_ptr<RecastMesh> getCachedMesh(ESM::RefId worldspace, const TilePosition& tilePosition) const;
|
2021-10-09 16:36:37 +00:00
|
|
|
|
2024-05-19 12:26:28 +00:00
|
|
|
std::shared_ptr<RecastMesh> getNewMesh(ESM::RefId worldspace, const TilePosition& tilePosition) const;
|
2021-06-29 01:49:21 +00:00
|
|
|
|
2022-08-26 18:33:34 +00:00
|
|
|
std::size_t getRevision() const { return mRevision; }
|
2018-04-20 23:57:01 +00:00
|
|
|
|
2022-08-28 14:43:43 +00:00
|
|
|
void reportNavMeshChange(const TilePosition& tilePosition, Version recastMeshVersion, Version navMeshVersion);
|
2021-04-18 14:51:52 +00:00
|
|
|
|
2022-08-26 18:33:34 +00:00
|
|
|
void addChangedTile(const TilePosition& tilePosition, ChangeType changeType);
|
|
|
|
|
2022-09-05 07:23:14 +00:00
|
|
|
std::map<osg::Vec2i, ChangeType> takeChangedTiles(const UpdateGuard* guard);
|
2022-08-26 18:33:34 +00:00
|
|
|
|
2024-05-19 18:03:34 +00:00
|
|
|
TileCachedRecastMeshManagerStats getStats() const;
|
|
|
|
|
2018-04-15 22:07:18 +00:00
|
|
|
private:
|
2022-08-28 14:43:43 +00:00
|
|
|
struct Report
|
|
|
|
{
|
|
|
|
std::size_t mRevision;
|
|
|
|
Version mNavMeshVersion;
|
|
|
|
};
|
2021-08-01 00:43:36 +00:00
|
|
|
|
2022-02-01 00:21:47 +00:00
|
|
|
struct ObjectData
|
|
|
|
{
|
2022-08-28 14:43:43 +00:00
|
|
|
RecastMeshObject mObject;
|
|
|
|
TilesPositionsRange mRange;
|
|
|
|
CommulativeAabb mAabb;
|
|
|
|
std::size_t mGeneration = 0;
|
|
|
|
std::size_t mRevision = 0;
|
|
|
|
std::optional<Report> mLastNavMeshReportedChange;
|
|
|
|
std::optional<Report> mLastNavMeshReport;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct WaterData
|
|
|
|
{
|
|
|
|
Water mWater;
|
|
|
|
std::optional<TilesPositionsRange> mRange;
|
|
|
|
std::size_t mRevision;
|
2022-02-01 00:21:47 +00:00
|
|
|
};
|
|
|
|
|
2022-08-28 14:43:43 +00:00
|
|
|
struct HeightfieldData
|
2022-02-03 21:24:26 +00:00
|
|
|
{
|
2022-08-28 14:43:43 +00:00
|
|
|
int mCellSize;
|
|
|
|
HeightfieldShape mShape;
|
|
|
|
std::optional<TilesPositionsRange> mRange;
|
|
|
|
std::size_t mRevision;
|
2022-02-03 21:24:26 +00:00
|
|
|
};
|
|
|
|
|
2022-08-28 14:43:43 +00:00
|
|
|
struct CachedTile
|
|
|
|
{
|
|
|
|
Version mVersion;
|
|
|
|
std::shared_ptr<RecastMesh> mRecastMesh;
|
|
|
|
};
|
|
|
|
|
|
|
|
using IndexPoint = boost::geometry::model::point<int, 2, boost::geometry::cs::cartesian>;
|
|
|
|
using IndexBox = boost::geometry::model::box<IndexPoint>;
|
|
|
|
using ObjectIndexValue = std::pair<IndexBox, ObjectData*>;
|
|
|
|
using WaterIndexValue = std::pair<IndexBox, std::map<osg::Vec2i, WaterData>::const_iterator>;
|
|
|
|
using HeightfieldIndexValue = std::pair<IndexBox, std::map<osg::Vec2i, HeightfieldData>::const_iterator>;
|
|
|
|
|
2021-11-06 12:46:43 +00:00
|
|
|
const RecastSettings& mSettings;
|
2022-02-01 00:21:47 +00:00
|
|
|
TilesPositionsRange mRange;
|
2024-05-19 12:26:28 +00:00
|
|
|
ESM::RefId mWorldspace;
|
2022-08-28 14:43:43 +00:00
|
|
|
std::unordered_map<ObjectId, std::unique_ptr<ObjectData>> mObjects;
|
|
|
|
boost::geometry::index::rtree<ObjectIndexValue, boost::geometry::index::quadratic<16>> mObjectIndex;
|
|
|
|
std::map<osg::Vec2i, WaterData> mWater;
|
|
|
|
std::map<osg::Vec2i, WaterData>::const_iterator mInfiniteWater = mWater.end();
|
|
|
|
boost::geometry::index::rtree<WaterIndexValue, boost::geometry::index::linear<4>> mWaterIndex;
|
|
|
|
std::map<osg::Vec2i, HeightfieldData> mHeightfields;
|
|
|
|
std::map<osg::Vec2i, HeightfieldData>::const_iterator mInfiniteHeightfield = mHeightfields.end();
|
|
|
|
boost::geometry::index::rtree<HeightfieldIndexValue, boost::geometry::index::linear<4>> mHeightfieldIndex;
|
2022-08-26 18:33:34 +00:00
|
|
|
std::map<osg::Vec2i, ChangeType> mChangedTiles;
|
2022-08-28 14:43:43 +00:00
|
|
|
std::map<TilePosition, CachedTile> mCache;
|
|
|
|
std::size_t mGeneration = 0;
|
2018-04-20 23:57:01 +00:00
|
|
|
std::size_t mRevision = 0;
|
2022-08-28 14:43:43 +00:00
|
|
|
mutable std::mutex mMutex;
|
2023-04-20 23:45:21 +00:00
|
|
|
UpdateGuard mUpdateGuard{ mMutex };
|
2022-08-28 14:43:43 +00:00
|
|
|
|
|
|
|
inline static IndexPoint makeIndexPoint(const TilePosition& tilePosition);
|
|
|
|
|
|
|
|
inline static IndexBox makeIndexBox(const TilesPositionsRange& range);
|
|
|
|
|
|
|
|
inline static ObjectIndexValue makeObjectIndexValue(const TilesPositionsRange& range, ObjectData* data);
|
|
|
|
|
|
|
|
inline static WaterIndexValue makeWaterIndexValue(
|
|
|
|
const TilesPositionsRange& range, std::map<osg::Vec2i, WaterData>::const_iterator it);
|
|
|
|
|
|
|
|
inline static HeightfieldIndexValue makeHeightfieldIndexValue(
|
|
|
|
const TilesPositionsRange& range, std::map<osg::Vec2i, HeightfieldData>::const_iterator it);
|
2019-02-16 21:48:07 +00:00
|
|
|
|
2022-08-28 14:43:43 +00:00
|
|
|
inline static auto makeIndexQuery(const TilePosition& tilePosition)
|
|
|
|
-> decltype(boost::geometry::index::intersects(IndexBox()));
|
2019-02-16 21:48:07 +00:00
|
|
|
|
2022-08-28 14:43:43 +00:00
|
|
|
inline std::shared_ptr<RecastMesh> makeMesh(const TilePosition& tilePosition) const;
|
2021-10-09 16:36:37 +00:00
|
|
|
|
2022-08-28 14:43:43 +00:00
|
|
|
inline void addChangedTiles(const std::optional<TilesPositionsRange>& range, ChangeType changeType);
|
2018-04-15 22:07:18 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|