Encapsulated gradient transform logic into separate class (#6586)

* First version of GradientTransform class.
The gradient transform logic is getting encapsulated into a class so that it can be cached and used by components in a much more optimal way than making ebus calls to the GradientTransform component on every transformed point.

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

* Moved GradientTransform into its own source files.

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

* Clean up and simplify GradientTransform logic.
Added extensive commenting and split TransformPositionToUVW into a separate method for normalizing (TransformPositionToUVWNormalized) so that there doesn't need to be any conditional logic.  There's no runtime variance as to which one needs to be called from a given call site.

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

* Added unit tests for GradientTransform.

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

* Add comparison operators to GradientTransform so we can easily tell when it has changed.

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

* Updated comments to be more Doxygen-friendly.

Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com>
This commit is contained in:
Mike Balfour
2021-12-29 13:44:03 -06:00
committed by GitHub
parent 49dd17f410
commit a10bf92739
17 changed files with 663 additions and 180 deletions
@@ -322,55 +322,17 @@ namespace GradientSignal
return false;
}
void GradientTransformComponent::TransformPositionToUVW(const AZ::Vector3& inPosition, AZ::Vector3& outUVW, const bool shouldNormalizeOutput, bool& wasPointRejected) const
void GradientTransformComponent::TransformPositionToUVW(const AZ::Vector3& inPosition, AZ::Vector3& outUVW, bool& wasPointRejected) const
{
AZStd::lock_guard<decltype(m_cacheMutex)> lock(m_cacheMutex);
m_gradientTransform.TransformPositionToUVW(inPosition, outUVW, wasPointRejected);
}
//transforming coordinate into "local" relative space of shape bounds
outUVW = m_shapeTransformInverse * inPosition;
if (!m_configuration.m_advancedMode || !m_configuration.m_is3d)
{
outUVW.SetZ(0.0f);
}
wasPointRejected = false;
if (m_shapeBounds.IsValid())
{
//all wrap types and transformations are applied after the coordinate is transformed into shape relative space
//this allows all calculations to be simplified and done using the shapes untransformed aabb
//outputting a value that can be used to sample a gradient in its local space
switch (m_configuration.m_wrappingType)
{
default:
case WrappingType::None:
outUVW = GetUnboundedPointInAabb(outUVW, m_shapeBounds);
break;
case WrappingType::ClampToEdge:
outUVW = GetClampedPointInAabb(outUVW, m_shapeBounds);
break;
case WrappingType::ClampToZero:
// We don't want to use m_shapeBounds.Contains() here because Contains() is inclusive on all edges.
// For uv consistency between clamped and unclamped states, we only want to accept uv ranges of [min, max),
// so we specifically need to exclude the max edges here.
wasPointRejected = !(outUVW.IsGreaterEqualThan(m_shapeBounds.GetMin()) && outUVW.IsLessThan(m_shapeBounds.GetMax()));
outUVW = GetClampedPointInAabb(outUVW, m_shapeBounds);
break;
case WrappingType::Mirror:
outUVW = GetMirroredPointInAabb(outUVW, m_shapeBounds);
break;
case WrappingType::Repeat:
outUVW = GetWrappedPointInAabb(outUVW, m_shapeBounds);
break;
}
}
outUVW *= m_configuration.m_frequencyZoom;
if (shouldNormalizeOutput)
{
outUVW = GetNormalizedPointInAabb(outUVW, m_shapeBounds);
}
void GradientTransformComponent::TransformPositionToUVWNormalized(
const AZ::Vector3& inPosition, AZ::Vector3& outUVW, bool& wasPointRejected) const
{
AZStd::lock_guard<decltype(m_cacheMutex)> lock(m_cacheMutex);
m_gradientTransform.TransformPositionToUVWNormalized(inPosition, outUVW, wasPointRejected);
}
void GradientTransformComponent::GetGradientLocalBounds(AZ::Aabb& bounds) const
@@ -499,6 +461,11 @@ namespace GradientSignal
shapeTransformFinal.SetTranslation(m_configuration.m_translate);
shapeTransformFinal.MultiplyByScale(m_configuration.m_scale);
m_shapeTransformInverse = shapeTransformFinal.GetInverseFull();
// Set everything up on the Gradient Transform
const bool use3dGradients = m_configuration.m_advancedMode && m_configuration.m_is3d;
m_gradientTransform = GradientTransform(
m_shapeBounds, shapeTransformFinal, use3dGradients, m_configuration.m_frequencyZoom, m_configuration.m_wrappingType);
}
AZ::EntityId GradientTransformComponent::GetShapeEntityId() const