Performance pass to Cloth CPU Skinning

- Added operator+(Matrix3x4), operator*(float), RetrieveScaleSq and GetReciprocalScaled to Matrix3x4. Used by Cloth CPU Linear Skinning. These operation will be performant as they use SIMD.
- Modified so there are no virtual functions calls at vertex level.
- Caching indices to simplify the loop when applying skinning.
- Caching static variables Matrix3x4 zero and DualQuaternion zero to avoid creating it for every vertex.
- Removing branching to skip joints when the weight is zero, these cases are rarely and this improves performance by removing branching from loops at vertex level.
- Changing skinning influences so it's a continuous block of memory.
- Caching the vector size() if a variable instead of directly using it in a for loop.
This commit is contained in:
Aaron Ruiz Mora
2021-05-04 12:09:56 +01:00
committed by GitHub
parent 83545c0243
commit 70bd3ea0ff
7 changed files with 388 additions and 210 deletions
@@ -231,6 +231,18 @@ namespace AZ
//! Compound assignment operator for matrix-matrix multiplication.
Matrix3x4& operator*=(const Matrix3x4& rhs);
//! Operator for matrix-matrix addition.
[[nodiscard]] Matrix3x4 operator+(const Matrix3x4& rhs) const;
//! Compound assignment operator for matrix-matrix addition.
Matrix3x4& operator+=(const Matrix3x4& rhs);
//! Operator for multiplying all matrix's elements with a scalar
[[nodiscard]] Matrix3x4 operator*(float scalar) const;
//! Compound assignment operator for multiplying all matrix's elements with a scalar
Matrix3x4& operator*=(float scalar);
//! Operator for transforming a Vector3.
[[nodiscard]] Vector3 operator*(const Vector3& rhs) const;
@@ -274,12 +286,18 @@ namespace AZ
//! Gets the scale part of the transformation (the length of the basis vectors).
[[nodiscard]] Vector3 RetrieveScale() const;
//! Gets the squared scale part of the transformation (the squared length of the basis vectors).
[[nodiscard]] Vector3 RetrieveScaleSq() const;
//! Gets the scale part of the transformation as in RetrieveScale, and also removes this scaling from the matrix.
Vector3 ExtractScale();
//! Multiplies the basis vectors of the matrix by the elements of the scale specified.
void MultiplyByScale(const Vector3& scale);
//! Returns a matrix with the reciprocal scale, keeping the same rotation and translation.
[[nodiscard]] Matrix3x4 GetReciprocalScaled() const;
//! Tests if the 3x3 part of the matrix is orthogonal.
bool IsOrthogonal(float tolerance = Constants::Tolerance) const;
@@ -487,6 +487,43 @@ namespace AZ
}
AZ_MATH_INLINE Matrix3x4 Matrix3x4::operator+(const Matrix3x4& rhs) const
{
return Matrix3x4
(
Simd::Vec4::Add(m_rows[0].GetSimdValue(), rhs.m_rows[0].GetSimdValue()),
Simd::Vec4::Add(m_rows[1].GetSimdValue(), rhs.m_rows[1].GetSimdValue()),
Simd::Vec4::Add(m_rows[2].GetSimdValue(), rhs.m_rows[2].GetSimdValue())
);
}
AZ_MATH_INLINE Matrix3x4& Matrix3x4::operator+=(const Matrix3x4& rhs)
{
*this = *this + rhs;
return *this;
}
AZ_MATH_INLINE Matrix3x4 Matrix3x4::operator*(float scalar) const
{
const Vector4 vector4Scalar(scalar);
return Matrix3x4
(
Simd::Vec4::Mul(m_rows[0].GetSimdValue(), vector4Scalar.GetSimdValue()),
Simd::Vec4::Mul(m_rows[1].GetSimdValue(), vector4Scalar.GetSimdValue()),
Simd::Vec4::Mul(m_rows[2].GetSimdValue(), vector4Scalar.GetSimdValue())
);
}
AZ_MATH_INLINE Matrix3x4& Matrix3x4::operator*=(float scalar)
{
*this = *this * scalar;
return *this;
}
AZ_MATH_INLINE Vector3 Matrix3x4::operator*(const Vector3& rhs) const
{
return Vector3
@@ -583,6 +620,12 @@ namespace AZ
}
AZ_MATH_INLINE Vector3 Matrix3x4::RetrieveScaleSq() const
{
return Vector3(GetColumn(0).GetLengthSq(), GetColumn(1).GetLengthSq(), GetColumn(2).GetLengthSq());
}
AZ_MATH_INLINE Vector3 Matrix3x4::ExtractScale()
{
const Vector3 scale = RetrieveScale();
@@ -600,6 +643,14 @@ namespace AZ
}
AZ_MATH_INLINE Matrix3x4 Matrix3x4::GetReciprocalScaled() const
{
Matrix3x4 result = *this;
result.MultiplyByScale(RetrieveScaleSq().GetReciprocal());
return result;
}
AZ_MATH_INLINE void Matrix3x4::Orthogonalize()
{
*this = GetOrthogonalized();