1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-01-30 09:15:38 +00:00

Move findPath-like navigator functions into a separate header

This commit is contained in:
elsid 2021-11-06 00:34:06 +01:00
parent 5e99454cc4
commit 9f808fbe3a
No known key found for this signature in database
GPG key ID: B845CB9FEE18AB40
11 changed files with 143 additions and 125 deletions

View file

@ -8,7 +8,7 @@
#include <components/misc/mathutil.hpp>
#include <components/sceneutil/positionattitudetransform.hpp>
#include <components/detournavigator/navigator.hpp>
#include <components/detournavigator/navigatorutils.hpp>
#include "../mwphysics/collisiontype.hpp"
@ -277,7 +277,7 @@ namespace MWMechanics
// If there is no path, try to find a point on a line from the actor position to target projected
// on navmesh to attack the target from there.
const auto navigator = world->getNavigator();
const auto hit = navigator->raycast(halfExtents, vActorPos, vTargetPos, navigatorFlags);
const auto hit = DetourNavigator::raycast(*navigator, halfExtents, vActorPos, vTargetPos, navigatorFlags);
if (hit.has_value() && (*hit - vTargetPos).length() <= rangeAttack)
{

View file

@ -5,7 +5,7 @@
#include <components/debug/debuglog.hpp>
#include <components/misc/rng.hpp>
#include <components/esm/aisequence.hpp>
#include <components/detournavigator/navigator.hpp>
#include <components/detournavigator/navigatorutils.hpp>
#include <components/misc/coordinateconverter.hpp>
#include "../mwbase/world.hpp"
@ -337,7 +337,8 @@ namespace MWMechanics
if (!isWaterCreature && !isFlyingCreature)
{
// findRandomPointAroundCircle uses wanderDistance as limit for random and not as exact distance
if (const auto destination = navigator->findRandomPointAroundCircle(halfExtents, mInitialActorPosition, wanderDistance, navigatorFlags))
if (const auto destination = DetourNavigator::findRandomPointAroundCircle(*navigator, halfExtents,
mInitialActorPosition, wanderDistance, navigatorFlags))
mDestination = *destination;
else
mDestination = getRandomPointAround(mInitialActorPosition, wanderRadius);

View file

@ -3,8 +3,7 @@
#include <iterator>
#include <limits>
#include <components/detournavigator/debug.hpp>
#include <components/detournavigator/navigator.hpp>
#include <components/detournavigator/navigatorutils.hpp>
#include <components/debug/debuglog.hpp>
#include <components/misc/coordinateconverter.hpp>
@ -114,7 +113,7 @@ namespace
bool operator()(const osg::Vec3f& start, const osg::Vec3f& end) const
{
const auto position = mNavigator->raycast(mHalfExtents, start, end, mFlags);
const auto position = DetourNavigator::raycast(*mNavigator, mHalfExtents, start, end, mFlags);
return position.has_value() && std::abs((position.value() - start).length2() - (end - start).length2()) <= 1;
}
};
@ -422,8 +421,8 @@ namespace MWMechanics
const auto world = MWBase::Environment::get().getWorld();
const auto stepSize = getPathStepSize(actor);
const auto navigator = world->getNavigator();
const auto status = navigator->findPath(halfExtents, stepSize, startPoint, endPoint, flags, areaCosts,
endTolerance, out);
const auto status = DetourNavigator::findPath(*navigator, halfExtents, stepSize,
startPoint, endPoint, flags, areaCosts, endTolerance, out);
if (pathType == PathType::Partial && status == DetourNavigator::Status::PartialPath)
return DetourNavigator::Status::Success;
@ -455,8 +454,8 @@ namespace MWMechanics
std::deque<osg::Vec3f> prePath;
auto prePathInserter = std::back_inserter(prePath);
const float endTolerance = 0;
const auto status = navigator->findPath(halfExtents, stepSize, startPoint, mPath.front(), flags, areaCosts,
endTolerance, prePathInserter);
const auto status = DetourNavigator::findPath(*navigator, halfExtents, stepSize,
startPoint, mPath.front(), flags, areaCosts, endTolerance, prePathInserter);
if (status == DetourNavigator::Status::NavMeshNotFound)
return;

View file

@ -28,6 +28,7 @@
#include <components/sceneutil/positionattitudetransform.hpp>
#include <components/detournavigator/navigator.hpp>
#include <components/detournavigator/settings.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/soundmanager.hpp"

View file

@ -2,6 +2,7 @@
#include <components/detournavigator/navigatorimpl.hpp>
#include <components/detournavigator/exceptions.hpp>
#include <components/detournavigator/navigatorutils.hpp>
#include <components/misc/rng.hpp>
#include <components/loadinglistener/loadinglistener.hpp>
#include <components/esm/loadland.hpp>
@ -136,7 +137,7 @@ namespace
TEST_F(DetourNavigatorNavigatorTest, find_path_for_empty_should_return_empty)
{
EXPECT_EQ(mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut),
EXPECT_EQ(findPath(*mNavigator, mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut),
Status::NavMeshNotFound);
EXPECT_EQ(mPath, std::deque<osg::Vec3f>());
}
@ -144,7 +145,7 @@ namespace
TEST_F(DetourNavigatorNavigatorTest, find_path_for_existing_agent_with_no_navmesh_should_throw_exception)
{
mNavigator->addAgent(mAgentHalfExtents);
EXPECT_EQ(mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut),
EXPECT_EQ(findPath(*mNavigator, mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut),
Status::StartPolygonNotFound);
}
@ -153,7 +154,7 @@ namespace
mNavigator->addAgent(mAgentHalfExtents);
mNavigator->addAgent(mAgentHalfExtents);
mNavigator->removeAgent(mAgentHalfExtents);
EXPECT_EQ(mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut),
EXPECT_EQ(findPath(*mNavigator, mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut),
Status::StartPolygonNotFound);
}
@ -173,7 +174,7 @@ namespace
mNavigator->update(mPlayerPosition);
mNavigator->wait(mListener, WaitConditionType::requiredTilesPresent);
EXPECT_EQ(mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut),
EXPECT_EQ(findPath(*mNavigator, mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut),
Status::Success);
EXPECT_THAT(mPath, ElementsAre(
@ -221,7 +222,7 @@ namespace
mNavigator->update(mPlayerPosition);
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
EXPECT_EQ(mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut),
EXPECT_EQ(findPath(*mNavigator, mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut),
Status::Success);
EXPECT_THAT(mPath, ElementsAre(
@ -255,7 +256,7 @@ namespace
mPath.clear();
mOut = std::back_inserter(mPath);
EXPECT_EQ(mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut),
EXPECT_EQ(findPath(*mNavigator, mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut),
Status::Success);
EXPECT_THAT(mPath, ElementsAre(
@ -305,7 +306,7 @@ namespace
mNavigator->update(mPlayerPosition);
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
EXPECT_EQ(mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut),
EXPECT_EQ(findPath(*mNavigator, mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut),
Status::Success);
EXPECT_THAT(mPath, ElementsAre(
@ -342,7 +343,7 @@ namespace
mPath.clear();
mOut = std::back_inserter(mPath);
EXPECT_EQ(mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut),
EXPECT_EQ(findPath(*mNavigator, mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut),
Status::Success);
EXPECT_THAT(mPath, ElementsAre(
@ -399,7 +400,7 @@ namespace
mNavigator->update(mPlayerPosition);
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
EXPECT_EQ(mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut),
EXPECT_EQ(findPath(*mNavigator, mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut),
Status::Success);
EXPECT_THAT(mPath, ElementsAre(
@ -486,7 +487,7 @@ namespace
mNavigator->update(mPlayerPosition);
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
EXPECT_EQ(mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut),
EXPECT_EQ(findPath(*mNavigator, mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut),
Status::Success);
EXPECT_THAT(mPath, ElementsAre(
@ -538,7 +539,7 @@ namespace
mEnd.x() = 0;
mEnd.z() = 300;
EXPECT_EQ(mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_swim, mAreaCosts, mEndTolerance, mOut),
EXPECT_EQ(findPath(*mNavigator, mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_swim, mAreaCosts, mEndTolerance, mOut),
Status::Success);
EXPECT_THAT(mPath, ElementsAre(
@ -583,7 +584,7 @@ namespace
mStart.x() = 0;
mEnd.x() = 0;
EXPECT_EQ(mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_swim | Flag_walk, mAreaCosts, mEndTolerance, mOut),
EXPECT_EQ(findPath(*mNavigator, mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_swim | Flag_walk, mAreaCosts, mEndTolerance, mOut),
Status::Success);
EXPECT_THAT(mPath, ElementsAre(
@ -628,7 +629,7 @@ namespace
mStart.x() = 0;
mEnd.x() = 0;
EXPECT_EQ(mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_swim | Flag_walk, mAreaCosts, mEndTolerance, mOut),
EXPECT_EQ(findPath(*mNavigator, mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_swim | Flag_walk, mAreaCosts, mEndTolerance, mOut),
Status::Success);
EXPECT_THAT(mPath, ElementsAre(
@ -673,7 +674,7 @@ namespace
mStart.x() = 0;
mEnd.x() = 0;
EXPECT_EQ(mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut),
EXPECT_EQ(findPath(*mNavigator, mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut),
Status::Success);
EXPECT_THAT(mPath, ElementsAre(
@ -722,7 +723,7 @@ namespace
mNavigator->update(mPlayerPosition);
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
EXPECT_EQ(mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut),
EXPECT_EQ(findPath(*mNavigator, mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut),
Status::Success);
EXPECT_THAT(mPath, ElementsAre(
@ -775,7 +776,7 @@ namespace
mNavigator->update(mPlayerPosition);
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
EXPECT_EQ(mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut),
EXPECT_EQ(findPath(*mNavigator, mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut),
Status::Success);
EXPECT_THAT(mPath, ElementsAre(
@ -822,7 +823,7 @@ namespace
Misc::Rng::init(42);
const auto result = mNavigator->findRandomPointAroundCircle(mAgentHalfExtents, mStart, 100.0, Flag_walk);
const auto result = findRandomPointAroundCircle(*mNavigator, mAgentHalfExtents, mStart, 100.0, Flag_walk);
ASSERT_THAT(result, Optional(Vec3fEq(-198.909332275390625, 123.06096649169921875, 1.99998414516448974609375)))
<< (result ? *result : osg::Vec3f());
@ -870,7 +871,7 @@ namespace
mNavigator->update(mPlayerPosition);
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
EXPECT_EQ(mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut),
EXPECT_EQ(findPath(*mNavigator, mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut),
Status::Success);
EXPECT_THAT(mPath, ElementsAre(
@ -954,7 +955,7 @@ namespace
mNavigator->update(mPlayerPosition);
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
const auto result = mNavigator->raycast(mAgentHalfExtents, mStart, mEnd, Flag_walk);
const auto result = raycast(*mNavigator, mAgentHalfExtents, mStart, mEnd, Flag_walk);
ASSERT_THAT(result, Optional(Vec3fEq(mEnd.x(), mEnd.y(), 1.99998295307159423828125)))
<< (result ? *result : osg::Vec3f());
@ -1019,7 +1020,7 @@ namespace
mNavigator->update(mPlayerPosition);
mNavigator->wait(mListener, WaitConditionType::requiredTilesPresent);
EXPECT_EQ(mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut),
EXPECT_EQ(findPath(*mNavigator, mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut),
Status::Success);
EXPECT_THAT(mPath, ElementsAre(
@ -1069,7 +1070,7 @@ namespace
mNavigator->update(mPlayerPosition);
mNavigator->wait(mListener, WaitConditionType::allJobsDone);
EXPECT_EQ(mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut),
EXPECT_EQ(findPath(*mNavigator, mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut),
Status::PartialPath);
EXPECT_THAT(mPath, ElementsAre(
@ -1116,7 +1117,7 @@ namespace
const float endTolerance = 1000.0f;
EXPECT_EQ(mNavigator->findPath(mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mAreaCosts, endTolerance, mOut),
EXPECT_EQ(findPath(*mNavigator, mAgentHalfExtents, mStepSize, mStart, mEnd, Flag_walk, mAreaCosts, endTolerance, mOut),
Status::Success);
EXPECT_THAT(mPath, ElementsAre(

View file

@ -196,6 +196,7 @@ add_component_dir(detournavigator
offmeshconnectionsmanager
preparednavmeshdata
navmeshcacheitem
navigatorutils
)
add_component_dir(loadinglistener

View file

@ -1,42 +1,10 @@
#include "findrandompointaroundcircle.hpp"
#include "navigator.hpp"
#include "raycast.hpp"
#include "navigatorimpl.hpp"
#include "navigatorstub.hpp"
#include "recastglobalallocator.hpp"
namespace DetourNavigator
{
std::optional<osg::Vec3f> Navigator::findRandomPointAroundCircle(const osg::Vec3f& agentHalfExtents,
const osg::Vec3f& start, const float maxRadius, const Flags includeFlags) const
{
const auto navMesh = getNavMesh(agentHalfExtents);
if (!navMesh)
return std::optional<osg::Vec3f>();
const auto settings = getSettings();
const auto result = DetourNavigator::findRandomPointAroundCircle(navMesh->lockConst()->getImpl(),
toNavMeshCoordinates(settings, agentHalfExtents), toNavMeshCoordinates(settings, start),
toNavMeshCoordinates(settings, maxRadius), includeFlags, settings);
if (!result)
return std::optional<osg::Vec3f>();
return std::optional<osg::Vec3f>(fromNavMeshCoordinates(settings, *result));
}
std::optional<osg::Vec3f> Navigator::raycast(const osg::Vec3f& agentHalfExtents, const osg::Vec3f& start,
const osg::Vec3f& end, const Flags includeFlags) const
{
const auto navMesh = getNavMesh(agentHalfExtents);
if (navMesh == nullptr)
return {};
const auto settings = getSettings();
const auto result = DetourNavigator::raycast(navMesh->lockConst()->getImpl(),
toNavMeshCoordinates(settings, agentHalfExtents), toNavMeshCoordinates(settings, start),
toNavMeshCoordinates(settings, end), includeFlags, settings);
if (!result)
return {};
return fromNavMeshCoordinates(settings, *result);
}
std::unique_ptr<Navigator> makeNavigator(const Settings& settings)
{
DetourNavigator::RecastGlobalAllocator::init();

View file

@ -1,9 +1,6 @@
#ifndef OPENMW_COMPONENTS_DETOURNAVIGATOR_NAVIGATOR_H
#define OPENMW_COMPONENTS_DETOURNAVIGATOR_NAVIGATOR_H
#include "findsmoothpath.hpp"
#include "flags.hpp"
#include "settings.hpp"
#include "objectid.hpp"
#include "navmeshcacheitem.hpp"
#include "recastmeshtiles.hpp"
@ -12,8 +9,6 @@
#include <components/resource/bulletshape.hpp>
#include <variant>
namespace ESM
{
struct Cell;
@ -27,6 +22,8 @@ namespace Loading
namespace DetourNavigator
{
struct Settings;
struct ObjectShapes
{
osg::ref_ptr<const Resource::BulletShapeInstance> mShapeInstance;
@ -166,38 +163,6 @@ namespace DetourNavigator
*/
virtual void wait(Loading::Listener& listener, WaitConditionType waitConditionType) = 0;
/**
* @brief findPath fills output iterator with points of scene surfaces to be used for actor to walk through.
* @param agentHalfExtents allows to find navmesh for given actor.
* @param start path from given point.
* @param end path at given point.
* @param includeFlags setup allowed surfaces for actor to walk.
* @param out the beginning of the destination range.
* @param endTolerance defines maximum allowed distance to end path point in addition to agentHalfExtents
* @return Output iterator to the element in the destination range, one past the last element of found path.
* Equal to out if no path is found.
*/
template <class OutputIterator>
Status findPath(const osg::Vec3f& agentHalfExtents, const float stepSize, const osg::Vec3f& start,
const osg::Vec3f& end, const Flags includeFlags, const DetourNavigator::AreaCosts& areaCosts,
float endTolerance, OutputIterator& out) const
{
static_assert(
std::is_same<
typename std::iterator_traits<OutputIterator>::iterator_category,
std::output_iterator_tag
>::value,
"out is not an OutputIterator"
);
const auto navMesh = getNavMesh(agentHalfExtents);
if (!navMesh)
return Status::NavMeshNotFound;
const auto settings = getSettings();
return findSmoothPath(navMesh->lockConst()->getImpl(), toNavMeshCoordinates(settings, agentHalfExtents),
toNavMeshCoordinates(settings, stepSize), toNavMeshCoordinates(settings, start),
toNavMeshCoordinates(settings, end), includeFlags, areaCosts, settings, endTolerance, out);
}
/**
* @brief getNavMesh returns navmesh for specific agent half extents
* @return navmesh
@ -214,28 +179,6 @@ namespace DetourNavigator
virtual void reportStats(unsigned int frameNumber, osg::Stats& stats) const = 0;
/**
* @brief findRandomPointAroundCircle returns random location on navmesh within the reach of specified location.
* @param agentHalfExtents allows to find navmesh for given actor.
* @param start path from given point.
* @param maxRadius limit maximum distance from start.
* @param includeFlags setup allowed surfaces for actor to walk.
* @return not empty optional with position if point is found and empty optional if point is not found.
*/
std::optional<osg::Vec3f> findRandomPointAroundCircle(const osg::Vec3f& agentHalfExtents,
const osg::Vec3f& start, const float maxRadius, const Flags includeFlags) const;
/**
* @brief raycast finds farest navmesh point from start on a line from start to end that has path from start.
* @param agentHalfExtents allows to find navmesh for given actor.
* @param start of the line
* @param end of the line
* @param includeFlags setup allowed surfaces for actor to walk.
* @return not empty optional with position if point is found and empty optional if point is not found.
*/
std::optional<osg::Vec3f> raycast(const osg::Vec3f& agentHalfExtents, const osg::Vec3f& start,
const osg::Vec3f& end, const Flags includeFlags) const;
virtual RecastMeshTiles getRecastMeshTiles() const = 0;
virtual float getMaxNavmeshAreaRealRadius() const = 0;

View file

@ -0,0 +1,37 @@
#include "navigatorutils.hpp"
#include "findrandompointaroundcircle.hpp"
#include "navigator.hpp"
#include "raycast.hpp"
namespace DetourNavigator
{
std::optional<osg::Vec3f> findRandomPointAroundCircle(const Navigator& navigator, const osg::Vec3f& agentHalfExtents,
const osg::Vec3f& start, const float maxRadius, const Flags includeFlags)
{
const auto navMesh = navigator.getNavMesh(agentHalfExtents);
if (!navMesh)
return std::nullopt;
const auto settings = navigator.getSettings();
const auto result = DetourNavigator::findRandomPointAroundCircle(navMesh->lockConst()->getImpl(),
toNavMeshCoordinates(settings, agentHalfExtents), toNavMeshCoordinates(settings, start),
toNavMeshCoordinates(settings, maxRadius), includeFlags, settings);
if (!result)
return std::nullopt;
return std::optional<osg::Vec3f>(fromNavMeshCoordinates(settings, *result));
}
std::optional<osg::Vec3f> raycast(const Navigator& navigator, const osg::Vec3f& agentHalfExtents, const osg::Vec3f& start,
const osg::Vec3f& end, const Flags includeFlags)
{
const auto navMesh = navigator.getNavMesh(agentHalfExtents);
if (navMesh == nullptr)
return std::nullopt;
const auto settings = navigator.getSettings();
const auto result = DetourNavigator::raycast(navMesh->lockConst()->getImpl(),
toNavMeshCoordinates(settings, agentHalfExtents), toNavMeshCoordinates(settings, start),
toNavMeshCoordinates(settings, end), includeFlags, settings);
if (!result)
return std::nullopt;
return fromNavMeshCoordinates(settings, *result);
}
}

View file

@ -0,0 +1,68 @@
#ifndef OPENMW_COMPONENTS_DETOURNAVIGATOR_NAVIGATORUTILS_H
#define OPENMW_COMPONENTS_DETOURNAVIGATOR_NAVIGATORUTILS_H
#include "findsmoothpath.hpp"
#include "flags.hpp"
#include "settings.hpp"
#include "navigator.hpp"
#include <optional>
namespace DetourNavigator
{
/**
* @brief findPath fills output iterator with points of scene surfaces to be used for actor to walk through.
* @param agentHalfExtents allows to find navmesh for given actor.
* @param start path from given point.
* @param end path at given point.
* @param includeFlags setup allowed surfaces for actor to walk.
* @param out the beginning of the destination range.
* @param endTolerance defines maximum allowed distance to end path point in addition to agentHalfExtents
* @return Output iterator to the element in the destination range, one past the last element of found path.
* Equal to out if no path is found.
*/
template <class OutputIterator>
inline Status findPath(const Navigator& navigator, const osg::Vec3f& agentHalfExtents, const float stepSize, const osg::Vec3f& start,
const osg::Vec3f& end, const Flags includeFlags, const DetourNavigator::AreaCosts& areaCosts,
float endTolerance, OutputIterator& out)
{
static_assert(
std::is_same<
typename std::iterator_traits<OutputIterator>::iterator_category,
std::output_iterator_tag
>::value,
"out is not an OutputIterator"
);
const auto navMesh = navigator.getNavMesh(agentHalfExtents);
if (navMesh == nullptr)
return Status::NavMeshNotFound;
const auto settings = navigator.getSettings();
return findSmoothPath(navMesh->lockConst()->getImpl(), toNavMeshCoordinates(settings, agentHalfExtents),
toNavMeshCoordinates(settings, stepSize), toNavMeshCoordinates(settings, start),
toNavMeshCoordinates(settings, end), includeFlags, areaCosts, settings, endTolerance, out);
}
/**
* @brief findRandomPointAroundCircle returns random location on navmesh within the reach of specified location.
* @param agentHalfExtents allows to find navmesh for given actor.
* @param start path from given point.
* @param maxRadius limit maximum distance from start.
* @param includeFlags setup allowed surfaces for actor to walk.
* @return not empty optional with position if point is found and empty optional if point is not found.
*/
std::optional<osg::Vec3f> findRandomPointAroundCircle(const Navigator& navigator, const osg::Vec3f& agentHalfExtents,
const osg::Vec3f& start, const float maxRadius, const Flags includeFlags);
/**
* @brief raycast finds farest navmesh point from start on a line from start to end that has path from start.
* @param agentHalfExtents allows to find navmesh for given actor.
* @param start of the line
* @param end of the line
* @param includeFlags setup allowed surfaces for actor to walk.
* @return not empty optional with position if point is found and empty optional if point is not found.
*/
std::optional<osg::Vec3f> raycast(const Navigator& navigator, const osg::Vec3f& agentHalfExtents, const osg::Vec3f& start,
const osg::Vec3f& end, const Flags includeFlags);
}
#endif

View file

@ -2,7 +2,6 @@
#define OPENMW_COMPONENTS_DETOURNAVIGATOR_SETTINGS_H
#include <chrono>
#include <optional>
#include <string>
namespace DetourNavigator