mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-21 08:53:52 +00:00
Merge branch 'concepts' into 'master'
Use concepts for some argument types See merge request OpenMW/openmw!3598
This commit is contained in:
commit
63875a7954
3 changed files with 37 additions and 54 deletions
|
@ -5,6 +5,7 @@
|
||||||
#include <components/esm3/loadland.hpp>
|
#include <components/esm3/loadland.hpp>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <iterator>
|
||||||
#include <random>
|
#include <random>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
|
@ -24,29 +25,25 @@ namespace
|
||||||
PreparedNavMeshData mValue;
|
PreparedNavMeshData mValue;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Random>
|
osg::Vec2i generateVec2i(int max, auto& random)
|
||||||
osg::Vec2i generateVec2i(int max, Random& random)
|
|
||||||
{
|
{
|
||||||
std::uniform_int_distribution<int> distribution(0, max);
|
std::uniform_int_distribution<int> distribution(0, max);
|
||||||
return osg::Vec2i(distribution(random), distribution(random));
|
return osg::Vec2i(distribution(random), distribution(random));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Random>
|
osg::Vec3f generateAgentHalfExtents(float min, float max, auto& random)
|
||||||
osg::Vec3f generateAgentHalfExtents(float min, float max, Random& random)
|
|
||||||
{
|
{
|
||||||
std::uniform_int_distribution<int> distribution(min, max);
|
std::uniform_int_distribution<int> distribution(min, max);
|
||||||
return osg::Vec3f(distribution(random), distribution(random), distribution(random));
|
return osg::Vec3f(distribution(random), distribution(random), distribution(random));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename OutputIterator, typename Random>
|
void generateVertices(std::output_iterator<int> auto out, std::size_t number, auto& random)
|
||||||
void generateVertices(OutputIterator out, std::size_t number, Random& random)
|
|
||||||
{
|
{
|
||||||
std::uniform_real_distribution<float> distribution(0.0, 1.0);
|
std::uniform_real_distribution<float> distribution(0.0, 1.0);
|
||||||
std::generate_n(out, 3 * (number - number % 3), [&] { return distribution(random); });
|
std::generate_n(out, 3 * (number - number % 3), [&] { return distribution(random); });
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename OutputIterator, typename Random>
|
void generateIndices(std::output_iterator<int> auto out, int max, std::size_t number, auto& random)
|
||||||
void generateIndices(OutputIterator out, int max, std::size_t number, Random& random)
|
|
||||||
{
|
{
|
||||||
std::uniform_int_distribution<int> distribution(0, max);
|
std::uniform_int_distribution<int> distribution(0, max);
|
||||||
std::generate_n(out, number - number % 3, [&] { return distribution(random); });
|
std::generate_n(out, number - number % 3, [&] { return distribution(random); });
|
||||||
|
@ -70,21 +67,18 @@ namespace
|
||||||
return AreaType_null;
|
return AreaType_null;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Random>
|
AreaType generateAreaType(auto& random)
|
||||||
AreaType generateAreaType(Random& random)
|
|
||||||
{
|
{
|
||||||
std::uniform_int_distribution<int> distribution(0, 4);
|
std::uniform_int_distribution<int> distribution(0, 4);
|
||||||
return toAreaType(distribution(random));
|
return toAreaType(distribution(random));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename OutputIterator, typename Random>
|
void generateAreaTypes(std::output_iterator<AreaType> auto out, std::size_t triangles, auto& random)
|
||||||
void generateAreaTypes(OutputIterator out, std::size_t triangles, Random& random)
|
|
||||||
{
|
{
|
||||||
std::generate_n(out, triangles, [&] { return generateAreaType(random); });
|
std::generate_n(out, triangles, [&] { return generateAreaType(random); });
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename OutputIterator, typename Random>
|
void generateWater(std::output_iterator<CellWater> auto out, std::size_t count, auto& random)
|
||||||
void generateWater(OutputIterator out, std::size_t count, Random& random)
|
|
||||||
{
|
{
|
||||||
std::uniform_real_distribution<float> distribution(0.0, 1.0);
|
std::uniform_real_distribution<float> distribution(0.0, 1.0);
|
||||||
std::generate_n(out, count, [&] {
|
std::generate_n(out, count, [&] {
|
||||||
|
@ -92,8 +86,7 @@ namespace
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Random>
|
Mesh generateMesh(std::size_t triangles, auto& random)
|
||||||
Mesh generateMesh(std::size_t triangles, Random& random)
|
|
||||||
{
|
{
|
||||||
std::uniform_real_distribution<float> distribution(0.0, 1.0);
|
std::uniform_real_distribution<float> distribution(0.0, 1.0);
|
||||||
std::vector<float> vertices;
|
std::vector<float> vertices;
|
||||||
|
@ -109,8 +102,7 @@ namespace
|
||||||
return Mesh(std::move(indices), std::move(vertices), std::move(areaTypes));
|
return Mesh(std::move(indices), std::move(vertices), std::move(areaTypes));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Random>
|
Heightfield generateHeightfield(auto& random)
|
||||||
Heightfield generateHeightfield(Random& random)
|
|
||||||
{
|
{
|
||||||
std::uniform_real_distribution<float> distribution(0.0, 1.0);
|
std::uniform_real_distribution<float> distribution(0.0, 1.0);
|
||||||
Heightfield result;
|
Heightfield result;
|
||||||
|
@ -127,8 +119,7 @@ namespace
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Random>
|
FlatHeightfield generateFlatHeightfield(auto& random)
|
||||||
FlatHeightfield generateFlatHeightfield(Random& random)
|
|
||||||
{
|
{
|
||||||
std::uniform_real_distribution<float> distribution(0.0, 1.0);
|
std::uniform_real_distribution<float> distribution(0.0, 1.0);
|
||||||
FlatHeightfield result;
|
FlatHeightfield result;
|
||||||
|
@ -138,8 +129,7 @@ namespace
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Random>
|
Key generateKey(std::size_t triangles, auto& random)
|
||||||
Key generateKey(std::size_t triangles, Random& random)
|
|
||||||
{
|
{
|
||||||
const CollisionShapeType agentShapeType = CollisionShapeType::Aabb;
|
const CollisionShapeType agentShapeType = CollisionShapeType::Aabb;
|
||||||
const osg::Vec3f agentHalfExtents = generateAgentHalfExtents(0.5, 1.5, random);
|
const osg::Vec3f agentHalfExtents = generateAgentHalfExtents(0.5, 1.5, random);
|
||||||
|
@ -158,14 +148,12 @@ namespace
|
||||||
|
|
||||||
constexpr std::size_t trianglesPerTile = 239;
|
constexpr std::size_t trianglesPerTile = 239;
|
||||||
|
|
||||||
template <typename OutputIterator, typename Random>
|
void generateKeys(std::output_iterator<Key> auto out, std::size_t count, auto& random)
|
||||||
void generateKeys(OutputIterator out, std::size_t count, Random& random)
|
|
||||||
{
|
{
|
||||||
std::generate_n(out, count, [&] { return generateKey(trianglesPerTile, random); });
|
std::generate_n(out, count, [&] { return generateKey(trianglesPerTile, random); });
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename OutputIterator, typename Random>
|
void fillCache(std::output_iterator<Key> auto out, auto& random, NavMeshTilesCache& cache)
|
||||||
void fillCache(OutputIterator out, Random& random, NavMeshTilesCache& cache)
|
|
||||||
{
|
{
|
||||||
std::size_t size = cache.getStats().mNavMeshCacheSize;
|
std::size_t size = cache.getStats().mNavMeshCacheSize;
|
||||||
|
|
||||||
|
|
|
@ -16,54 +16,54 @@
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <iterator>
|
||||||
#include <span>
|
#include <span>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace DetourNavigator
|
namespace DetourNavigator
|
||||||
{
|
{
|
||||||
template <class OutputIterator, class Function>
|
template <std::output_iterator<osg::Vec3f> OutputIterator>
|
||||||
class OutputTransformIterator
|
class FromNavMeshCoordinatesIterator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit OutputTransformIterator(OutputIterator& impl, Function&& function)
|
using iterator_category = std::output_iterator_tag;
|
||||||
|
using value_type = osg::Vec3f;
|
||||||
|
using difference_type = std::ptrdiff_t;
|
||||||
|
using pointer = osg::Vec3f*;
|
||||||
|
using reference = osg::Vec3f&;
|
||||||
|
|
||||||
|
explicit FromNavMeshCoordinatesIterator(OutputIterator& impl, const RecastSettings& settings)
|
||||||
: mImpl(impl)
|
: mImpl(impl)
|
||||||
, mFunction(std::forward<Function>(function))
|
, mSettings(settings)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
OutputTransformIterator& operator*() { return *this; }
|
FromNavMeshCoordinatesIterator& operator*() { return *this; }
|
||||||
|
|
||||||
OutputTransformIterator& operator++()
|
FromNavMeshCoordinatesIterator& operator++()
|
||||||
{
|
{
|
||||||
++mImpl.get();
|
++mImpl.get();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
OutputTransformIterator operator++(int)
|
FromNavMeshCoordinatesIterator operator++(int)
|
||||||
{
|
{
|
||||||
const auto copy = *this;
|
const auto copy = *this;
|
||||||
++(*this);
|
++(*this);
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
OutputTransformIterator& operator=(const osg::Vec3f& value)
|
FromNavMeshCoordinatesIterator& operator=(const osg::Vec3f& value)
|
||||||
{
|
{
|
||||||
*mImpl.get() = mFunction(value);
|
*mImpl.get() = fromNavMeshCoordinates(mSettings, value);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::reference_wrapper<OutputIterator> mImpl;
|
std::reference_wrapper<OutputIterator> mImpl;
|
||||||
Function mFunction;
|
std::reference_wrapper<const RecastSettings> mSettings;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class OutputIterator>
|
|
||||||
auto withFromNavMeshCoordinates(OutputIterator& impl, const RecastSettings& settings)
|
|
||||||
{
|
|
||||||
return OutputTransformIterator(
|
|
||||||
impl, [&settings](const osg::Vec3f& value) { return fromNavMeshCoordinates(settings, value); });
|
|
||||||
}
|
|
||||||
|
|
||||||
inline std::optional<std::size_t> findPath(const dtNavMeshQuery& navMeshQuery, const dtPolyRef startRef,
|
inline std::optional<std::size_t> findPath(const dtNavMeshQuery& navMeshQuery, const dtPolyRef startRef,
|
||||||
const dtPolyRef endRef, const osg::Vec3f& startPos, const osg::Vec3f& endPos, const dtQueryFilter& queryFilter,
|
const dtPolyRef endRef, const osg::Vec3f& startPos, const osg::Vec3f& endPos, const dtQueryFilter& queryFilter,
|
||||||
std::span<dtPolyRef> pathBuffer)
|
std::span<dtPolyRef> pathBuffer)
|
||||||
|
@ -78,10 +78,9 @@ namespace DetourNavigator
|
||||||
return static_cast<std::size_t>(pathLen);
|
return static_cast<std::size_t>(pathLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class OutputIterator>
|
|
||||||
Status makeSmoothPath(const dtNavMeshQuery& navMeshQuery, const osg::Vec3f& start, const osg::Vec3f& end,
|
Status makeSmoothPath(const dtNavMeshQuery& navMeshQuery, const osg::Vec3f& start, const osg::Vec3f& end,
|
||||||
std::span<dtPolyRef> polygonPath, std::size_t polygonPathSize, std::size_t maxSmoothPathSize,
|
std::span<dtPolyRef> polygonPath, std::size_t polygonPathSize, std::size_t maxSmoothPathSize,
|
||||||
OutputIterator& out)
|
std::output_iterator<osg::Vec3f> auto& out)
|
||||||
{
|
{
|
||||||
assert(polygonPathSize <= polygonPath.size());
|
assert(polygonPathSize <= polygonPath.size());
|
||||||
|
|
||||||
|
@ -102,10 +101,9 @@ namespace DetourNavigator
|
||||||
return Status::Success;
|
return Status::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class OutputIterator>
|
|
||||||
Status findSmoothPath(const dtNavMeshQuery& navMeshQuery, const osg::Vec3f& halfExtents, const osg::Vec3f& start,
|
Status findSmoothPath(const dtNavMeshQuery& navMeshQuery, const osg::Vec3f& halfExtents, const osg::Vec3f& start,
|
||||||
const osg::Vec3f& end, const Flags includeFlags, const AreaCosts& areaCosts, const DetourSettings& settings,
|
const osg::Vec3f& end, const Flags includeFlags, const AreaCosts& areaCosts, const DetourSettings& settings,
|
||||||
float endTolerance, OutputIterator out)
|
float endTolerance, std::output_iterator<osg::Vec3f> auto out)
|
||||||
{
|
{
|
||||||
dtQueryFilter queryFilter;
|
dtQueryFilter queryFilter;
|
||||||
queryFilter.setIncludeFlags(includeFlags);
|
queryFilter.setIncludeFlags(includeFlags);
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
#include <components/misc/guarded.hpp>
|
#include <components/misc/guarded.hpp>
|
||||||
|
|
||||||
|
#include <iterator>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
|
||||||
namespace DetourNavigator
|
namespace DetourNavigator
|
||||||
|
@ -21,22 +22,18 @@ namespace DetourNavigator
|
||||||
* @param includeFlags setup allowed surfaces for actor to walk.
|
* @param includeFlags setup allowed surfaces for actor to walk.
|
||||||
* @param out the beginning of the destination range.
|
* @param out the beginning of the destination range.
|
||||||
* @param endTolerance defines maximum allowed distance to end path point in addition to agentHalfExtents
|
* @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.
|
* @return Status.
|
||||||
* Equal to out if no path is found.
|
* Equal to out if no path is found.
|
||||||
*/
|
*/
|
||||||
template <class OutputIterator>
|
|
||||||
inline Status findPath(const Navigator& navigator, const AgentBounds& agentBounds, const osg::Vec3f& start,
|
inline Status findPath(const Navigator& navigator, const AgentBounds& agentBounds, const osg::Vec3f& start,
|
||||||
const osg::Vec3f& end, const Flags includeFlags, const AreaCosts& areaCosts, float endTolerance,
|
const osg::Vec3f& end, const Flags includeFlags, const AreaCosts& areaCosts, float endTolerance,
|
||||||
OutputIterator out)
|
std::output_iterator<osg::Vec3f> auto 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(agentBounds);
|
const auto navMesh = navigator.getNavMesh(agentBounds);
|
||||||
if (navMesh == nullptr)
|
if (navMesh == nullptr)
|
||||||
return Status::NavMeshNotFound;
|
return Status::NavMeshNotFound;
|
||||||
const Settings& settings = navigator.getSettings();
|
const Settings& settings = navigator.getSettings();
|
||||||
auto outTransform = withFromNavMeshCoordinates(out, settings.mRecast);
|
FromNavMeshCoordinatesIterator outTransform(out, settings.mRecast);
|
||||||
const auto locked = navMesh->lock();
|
const auto locked = navMesh->lock();
|
||||||
return findSmoothPath(locked->getQuery(), toNavMeshCoordinates(settings.mRecast, agentBounds.mHalfExtents),
|
return findSmoothPath(locked->getQuery(), toNavMeshCoordinates(settings.mRecast, agentBounds.mHalfExtents),
|
||||||
toNavMeshCoordinates(settings.mRecast, start), toNavMeshCoordinates(settings.mRecast, end), includeFlags,
|
toNavMeshCoordinates(settings.mRecast, start), toNavMeshCoordinates(settings.mRecast, end), includeFlags,
|
||||||
|
|
Loading…
Reference in a new issue