Optimize Matrix decomposition to use Matrix3x3 for rotation

This commit is contained in:
Wojtek Figat
2024-02-20 17:51:48 +01:00
parent 9e747eb98a
commit 8fa8eeb094
7 changed files with 83 additions and 16 deletions

View File

@@ -171,7 +171,7 @@ namespace FlaxEngine
/// <param name="ray">The ray to test.</param>
/// <param name="distance">When the method completes, contains the distance of the intersection, or 0 if there was no intersection.</param>
/// <returns>Whether the two objects intersected.</returns>
[Obsolete("Deprecated in 1.4")]
[Obsolete("Deprecated in v1.4")]
public bool Intersects(ref Ray ray, out float distance)
{
var result = CollisionsHelper.RayIntersectsBox(ref ray, ref this, out Real dst);

View File

@@ -101,7 +101,7 @@ void Matrix::Decompose(Float3& scale, Float3& translation) const
void Matrix::Decompose(Transform& transform) const
{
Matrix rotationMatrix;
Matrix3x3 rotationMatrix;
Float3 translation;
Decompose(transform.Scale, rotationMatrix, translation);
transform.Translation = translation;
@@ -110,12 +110,12 @@ void Matrix::Decompose(Transform& transform) const
void Matrix::Decompose(Float3& scale, Quaternion& rotation, Float3& translation) const
{
Matrix rotationMatrix;
Matrix3x3 rotationMatrix;
Decompose(scale, rotationMatrix, translation);
Quaternion::RotationMatrix(rotationMatrix, rotation);
}
void Matrix::Decompose(Float3& scale, Matrix& rotation, Float3& translation) const
void Matrix::Decompose(Float3& scale, Matrix3x3& rotation, Float3& translation) const
{
// Get the translation
translation = Float3(M41, M42, M43);
@@ -127,7 +127,7 @@ void Matrix::Decompose(Float3& scale, Matrix& rotation, Float3& translation) con
Math::Sqrt(M31 * M31 + M32 * M32 + M33 * M33));
// If any of the scaling factors are zero, than the rotation matrix can not exist
rotation = Identity;
rotation = Matrix3x3::Identity;
if (scale.IsAnyZero())
return;
@@ -145,6 +145,14 @@ void Matrix::Decompose(Float3& scale, Matrix& rotation, Float3& translation) con
scale.Z = Float3::Dot(at, GetBackward()) > 0.0f ? scale.Z : -scale.Z;
}
void Matrix::Decompose(Float3& scale, Matrix& rotation, Float3& translation) const
{
// [Deprecated on 20.02.2024, expires on 20.02.2026]
Matrix3x3 r;
Decompose(scale, r, translation);
rotation = Matrix(r);
}
Matrix Matrix::Transpose(const Matrix& value)
{
Matrix result;

View File

@@ -330,6 +330,30 @@ namespace FlaxEngine
M44 = values[15];
}
/// <summary>
/// Initializes a new instance of the <see cref="Matrix" /> struct.
/// </summary>
/// <param name="m">The rotation/scale matrix.</param>
public Matrix(Matrix3x3 m)
{
M11 = m.M11;
M12 = m.M12;
M13 = m.M13;
M14 = 0;
M21 = m.M21;
M22 = m.M22;
M23 = m.M23;
M24 = 0;
M31 = m.M31;
M32 = m.M32;
M33 = m.M33;
M34 = 0;
M41 = 0;
M42 = 0;
M43 = 0;
M44 = 1;
}
/// <summary>
/// Gets or sets the first row in the matrix; that is M11, M12, M13, and M14.
/// </summary>
@@ -747,7 +771,7 @@ namespace FlaxEngine
/// <remarks>This method is designed to decompose an SRT transformation matrix only.</remarks>
public void Decompose(out Transform transform)
{
Decompose(out transform.Scale, out Matrix rotationMatrix, out Float3 translation);
Decompose(out transform.Scale, out Matrix3x3 rotationMatrix, out Float3 translation);
Quaternion.RotationMatrix(ref rotationMatrix, out transform.Orientation);
transform.Translation = translation;
}
@@ -759,7 +783,7 @@ namespace FlaxEngine
/// <param name="rotation">When the method completes, contains the rotation component of the decomposed matrix.</param>
/// <param name="translation">When the method completes, contains the translation component of the decomposed matrix.</param>
/// <remarks>This method is designed to decompose an SRT transformation matrix only.</remarks>
public void Decompose(out Float3 scale, out Matrix rotation, out Float3 translation)
public void Decompose(out Float3 scale, out Matrix3x3 rotation, out Float3 translation)
{
// Get the translation
translation.X = M41;
@@ -774,12 +798,12 @@ namespace FlaxEngine
// If any of the scaling factors are zero, than the rotation matrix can not exist
if (Mathf.IsZero(scale.X) || Mathf.IsZero(scale.Y) || Mathf.IsZero(scale.Z))
{
rotation = Identity;
rotation = Matrix3x3.Identity;
return;
}
// The rotation is the left over matrix after dividing out the scaling
rotation = new Matrix
rotation = new Matrix3x3
{
M11 = M11 / scale.X,
M12 = M12 / scale.X,
@@ -790,10 +814,24 @@ namespace FlaxEngine
M31 = M31 / scale.Z,
M32 = M32 / scale.Z,
M33 = M33 / scale.Z,
M44 = 1f
};
}
/// <summary>
/// Decomposes a matrix into a scale, rotation, and translation.
/// [Deprecated on 20.02.2024, expires on 20.02.2026]
/// </summary>
/// <param name="scale">When the method completes, contains the scaling component of the decomposed matrix.</param>
/// <param name="rotation">When the method completes, contains the rotation component of the decomposed matrix.</param>
/// <param name="translation">When the method completes, contains the translation component of the decomposed matrix.</param>
/// <remarks>This method is designed to decompose an SRT transformation matrix only.</remarks>
[Obsolete("Deprecated in v1.8")]
public void Decompose(out Float3 scale, out Matrix rotation, out Float3 translation)
{
Decompose(out scale, out Matrix3x3 r, out translation);
rotation = new Matrix(r);
}
/// <summary>
/// Decomposes a matrix into a scale, rotation, and translation.
/// </summary>
@@ -803,7 +841,7 @@ namespace FlaxEngine
/// <remarks>This method is designed to decompose an SRT transformation matrix only.</remarks>
public void Decompose(out Float3 scale, out Quaternion rotation, out Float3 translation)
{
Decompose(out scale, out Matrix rotationMatrix, out translation);
Decompose(out scale, out Matrix3x3 rotationMatrix, out translation);
Quaternion.RotationMatrix(ref rotationMatrix, out rotation);
}

View File

@@ -480,7 +480,8 @@ public:
/// <param name="rotation">When the method completes, contains the rotation component of the decomposed matrix.</param>
/// <param name="translation">When the method completes, contains the translation component of the decomposed matrix.</param>
/// <remarks>This method is designed to decompose an SRT transformation matrix only.</remarks>
void Decompose(Float3& scale, Matrix& rotation, Float3& translation) const;
void Decompose(Float3& scale, Matrix3x3& rotation, Float3& translation) const;
DEPRECATED void Decompose(Float3& scale, Matrix& rotation, Float3& translation) const;
public:
Matrix operator*(const float scale) const

View File

@@ -185,6 +185,23 @@ namespace FlaxEngine
M33 = values[8];
}
/// <summary>
/// Initializes a new instance of the <see cref="Matrix3x3" /> struct.
/// </summary>
/// <param name="m">The rotation/scale matrix.</param>
public Matrix3x3(Matrix m)
{
M11 = m.M11;
M12 = m.M12;
M13 = m.M13;
M21 = m.M21;
M22 = m.M22;
M23 = m.M23;
M31 = m.M31;
M32 = m.M32;
M33 = m.M33;
}
/// <summary>
/// Gets or sets the first row in the Matrix3x3; that is M11, M12, M13
/// </summary>

View File

@@ -18,17 +18,20 @@ API_STRUCT() struct FLAXENGINE_API Transform
/// <summary>
/// The translation vector of the transform.
/// </summary>
API_FIELD(Attributes="EditorOrder(10), EditorDisplay(null, \"Position\")") Vector3 Translation;
API_FIELD(Attributes="EditorOrder(10), EditorDisplay(null, \"Position\")")
Vector3 Translation;
/// <summary>
/// The rotation of the transform.
/// </summary>
API_FIELD(Attributes="EditorOrder(20), EditorDisplay(null, \"Rotation\")") Quaternion Orientation;
API_FIELD(Attributes="EditorOrder(20), EditorDisplay(null, \"Rotation\")")
Quaternion Orientation;
/// <summary>
/// The scale vector of the transform.
/// </summary>
API_FIELD(Attributes="EditorOrder(30), Limit(float.MinValue, float.MaxValue, 0.01f)") Float3 Scale;
API_FIELD(Attributes="EditorOrder(30), Limit(float.MinValue, float.MaxValue, 0.01f)")
Float3 Scale;
public:
/// <summary>