[Terrain] First pass of the ProcessList and ProcessRegion APIs for retrieving surface data (#6729)
* [Terrain] First pass of the ProcessList and ProcessRegion APIs for retrieving surface data Signed-off-by: amzn-sj <srikkant@amazon.com> * Add a couple of more tests. The expected values were plugged in based on the values generated by the brute force approach. Signed-off-by: amzn-sj <srikkant@amazon.com> * Move some declarations out of loops since they can be reused. Signed-off-by: amzn-sj <srikkant@amazon.com> * Update all the per position callbacks to pass SurfacePoint refs. Construct only one SurfacePoint object outside the loop which can be reused. Signed-off-by: amzn-sj <srikkant@amazon.com> * Update tests to use the new per position callbacks Signed-off-by: amzn-sj <srikkant@amazon.com> * Add ProcessRegion functions to the terrain benchmark. Signed-off-by: amzn-sj <srikkant@amazon.com> * Change C style static casts to aznumeric_cast. Add maybe_unused to unused params in benchmarks. Signed-off-by: amzn-sj <srikkant@amazon.com> * Update the ProcessList API functions to use array_view instead of a vector. This includes some additional changes to satisfy build dependencies. Signed-off-by: amzn-sj <srikkant@amazon.com> * Add ProcessList API functions to benchmarks Signed-off-by: amzn-sj <srikkant@amazon.com> * Update the ProcessList API functions to take Vector2 as input positions Signed-off-by: amzn-sj <srikkant@amazon.com> * Revert changes to AtomCore library split. Add partial implementation of span(mostly just copied over from array_view) to AzCore std containers. Signed-off-by: amzn-sj <srikkant@amazon.com> * Adding some const/non-const overloads that were missing in span Signed-off-by: amzn-sj <srikkant@amazon.com> * Move input position list generation to a function Signed-off-by: amzn-sj <srikkant@amazon.com> * Bring back Vector3 version of ProcessList functions. Rename Vector2 version to follow similar pattern as the Get functions. Signed-off-by: amzn-sj <srikkant@amazon.com> * Split span.h into .h/.inl files Signed-off-by: amzn-sj <srikkant@amazon.com> * Add [mayby_unused] for unused parameters to fix build errors Signed-off-by: amzn-sj <srikkant@amazon.com>
This commit is contained in:
@@ -64,6 +64,8 @@ set(FILES
|
||||
containers/rbtree.h
|
||||
containers/ring_buffer.h
|
||||
containers/set.h
|
||||
containers/span.h
|
||||
containers/span.inl
|
||||
containers/stack.h
|
||||
containers/unordered_map.h
|
||||
containers/unordered_set.h
|
||||
|
||||
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
#include <AzCore/std/containers/fixed_vector.h>
|
||||
#include <AzCore/std/containers/array.h>
|
||||
|
||||
namespace AZStd
|
||||
{
|
||||
/**
|
||||
* First pass partial implementation of span copied over from array_view. It
|
||||
* returns non-const iterator/pointers. first(), last(), and subspan()
|
||||
* are yet to be implemented. It does not maintain storage for the data,
|
||||
* but just holds pointers to mark the beginning and end of the array.
|
||||
* It can be conveniently constructed from a variety of other container
|
||||
* types like array, vector, and fixed_vector.
|
||||
*
|
||||
* Example:
|
||||
* Given "void Func(AZStd::span<int> a) {...}" you can call...
|
||||
* - Func({1,2,3});
|
||||
* - AZStd::array<int,3> a = {1,2,3};
|
||||
* Func(a);
|
||||
* - AZStd::vector<int> v = {1,2,3};
|
||||
* Func(v);
|
||||
* - AZStd::fixed_vector<int,10> fv = {1,2,3};
|
||||
* Func(fv);
|
||||
*
|
||||
* Since the span does not copy and store any data, it is only valid as long as the data used to create it is valid.
|
||||
*/
|
||||
template <class Element>
|
||||
class span final
|
||||
{
|
||||
public:
|
||||
using value_type = Element;
|
||||
|
||||
using pointer = value_type*;
|
||||
using const_pointer = const value_type*;
|
||||
|
||||
using reference = value_type&;
|
||||
using const_reference = const value_type&;
|
||||
|
||||
using size_type = AZStd::size_t;
|
||||
using difference_type = AZStd::ptrdiff_t;
|
||||
|
||||
using iterator = value_type*;
|
||||
using const_iterator = const value_type*;
|
||||
using reverse_iterator = AZStd::reverse_iterator<iterator>;
|
||||
using const_reverse_iterator = AZStd::reverse_iterator<const_iterator>;
|
||||
|
||||
constexpr span();
|
||||
|
||||
~span() = default;
|
||||
|
||||
constexpr span(pointer s, size_type length);
|
||||
|
||||
constexpr span(pointer first, const_pointer last);
|
||||
|
||||
// We explicitly delete this constructor because it's too easy to accidentally
|
||||
// create a span to just the first element instead of an entire array.
|
||||
constexpr span(const_pointer s) = delete;
|
||||
|
||||
template<AZStd::size_t N>
|
||||
constexpr span(AZStd::array<value_type, N>& data);
|
||||
|
||||
constexpr span(AZStd::vector<value_type>& data);
|
||||
|
||||
template<AZStd::size_t N>
|
||||
constexpr span(AZStd::fixed_vector<value_type, N>& data);
|
||||
|
||||
template<AZStd::size_t N>
|
||||
constexpr span(const AZStd::array<value_type, N>& data);
|
||||
|
||||
constexpr span(const AZStd::vector<value_type>& data);
|
||||
|
||||
template<AZStd::size_t N>
|
||||
constexpr span(const AZStd::fixed_vector<value_type, N>& data);
|
||||
|
||||
constexpr span(const span&) = default;
|
||||
|
||||
constexpr span(span&& other);
|
||||
|
||||
constexpr span& operator=(const span& other) = default;
|
||||
|
||||
constexpr span& operator=(span&& other);
|
||||
|
||||
constexpr size_type size() const;
|
||||
|
||||
constexpr bool empty() const;
|
||||
|
||||
constexpr pointer data();
|
||||
constexpr const_pointer data() const;
|
||||
|
||||
constexpr const_reference operator[](size_type index) const;
|
||||
constexpr reference operator[](size_type index);
|
||||
|
||||
constexpr void erase();
|
||||
|
||||
constexpr iterator begin();
|
||||
constexpr iterator end();
|
||||
constexpr const_iterator begin() const;
|
||||
constexpr const_iterator end() const;
|
||||
|
||||
constexpr const_iterator cbegin() const;
|
||||
constexpr const_iterator cend() const;
|
||||
|
||||
constexpr reverse_iterator rbegin();
|
||||
constexpr reverse_iterator rend();
|
||||
constexpr const_reverse_iterator rbegin() const;
|
||||
constexpr const_reverse_iterator rend() const;
|
||||
|
||||
constexpr const_reverse_iterator crbegin() const;
|
||||
constexpr const_reverse_iterator crend() const;
|
||||
|
||||
friend bool operator==(span lhs, span rhs)
|
||||
{
|
||||
return lhs.m_begin == rhs.m_begin && lhs.m_end == rhs.m_end;
|
||||
}
|
||||
|
||||
friend bool operator!=(span lhs, span rhs) { return !(lhs == rhs); }
|
||||
friend bool operator< (span lhs, span rhs) { return lhs.m_begin < rhs.m_begin || lhs.m_begin == rhs.m_begin && lhs.m_end < rhs.m_end; }
|
||||
friend bool operator> (span lhs, span rhs) { return lhs.m_begin > rhs.m_begin || lhs.m_begin == rhs.m_begin && lhs.m_end > rhs.m_end; }
|
||||
friend bool operator<=(span lhs, span rhs) { return lhs == rhs || lhs < rhs; }
|
||||
friend bool operator>=(span lhs, span rhs) { return lhs == rhs || lhs > rhs; }
|
||||
|
||||
private:
|
||||
pointer m_begin;
|
||||
pointer m_end;
|
||||
};
|
||||
} // namespace AZStd
|
||||
|
||||
#include <AzCore/std/containers/span.inl>
|
||||
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
namespace AZStd
|
||||
{
|
||||
template <class Element>
|
||||
inline constexpr span<Element>::span()
|
||||
: m_begin(nullptr)
|
||||
, m_end(nullptr)
|
||||
{ }
|
||||
|
||||
template <class Element>
|
||||
inline constexpr span<Element>::span(pointer s, size_type length)
|
||||
: m_begin(s)
|
||||
, m_end(m_begin + length)
|
||||
{
|
||||
if (length == 0) erase();
|
||||
}
|
||||
|
||||
template <class Element>
|
||||
inline constexpr span<Element>::span(pointer first, const_pointer last)
|
||||
: m_begin(first)
|
||||
, m_end(last)
|
||||
{ }
|
||||
|
||||
template <class Element>
|
||||
template<AZStd::size_t N>
|
||||
inline constexpr span<Element>::span(AZStd::array<Element, N>& data)
|
||||
: m_begin(data.data())
|
||||
, m_end(m_begin + data.size())
|
||||
{ }
|
||||
|
||||
template <class Element>
|
||||
inline constexpr span<Element>::span(AZStd::vector<Element>& data)
|
||||
: m_begin(data.data())
|
||||
, m_end(m_begin + data.size())
|
||||
{ }
|
||||
|
||||
template <class Element>
|
||||
template<AZStd::size_t N>
|
||||
inline constexpr span<Element>::span(AZStd::fixed_vector<Element, N>& data)
|
||||
: m_begin(data.data())
|
||||
, m_end(m_begin + data.size())
|
||||
{ }
|
||||
|
||||
template <class Element>
|
||||
template<AZStd::size_t N>
|
||||
inline constexpr span<Element>::span(const AZStd::array<Element, N>& data)
|
||||
: m_begin(data.data())
|
||||
, m_end(m_begin + data.size())
|
||||
{ }
|
||||
|
||||
template <class Element>
|
||||
inline constexpr span<Element>::span(const AZStd::vector<Element>& data)
|
||||
: m_begin(data.data())
|
||||
, m_end(m_begin + data.size())
|
||||
{ }
|
||||
|
||||
template <class Element>
|
||||
template<AZStd::size_t N>
|
||||
inline constexpr span<Element>::span(const AZStd::fixed_vector<Element, N>& data)
|
||||
: m_begin(data.data())
|
||||
, m_end(m_begin + data.size())
|
||||
{ }
|
||||
|
||||
template <class Element>
|
||||
inline constexpr span<Element>::span(span&& other)
|
||||
: span(other.m_begin, other.m_end)
|
||||
{
|
||||
#if AZ_DEBUG_BUILD // Clearing the original pointers isn't necessary, but is good for debugging
|
||||
other.m_begin = nullptr;
|
||||
other.m_end = nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class Element>
|
||||
inline constexpr AZStd::size_t span<Element>::size() const { return m_end - m_begin; }
|
||||
|
||||
template <class Element>
|
||||
inline constexpr bool span<Element>::empty() const { return m_end == m_begin; }
|
||||
|
||||
template <class Element>
|
||||
inline constexpr Element* span<Element>::data() { return m_begin; }
|
||||
|
||||
template <class Element>
|
||||
inline constexpr const Element* span<Element>::data() const { return m_begin; }
|
||||
|
||||
template <class Element>
|
||||
inline constexpr span<Element>& span<Element>::operator=(span<Element>&& other)
|
||||
{
|
||||
m_begin = other.m_begin;
|
||||
m_end = other.m_end;
|
||||
#if AZ_DEBUG_BUILD // Clearing the original pointers isn't necessary, but is good for debugging
|
||||
other.m_begin = nullptr;
|
||||
other.m_end = nullptr;
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class Element>
|
||||
inline constexpr const Element& span<Element>::operator[](AZStd::size_t index) const
|
||||
{
|
||||
AZ_Assert(index < size(), "index value is out of range");
|
||||
return m_begin[index];
|
||||
}
|
||||
|
||||
template <class Element>
|
||||
inline constexpr Element& span<Element>::operator[](AZStd::size_t index)
|
||||
{
|
||||
AZ_Assert(index < size(), "index value is out of range");
|
||||
return m_begin[index];
|
||||
}
|
||||
|
||||
template <class Element>
|
||||
inline constexpr void span<Element>::erase() { m_begin = m_end = nullptr; }
|
||||
|
||||
template <class Element>
|
||||
inline constexpr Element* span<Element>::begin() { return m_begin; }
|
||||
template <class Element>
|
||||
inline constexpr Element* span<Element>::end() { return m_end; }
|
||||
template <class Element>
|
||||
inline constexpr const Element* span<Element>::begin() const { return m_begin; }
|
||||
template <class Element>
|
||||
inline constexpr const Element* span<Element>::end() const { return m_end; }
|
||||
|
||||
template <class Element>
|
||||
inline constexpr const Element* span<Element>::cbegin() const { return m_begin; }
|
||||
template <class Element>
|
||||
inline constexpr const Element* span<Element>::cend() const { return m_end; }
|
||||
|
||||
template <class Element>
|
||||
inline constexpr AZStd::reverse_iterator<Element*> span<Element>::rbegin() { return AZStd::reverse_iterator<Element*>(m_end); }
|
||||
template <class Element>
|
||||
inline constexpr AZStd::reverse_iterator<Element*> span<Element>::rend() { return AZStd::reverse_iterator<Element*>(m_begin); }
|
||||
template <class Element>
|
||||
inline constexpr AZStd::reverse_iterator<const Element*> span<Element>::rbegin() const { return AZStd::reverse_iterator<const Element*>(m_end); }
|
||||
template <class Element>
|
||||
inline constexpr AZStd::reverse_iterator<const Element*> span<Element>::rend() const { return AZStd::reverse_iterator<const Element*>(m_begin); }
|
||||
|
||||
template <class Element>
|
||||
inline constexpr AZStd::reverse_iterator<const Element*> span<Element>::crbegin() const { return AZStd::reverse_iterator<const Element*>(cend()); }
|
||||
template <class Element>
|
||||
inline constexpr AZStd::reverse_iterator<const Element*> span<Element>::crend() const { return AZStd::reverse_iterator<const Element*>(cbegin()); }
|
||||
} // namespace AZStd
|
||||
@@ -11,12 +11,15 @@
|
||||
#include <AzCore/Math/Vector2.h>
|
||||
#include <AzCore/Math/Vector3.h>
|
||||
#include <AzCore/Math/Aabb.h>
|
||||
#include <AzCore/std/containers/span.h>
|
||||
#include <AzFramework/SurfaceData/SurfaceData.h>
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
namespace Terrain
|
||||
{
|
||||
typedef AZStd::function<void(size_t xIndex, size_t yIndex, const SurfaceData::SurfacePoint& surfacePoint, bool terrainExists)> SurfacePointRegionFillCallback;
|
||||
typedef AZStd::function<void(const SurfaceData::SurfacePoint& surfacePoint, bool terrainExists)> SurfacePointListFillCallback;
|
||||
|
||||
//! Shared interface for terrain system implementations
|
||||
class TerrainDataRequests
|
||||
@@ -131,6 +134,53 @@ namespace AzFramework
|
||||
Sampler sampleFilter = Sampler::DEFAULT,
|
||||
bool* terrainExistsPtr = nullptr) const = 0;
|
||||
|
||||
//! Given a list of XY coordinates, call the provided callback function with surface data corresponding to each
|
||||
//! XY coordinate in the list.
|
||||
virtual void ProcessHeightsFromList(const AZStd::span<AZ::Vector3>& inPositions,
|
||||
SurfacePointListFillCallback perPositionCallback,
|
||||
Sampler sampleFilter = Sampler::DEFAULT) const = 0;
|
||||
virtual void ProcessNormalsFromList(const AZStd::span<AZ::Vector3>& inPositions,
|
||||
SurfacePointListFillCallback perPositionCallback,
|
||||
Sampler sampleFilter = Sampler::DEFAULT) const = 0;
|
||||
virtual void ProcessSurfaceWeightsFromList(const AZStd::span<AZ::Vector3>& inPositions,
|
||||
SurfacePointListFillCallback perPositionCallback,
|
||||
Sampler sampleFilter = Sampler::DEFAULT) const = 0;
|
||||
virtual void ProcessSurfacePointsFromList(const AZStd::span<AZ::Vector3>& inPositions,
|
||||
SurfacePointListFillCallback perPositionCallback,
|
||||
Sampler sampleFilter = Sampler::DEFAULT) const = 0;
|
||||
virtual void ProcessHeightsFromListOfVector2(const AZStd::span<AZ::Vector2>& inPositions,
|
||||
SurfacePointListFillCallback perPositionCallback,
|
||||
Sampler sampleFilter = Sampler::DEFAULT) const = 0;
|
||||
virtual void ProcessNormalsFromListOfVector2(const AZStd::span<AZ::Vector2>& inPositions,
|
||||
SurfacePointListFillCallback perPositionCallback,
|
||||
Sampler sampleFilter = Sampler::DEFAULT) const = 0;
|
||||
virtual void ProcessSurfaceWeightsFromListOfVector2(const AZStd::span<AZ::Vector2>& inPositions,
|
||||
SurfacePointListFillCallback perPositionCallback,
|
||||
Sampler sampleFilter = Sampler::DEFAULT) const = 0;
|
||||
virtual void ProcessSurfacePointsFromListOfVector2(const AZStd::span<AZ::Vector2>& inPositions,
|
||||
SurfacePointListFillCallback perPositionCallback,
|
||||
Sampler sampleFilter = Sampler::DEFAULT) const = 0;
|
||||
|
||||
//! Given a region(aabb) and a step size, call the provided callback function with surface data corresponding to the
|
||||
//! coordinates in the region.
|
||||
virtual void ProcessHeightsFromRegion(const AZ::Aabb& inRegion,
|
||||
const AZ::Vector2& stepSize,
|
||||
SurfacePointRegionFillCallback perPositionCallback,
|
||||
Sampler sampleFilter = Sampler::DEFAULT) const = 0;
|
||||
virtual void ProcessNormalsFromRegion(const AZ::Aabb& inRegion,
|
||||
const AZ::Vector2& stepSize,
|
||||
SurfacePointRegionFillCallback perPositionCallback,
|
||||
Sampler sampleFilter = Sampler::DEFAULT) const = 0;
|
||||
virtual void ProcessSurfaceWeightsFromRegion(const AZ::Aabb& inRegion,
|
||||
const AZ::Vector2& stepSize,
|
||||
SurfacePointRegionFillCallback perPositionCallback,
|
||||
Sampler sampleFilter = Sampler::DEFAULT) const = 0;
|
||||
virtual void ProcessSurfacePointsFromRegion(const AZ::Aabb& inRegion,
|
||||
const AZ::Vector2& stepSize,
|
||||
SurfacePointRegionFillCallback perPositionCallback,
|
||||
Sampler sampleFilter = Sampler::DEFAULT) const = 0;
|
||||
|
||||
|
||||
private:
|
||||
// Private variations of the GetSurfacePoint API exposed to BehaviorContext that returns a value instead of
|
||||
// using an "out" parameter. The "out" parameter is useful for reusing memory allocated in SurfacePoint when
|
||||
|
||||
@@ -76,5 +76,29 @@ namespace UnitTest
|
||||
GetSurfacePointFromVector2, void(const AZ::Vector2&, AzFramework::SurfaceData::SurfacePoint&, Sampler, bool*));
|
||||
MOCK_CONST_METHOD5(
|
||||
GetSurfacePointFromFloats, void(float, float, AzFramework::SurfaceData::SurfacePoint&, Sampler, bool*));
|
||||
MOCK_CONST_METHOD3(
|
||||
ProcessHeightsFromList, void(const AZStd::span<AZ::Vector3>&, AzFramework::Terrain::SurfacePointListFillCallback, Sampler));
|
||||
MOCK_CONST_METHOD3(
|
||||
ProcessNormalsFromList, void(const AZStd::span<AZ::Vector3>&, AzFramework::Terrain::SurfacePointListFillCallback, Sampler));
|
||||
MOCK_CONST_METHOD3(
|
||||
ProcessSurfaceWeightsFromList, void(const AZStd::span<AZ::Vector3>&, AzFramework::Terrain::SurfacePointListFillCallback, Sampler));
|
||||
MOCK_CONST_METHOD3(
|
||||
ProcessSurfacePointsFromList, void(const AZStd::span<AZ::Vector3>&, AzFramework::Terrain::SurfacePointListFillCallback, Sampler));
|
||||
MOCK_CONST_METHOD3(
|
||||
ProcessHeightsFromListOfVector2, void(const AZStd::span<AZ::Vector2>&, AzFramework::Terrain::SurfacePointListFillCallback, Sampler));
|
||||
MOCK_CONST_METHOD3(
|
||||
ProcessNormalsFromListOfVector2, void(const AZStd::span<AZ::Vector2>&, AzFramework::Terrain::SurfacePointListFillCallback, Sampler));
|
||||
MOCK_CONST_METHOD3(
|
||||
ProcessSurfaceWeightsFromListOfVector2, void(const AZStd::span<AZ::Vector2>&, AzFramework::Terrain::SurfacePointListFillCallback, Sampler));
|
||||
MOCK_CONST_METHOD3(
|
||||
ProcessSurfacePointsFromListOfVector2, void(const AZStd::span<AZ::Vector2>&, AzFramework::Terrain::SurfacePointListFillCallback, Sampler));
|
||||
MOCK_CONST_METHOD4(
|
||||
ProcessHeightsFromRegion, void(const AZ::Aabb&, const AZ::Vector2&, AzFramework::Terrain::SurfacePointRegionFillCallback, Sampler));
|
||||
MOCK_CONST_METHOD4(
|
||||
ProcessNormalsFromRegion, void(const AZ::Aabb&, const AZ::Vector2&, AzFramework::Terrain::SurfacePointRegionFillCallback, Sampler));
|
||||
MOCK_CONST_METHOD4(
|
||||
ProcessSurfaceWeightsFromRegion, void(const AZ::Aabb&, const AZ::Vector2&, AzFramework::Terrain::SurfacePointRegionFillCallback, Sampler));
|
||||
MOCK_CONST_METHOD4(
|
||||
ProcessSurfacePointsFromRegion, void(const AZ::Aabb&, const AZ::Vector2&, AzFramework::Terrain::SurfacePointRegionFillCallback, Sampler));
|
||||
};
|
||||
} // namespace UnitTest
|
||||
|
||||
Reference in New Issue
Block a user