Last active
March 4, 2025 03:21
-
-
Save ogxd/c48b5413994ebcf224ae765a7f07ee8e to your computer and use it in GitHub Desktop.
Get or set a Transform matrix using TRS decompositions
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
public static class TransformExtensions { | |
private static void GetTRS(this Matrix4x4 matrix, out Vector3 translation, out Quaternion rotation, out Vector3 scale) | |
{ | |
float det = matrix.GetDeterminant(); | |
// Scale | |
scale.x = matrix.MultiplyVector(new Vector3(1, 0, 0)).magnitude; | |
scale.y = matrix.MultiplyVector(new Vector3(0, 1, 0)).magnitude; | |
scale.z = matrix.MultiplyVector(new Vector3(0, 0, 1)).magnitude; | |
scale = (det < 0) ? -scale : scale; | |
// Rotation | |
Matrix4x4 rotationMatrix = matrix; | |
rotationMatrix.m03 = rotationMatrix.m13 = rotationMatrix.m23 = 0f; | |
rotationMatrix = rotationMatrix * new Matrix4x4 { m00 = 1f / scale.x, m11 = 1f / scale.y, m22 = 1f / scale.z, m33 = 1 }; | |
rotation = Quaternion.LookRotation(rotationMatrix.GetColumn(2), rotationMatrix.GetColumn(1)); | |
// Position | |
translation = matrix.GetColumn(3); | |
} | |
private static float GetDeterminant(this Matrix4x4 matrix) { | |
return matrix.m00 * (matrix.m11 * matrix.m22 - matrix.m12 * matrix.m21) - | |
matrix.m10 * (matrix.m01 * matrix.m22 - matrix.m02 * matrix.m21) + | |
matrix.m20 * (matrix.m01 * matrix.m12 - matrix.m02 * matrix.m11); | |
} | |
public static void SetFromLocalMatrix(this Transform transform, Matrix4x4 matrix, bool isLeftHanded, bool isZup, float scaleFactor) { | |
matrix.GetTRS(out Vector3 t, out Quaternion r, out Vector3 s); | |
// Apply scale factor | |
t *= scaleFactor; | |
// If matrix is from Z-up system, we convert the TRS to match Unity's Y-up system | |
if (isZup) { | |
t = new Vector3(t.x, t.z, t.y); | |
r = new Quaternion(r.x, r.z, r.y, -r.w); | |
s = new Vector3(s.x, s.z, s.y); | |
} | |
// If matrix is from Left-Handed system, we convert the TRS to match Unity's Right-Handed system | |
if (!isLeftHanded) { | |
t = new Vector3(-t.x, t.y, t.z); | |
r = new Quaternion(-r.x, r.y, r.z, -r.w); | |
} | |
// Assign local TRS to transform | |
transform.localPosition = t; | |
transform.localRotation = r; | |
transform.localScale = s; | |
} | |
public static Matrix4x4 GetLocalMatrix(this Transform transform, bool isLeftHanded, bool isZup, float scaleFactor) | |
{ | |
Vector3 t = transform.localPosition; | |
Quaternion r = transform.localRotation; | |
Vector3 s = transform.localScale; | |
t *= scaleFactor; | |
// If matrix should is for Z-up system, we convert the TRS from Unity's Y-up system | |
if (isZup) { | |
t = new Vector3(t.x, t.z, t.y); | |
r = new Quaternion(r.x, r.z, r.y, -r.w); | |
s = new Vector3(s.x, s.z, s.y); | |
} | |
// If matrix should is for Left-Handed system, we convert the TRS from Unity's Right-Handed system | |
if (!isLeftHanded) { | |
t = new Vector3(-t.x, t.y, t.z); | |
r = new Quaternion(-r.x, r.y, r.z, -r.w); | |
} | |
Matrix4x4 matrix = Matrix4x4.identity; | |
matrix.SetTRS(t, r, s); | |
return matrix; | |
} | |
public static Matrix4x4 GetWorldMatrix(this Transform transform, bool isLeftHanded, bool isZup, float scaleFactor) | |
{ | |
Vector3 t = transform.position; | |
Quaternion r = transform.rotation; | |
Vector3 s = transform.lossyScale; | |
t *= scaleFactor; | |
// If matrix should is for Z-up system, we convert the TRS from Unity's Y-up system | |
if (isZup) { | |
t = new Vector3(t.x, t.z, t.y); | |
r = new Quaternion(r.x, r.z, r.y, -r.w); | |
s = new Vector3(s.x, s.z, s.y); | |
} | |
// If matrix should is for Left-Handed system, we convert the TRS from Unity's Right-Handed system | |
if (!isLeftHanded) { | |
t = new Vector3(-t.x, t.y, t.z); | |
r = new Quaternion(-r.x, r.y, r.z, -r.w); | |
} | |
Matrix4x4 matrix = Matrix4x4.identity; | |
matrix.SetTRS(t, r, s); | |
return matrix; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment