Optimize surface providers (#7631)
* Add comparison operators to SurfaceTagWeight. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Changed AddSurfaceTagWeight to always combine weights. This simplifies the API a bit and defines the behavior if someone ever tries to add a duplicate tag. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Added benchmarks for measuring the performance-critical APIs. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Changed SurfaceTagWeights to a fixed_vector. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Add inPosition to AddSurfacePoint. This will be used to detect which input the surface point is associated with. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Add inPositionIndex to the appropriate APIs. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Switched Gradient Surface benchmarks to use actual surface components. The gradient unit tests and benchmarks were previously using a mock surface data system, which led to misleading benchmark results. Now, the actual SurfaceData system gets constructed, and the tests use a mock provider, but the benchmarks use actual shape providers for more realistic benchmarking. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Fixed unit tests to have better query ranges. Half of each previous range was querying outside the surface provider's data. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * First attempt at removing SurfacePointLists. This currently runs significantly slower than the previous code but passes the unit tests. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Another attempt at optimization. This one runs faster than the previous, but still slow. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Fix the cmake dependency so that the gradient tests rebuild SurfaceData.dll when run. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Switch SurfaceAltitudeGradient over to the new bulk API. Also, optimized the non-bulk API by having it reuse the SurfacePointList to avoid the repeated allocation / deallocation cost. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Switched to using an indirect index so that all allocations are consecutive in our reserved buffer. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Switched back to SurfaceTagWeight again. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Added runtime dependency to LmbrCentral for unit tests. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Switched code over to use the full EnumeratePoints in most cases. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Added knowledge of max surface point creation into the system. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Add generic GetSurfacePointsFromList API implementation for surface providers. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Fixed implementation to use the correct maximum number of input points based on the surface providers being queried. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Fix out-of-bounds references on empty lists. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Fix memory allocation that caused benchmark runs to crash. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Starting to clean up the API. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Move SurfacePointList into separate files for easier maintainability. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Fixed bug where too many points were filtered out due to using the position Z as a part of the AABB check. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Made FilterPoints an internal part of SurfacePointList so we can choose when and how to perform the filtering. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Final cleanup / comments. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Added includes for non-unity builds. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Optimized GetValues() implementations. Also consolidated GetValue() and GetValues() down to a single implementation under the covers for easier maintenance. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Changed how unit tests initialize the mock lists to try and fix the linux errors. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Switch to explicit span declarations to help ensure this works with linux. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Fixed compile error. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Make the bulk terrain APIs take in const Vector instead of non-const. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Optimize the surface data providers for bulk queries. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com>
This commit is contained in:
@@ -140,28 +140,28 @@ namespace AzFramework
|
||||
|
||||
//! 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,
|
||||
virtual void ProcessHeightsFromList(const AZStd::span<const AZ::Vector3>& inPositions,
|
||||
SurfacePointListFillCallback perPositionCallback,
|
||||
Sampler sampleFilter = Sampler::DEFAULT) const = 0;
|
||||
virtual void ProcessNormalsFromList(const AZStd::span<AZ::Vector3>& inPositions,
|
||||
virtual void ProcessNormalsFromList(const AZStd::span<const AZ::Vector3>& inPositions,
|
||||
SurfacePointListFillCallback perPositionCallback,
|
||||
Sampler sampleFilter = Sampler::DEFAULT) const = 0;
|
||||
virtual void ProcessSurfaceWeightsFromList(const AZStd::span<AZ::Vector3>& inPositions,
|
||||
virtual void ProcessSurfaceWeightsFromList(const AZStd::span<const AZ::Vector3>& inPositions,
|
||||
SurfacePointListFillCallback perPositionCallback,
|
||||
Sampler sampleFilter = Sampler::DEFAULT) const = 0;
|
||||
virtual void ProcessSurfacePointsFromList(const AZStd::span<AZ::Vector3>& inPositions,
|
||||
virtual void ProcessSurfacePointsFromList(const AZStd::span<const AZ::Vector3>& inPositions,
|
||||
SurfacePointListFillCallback perPositionCallback,
|
||||
Sampler sampleFilter = Sampler::DEFAULT) const = 0;
|
||||
virtual void ProcessHeightsFromListOfVector2(const AZStd::span<AZ::Vector2>& inPositions,
|
||||
virtual void ProcessHeightsFromListOfVector2(const AZStd::span<const AZ::Vector2>& inPositions,
|
||||
SurfacePointListFillCallback perPositionCallback,
|
||||
Sampler sampleFilter = Sampler::DEFAULT) const = 0;
|
||||
virtual void ProcessNormalsFromListOfVector2(const AZStd::span<AZ::Vector2>& inPositions,
|
||||
virtual void ProcessNormalsFromListOfVector2(const AZStd::span<const AZ::Vector2>& inPositions,
|
||||
SurfacePointListFillCallback perPositionCallback,
|
||||
Sampler sampleFilter = Sampler::DEFAULT) const = 0;
|
||||
virtual void ProcessSurfaceWeightsFromListOfVector2(const AZStd::span<AZ::Vector2>& inPositions,
|
||||
virtual void ProcessSurfaceWeightsFromListOfVector2(const AZStd::span<const AZ::Vector2>& inPositions,
|
||||
SurfacePointListFillCallback perPositionCallback,
|
||||
Sampler sampleFilter = Sampler::DEFAULT) const = 0;
|
||||
virtual void ProcessSurfacePointsFromListOfVector2(const AZStd::span<AZ::Vector2>& inPositions,
|
||||
virtual void ProcessSurfacePointsFromListOfVector2(const AZStd::span<const AZ::Vector2>& inPositions,
|
||||
SurfacePointListFillCallback perPositionCallback,
|
||||
Sampler sampleFilter = Sampler::DEFAULT) const = 0;
|
||||
|
||||
@@ -272,42 +272,42 @@ namespace AzFramework
|
||||
//! Asynchronous versions of the various 'Process*' API functions declared above.
|
||||
//! It's the responsibility of the caller to ensure all callbacks are threadsafe.
|
||||
virtual AZStd::shared_ptr<TerrainJobContext> ProcessHeightsFromListAsync(
|
||||
const AZStd::span<AZ::Vector3>& inPositions,
|
||||
const AZStd::span<const AZ::Vector3>& inPositions,
|
||||
SurfacePointListFillCallback perPositionCallback,
|
||||
Sampler sampleFilter = Sampler::DEFAULT,
|
||||
AZStd::shared_ptr<ProcessAsyncParams> params = nullptr) const = 0;
|
||||
virtual AZStd::shared_ptr<TerrainJobContext> ProcessNormalsFromListAsync(
|
||||
const AZStd::span<AZ::Vector3>& inPositions,
|
||||
const AZStd::span<const AZ::Vector3>& inPositions,
|
||||
SurfacePointListFillCallback perPositionCallback,
|
||||
Sampler sampleFilter = Sampler::DEFAULT,
|
||||
AZStd::shared_ptr<ProcessAsyncParams> params = nullptr) const = 0;
|
||||
virtual AZStd::shared_ptr<TerrainJobContext> ProcessSurfaceWeightsFromListAsync(
|
||||
const AZStd::span<AZ::Vector3>& inPositions,
|
||||
const AZStd::span<const AZ::Vector3>& inPositions,
|
||||
SurfacePointListFillCallback perPositionCallback,
|
||||
Sampler sampleFilter = Sampler::DEFAULT,
|
||||
AZStd::shared_ptr<ProcessAsyncParams> params = nullptr) const = 0;
|
||||
virtual AZStd::shared_ptr<TerrainJobContext> ProcessSurfacePointsFromListAsync(
|
||||
const AZStd::span<AZ::Vector3>& inPositions,
|
||||
const AZStd::span<const AZ::Vector3>& inPositions,
|
||||
SurfacePointListFillCallback perPositionCallback,
|
||||
Sampler sampleFilter = Sampler::DEFAULT,
|
||||
AZStd::shared_ptr<ProcessAsyncParams> params = nullptr) const = 0;
|
||||
virtual AZStd::shared_ptr<TerrainJobContext> ProcessHeightsFromListOfVector2Async(
|
||||
const AZStd::span<AZ::Vector2>& inPositions,
|
||||
const AZStd::span<const AZ::Vector2>& inPositions,
|
||||
SurfacePointListFillCallback perPositionCallback,
|
||||
Sampler sampleFilter = Sampler::DEFAULT,
|
||||
AZStd::shared_ptr<ProcessAsyncParams> params = nullptr) const = 0;
|
||||
virtual AZStd::shared_ptr<TerrainJobContext> ProcessNormalsFromListOfVector2Async(
|
||||
const AZStd::span<AZ::Vector2>& inPositions,
|
||||
const AZStd::span<const AZ::Vector2>& inPositions,
|
||||
SurfacePointListFillCallback perPositionCallback,
|
||||
Sampler sampleFilter = Sampler::DEFAULT,
|
||||
AZStd::shared_ptr<ProcessAsyncParams> params = nullptr) const = 0;
|
||||
virtual AZStd::shared_ptr<TerrainJobContext> ProcessSurfaceWeightsFromListOfVector2Async(
|
||||
const AZStd::span<AZ::Vector2>& inPositions,
|
||||
const AZStd::span<const AZ::Vector2>& inPositions,
|
||||
SurfacePointListFillCallback perPositionCallback,
|
||||
Sampler sampleFilter = Sampler::DEFAULT,
|
||||
AZStd::shared_ptr<ProcessAsyncParams> params = nullptr) const = 0;
|
||||
virtual AZStd::shared_ptr<TerrainJobContext> ProcessSurfacePointsFromListOfVector2Async(
|
||||
const AZStd::span<AZ::Vector2>& inPositions,
|
||||
const AZStd::span<const AZ::Vector2>& inPositions,
|
||||
SurfacePointListFillCallback perPositionCallback,
|
||||
Sampler sampleFilter = Sampler::DEFAULT,
|
||||
AZStd::shared_ptr<ProcessAsyncParams> params = nullptr) const = 0;
|
||||
|
||||
@@ -77,21 +77,21 @@ namespace UnitTest
|
||||
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));
|
||||
ProcessHeightsFromList, void(const AZStd::span<const AZ::Vector3>&, AzFramework::Terrain::SurfacePointListFillCallback, Sampler));
|
||||
MOCK_CONST_METHOD3(
|
||||
ProcessNormalsFromList, void(const AZStd::span<AZ::Vector3>&, AzFramework::Terrain::SurfacePointListFillCallback, Sampler));
|
||||
ProcessNormalsFromList, void(const AZStd::span<const AZ::Vector3>&, AzFramework::Terrain::SurfacePointListFillCallback, Sampler));
|
||||
MOCK_CONST_METHOD3(
|
||||
ProcessSurfaceWeightsFromList, void(const AZStd::span<AZ::Vector3>&, AzFramework::Terrain::SurfacePointListFillCallback, Sampler));
|
||||
ProcessSurfaceWeightsFromList, void(const AZStd::span<const AZ::Vector3>&, AzFramework::Terrain::SurfacePointListFillCallback, Sampler));
|
||||
MOCK_CONST_METHOD3(
|
||||
ProcessSurfacePointsFromList, void(const AZStd::span<AZ::Vector3>&, AzFramework::Terrain::SurfacePointListFillCallback, Sampler));
|
||||
ProcessSurfacePointsFromList, void(const AZStd::span<const AZ::Vector3>&, AzFramework::Terrain::SurfacePointListFillCallback, Sampler));
|
||||
MOCK_CONST_METHOD3(
|
||||
ProcessHeightsFromListOfVector2, void(const AZStd::span<AZ::Vector2>&, AzFramework::Terrain::SurfacePointListFillCallback, Sampler));
|
||||
ProcessHeightsFromListOfVector2, void(const AZStd::span<const AZ::Vector2>&, AzFramework::Terrain::SurfacePointListFillCallback, Sampler));
|
||||
MOCK_CONST_METHOD3(
|
||||
ProcessNormalsFromListOfVector2, void(const AZStd::span<AZ::Vector2>&, AzFramework::Terrain::SurfacePointListFillCallback, Sampler));
|
||||
ProcessNormalsFromListOfVector2, void(const AZStd::span<const AZ::Vector2>&, AzFramework::Terrain::SurfacePointListFillCallback, Sampler));
|
||||
MOCK_CONST_METHOD3(
|
||||
ProcessSurfaceWeightsFromListOfVector2, void(const AZStd::span<AZ::Vector2>&, AzFramework::Terrain::SurfacePointListFillCallback, Sampler));
|
||||
ProcessSurfaceWeightsFromListOfVector2, void(const AZStd::span<const AZ::Vector2>&, AzFramework::Terrain::SurfacePointListFillCallback, Sampler));
|
||||
MOCK_CONST_METHOD3(
|
||||
ProcessSurfacePointsFromListOfVector2, void(const AZStd::span<AZ::Vector2>&, AzFramework::Terrain::SurfacePointListFillCallback, Sampler));
|
||||
ProcessSurfacePointsFromListOfVector2, void(const AZStd::span<const AZ::Vector2>&, AzFramework::Terrain::SurfacePointListFillCallback, Sampler));
|
||||
MOCK_CONST_METHOD2(
|
||||
GetNumSamplesFromRegion, AZStd::pair<size_t, size_t>(const AZ::Aabb&, const AZ::Vector2&));
|
||||
MOCK_CONST_METHOD4(
|
||||
@@ -107,21 +107,21 @@ namespace UnitTest
|
||||
MOCK_CONST_METHOD1(
|
||||
GetClosestIntersection, AzFramework::RenderGeometry::RayResult(const AzFramework::RenderGeometry::RayRequest&));
|
||||
MOCK_CONST_METHOD4(
|
||||
ProcessHeightsFromListAsync, AZStd::shared_ptr<TerrainJobContext>(const AZStd::span<AZ::Vector3>&, AzFramework::Terrain::SurfacePointListFillCallback, Sampler, AZStd::shared_ptr<ProcessAsyncParams>));
|
||||
ProcessHeightsFromListAsync, AZStd::shared_ptr<TerrainJobContext>(const AZStd::span<const AZ::Vector3>&, AzFramework::Terrain::SurfacePointListFillCallback, Sampler, AZStd::shared_ptr<ProcessAsyncParams>));
|
||||
MOCK_CONST_METHOD4(
|
||||
ProcessNormalsFromListAsync, AZStd::shared_ptr<TerrainJobContext>(const AZStd::span<AZ::Vector3>&, AzFramework::Terrain::SurfacePointListFillCallback, Sampler, AZStd::shared_ptr<ProcessAsyncParams>));
|
||||
ProcessNormalsFromListAsync, AZStd::shared_ptr<TerrainJobContext>(const AZStd::span<const AZ::Vector3>&, AzFramework::Terrain::SurfacePointListFillCallback, Sampler, AZStd::shared_ptr<ProcessAsyncParams>));
|
||||
MOCK_CONST_METHOD4(
|
||||
ProcessSurfaceWeightsFromListAsync, AZStd::shared_ptr<TerrainJobContext>(const AZStd::span<AZ::Vector3>&, AzFramework::Terrain::SurfacePointListFillCallback, Sampler, AZStd::shared_ptr<ProcessAsyncParams>));
|
||||
ProcessSurfaceWeightsFromListAsync, AZStd::shared_ptr<TerrainJobContext>(const AZStd::span<const AZ::Vector3>&, AzFramework::Terrain::SurfacePointListFillCallback, Sampler, AZStd::shared_ptr<ProcessAsyncParams>));
|
||||
MOCK_CONST_METHOD4(
|
||||
ProcessSurfacePointsFromListAsync, AZStd::shared_ptr<TerrainJobContext>(const AZStd::span<AZ::Vector3>&, AzFramework::Terrain::SurfacePointListFillCallback, Sampler, AZStd::shared_ptr<ProcessAsyncParams>));
|
||||
ProcessSurfacePointsFromListAsync, AZStd::shared_ptr<TerrainJobContext>(const AZStd::span<const AZ::Vector3>&, AzFramework::Terrain::SurfacePointListFillCallback, Sampler, AZStd::shared_ptr<ProcessAsyncParams>));
|
||||
MOCK_CONST_METHOD4(
|
||||
ProcessHeightsFromListOfVector2Async, AZStd::shared_ptr<TerrainJobContext>(const AZStd::span<AZ::Vector2>&, AzFramework::Terrain::SurfacePointListFillCallback, Sampler, AZStd::shared_ptr<ProcessAsyncParams>));
|
||||
ProcessHeightsFromListOfVector2Async, AZStd::shared_ptr<TerrainJobContext>(const AZStd::span<const AZ::Vector2>&, AzFramework::Terrain::SurfacePointListFillCallback, Sampler, AZStd::shared_ptr<ProcessAsyncParams>));
|
||||
MOCK_CONST_METHOD4(
|
||||
ProcessNormalsFromListOfVector2Async, AZStd::shared_ptr<TerrainJobContext>(const AZStd::span<AZ::Vector2>&, AzFramework::Terrain::SurfacePointListFillCallback, Sampler, AZStd::shared_ptr<ProcessAsyncParams>));
|
||||
ProcessNormalsFromListOfVector2Async, AZStd::shared_ptr<TerrainJobContext>(const AZStd::span<const AZ::Vector2>&, AzFramework::Terrain::SurfacePointListFillCallback, Sampler, AZStd::shared_ptr<ProcessAsyncParams>));
|
||||
MOCK_CONST_METHOD4(
|
||||
ProcessSurfaceWeightsFromListOfVector2Async, AZStd::shared_ptr<TerrainJobContext>(const AZStd::span<AZ::Vector2>&, AzFramework::Terrain::SurfacePointListFillCallback, Sampler, AZStd::shared_ptr<ProcessAsyncParams>));
|
||||
ProcessSurfaceWeightsFromListOfVector2Async, AZStd::shared_ptr<TerrainJobContext>(const AZStd::span<const AZ::Vector2>&, AzFramework::Terrain::SurfacePointListFillCallback, Sampler, AZStd::shared_ptr<ProcessAsyncParams>));
|
||||
MOCK_CONST_METHOD4(
|
||||
ProcessSurfacePointsFromListOfVector2Async, AZStd::shared_ptr<TerrainJobContext>(const AZStd::span<AZ::Vector2>&, AzFramework::Terrain::SurfacePointListFillCallback, Sampler, AZStd::shared_ptr<ProcessAsyncParams>));
|
||||
ProcessSurfacePointsFromListOfVector2Async, AZStd::shared_ptr<TerrainJobContext>(const AZStd::span<const AZ::Vector2>&, AzFramework::Terrain::SurfacePointListFillCallback, Sampler, AZStd::shared_ptr<ProcessAsyncParams>));
|
||||
MOCK_CONST_METHOD5(
|
||||
ProcessHeightsFromRegionAsync, AZStd::shared_ptr<TerrainJobContext>(const AZ::Aabb&, const AZ::Vector2&, AzFramework::Terrain::SurfacePointRegionFillCallback, Sampler, AZStd::shared_ptr<ProcessAsyncParams>));
|
||||
MOCK_CONST_METHOD5(
|
||||
|
||||
+28
-26
@@ -144,44 +144,46 @@ namespace SurfaceData
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SurfaceDataMeshComponent::DoRayTrace(const AZ::Vector3& inPosition, AZ::Vector3& outPosition, AZ::Vector3& outNormal) const
|
||||
void SurfaceDataMeshComponent::GetSurfacePoints(const AZ::Vector3& inPosition, SurfacePointList& surfacePointList) const
|
||||
{
|
||||
GetSurfacePointsFromList(AZStd::span<const AZ::Vector3>(&inPosition, 1), surfacePointList);
|
||||
}
|
||||
|
||||
void SurfaceDataMeshComponent::GetSurfacePointsFromList(
|
||||
AZStd::span<const AZ::Vector3> inPositions, SurfacePointList& surfacePointList) const
|
||||
{
|
||||
AZ::Vector3 hitPosition;
|
||||
AZ::Vector3 hitNormal;
|
||||
|
||||
AZStd::shared_lock<decltype(m_cacheMutex)> lock(m_cacheMutex);
|
||||
|
||||
// test AABB as first pass to claim the point
|
||||
const AZ::Vector3 testPosition = AZ::Vector3(
|
||||
inPosition.GetX(),
|
||||
inPosition.GetY(),
|
||||
(m_meshBounds.GetMax().GetZ() + m_meshBounds.GetMin().GetZ()) * 0.5f);
|
||||
|
||||
if (!m_meshBounds.Contains(testPosition))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
AZ::RPI::ModelAsset* mesh = m_meshAssetData.GetAs<AZ::RPI::ModelAsset>();
|
||||
if (!mesh)
|
||||
{
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
const AZ::Vector3 rayStart = AZ::Vector3(inPosition.GetX(), inPosition.GetY(), m_meshBounds.GetMax().GetZ() + s_rayAABBHeightPadding);
|
||||
const AZ::Vector3 rayEnd = AZ::Vector3(inPosition.GetX(), inPosition.GetY(), m_meshBounds.GetMin().GetZ() - s_rayAABBHeightPadding);
|
||||
return GetMeshRayIntersection(
|
||||
*mesh, m_meshWorldTM, m_meshWorldTMInverse, m_meshNonUniformScale, rayStart, rayEnd, outPosition, outNormal);
|
||||
}
|
||||
|
||||
|
||||
void SurfaceDataMeshComponent::GetSurfacePoints(const AZ::Vector3& inPosition, SurfacePointList& surfacePointList) const
|
||||
{
|
||||
AZ::Vector3 hitPosition;
|
||||
AZ::Vector3 hitNormal;
|
||||
if (DoRayTrace(inPosition, hitPosition, hitNormal))
|
||||
for (auto& inPosition : inPositions)
|
||||
{
|
||||
surfacePointList.AddSurfacePoint(GetEntityId(), inPosition, hitPosition, hitNormal, m_newPointWeights);
|
||||
// test AABB as first pass to claim the point
|
||||
if (SurfaceData::AabbContains2D(m_meshBounds, inPosition))
|
||||
{
|
||||
const AZ::Vector3 rayStart =
|
||||
AZ::Vector3(inPosition.GetX(), inPosition.GetY(), m_meshBounds.GetMax().GetZ() + s_rayAABBHeightPadding);
|
||||
const AZ::Vector3 rayEnd =
|
||||
AZ::Vector3(inPosition.GetX(), inPosition.GetY(), m_meshBounds.GetMin().GetZ() - s_rayAABBHeightPadding);
|
||||
bool rayHit = GetMeshRayIntersection(
|
||||
*mesh, m_meshWorldTM, m_meshWorldTMInverse, m_meshNonUniformScale, rayStart, rayEnd, hitPosition, hitNormal);
|
||||
|
||||
if (rayHit)
|
||||
{
|
||||
surfacePointList.AddSurfacePoint(GetEntityId(), inPosition, hitPosition, hitNormal, m_newPointWeights);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
AZ::Aabb SurfaceDataMeshComponent::GetSurfaceAabb() const
|
||||
{
|
||||
return m_meshBounds;
|
||||
|
||||
+1
-1
@@ -80,9 +80,9 @@ namespace SurfaceData
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// SurfaceDataProviderRequestBus
|
||||
void GetSurfacePoints(const AZ::Vector3& inPosition, SurfacePointList& surfacePointList) const override;
|
||||
void GetSurfacePointsFromList(AZStd::span<const AZ::Vector3> inPositions, SurfacePointList& surfacePointList) const override;
|
||||
|
||||
private:
|
||||
bool DoRayTrace(const AZ::Vector3& inPosition, AZ::Vector3& outPosition, AZ::Vector3& outNormal) const;
|
||||
void UpdateMeshData();
|
||||
void OnCompositionChanged();
|
||||
|
||||
|
||||
-20
@@ -108,29 +108,9 @@ namespace GradientSignal
|
||||
void AddTag(AZStd::string tag) override;
|
||||
|
||||
private:
|
||||
static float CalculateAltitudeRatio(const SurfaceData::SurfacePointList& points, size_t inPositionIndex, float altitudeMin, float altitudeMax)
|
||||
{
|
||||
if (points.IsEmpty(inPositionIndex))
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
// GetSurfacePoints (which was used to populate the points list) always returns points in decreasing height order, so the
|
||||
// first point in the list contains the highest altitude.
|
||||
const float highestAltitude = points.GetHighestSurfacePoint(inPositionIndex).m_position.GetZ();
|
||||
|
||||
// Turn the absolute altitude value into a 0-1 value by returning the % of the given altitude range that it falls at.
|
||||
return GetRatio(altitudeMin, altitudeMax, highestAltitude);
|
||||
}
|
||||
|
||||
mutable AZStd::shared_mutex m_cacheMutex;
|
||||
SurfaceAltitudeGradientConfig m_configuration;
|
||||
LmbrCentral::DependencyMonitor m_dependencyMonitor;
|
||||
AZStd::atomic_bool m_dirty{ false };
|
||||
|
||||
// m_surfacePointList exists here because it will more efficiently reuse memory across GetValue() calls if it stays constructed.
|
||||
// The mutex exists to ensure that we don't try to use it from GetValue() in multiple threads at once.
|
||||
mutable AZStd::recursive_mutex m_surfacePointListMutex;
|
||||
mutable SurfaceData::SurfacePointList m_surfacePointList;
|
||||
};
|
||||
}
|
||||
|
||||
-19
@@ -82,25 +82,6 @@ namespace GradientSignal
|
||||
void AddTag(AZStd::string tag) override;
|
||||
|
||||
private:
|
||||
static float GetMaxSurfaceWeight(const SurfaceData::SurfacePointList& points)
|
||||
{
|
||||
float result = 0.0f;
|
||||
points.EnumeratePoints([&result](
|
||||
[[maybe_unused]] size_t inPositionIndex, [[maybe_unused]] const AZ::Vector3& position,
|
||||
[[maybe_unused]] const AZ::Vector3& normal, const SurfaceData::SurfaceTagWeights& masks) -> bool
|
||||
{
|
||||
masks.EnumerateWeights(
|
||||
[&result]([[maybe_unused]] AZ::Crc32 surfaceType, float weight) -> bool
|
||||
{
|
||||
result = AZ::GetMax(AZ::GetClamp(weight, 0.0f, 1.0f), result);
|
||||
return true;
|
||||
});
|
||||
return true;
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
SurfaceMaskGradientConfig m_configuration;
|
||||
LmbrCentral::DependencyMonitor m_dependencyMonitor;
|
||||
};
|
||||
|
||||
-33
@@ -124,39 +124,6 @@ namespace GradientSignal
|
||||
void SetFallOffMidpoint(float midpoint) override;
|
||||
|
||||
private:
|
||||
float GetSlopeRatio(const SurfaceData::SurfacePointList& points, float angleMin, float angleMax) const
|
||||
{
|
||||
constexpr size_t inPositionIndex = 0;
|
||||
if (points.IsEmpty(inPositionIndex))
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
// Assuming our surface normal vector is actually normalized, we can get the slope
|
||||
// by just grabbing the Z value. It's the same thing as normal.Dot(AZ::Vector3::CreateAxisZ()).
|
||||
auto highestSurfacePoint = points.GetHighestSurfacePoint(inPositionIndex);
|
||||
AZ_Assert(
|
||||
highestSurfacePoint.m_normal.GetNormalized().IsClose(highestSurfacePoint.m_normal),
|
||||
"Surface normals are expected to be normalized");
|
||||
const float slope = highestSurfacePoint.m_normal.GetZ();
|
||||
// Convert slope back to an angle so that we can lerp in "angular space", not "slope value space".
|
||||
// (We want our 0-1 range to be linear across the range of angles)
|
||||
const float slopeAngle = acosf(slope);
|
||||
|
||||
switch (m_configuration.m_rampType)
|
||||
{
|
||||
case SurfaceSlopeGradientConfig::RampType::SMOOTH_STEP:
|
||||
return m_configuration.m_smoothStep.GetSmoothedValue(GetRatio(angleMin, angleMax, slopeAngle));
|
||||
case SurfaceSlopeGradientConfig::RampType::LINEAR_RAMP_UP:
|
||||
// For ramp up, linearly interpolate from min to max.
|
||||
return GetRatio(angleMin, angleMax, slopeAngle);
|
||||
case SurfaceSlopeGradientConfig::RampType::LINEAR_RAMP_DOWN:
|
||||
default:
|
||||
// For ramp down, linearly interpolate from max to min.
|
||||
return GetRatio(angleMax, angleMin, slopeAngle);
|
||||
}
|
||||
}
|
||||
|
||||
SurfaceSlopeGradientConfig m_configuration;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -202,18 +202,9 @@ namespace GradientSignal
|
||||
|
||||
float SurfaceAltitudeGradientComponent::GetValue(const GradientSampleParams& sampleParams) const
|
||||
{
|
||||
// For GetValue(), we reuse our SurfacePointList for the GetSurfacePoints query to avoid the repeated cost of memory allocation
|
||||
// and deallocation across GetValue() calls. However, this also means we can only use it from one thread at a time, so lock a
|
||||
// mutex to ensure no other threads call GetValue() at the same time.
|
||||
AZStd::unique_lock<decltype(m_surfacePointListMutex)> surfacePointLock(m_surfacePointListMutex);
|
||||
|
||||
AZStd::shared_lock<decltype(m_cacheMutex)> lock(m_cacheMutex);
|
||||
|
||||
SurfaceData::SurfaceDataSystemRequestBus::Broadcast(&SurfaceData::SurfaceDataSystemRequestBus::Events::GetSurfacePoints,
|
||||
sampleParams.m_position, m_configuration.m_surfaceTagsToSample, m_surfacePointList);
|
||||
|
||||
constexpr size_t inPositionIndex = 0;
|
||||
return CalculateAltitudeRatio(m_surfacePointList, inPositionIndex, m_configuration.m_altitudeMin, m_configuration.m_altitudeMax);
|
||||
float result = 0.0f;
|
||||
GetValues(AZStd::span<const AZ::Vector3>(&sampleParams.m_position, 1), AZStd::span<float>(&result, 1));
|
||||
return result;
|
||||
}
|
||||
|
||||
void SurfaceAltitudeGradientComponent::GetValues(AZStd::span<const AZ::Vector3> positions, AZStd::span<float> outValues) const
|
||||
@@ -231,17 +222,20 @@ namespace GradientSignal
|
||||
&SurfaceData::SurfaceDataSystemRequestBus::Events::GetSurfacePointsFromList, positions, m_configuration.m_surfaceTagsToSample,
|
||||
points);
|
||||
|
||||
if (points.IsEmpty())
|
||||
// For each position, turn the height into a 0-1 value based on our min/max altitudes.
|
||||
for (size_t index = 0; index < positions.size(); index++)
|
||||
{
|
||||
// No surface data, so no output values.
|
||||
AZStd::fill(outValues.begin(), outValues.end(), 0.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
// For each position, turn the height into a 0-1 value based on our min/max altitudes.
|
||||
for (size_t index = 0; index < positions.size(); index++)
|
||||
if (!points.IsEmpty(index))
|
||||
{
|
||||
outValues[index] = CalculateAltitudeRatio(points, index, m_configuration.m_altitudeMin, m_configuration.m_altitudeMax);
|
||||
// Get the point with the highest Z value and use that for the altitude.
|
||||
const float highestAltitude = points.GetHighestSurfacePoint(index).m_position.GetZ();
|
||||
|
||||
// Turn the absolute altitude value into a 0-1 value by returning the % of the given altitude range that it falls at.
|
||||
outValues[index] = GetRatio(m_configuration.m_altitudeMin, m_configuration.m_altitudeMax, highestAltitude);
|
||||
}
|
||||
else
|
||||
{
|
||||
outValues[index] = 0.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,16 +162,7 @@ namespace GradientSignal
|
||||
float SurfaceMaskGradientComponent::GetValue(const GradientSampleParams& params) const
|
||||
{
|
||||
float result = 0.0f;
|
||||
|
||||
if (!m_configuration.m_surfaceTagList.empty())
|
||||
{
|
||||
SurfaceData::SurfacePointList points;
|
||||
SurfaceData::SurfaceDataSystemRequestBus::Broadcast(&SurfaceData::SurfaceDataSystemRequestBus::Events::GetSurfacePoints,
|
||||
params.m_position, m_configuration.m_surfaceTagList, points);
|
||||
|
||||
result = GetMaxSurfaceWeight(points);
|
||||
}
|
||||
|
||||
GetValues(AZStd::span<const AZ::Vector3>(¶ms.m_position, 1), AZStd::span<float>(&result, 1));
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -183,34 +174,31 @@ namespace GradientSignal
|
||||
return;
|
||||
}
|
||||
|
||||
bool valuesFound = false;
|
||||
// Initialize all our output values to 0.
|
||||
AZStd::fill(outValues.begin(), outValues.end(), 0.0f);
|
||||
|
||||
if (!m_configuration.m_surfaceTagList.empty())
|
||||
{
|
||||
// Rather than calling GetSurfacePoints on the EBus repeatedly in a loop, we instead pass a lambda into the EBus that contains
|
||||
// the loop within it so that we can avoid the repeated EBus-calling overhead.
|
||||
SurfaceData::SurfacePointList points;
|
||||
SurfaceData::SurfaceDataSystemRequestBus::Broadcast(
|
||||
[this, positions, &outValues, &valuesFound](SurfaceData::SurfaceDataSystemRequestBus::Events* surfaceDataRequests)
|
||||
{
|
||||
// It's possible that there's nothing connected to the EBus, so keep track of the fact that we have valid results.
|
||||
valuesFound = true;
|
||||
SurfaceData::SurfacePointList points;
|
||||
&SurfaceData::SurfaceDataSystemRequestBus::Events::GetSurfacePointsFromList, positions, m_configuration.m_surfaceTagList,
|
||||
points);
|
||||
|
||||
for (size_t index = 0; index < positions.size(); index++)
|
||||
{
|
||||
points.Clear();
|
||||
surfaceDataRequests->GetSurfacePoints(positions[index], m_configuration.m_surfaceTagList, points);
|
||||
outValues[index] = GetMaxSurfaceWeight(points);
|
||||
}
|
||||
// For each position, get the max surface weight that matches our filter and that appears at that position.
|
||||
points.EnumeratePoints(
|
||||
[&outValues](
|
||||
size_t inPositionIndex, [[maybe_unused]] const AZ::Vector3& position, [[maybe_unused]] const AZ::Vector3& normal,
|
||||
const SurfaceData::SurfaceTagWeights& masks) -> bool
|
||||
{
|
||||
masks.EnumerateWeights(
|
||||
[inPositionIndex, &outValues]([[maybe_unused]] AZ::Crc32 surfaceType, float weight) -> bool
|
||||
{
|
||||
outValues[inPositionIndex] = AZ::GetMax(AZ::GetClamp(weight, 0.0f, 1.0f), outValues[inPositionIndex]);
|
||||
return true;
|
||||
});
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
if (!valuesFound)
|
||||
{
|
||||
// No surface tags, so no output values.
|
||||
AZStd::fill(outValues.begin(), outValues.end(), 0.0f);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
size_t SurfaceMaskGradientComponent::GetNumTags() const
|
||||
|
||||
@@ -205,14 +205,9 @@ namespace GradientSignal
|
||||
|
||||
float SurfaceSlopeGradientComponent::GetValue(const GradientSampleParams& sampleParams) const
|
||||
{
|
||||
SurfaceData::SurfacePointList points;
|
||||
SurfaceData::SurfaceDataSystemRequestBus::Broadcast(&SurfaceData::SurfaceDataSystemRequestBus::Events::GetSurfacePoints,
|
||||
sampleParams.m_position, m_configuration.m_surfaceTagsToSample, points);
|
||||
|
||||
const float angleMin = AZ::DegToRad(AZ::GetClamp(m_configuration.m_slopeMin, 0.0f, 90.0f));
|
||||
const float angleMax = AZ::DegToRad(AZ::GetClamp(m_configuration.m_slopeMax, 0.0f, 90.0f));
|
||||
|
||||
return GetSlopeRatio(points, angleMin, angleMax);
|
||||
float result = 0.0f;
|
||||
GetValues(AZStd::span<const AZ::Vector3>(&sampleParams.m_position, 1), AZStd::span<float>(&result, 1));
|
||||
return result;
|
||||
}
|
||||
|
||||
void SurfaceSlopeGradientComponent::GetValues(AZStd::span<const AZ::Vector3> positions, AZStd::span<float> outValues) const
|
||||
@@ -223,32 +218,49 @@ namespace GradientSignal
|
||||
return;
|
||||
}
|
||||
|
||||
bool valuesFound = false;
|
||||
|
||||
// Rather than calling GetSurfacePoints on the EBus repeatedly in a loop, we instead pass a lambda into the EBus that contains
|
||||
// the loop within it so that we can avoid the repeated EBus-calling overhead.
|
||||
SurfaceData::SurfacePointList points;
|
||||
SurfaceData::SurfaceDataSystemRequestBus::Broadcast(
|
||||
[this, positions, &outValues, &valuesFound](SurfaceData::SurfaceDataSystemRequestBus::Events* surfaceDataRequests)
|
||||
{
|
||||
// It's possible that there's nothing connected to the EBus, so keep track of the fact that we have valid results.
|
||||
valuesFound = true;
|
||||
SurfaceData::SurfacePointList points;
|
||||
&SurfaceData::SurfaceDataSystemRequestBus::Events::GetSurfacePointsFromList, positions, m_configuration.m_surfaceTagsToSample,
|
||||
points);
|
||||
|
||||
const float angleMin = AZ::DegToRad(AZ::GetClamp(m_configuration.m_slopeMin, 0.0f, 90.0f));
|
||||
const float angleMax = AZ::DegToRad(AZ::GetClamp(m_configuration.m_slopeMax, 0.0f, 90.0f));
|
||||
const float angleMin = AZ::DegToRad(AZ::GetClamp(m_configuration.m_slopeMin, 0.0f, 90.0f));
|
||||
const float angleMax = AZ::DegToRad(AZ::GetClamp(m_configuration.m_slopeMax, 0.0f, 90.0f));
|
||||
|
||||
for (size_t index = 0; index < positions.size(); index++)
|
||||
{
|
||||
points.Clear();
|
||||
surfaceDataRequests->GetSurfacePoints(positions[index], m_configuration.m_surfaceTagsToSample, points);
|
||||
outValues[index] = GetSlopeRatio(points, angleMin, angleMax);
|
||||
}
|
||||
});
|
||||
|
||||
if (!valuesFound)
|
||||
for (size_t index = 0; index < positions.size(); index++)
|
||||
{
|
||||
// No surface tags, so no output values.
|
||||
AZStd::fill(outValues.begin(), outValues.end(), 0.0f);
|
||||
if (points.IsEmpty(index))
|
||||
{
|
||||
outValues[index] = 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Assuming our surface normal vector is actually normalized, we can get the slope
|
||||
// by just grabbing the Z value. It's the same thing as normal.Dot(AZ::Vector3::CreateAxisZ()).
|
||||
auto highestSurfacePoint = points.GetHighestSurfacePoint(index);
|
||||
AZ_Assert(
|
||||
highestSurfacePoint.m_normal.GetNormalized().IsClose(highestSurfacePoint.m_normal),
|
||||
"Surface normals are expected to be normalized");
|
||||
const float slope = highestSurfacePoint.m_normal.GetZ();
|
||||
// Convert slope back to an angle so that we can lerp in "angular space", not "slope value space".
|
||||
// (We want our 0-1 range to be linear across the range of angles)
|
||||
const float slopeAngle = acosf(slope);
|
||||
|
||||
switch (m_configuration.m_rampType)
|
||||
{
|
||||
case SurfaceSlopeGradientConfig::RampType::SMOOTH_STEP:
|
||||
outValues[index] = m_configuration.m_smoothStep.GetSmoothedValue(GetRatio(angleMin, angleMax, slopeAngle));
|
||||
break;
|
||||
case SurfaceSlopeGradientConfig::RampType::LINEAR_RAMP_UP:
|
||||
// For ramp up, linearly interpolate from min to max.
|
||||
outValues[index] = GetRatio(angleMin, angleMax, slopeAngle);
|
||||
break;
|
||||
case SurfaceSlopeGradientConfig::RampType::LINEAR_RAMP_DOWN:
|
||||
default:
|
||||
// For ramp down, linearly interpolate from max to min.
|
||||
outValues[index] = GetRatio(angleMax, angleMin, slopeAngle);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -82,6 +82,7 @@ namespace SurfaceData
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// SurfaceDataProviderRequestBus
|
||||
void GetSurfacePoints(const AZ::Vector3& inPosition, SurfacePointList& surfacePointList) const override;
|
||||
void GetSurfacePointsFromList(AZStd::span<const AZ::Vector3> inPositions, SurfacePointList& surfacePointList) const override;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// SurfaceDataModifierRequestBus
|
||||
|
||||
@@ -66,6 +66,7 @@ namespace SurfaceData
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// SurfaceDataProviderRequestBus
|
||||
void GetSurfacePoints(const AZ::Vector3& inPosition, SurfacePointList& surfacePointList) const override;
|
||||
void GetSurfacePointsFromList(AZStd::span<const AZ::Vector3> inPositions, SurfacePointList& surfacePointList) const override;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// SurfaceDataModifierRequestBus
|
||||
|
||||
@@ -185,8 +185,6 @@ namespace SurfaceData
|
||||
|
||||
bool SurfaceDataColliderComponent::DoRayTrace(const AZ::Vector3& inPosition, bool queryPointOnly, AZ::Vector3& outPosition, AZ::Vector3& outNormal) const
|
||||
{
|
||||
AZStd::shared_lock<decltype(m_cacheMutex)> lock(m_cacheMutex);
|
||||
|
||||
// test AABB as first pass to claim the point
|
||||
const AZ::Vector3 testPosition = AZ::Vector3(
|
||||
inPosition.GetX(),
|
||||
@@ -229,18 +227,45 @@ namespace SurfaceData
|
||||
|
||||
void SurfaceDataColliderComponent::GetSurfacePoints(const AZ::Vector3& inPosition, SurfacePointList& surfacePointList) const
|
||||
{
|
||||
AZ::Vector3 hitPosition;
|
||||
AZ::Vector3 hitNormal;
|
||||
|
||||
// We want a full raycast, so don't just query the start point.
|
||||
constexpr bool queryPointOnly = false;
|
||||
|
||||
if (DoRayTrace(inPosition, queryPointOnly, hitPosition, hitNormal))
|
||||
{
|
||||
surfacePointList.AddSurfacePoint(GetEntityId(), inPosition, hitPosition, hitNormal, m_newPointWeights);
|
||||
}
|
||||
GetSurfacePointsFromList(AZStd::span<const AZ::Vector3>(&inPosition, 1), surfacePointList);
|
||||
}
|
||||
|
||||
void SurfaceDataColliderComponent::GetSurfacePointsFromList(
|
||||
AZStd::span<const AZ::Vector3> inPositions, SurfacePointList& surfacePointList) const
|
||||
{
|
||||
AzPhysics::SimulatedBodyComponentRequestsBus::Event(
|
||||
GetEntityId(),
|
||||
[this, inPositions, &surfacePointList](AzPhysics::SimulatedBodyComponentRequestsBus::Events* simBody)
|
||||
{
|
||||
AZStd::shared_lock<decltype(m_cacheMutex)> lock(m_cacheMutex);
|
||||
|
||||
AzPhysics::RayCastRequest request;
|
||||
request.m_direction = -AZ::Vector3::CreateAxisZ();
|
||||
|
||||
for (auto& inPosition : inPositions)
|
||||
{
|
||||
// test AABB as first pass to claim the point
|
||||
if (SurfaceData::AabbContains2D(m_colliderBounds, inPosition))
|
||||
{
|
||||
// We're casting the ray to look for a collision, so start at the top of the collider and cast downwards
|
||||
// the full height of the collider.
|
||||
request.m_start = AZ::Vector3(inPosition.GetX(), inPosition.GetY(), m_colliderBounds.GetMax().GetZ());
|
||||
request.m_distance = m_colliderBounds.GetExtents().GetZ();
|
||||
|
||||
AzPhysics::SceneQueryHit result = simBody->RayCast(request);
|
||||
|
||||
if (result)
|
||||
{
|
||||
surfacePointList.AddSurfacePoint(
|
||||
GetEntityId(), inPosition, result.m_position, result.m_normal, m_newPointWeights);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
void SurfaceDataColliderComponent::ModifySurfacePoints(SurfacePointList& surfacePointList) const
|
||||
{
|
||||
AZStd::shared_lock<decltype(m_cacheMutex)> lock(m_cacheMutex);
|
||||
|
||||
@@ -143,24 +143,48 @@ namespace SurfaceData
|
||||
}
|
||||
|
||||
void SurfaceDataShapeComponent::GetSurfacePoints(const AZ::Vector3& inPosition, SurfacePointList& surfacePointList) const
|
||||
{
|
||||
GetSurfacePointsFromList(AZStd::span<const AZ::Vector3>(&inPosition, 1), surfacePointList);
|
||||
}
|
||||
|
||||
void SurfaceDataShapeComponent::GetSurfacePointsFromList(
|
||||
AZStd::span<const AZ::Vector3> inPositions, SurfacePointList& surfacePointList) const
|
||||
{
|
||||
AZStd::shared_lock<decltype(m_cacheMutex)> lock(m_cacheMutex);
|
||||
|
||||
if (m_shapeBoundsIsValid && SurfaceData::AabbContains2D(m_shapeBounds, inPosition))
|
||||
if (!m_shapeBoundsIsValid)
|
||||
{
|
||||
const AZ::Vector3 rayOrigin = AZ::Vector3(inPosition.GetX(), inPosition.GetY(), m_shapeBounds.GetMax().GetZ());
|
||||
const AZ::Vector3 rayDirection = -AZ::Vector3::CreateAxisZ();
|
||||
float intersectionDistance = 0.0f;
|
||||
bool hitShape = false;
|
||||
LmbrCentral::ShapeComponentRequestsBus::EventResult(hitShape, GetEntityId(), &LmbrCentral::ShapeComponentRequestsBus::Events::IntersectRay, rayOrigin, rayDirection, intersectionDistance);
|
||||
if (hitShape)
|
||||
{
|
||||
AZ::Vector3 position = rayOrigin + intersectionDistance * rayDirection;
|
||||
surfacePointList.AddSurfacePoint(GetEntityId(), inPosition, position, AZ::Vector3::CreateAxisZ(), m_newPointWeights);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
LmbrCentral::ShapeComponentRequestsBus::Event(
|
||||
GetEntityId(),
|
||||
[this, inPositions, &surfacePointList](LmbrCentral::ShapeComponentRequestsBus::Events* shape)
|
||||
{
|
||||
const AZ::Vector3 rayDirection = -AZ::Vector3::CreateAxisZ();
|
||||
|
||||
// Shapes don't currently have a way to query normals at a point intersection, so we'll just return a Z-up normal
|
||||
// until they get support for it.
|
||||
const AZ::Vector3 surfacePointNormal = AZ::Vector3::CreateAxisZ();
|
||||
|
||||
for (auto& inPosition : inPositions)
|
||||
{
|
||||
if (SurfaceData::AabbContains2D(m_shapeBounds, inPosition))
|
||||
{
|
||||
const AZ::Vector3 rayOrigin = AZ::Vector3(inPosition.GetX(), inPosition.GetY(), m_shapeBounds.GetMax().GetZ());
|
||||
float intersectionDistance = 0.0f;
|
||||
bool hitShape = shape->IntersectRay(rayOrigin, rayDirection, intersectionDistance);
|
||||
if (hitShape)
|
||||
{
|
||||
AZ::Vector3 position = rayOrigin + intersectionDistance * rayDirection;
|
||||
surfacePointList.AddSurfacePoint(GetEntityId(), inPosition, position, surfacePointNormal, m_newPointWeights);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
void SurfaceDataShapeComponent::ModifySurfacePoints(SurfacePointList& surfacePointList) const
|
||||
{
|
||||
AZStd::shared_lock<decltype(m_cacheMutex)> lock(m_cacheMutex);
|
||||
|
||||
@@ -145,29 +145,42 @@ namespace Terrain
|
||||
|
||||
void TerrainSurfaceDataSystemComponent::GetSurfacePoints(
|
||||
const AZ::Vector3& inPosition, SurfaceData::SurfacePointList& surfacePointList) const
|
||||
{
|
||||
GetSurfacePointsFromList(AZStd::span<const AZ::Vector3>(&inPosition, 1), surfacePointList);
|
||||
}
|
||||
|
||||
void TerrainSurfaceDataSystemComponent::GetSurfacePointsFromList(
|
||||
AZStd::span<const AZ::Vector3> inPositions, SurfaceData::SurfacePointList& surfacePointList) const
|
||||
{
|
||||
if (!m_terrainBoundsIsValid)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bool isTerrainValidAtPoint = false;
|
||||
AzFramework::SurfaceData::SurfacePoint terrainSurfacePoint;
|
||||
AzFramework::Terrain::TerrainDataRequestBus::Broadcast(&AzFramework::Terrain::TerrainDataRequestBus::Events::GetSurfacePoint,
|
||||
inPosition, terrainSurfacePoint, AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR,
|
||||
&isTerrainValidAtPoint);
|
||||
size_t inPositionIndex = 0;
|
||||
|
||||
const bool isHole = !isTerrainValidAtPoint;
|
||||
AzFramework::Terrain::TerrainDataRequestBus::Broadcast(
|
||||
&AzFramework::Terrain::TerrainDataRequestBus::Events::ProcessSurfacePointsFromList, inPositions,
|
||||
[this, inPositions, &inPositionIndex, &surfacePointList]
|
||||
(const AzFramework::SurfaceData::SurfacePoint& surfacePoint, bool terrainExists)
|
||||
{
|
||||
AZ_Assert(inPositionIndex < inPositions.size(), "Too many points returned from ProcessSurfacePointsFromList");
|
||||
|
||||
SurfaceData::SurfaceTagWeights weights(terrainSurfacePoint.m_surfaceTags);
|
||||
SurfaceData::SurfaceTagWeights weights(surfacePoint.m_surfaceTags);
|
||||
|
||||
// Always add a "terrain" or "terrainHole" tag.
|
||||
const AZ::Crc32 terrainTag = isHole ? Constants::s_terrainHoleTagCrc : Constants::s_terrainTagCrc;
|
||||
weights.AddSurfaceTagWeight(terrainTag, 1.0f);
|
||||
// Always add a "terrain" or "terrainHole" tag.
|
||||
const AZ::Crc32 terrainTag = terrainExists ? Constants::s_terrainTagCrc : Constants::s_terrainHoleTagCrc;
|
||||
weights.AddSurfaceTagWeight(terrainTag, 1.0f);
|
||||
|
||||
surfacePointList.AddSurfacePoint(GetEntityId(), inPosition, terrainSurfacePoint.m_position, terrainSurfacePoint.m_normal, weights);
|
||||
surfacePointList.AddSurfacePoint(
|
||||
GetEntityId(), inPositions[inPositionIndex], surfacePoint.m_position, surfacePoint.m_normal, weights);
|
||||
|
||||
inPositionIndex++;
|
||||
},
|
||||
AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR);
|
||||
}
|
||||
|
||||
|
||||
AZ::Aabb TerrainSurfaceDataSystemComponent::GetSurfaceAabb() const
|
||||
{
|
||||
auto terrain = AzFramework::Terrain::TerrainDataRequestBus::FindFirstHandler();
|
||||
|
||||
@@ -59,6 +59,8 @@ namespace Terrain
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// SurfaceDataProviderRequestBus
|
||||
void GetSurfacePoints(const AZ::Vector3& inPosition, SurfaceData::SurfacePointList& surfacePointList) const override;
|
||||
void GetSurfacePointsFromList(
|
||||
AZStd::span<const AZ::Vector3> inPositions, SurfaceData::SurfacePointList& surfacePointList) const override;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// AzFramework::Terrain::TerrainDataNotificationBus
|
||||
|
||||
@@ -192,7 +192,7 @@ bool TerrainSystem::InWorldBounds(float x, float y) const
|
||||
}
|
||||
|
||||
// Generate positions to be queried based on the sampler type.
|
||||
void TerrainSystem::GenerateQueryPositions(const AZStd::span<AZ::Vector3>& inPositions,
|
||||
void TerrainSystem::GenerateQueryPositions(const AZStd::span<const AZ::Vector3>& inPositions,
|
||||
AZStd::vector<AZ::Vector3>& outPositions,
|
||||
Sampler sampler) const
|
||||
{
|
||||
@@ -253,7 +253,7 @@ AZStd::vector<AZ::Vector3> TerrainSystem::GenerateInputPositionsFromRegion(
|
||||
}
|
||||
|
||||
void TerrainSystem::MakeBulkQueries(
|
||||
const AZStd::span<AZ::Vector3> inPositions,
|
||||
const AZStd::span<const AZ::Vector3> inPositions,
|
||||
AZStd::span<AZ::Vector3> outPositions,
|
||||
AZStd::span<bool> outTerrainExists,
|
||||
AZStd::span<AzFramework::SurfaceData::SurfaceTagWeightList> outSurfaceWeights,
|
||||
@@ -296,7 +296,7 @@ void TerrainSystem::MakeBulkQueries(
|
||||
if (prevAreaId != AZ::EntityId())
|
||||
{
|
||||
size_t spanLength = (windowEnd - windowStart) + 1;
|
||||
queryCallback(AZStd::span<AZ::Vector3>(inPositions.begin() + windowStart, spanLength),
|
||||
queryCallback(AZStd::span<const AZ::Vector3>(inPositions.begin() + windowStart, spanLength),
|
||||
AZStd::span<AZ::Vector3>(outPositions.begin() + windowStart, spanLength),
|
||||
AZStd::span<bool>(outTerrainExists.begin() + windowStart, spanLength),
|
||||
AZStd::span<AzFramework::SurfaceData::SurfaceTagWeightList>(outSurfaceWeights.begin() + windowStart, spanLength),
|
||||
@@ -311,7 +311,7 @@ void TerrainSystem::MakeBulkQueries(
|
||||
}
|
||||
}
|
||||
|
||||
void TerrainSystem::GetHeightsSynchronous(const AZStd::span<AZ::Vector3>& inPositions, Sampler sampler,
|
||||
void TerrainSystem::GetHeightsSynchronous(const AZStd::span<const AZ::Vector3>& inPositions, Sampler sampler,
|
||||
AZStd::span<float> heights, AZStd::span<bool> terrainExists) const
|
||||
{
|
||||
AZStd::shared_lock<AZStd::shared_mutex> lock(m_areaMutex);
|
||||
@@ -328,7 +328,7 @@ void TerrainSystem::GetHeightsSynchronous(const AZStd::span<AZ::Vector3>& inPosi
|
||||
|
||||
GenerateQueryPositions(inPositions, outPositions, sampler);
|
||||
|
||||
auto callback = []([[maybe_unused]] const AZStd::span<AZ::Vector3> inPositions,
|
||||
auto callback = []([[maybe_unused]] const AZStd::span<const AZ::Vector3> inPositions,
|
||||
AZStd::span<AZ::Vector3> outPositions,
|
||||
AZStd::span<bool> outTerrainExists,
|
||||
[[maybe_unused]] AZStd::span<AzFramework::SurfaceData::SurfaceTagWeightList> outSurfaceWeights,
|
||||
@@ -516,7 +516,7 @@ bool TerrainSystem::GetIsHoleFromFloats(float x, float y, Sampler sampler) const
|
||||
return !terrainExists;
|
||||
}
|
||||
|
||||
void TerrainSystem::GetNormalsSynchronous(const AZStd::span<AZ::Vector3>& inPositions, Sampler sampler,
|
||||
void TerrainSystem::GetNormalsSynchronous(const AZStd::span<const AZ::Vector3>& inPositions, Sampler sampler,
|
||||
AZStd::span<AZ::Vector3> normals, AZStd::span<bool> terrainExists) const
|
||||
{
|
||||
AZStd::vector<AZ::Vector3> directionVectors;
|
||||
@@ -685,7 +685,7 @@ AzFramework::RenderGeometry::RayResult TerrainSystem::GetClosestIntersection(
|
||||
}
|
||||
|
||||
AZStd::shared_ptr<AzFramework::Terrain::TerrainDataRequests::TerrainJobContext> TerrainSystem::ProcessHeightsFromListAsync(
|
||||
const AZStd::span<AZ::Vector3>& inPositions,
|
||||
const AZStd::span<const AZ::Vector3>& inPositions,
|
||||
AzFramework::Terrain::SurfacePointListFillCallback perPositionCallback,
|
||||
Sampler sampleFilter,
|
||||
AZStd::shared_ptr<ProcessAsyncParams> params) const
|
||||
@@ -695,7 +695,7 @@ AZStd::shared_ptr<AzFramework::Terrain::TerrainDataRequests::TerrainJobContext>
|
||||
}
|
||||
|
||||
AZStd::shared_ptr<AzFramework::Terrain::TerrainDataRequests::TerrainJobContext> TerrainSystem::ProcessNormalsFromListAsync(
|
||||
const AZStd::span<AZ::Vector3>& inPositions,
|
||||
const AZStd::span<const AZ::Vector3>& inPositions,
|
||||
AzFramework::Terrain::SurfacePointListFillCallback perPositionCallback,
|
||||
Sampler sampleFilter,
|
||||
AZStd::shared_ptr<ProcessAsyncParams> params) const
|
||||
@@ -705,7 +705,7 @@ AZStd::shared_ptr<AzFramework::Terrain::TerrainDataRequests::TerrainJobContext>
|
||||
}
|
||||
|
||||
AZStd::shared_ptr<AzFramework::Terrain::TerrainDataRequests::TerrainJobContext> TerrainSystem::ProcessSurfaceWeightsFromListAsync(
|
||||
const AZStd::span<AZ::Vector3>& inPositions,
|
||||
const AZStd::span<const AZ::Vector3>& inPositions,
|
||||
AzFramework::Terrain::SurfacePointListFillCallback perPositionCallback,
|
||||
Sampler sampleFilter,
|
||||
AZStd::shared_ptr<ProcessAsyncParams> params) const
|
||||
@@ -715,7 +715,7 @@ AZStd::shared_ptr<AzFramework::Terrain::TerrainDataRequests::TerrainJobContext>
|
||||
}
|
||||
|
||||
AZStd::shared_ptr<AzFramework::Terrain::TerrainDataRequests::TerrainJobContext> TerrainSystem::ProcessSurfacePointsFromListAsync(
|
||||
const AZStd::span<AZ::Vector3>& inPositions,
|
||||
const AZStd::span<const AZ::Vector3>& inPositions,
|
||||
AzFramework::Terrain::SurfacePointListFillCallback perPositionCallback,
|
||||
Sampler sampleFilter,
|
||||
AZStd::shared_ptr<ProcessAsyncParams> params) const
|
||||
@@ -725,7 +725,7 @@ AZStd::shared_ptr<AzFramework::Terrain::TerrainDataRequests::TerrainJobContext>
|
||||
}
|
||||
|
||||
AZStd::shared_ptr<AzFramework::Terrain::TerrainDataRequests::TerrainJobContext> TerrainSystem::ProcessHeightsFromListOfVector2Async(
|
||||
const AZStd::span<AZ::Vector2>& inPositions,
|
||||
const AZStd::span<const AZ::Vector2>& inPositions,
|
||||
AzFramework::Terrain::SurfacePointListFillCallback perPositionCallback,
|
||||
Sampler sampleFilter,
|
||||
AZStd::shared_ptr<ProcessAsyncParams> params) const
|
||||
@@ -735,7 +735,7 @@ AZStd::shared_ptr<AzFramework::Terrain::TerrainDataRequests::TerrainJobContext>
|
||||
}
|
||||
|
||||
AZStd::shared_ptr<AzFramework::Terrain::TerrainDataRequests::TerrainJobContext> TerrainSystem::ProcessNormalsFromListOfVector2Async(
|
||||
const AZStd::span<AZ::Vector2>& inPositions,
|
||||
const AZStd::span<const AZ::Vector2>& inPositions,
|
||||
AzFramework::Terrain::SurfacePointListFillCallback perPositionCallback,
|
||||
Sampler sampleFilter,
|
||||
AZStd::shared_ptr<ProcessAsyncParams> params) const
|
||||
@@ -745,7 +745,7 @@ AZStd::shared_ptr<AzFramework::Terrain::TerrainDataRequests::TerrainJobContext>
|
||||
}
|
||||
|
||||
AZStd::shared_ptr<AzFramework::Terrain::TerrainDataRequests::TerrainJobContext> TerrainSystem::ProcessSurfaceWeightsFromListOfVector2Async(
|
||||
const AZStd::span<AZ::Vector2>& inPositions,
|
||||
const AZStd::span<const AZ::Vector2>& inPositions,
|
||||
AzFramework::Terrain::SurfacePointListFillCallback perPositionCallback,
|
||||
Sampler sampleFilter,
|
||||
AZStd::shared_ptr<ProcessAsyncParams> params) const
|
||||
@@ -755,7 +755,7 @@ AZStd::shared_ptr<AzFramework::Terrain::TerrainDataRequests::TerrainJobContext>
|
||||
}
|
||||
|
||||
AZStd::shared_ptr<AzFramework::Terrain::TerrainDataRequests::TerrainJobContext> TerrainSystem::ProcessSurfacePointsFromListOfVector2Async(
|
||||
const AZStd::span<AZ::Vector2>& inPositions,
|
||||
const AZStd::span<const AZ::Vector2>& inPositions,
|
||||
AzFramework::Terrain::SurfacePointListFillCallback perPositionCallback,
|
||||
Sampler sampleFilter,
|
||||
AZStd::shared_ptr<ProcessAsyncParams> params) const
|
||||
@@ -830,7 +830,7 @@ AZ::EntityId TerrainSystem::FindBestAreaEntityAtPosition(float x, float y, AZ::A
|
||||
}
|
||||
|
||||
void TerrainSystem::GetOrderedSurfaceWeightsFromList(
|
||||
const AZStd::span<AZ::Vector3>& inPositions,
|
||||
const AZStd::span<const AZ::Vector3>& inPositions,
|
||||
[[maybe_unused]] Sampler sampler,
|
||||
AZStd::span<AzFramework::SurfaceData::SurfaceTagWeightList> outSurfaceWeightsList,
|
||||
AZStd::span<bool> terrainExists) const
|
||||
@@ -841,7 +841,7 @@ void TerrainSystem::GetOrderedSurfaceWeightsFromList(
|
||||
GetHeightsSynchronous(inPositions, AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT, heights, terrainExists);
|
||||
}
|
||||
|
||||
auto callback = [](const AZStd::span<AZ::Vector3> inPositions,
|
||||
auto callback = [](const AZStd::span<const AZ::Vector3> inPositions,
|
||||
[[maybe_unused]] AZStd::span<AZ::Vector3> outPositions,
|
||||
[[maybe_unused]] AZStd::span<bool> outTerrainExists,
|
||||
AZStd::span<AzFramework::SurfaceData::SurfaceTagWeightList> outSurfaceWeights,
|
||||
@@ -929,7 +929,7 @@ const char* TerrainSystem::GetMaxSurfaceName(
|
||||
}
|
||||
|
||||
void TerrainSystem::ProcessHeightsFromList(
|
||||
const AZStd::span<AZ::Vector3>& inPositions,
|
||||
const AZStd::span<const AZ::Vector3>& inPositions,
|
||||
AzFramework::Terrain::SurfacePointListFillCallback perPositionCallback,
|
||||
Sampler sampleFilter) const
|
||||
{
|
||||
@@ -953,7 +953,7 @@ void TerrainSystem::ProcessHeightsFromList(
|
||||
}
|
||||
|
||||
void TerrainSystem::ProcessNormalsFromList(
|
||||
const AZStd::span<AZ::Vector3>& inPositions,
|
||||
const AZStd::span<const AZ::Vector3>& inPositions,
|
||||
AzFramework::Terrain::SurfacePointListFillCallback perPositionCallback,
|
||||
Sampler sampleFilter) const
|
||||
{
|
||||
@@ -977,7 +977,7 @@ void TerrainSystem::ProcessNormalsFromList(
|
||||
}
|
||||
|
||||
void TerrainSystem::ProcessSurfaceWeightsFromList(
|
||||
const AZStd::span<AZ::Vector3>& inPositions,
|
||||
const AZStd::span<const AZ::Vector3>& inPositions,
|
||||
AzFramework::Terrain::SurfacePointListFillCallback perPositionCallback,
|
||||
Sampler sampleFilter) const
|
||||
{
|
||||
@@ -1001,7 +1001,7 @@ void TerrainSystem::ProcessSurfaceWeightsFromList(
|
||||
}
|
||||
|
||||
void TerrainSystem::ProcessSurfacePointsFromList(
|
||||
const AZStd::span<AZ::Vector3>& inPositions,
|
||||
const AZStd::span<const AZ::Vector3>& inPositions,
|
||||
AzFramework::Terrain::SurfacePointListFillCallback perPositionCallback,
|
||||
Sampler sampleFilter) const
|
||||
{
|
||||
@@ -1034,7 +1034,7 @@ void TerrainSystem::ProcessSurfacePointsFromList(
|
||||
}
|
||||
|
||||
void TerrainSystem::ProcessHeightsFromListOfVector2(
|
||||
const AZStd::span<AZ::Vector2>& inPositions,
|
||||
const AZStd::span<const AZ::Vector2>& inPositions,
|
||||
AzFramework::Terrain::SurfacePointListFillCallback perPositionCallback,
|
||||
Sampler sampleFilter) const
|
||||
{
|
||||
@@ -1054,7 +1054,7 @@ void TerrainSystem::ProcessHeightsFromListOfVector2(
|
||||
}
|
||||
|
||||
void TerrainSystem::ProcessNormalsFromListOfVector2(
|
||||
const AZStd::span<AZ::Vector2>& inPositions,
|
||||
const AZStd::span<const AZ::Vector2>& inPositions,
|
||||
AzFramework::Terrain::SurfacePointListFillCallback perPositionCallback,
|
||||
Sampler sampleFilter) const
|
||||
{
|
||||
@@ -1074,7 +1074,7 @@ void TerrainSystem::ProcessNormalsFromListOfVector2(
|
||||
}
|
||||
|
||||
void TerrainSystem::ProcessSurfaceWeightsFromListOfVector2(
|
||||
const AZStd::span<AZ::Vector2>& inPositions,
|
||||
const AZStd::span<const AZ::Vector2>& inPositions,
|
||||
AzFramework::Terrain::SurfacePointListFillCallback perPositionCallback,
|
||||
Sampler sampleFilter) const
|
||||
{
|
||||
@@ -1094,7 +1094,7 @@ void TerrainSystem::ProcessSurfaceWeightsFromListOfVector2(
|
||||
}
|
||||
|
||||
void TerrainSystem::ProcessSurfacePointsFromListOfVector2(
|
||||
const AZStd::span<AZ::Vector2>& inPositions,
|
||||
const AZStd::span<const AZ::Vector2>& inPositions,
|
||||
AzFramework::Terrain::SurfacePointListFillCallback perPositionCallback,
|
||||
Sampler sampleFilter) const
|
||||
{
|
||||
|
||||
@@ -140,28 +140,28 @@ namespace Terrain
|
||||
|
||||
//! 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,
|
||||
virtual void ProcessHeightsFromList(const AZStd::span<const AZ::Vector3>& inPositions,
|
||||
AzFramework::Terrain::SurfacePointListFillCallback perPositionCallback,
|
||||
Sampler sampleFilter = Sampler::DEFAULT) const override;
|
||||
virtual void ProcessNormalsFromList(const AZStd::span<AZ::Vector3>& inPositions,
|
||||
virtual void ProcessNormalsFromList(const AZStd::span<const AZ::Vector3>& inPositions,
|
||||
AzFramework::Terrain::SurfacePointListFillCallback perPositionCallback,
|
||||
Sampler sampleFilter = Sampler::DEFAULT) const override;
|
||||
virtual void ProcessSurfaceWeightsFromList(const AZStd::span<AZ::Vector3>& inPositions,
|
||||
virtual void ProcessSurfaceWeightsFromList(const AZStd::span<const AZ::Vector3>& inPositions,
|
||||
AzFramework::Terrain::SurfacePointListFillCallback perPositionCallback,
|
||||
Sampler sampleFilter = Sampler::DEFAULT) const override;
|
||||
virtual void ProcessSurfacePointsFromList(const AZStd::span<AZ::Vector3>& inPositions,
|
||||
virtual void ProcessSurfacePointsFromList(const AZStd::span<const AZ::Vector3>& inPositions,
|
||||
AzFramework::Terrain::SurfacePointListFillCallback perPositionCallback,
|
||||
Sampler sampleFilter = Sampler::DEFAULT) const override;
|
||||
virtual void ProcessHeightsFromListOfVector2(const AZStd::span<AZ::Vector2>& inPositions,
|
||||
virtual void ProcessHeightsFromListOfVector2(const AZStd::span<const AZ::Vector2>& inPositions,
|
||||
AzFramework::Terrain::SurfacePointListFillCallback perPositionCallback,
|
||||
Sampler sampleFilter = Sampler::DEFAULT) const override;
|
||||
virtual void ProcessNormalsFromListOfVector2(const AZStd::span<AZ::Vector2>& inPositions,
|
||||
virtual void ProcessNormalsFromListOfVector2(const AZStd::span<const AZ::Vector2>& inPositions,
|
||||
AzFramework::Terrain::SurfacePointListFillCallback perPositionCallback,
|
||||
Sampler sampleFilter = Sampler::DEFAULT) const override;
|
||||
virtual void ProcessSurfaceWeightsFromListOfVector2(const AZStd::span<AZ::Vector2>& inPositions,
|
||||
virtual void ProcessSurfaceWeightsFromListOfVector2(const AZStd::span<const AZ::Vector2>& inPositions,
|
||||
AzFramework::Terrain::SurfacePointListFillCallback perPositionCallback,
|
||||
Sampler sampleFilter = Sampler::DEFAULT) const override;
|
||||
virtual void ProcessSurfacePointsFromListOfVector2(const AZStd::span<AZ::Vector2>& inPositions,
|
||||
virtual void ProcessSurfacePointsFromListOfVector2(const AZStd::span<const AZ::Vector2>& inPositions,
|
||||
AzFramework::Terrain::SurfacePointListFillCallback perPositionCallback,
|
||||
Sampler sampleFilter = Sampler::DEFAULT) const override;
|
||||
|
||||
@@ -194,42 +194,42 @@ namespace Terrain
|
||||
const AzFramework::RenderGeometry::RayRequest& ray) const override;
|
||||
|
||||
AZStd::shared_ptr<TerrainJobContext> ProcessHeightsFromListAsync(
|
||||
const AZStd::span<AZ::Vector3>& inPositions,
|
||||
const AZStd::span<const AZ::Vector3>& inPositions,
|
||||
AzFramework::Terrain::SurfacePointListFillCallback perPositionCallback,
|
||||
Sampler sampleFilter = Sampler::DEFAULT,
|
||||
AZStd::shared_ptr<ProcessAsyncParams> params = nullptr) const override;
|
||||
AZStd::shared_ptr<TerrainJobContext> ProcessNormalsFromListAsync(
|
||||
const AZStd::span<AZ::Vector3>& inPositions,
|
||||
const AZStd::span<const AZ::Vector3>& inPositions,
|
||||
AzFramework::Terrain::SurfacePointListFillCallback perPositionCallback,
|
||||
Sampler sampleFilter = Sampler::DEFAULT,
|
||||
AZStd::shared_ptr<ProcessAsyncParams> params = nullptr) const override;
|
||||
AZStd::shared_ptr<TerrainJobContext> ProcessSurfaceWeightsFromListAsync(
|
||||
const AZStd::span<AZ::Vector3>& inPositions,
|
||||
const AZStd::span<const AZ::Vector3>& inPositions,
|
||||
AzFramework::Terrain::SurfacePointListFillCallback perPositionCallback,
|
||||
Sampler sampleFilter = Sampler::DEFAULT,
|
||||
AZStd::shared_ptr<ProcessAsyncParams> params = nullptr) const override;
|
||||
AZStd::shared_ptr<TerrainJobContext> ProcessSurfacePointsFromListAsync(
|
||||
const AZStd::span<AZ::Vector3>& inPositions,
|
||||
const AZStd::span<const AZ::Vector3>& inPositions,
|
||||
AzFramework::Terrain::SurfacePointListFillCallback perPositionCallback,
|
||||
Sampler sampleFilter = Sampler::DEFAULT,
|
||||
AZStd::shared_ptr<ProcessAsyncParams> params = nullptr) const override;
|
||||
AZStd::shared_ptr<TerrainJobContext> ProcessHeightsFromListOfVector2Async(
|
||||
const AZStd::span<AZ::Vector2>& inPositions,
|
||||
const AZStd::span<const AZ::Vector2>& inPositions,
|
||||
AzFramework::Terrain::SurfacePointListFillCallback perPositionCallback,
|
||||
Sampler sampleFilter = Sampler::DEFAULT,
|
||||
AZStd::shared_ptr<ProcessAsyncParams> params = nullptr) const override;
|
||||
AZStd::shared_ptr<TerrainJobContext> ProcessNormalsFromListOfVector2Async(
|
||||
const AZStd::span<AZ::Vector2>& inPositions,
|
||||
const AZStd::span<const AZ::Vector2>& inPositions,
|
||||
AzFramework::Terrain::SurfacePointListFillCallback perPositionCallback,
|
||||
Sampler sampleFilter = Sampler::DEFAULT,
|
||||
AZStd::shared_ptr<ProcessAsyncParams> params = nullptr) const override;
|
||||
AZStd::shared_ptr<TerrainJobContext> ProcessSurfaceWeightsFromListOfVector2Async(
|
||||
const AZStd::span<AZ::Vector2>& inPositions,
|
||||
const AZStd::span<const AZ::Vector2>& inPositions,
|
||||
AzFramework::Terrain::SurfacePointListFillCallback perPositionCallback,
|
||||
Sampler sampleFilter = Sampler::DEFAULT,
|
||||
AZStd::shared_ptr<ProcessAsyncParams> params = nullptr) const override;
|
||||
AZStd::shared_ptr<TerrainJobContext> ProcessSurfacePointsFromListOfVector2Async(
|
||||
const AZStd::span<AZ::Vector2>& inPositions,
|
||||
const AZStd::span<const AZ::Vector2>& inPositions,
|
||||
AzFramework::Terrain::SurfacePointListFillCallback perPositionCallback,
|
||||
Sampler sampleFilter = Sampler::DEFAULT,
|
||||
AZStd::shared_ptr<ProcessAsyncParams> params = nullptr) const override;
|
||||
@@ -262,7 +262,7 @@ namespace Terrain
|
||||
template<typename SynchronousFunctionType, typename VectorType>
|
||||
AZStd::shared_ptr<TerrainJobContext> ProcessFromListAsync(
|
||||
SynchronousFunctionType synchronousFunction,
|
||||
const AZStd::span<VectorType>& inPositions,
|
||||
const AZStd::span<const VectorType>& inPositions,
|
||||
AzFramework::Terrain::SurfacePointListFillCallback perPositionCallback,
|
||||
Sampler sampleFilter = Sampler::DEFAULT,
|
||||
AZStd::shared_ptr<ProcessAsyncParams> params = nullptr) const;
|
||||
@@ -291,31 +291,31 @@ namespace Terrain
|
||||
AZ::Vector3 GetNormalSynchronous(float x, float y, Sampler sampler, bool* terrainExistsPtr) const;
|
||||
|
||||
typedef AZStd::function<void(
|
||||
const AZStd::span<AZ::Vector3> inPositions,
|
||||
const AZStd::span<const AZ::Vector3> inPositions,
|
||||
AZStd::span<AZ::Vector3> outPositions,
|
||||
AZStd::span<bool> outTerrainExists,
|
||||
AZStd::span<AzFramework::SurfaceData::SurfaceTagWeightList> outSurfaceWeights,
|
||||
AZ::EntityId areaId)> BulkQueriesCallback;
|
||||
|
||||
void GetHeightsSynchronous(
|
||||
const AZStd::span<AZ::Vector3>& inPositions,
|
||||
const AZStd::span<const AZ::Vector3>& inPositions,
|
||||
Sampler sampler, AZStd::span<float> heights,
|
||||
AZStd::span<bool> terrainExists) const;
|
||||
void GetNormalsSynchronous(
|
||||
const AZStd::span<AZ::Vector3>& inPositions,
|
||||
const AZStd::span<const AZ::Vector3>& inPositions,
|
||||
Sampler sampler, AZStd::span<AZ::Vector3> normals,
|
||||
AZStd::span<bool> terrainExists) const;
|
||||
void GetOrderedSurfaceWeightsFromList(
|
||||
const AZStd::span<AZ::Vector3>& inPositions, Sampler sampler,
|
||||
const AZStd::span<const AZ::Vector3>& inPositions, Sampler sampler,
|
||||
AZStd::span<AzFramework::SurfaceData::SurfaceTagWeightList> outSurfaceWeightsList,
|
||||
AZStd::span<bool> terrainExists) const;
|
||||
void MakeBulkQueries(
|
||||
const AZStd::span<AZ::Vector3> inPositions,
|
||||
const AZStd::span<const AZ::Vector3> inPositions,
|
||||
AZStd::span<AZ::Vector3> outPositions,
|
||||
AZStd::span<bool> outTerrainExists,
|
||||
AZStd::span<AzFramework::SurfaceData::SurfaceTagWeightList> outSurfaceWieghts,
|
||||
BulkQueriesCallback queryCallback) const;
|
||||
void GenerateQueryPositions(const AZStd::span<AZ::Vector3>& inPositions,
|
||||
void GenerateQueryPositions(const AZStd::span<const AZ::Vector3>& inPositions,
|
||||
AZStd::vector<AZ::Vector3>& outPositions,
|
||||
Sampler sampler) const;
|
||||
AZStd::vector<AZ::Vector3> GenerateInputPositionsFromRegion(
|
||||
@@ -361,7 +361,7 @@ namespace Terrain
|
||||
template<typename SynchronousFunctionType, typename VectorType>
|
||||
inline AZStd::shared_ptr<AzFramework::Terrain::TerrainDataRequests::TerrainJobContext> TerrainSystem::ProcessFromListAsync(
|
||||
SynchronousFunctionType synchronousFunction,
|
||||
const AZStd::span<VectorType>& inPositions,
|
||||
const AZStd::span<const VectorType>& inPositions,
|
||||
AzFramework::Terrain::SurfacePointListFillCallback perPositionCallback,
|
||||
Sampler sampleFilter,
|
||||
AZStd::shared_ptr<ProcessAsyncParams> params) const
|
||||
@@ -397,7 +397,7 @@ namespace Terrain
|
||||
const size_t subSpanCount = (i < numJobs - 1) ? numPositionsPerJob : AZStd::dynamic_extent;
|
||||
|
||||
// Define the job function using the sub span of positions to process.
|
||||
const AZStd::span<VectorType>& positionsToProcess = inPositions.subspan(subSpanOffset, subSpanCount);
|
||||
const AZStd::span<const VectorType>& positionsToProcess = inPositions.subspan(subSpanOffset, subSpanCount);
|
||||
auto jobFunction = [this, synchronousFunction, positionsToProcess, perPositionCallback, sampleFilter, jobContext, params]()
|
||||
{
|
||||
// Process the sub span of positions, unless the associated job context has been cancelled.
|
||||
|
||||
Reference in New Issue
Block a user