diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 1728af659..217e6d367 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -57,7 +57,7 @@ namespace MWMechanics namespace DetourNavigator { - class Navigator; + struct Navigator; } namespace MWWorld diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index 2a48097bd..e04404f2b 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -59,7 +59,7 @@ namespace SceneUtil namespace DetourNavigator { - class Navigator; + struct Navigator; struct Settings; } diff --git a/apps/openmw/mwworld/scene.hpp b/apps/openmw/mwworld/scene.hpp index 00f5f98b8..0f1ae7298 100644 --- a/apps/openmw/mwworld/scene.hpp +++ b/apps/openmw/mwworld/scene.hpp @@ -30,7 +30,7 @@ namespace Loading namespace DetourNavigator { - class Navigator; + struct Navigator; class Water; } diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index a6f0616e2..65d629384 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -24,7 +24,7 @@ #include #include -#include +#include #include #include "../mwbase/environment.hpp" @@ -206,7 +206,7 @@ namespace MWWorld DetourNavigator::Log::instance().setSink(std::unique_ptr( new DetourNavigator::FileSink(Settings::Manager::getString("log path", "Navigator")))); DetourNavigator::RecastGlobalAllocator::init(); - mNavigator.reset(new DetourNavigator::Navigator(navigatorSettings)); + mNavigator.reset(new DetourNavigator::NavigatorImpl(navigatorSettings)); mRendering.reset(new MWRender::RenderingManager(viewer, rootNode, resourceSystem, workQueue, &mFallback, resourcePath, *mNavigator)); mProjectileManager.reset(new ProjectileManager(mRendering->getLightRoot(), resourceSystem, mRendering.get(), mPhysics.get())); diff --git a/apps/openmw_test_suite/detournavigator/navigator.cpp b/apps/openmw_test_suite/detournavigator/navigator.cpp index febbc0387..288392143 100644 --- a/apps/openmw_test_suite/detournavigator/navigator.cpp +++ b/apps/openmw_test_suite/detournavigator/navigator.cpp @@ -1,6 +1,6 @@ #include "operators.hpp" -#include +#include #include #include @@ -61,7 +61,7 @@ namespace mSettings.mMaxSmoothPathSize = 1024; mSettings.mTrianglesPerChunk = 256; mSettings.mMaxPolys = 4096; - mNavigator.reset(new Navigator(mSettings)); + mNavigator.reset(new NavigatorImpl(mSettings)); } }; diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index bb45542e4..50fd59006 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -164,7 +164,7 @@ add_component_dir(detournavigator recastmeshmanager cachedrecastmeshmanager navmeshmanager - navigator + navigatorimpl asyncnavmeshupdater chunkytrimesh recastmesh diff --git a/components/detournavigator/navigator.hpp b/components/detournavigator/navigator.hpp index 0bdc79e8a..529b539c8 100644 --- a/components/detournavigator/navigator.hpp +++ b/components/detournavigator/navigator.hpp @@ -3,9 +3,9 @@ #include "findsmoothpath.hpp" #include "flags.hpp" -#include "navmeshmanager.hpp" #include "settings.hpp" -#include "settingsutils.hpp" +#include "objectid.hpp" +#include "navmeshcacheitem.hpp" namespace DetourNavigator { @@ -33,33 +33,28 @@ namespace DetourNavigator }; /** - * @brief Top level class of detournavigator componenet. Navigator allows to build a scene with navmesh and find + * @brief Top level interface of detournavigator component. Navigator allows to build a scene with navmesh and find * a path for an agent there. Scene contains agents, geometry objects and water. Agent are distinguished only by * half extents. Each object has unique identifier and could be added, updated or removed. Water could be added once * for each world cell at given level of height. Navmesh builds asynchronously in separate threads. To start build * navmesh call update method. */ - class Navigator + struct Navigator { - public: - /** - * @brief Navigator constructor initializes all internal data. Constructed object is ready to build a scene. - * @param settings allows to customize navigator work. Constructor is only place to set navigator settings. - */ - Navigator(const Settings& settings); + virtual ~Navigator() = default; /** * @brief addAgent should be called for each agent even if all of them has same half extents. * @param agentHalfExtents allows to setup bounding cylinder for each agent, for each different half extents * there is different navmesh. */ - void addAgent(const osg::Vec3f& agentHalfExtents); + virtual void addAgent(const osg::Vec3f& agentHalfExtents) = 0; /** * @brief removeAgent should be called for each agent even if all of them has same half extents * @param agentHalfExtents allows determine which agent to remove */ - void removeAgent(const osg::Vec3f& agentHalfExtents); + virtual void removeAgent(const osg::Vec3f& agentHalfExtents) = 0; /** * @brief addObject is used to add object represented by single btCollisionShape and btTransform. @@ -68,7 +63,7 @@ namespace DetourNavigator * @param transform allows to setup object geometry according to its world state. * @return true if object is added, false if there is already object with given id. */ - bool addObject(const ObjectId id, const btCollisionShape& shape, const btTransform& transform); + virtual bool addObject(const ObjectId id, const btCollisionShape& shape, const btTransform& transform) = 0; /** * @brief addObject is used to add complex object with allowed to walk and avoided to walk shapes @@ -77,7 +72,7 @@ namespace DetourNavigator * @param transform allows to setup objects geometry according to its world state * @return true if object is added, false if there is already object with given id */ - bool addObject(const ObjectId id, const ObjectShapes& shapes, const btTransform& transform); + virtual bool addObject(const ObjectId id, const ObjectShapes& shapes, const btTransform& transform) = 0; /** * @brief addObject is used to add doors. @@ -86,7 +81,7 @@ namespace DetourNavigator * @param transform allows to setup objects geometry according to its world state. * @return true if object is added, false if there is already object with given id. */ - bool addObject(const ObjectId id, const DoorShapes& shapes, const btTransform& transform); + virtual bool addObject(const ObjectId id, const DoorShapes& shapes, const btTransform& transform) = 0; /** * @brief updateObject replace object geometry by given data. @@ -95,7 +90,7 @@ namespace DetourNavigator * @param transform allows to setup objects geometry according to its world state. * @return true if object is updated, false if there is no object with given id. */ - bool updateObject(const ObjectId id, const btCollisionShape& shape, const btTransform& transform); + virtual bool updateObject(const ObjectId id, const btCollisionShape& shape, const btTransform& transform) = 0; /** * @brief updateObject replace object geometry by given data. @@ -104,7 +99,7 @@ namespace DetourNavigator * @param transform allows to setup objects geometry according to its world state. * @return true if object is updated, false if there is no object with given id. */ - bool updateObject(const ObjectId id, const ObjectShapes& shapes, const btTransform& transform); + virtual bool updateObject(const ObjectId id, const ObjectShapes& shapes, const btTransform& transform) = 0; /** * @brief updateObject replace object geometry by given data. @@ -113,14 +108,14 @@ namespace DetourNavigator * @param transform allows to setup objects geometry according to its world state. * @return true if object is updated, false if there is no object with given id. */ - bool updateObject(const ObjectId id, const DoorShapes& shapes, const btTransform& transform); + virtual bool updateObject(const ObjectId id, const DoorShapes& shapes, const btTransform& transform) = 0; /** * @brief removeObject to make it no more available at the scene. * @param id is used to find object. * @return true if object is removed, false if there is no object with given id. */ - bool removeObject(const ObjectId id); + virtual bool removeObject(const ObjectId id) = 0; /** * @brief addWater is used to set water level at given world cell. @@ -132,26 +127,26 @@ namespace DetourNavigator * at least single object is added to the scene, false if there is already water for given cell or there is no * any other objects. */ - bool addWater(const osg::Vec2i& cellPosition, const int cellSize, const btScalar level, - const btTransform& transform); + virtual bool addWater(const osg::Vec2i& cellPosition, const int cellSize, const btScalar level, + const btTransform& transform) = 0; /** * @brief removeWater to make it no more available at the scene. * @param cellPosition allows to find cell. * @return true if there was water at given cell. */ - bool removeWater(const osg::Vec2i& cellPosition); + virtual bool removeWater(const osg::Vec2i& cellPosition) = 0; /** * @brief update start background navmesh update using current scene state. * @param playerPosition setup initial point to order build tiles of navmesh. */ - void update(const osg::Vec3f& playerPosition); + virtual void update(const osg::Vec3f& playerPosition) = 0; /** * @brief wait locks thread until all tiles are updated from last update call. */ - void wait(); + virtual void wait() = 0; /** * @brief findPath fills output iterator with points of scene surfaces to be used for actor to walk through. @@ -186,26 +181,15 @@ namespace DetourNavigator * @brief getNavMesh returns navmesh for specific agent half extents * @return navmesh */ - SharedNavMeshCacheItem getNavMesh(const osg::Vec3f& agentHalfExtents) const; + virtual SharedNavMeshCacheItem getNavMesh(const osg::Vec3f& agentHalfExtents) const = 0; /** * @brief getNavMeshes returns all current navmeshes * @return map of agent half extents to navmesh */ - std::map getNavMeshes() const; + virtual std::map getNavMeshes() const = 0; - Settings getSettings() const; - - private: - Settings mSettings; - NavMeshManager mNavMeshManager; - std::map mAgents; - std::unordered_map mAvoidIds; - std::unordered_map mWaterIds; - - void updateAvoidShapeId(const ObjectId id, const ObjectId avoidId); - void updateWaterShapeId(const ObjectId id, const ObjectId waterId); - void updateId(const ObjectId id, const ObjectId waterId, std::unordered_map& ids); + virtual Settings getSettings() const = 0; }; } diff --git a/components/detournavigator/navigator.cpp b/components/detournavigator/navigatorimpl.cpp similarity index 66% rename from components/detournavigator/navigator.cpp rename to components/detournavigator/navigatorimpl.cpp index ddd985021..1b83769f4 100644 --- a/components/detournavigator/navigator.cpp +++ b/components/detournavigator/navigatorimpl.cpp @@ -1,4 +1,4 @@ -#include "navigator.hpp" +#include "navigatorimpl.hpp" #include "debug.hpp" #include "settingsutils.hpp" @@ -6,19 +6,19 @@ namespace DetourNavigator { - Navigator::Navigator(const Settings& settings) + NavigatorImpl::NavigatorImpl(const Settings& settings) : mSettings(settings) , mNavMeshManager(mSettings) { } - void Navigator::addAgent(const osg::Vec3f& agentHalfExtents) + void NavigatorImpl::addAgent(const osg::Vec3f& agentHalfExtents) { ++mAgents[agentHalfExtents]; mNavMeshManager.addAgent(agentHalfExtents); } - void Navigator::removeAgent(const osg::Vec3f& agentHalfExtents) + void NavigatorImpl::removeAgent(const osg::Vec3f& agentHalfExtents) { const auto it = mAgents.find(agentHalfExtents); if (it == mAgents.end() || --it->second) @@ -27,12 +27,12 @@ namespace DetourNavigator mNavMeshManager.reset(agentHalfExtents); } - bool Navigator::addObject(const ObjectId id, const btCollisionShape& shape, const btTransform& transform) + bool NavigatorImpl::addObject(const ObjectId id, const btCollisionShape& shape, const btTransform& transform) { return mNavMeshManager.addObject(id, shape, transform, AreaType_ground); } - bool Navigator::addObject(const ObjectId id, const ObjectShapes& shapes, const btTransform& transform) + bool NavigatorImpl::addObject(const ObjectId id, const ObjectShapes& shapes, const btTransform& transform) { bool result = addObject(id, shapes.mShape, transform); if (shapes.mAvoid) @@ -47,7 +47,7 @@ namespace DetourNavigator return result; } - bool Navigator::addObject(const ObjectId id, const DoorShapes& shapes, const btTransform& transform) + bool NavigatorImpl::addObject(const ObjectId id, const DoorShapes& shapes, const btTransform& transform) { if (addObject(id, static_cast(shapes), transform)) { @@ -61,12 +61,12 @@ namespace DetourNavigator return false; } - bool Navigator::updateObject(const ObjectId id, const btCollisionShape& shape, const btTransform& transform) + bool NavigatorImpl::updateObject(const ObjectId id, const btCollisionShape& shape, const btTransform& transform) { return mNavMeshManager.updateObject(id, shape, transform, AreaType_ground); } - bool Navigator::updateObject(const ObjectId id, const ObjectShapes& shapes, const btTransform& transform) + bool NavigatorImpl::updateObject(const ObjectId id, const ObjectShapes& shapes, const btTransform& transform) { bool result = updateObject(id, shapes.mShape, transform); if (shapes.mAvoid) @@ -81,12 +81,12 @@ namespace DetourNavigator return result; } - bool Navigator::updateObject(const ObjectId id, const DoorShapes& shapes, const btTransform& transform) + bool NavigatorImpl::updateObject(const ObjectId id, const DoorShapes& shapes, const btTransform& transform) { return updateObject(id, static_cast(shapes), transform); } - bool Navigator::removeObject(const ObjectId id) + bool NavigatorImpl::removeObject(const ObjectId id) { bool result = mNavMeshManager.removeObject(id); const auto avoid = mAvoidIds.find(id); @@ -99,55 +99,55 @@ namespace DetourNavigator return result; } - bool Navigator::addWater(const osg::Vec2i& cellPosition, const int cellSize, const btScalar level, + bool NavigatorImpl::addWater(const osg::Vec2i& cellPosition, const int cellSize, const btScalar level, const btTransform& transform) { return mNavMeshManager.addWater(cellPosition, cellSize, btTransform(transform.getBasis(), btVector3(transform.getOrigin().x(), transform.getOrigin().y(), level))); } - bool Navigator::removeWater(const osg::Vec2i& cellPosition) + bool NavigatorImpl::removeWater(const osg::Vec2i& cellPosition) { return mNavMeshManager.removeWater(cellPosition); } - void Navigator::update(const osg::Vec3f& playerPosition) + void NavigatorImpl::update(const osg::Vec3f& playerPosition) { for (const auto& v : mAgents) mNavMeshManager.update(playerPosition, v.first); } - void Navigator::wait() + void NavigatorImpl::wait() { mNavMeshManager.wait(); } - SharedNavMeshCacheItem Navigator::getNavMesh(const osg::Vec3f& agentHalfExtents) const + SharedNavMeshCacheItem NavigatorImpl::getNavMesh(const osg::Vec3f& agentHalfExtents) const { return mNavMeshManager.getNavMesh(agentHalfExtents); } - std::map Navigator::getNavMeshes() const + std::map NavigatorImpl::getNavMeshes() const { return mNavMeshManager.getNavMeshes(); } - Settings Navigator::getSettings() const + Settings NavigatorImpl::getSettings() const { return mSettings; } - void Navigator::updateAvoidShapeId(const ObjectId id, const ObjectId avoidId) + void NavigatorImpl::updateAvoidShapeId(const ObjectId id, const ObjectId avoidId) { updateId(id, avoidId, mWaterIds); } - void Navigator::updateWaterShapeId(const ObjectId id, const ObjectId waterId) + void NavigatorImpl::updateWaterShapeId(const ObjectId id, const ObjectId waterId) { updateId(id, waterId, mWaterIds); } - void Navigator::updateId(const ObjectId id, const ObjectId updateId, std::unordered_map& ids) + void NavigatorImpl::updateId(const ObjectId id, const ObjectId updateId, std::unordered_map& ids) { auto inserted = ids.insert(std::make_pair(id, updateId)); if (!inserted.second) diff --git a/components/detournavigator/navigatorimpl.hpp b/components/detournavigator/navigatorimpl.hpp new file mode 100644 index 000000000..975055984 --- /dev/null +++ b/components/detournavigator/navigatorimpl.hpp @@ -0,0 +1,64 @@ +#ifndef OPENMW_COMPONENTS_DETOURNAVIGATOR_NAVIGATORIMPL_H +#define OPENMW_COMPONENTS_DETOURNAVIGATOR_NAVIGATORIMPL_H + +#include "navigator.hpp" +#include "navmeshmanager.hpp" + +namespace DetourNavigator +{ + class NavigatorImpl final : public Navigator + { + public: + /** + * @brief Navigator constructor initializes all internal data. Constructed object is ready to build a scene. + * @param settings allows to customize navigator work. Constructor is only place to set navigator settings. + */ + NavigatorImpl(const Settings& settings); + + void addAgent(const osg::Vec3f& agentHalfExtents) override; + + void removeAgent(const osg::Vec3f& agentHalfExtents) override; + + bool addObject(const ObjectId id, const btCollisionShape& shape, const btTransform& transform) override; + + bool addObject(const ObjectId id, const ObjectShapes& shapes, const btTransform& transform) override; + + bool addObject(const ObjectId id, const DoorShapes& shapes, const btTransform& transform) override; + + bool updateObject(const ObjectId id, const btCollisionShape& shape, const btTransform& transform) override; + + bool updateObject(const ObjectId id, const ObjectShapes& shapes, const btTransform& transform) override; + + bool updateObject(const ObjectId id, const DoorShapes& shapes, const btTransform& transform) override; + + bool removeObject(const ObjectId id) override; + + bool addWater(const osg::Vec2i& cellPosition, const int cellSize, const btScalar level, + const btTransform& transform) override; + + bool removeWater(const osg::Vec2i& cellPosition) override; + + void update(const osg::Vec3f& playerPosition) override; + + void wait() override; + + SharedNavMeshCacheItem getNavMesh(const osg::Vec3f& agentHalfExtents) const override; + + std::map getNavMeshes() const override; + + Settings getSettings() const override; + + private: + Settings mSettings; + NavMeshManager mNavMeshManager; + std::map mAgents; + std::unordered_map mAvoidIds; + std::unordered_map mWaterIds; + + void updateAvoidShapeId(const ObjectId id, const ObjectId avoidId); + void updateWaterShapeId(const ObjectId id, const ObjectId waterId); + void updateId(const ObjectId id, const ObjectId waterId, std::unordered_map& ids); + }; +} + +#endif