First batch of GetValues() overrides (#6852)

* Benchmarks and tests for Image and Constant GetValues

Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com>

* Verify GetValues for Perlin and Random Gradients

Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com>

* Standardized the assert format for GetValues().

Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com>

* More GetValues unit tests and test cleanup

Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com>

* Fixed typos

Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com>

* GetValues() unit tests for surface gradients.

Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com>

* Benchmarks for ShapeAreaFalloff Gradient

Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com>

* Added benchmarks for all remaining gradients and cleaned up the helper methods.

Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com>

* Renamed class for better report formatting.

Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com>

* Added missing Mocks dependencies for the Editor tests.

Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com>

* First batch of specific GetValues() overrides.
Each one is measurably faster than the generic version.  Also, in ShapeAreaFalloffGradient, I optimized and simplified the logic a bit, so GetValue() is marginally faster too.

Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com>
This commit is contained in:
Mike Balfour
2022-01-13 14:50:54 -06:00
committed by GitHub
parent 62e7483b0e
commit 79431f5e5f
10 changed files with 194 additions and 20 deletions
@@ -157,21 +157,62 @@ namespace GradientSignal
float ShapeAreaFalloffGradientComponent::GetValue(const GradientSampleParams& sampleParams) const
{
AZ_PROFILE_FUNCTION(Entity);
float distance = 0.0f;
LmbrCentral::ShapeComponentRequestsBus::EventResult(distance, m_configuration.m_shapeEntityId, &LmbrCentral::ShapeComponentRequestsBus::Events::DistanceFromPoint, sampleParams.m_position);
// In the special case of 0 falloff, make sure that all points inside the shape (0 distance) return
// 1.0, and all points outside the shape return 0.
if (m_configuration.m_falloffWidth == 0.0f)
// Since this is outer falloff, distance should give us values from 1.0 at the minimum distance to 0.0 at the maximum distance.
// The statement is written specifically to handle the 0 falloff case as well. For 0 falloff, all points inside the shape
// (0 distance) return 1.0, and all points outside the shape return 0. This works because division by 0 gives infinity, which gets
// clamped by the GetMax() to 0. However, if distance == 0, it would give us NaN, so we have the separate conditional check to
// handle that case and clamp to 1.0.
return (distance <= 0.0f) ? 1.0f : AZ::GetMax(1.0f - (distance / m_configuration.m_falloffWidth), 0.0f);
}
void ShapeAreaFalloffGradientComponent::GetValues(AZStd::array_view<AZ::Vector3> positions, AZStd::array_view<float> outValues) const
{
if (positions.size() != outValues.size())
{
return (distance > 0.0f) ? 0.0f : 1.0f;
AZ_Assert(false, "input and output lists are different sizes (%zu vs %zu).", positions.size(), outValues.size());
return;
}
// Since this is outer falloff, distance should give us values from 1.0 at the minimum distance
// to 0.0 at the maximum distance.
return GetRatio(m_configuration.m_falloffWidth, 0.0f, distance);
bool shapeConnected = false;
const float falloffWidth = m_configuration.m_falloffWidth;
LmbrCentral::ShapeComponentRequestsBus::Event(
m_configuration.m_shapeEntityId,
[falloffWidth, positions, &outValues, &shapeConnected](LmbrCentral::ShapeComponentRequestsBus::Events* shapeRequests)
{
shapeConnected = true;
for (size_t index = 0; index < positions.size(); index++)
{
// The const_cast is necessary for now since array_view currently only supports const entries.
// If/when array_view is fixed to support non-const, or AZStd::span gets created, the const_cast can get removed.
auto& outValue = const_cast<float&>(outValues[index]);
float distance = shapeRequests->DistanceFromPoint(positions[index]);
// Since this is outer falloff, distance should give us values from 1.0 at the minimum distance to 0.0 at the maximum
// distance. The statement is written specifically to handle the 0 falloff case as well. For 0 falloff, all points
// inside the shape (0 distance) return 1.0, and all points outside the shape return 0. This works because division by 0
// gives infinity, which gets clamped by the GetMax() to 0. However, if distance == 0, it would give us NaN, so we have
// the separate conditional check to handle that case and clamp to 1.0.
outValue = (distance <= 0.0f) ? 1.0f : AZ::GetMax(1.0f - (distance / falloffWidth), 0.0f);
}
});
// If there's no shape, there's no falloff.
if (!shapeConnected)
{
for (size_t index = 0; index < positions.size(); index++)
{
// The const_cast is necessary for now since array_view currently only supports const entries.
// If/when array_view is fixed to support non-const, or AZStd::span gets created, the const_cast can get removed.
auto& outValue = const_cast<float&>(outValues[index]);
outValue = 1.0f;
}
}
}
AZ::EntityId ShapeAreaFalloffGradientComponent::GetShapeEntityId() const