summaryrefslogtreecommitdiffhomepage
path: root/src/raymath.h
diff options
context:
space:
mode:
authorVitoTringolo <[email protected]>2024-06-28 09:53:29 +0200
committerGitHub <[email protected]>2024-06-28 09:53:29 +0200
commit05d76c74a61444f1daba82100a0b69e5d66520ed (patch)
tree6e6a3eed9df29b03e7948aa1189caf4e3d8f37e4 /src/raymath.h
parent5e91444e3e6a96813a491070de88358403ab5a75 (diff)
downloadraylib-05d76c74a61444f1daba82100a0b69e5d66520ed.tar.gz
raylib-05d76c74a61444f1daba82100a0b69e5d66520ed.zip
Fix GLTF animations (#4107)
Co-authored-by: Vito Tringolo <[email protected]>
Diffstat (limited to 'src/raymath.h')
-rw-r--r--src/raymath.h50
1 files changed, 50 insertions, 0 deletions
diff --git a/src/raymath.h b/src/raymath.h
index 8b69cbd5..63947ee8 100644
--- a/src/raymath.h
+++ b/src/raymath.h
@@ -2525,4 +2525,54 @@ RMAPI int QuaternionEquals(Quaternion p, Quaternion q)
return result;
}
+// Decompose a transformation matrix into its rotational, translational and scaling components
+RMAPI void MatrixDecompose(Matrix mat, Vector3 *translation, Quaternion *rotation, Vector3 *scale)
+{
+ // Extract translation.
+ translation->x = mat.m12;
+ translation->y = mat.m13;
+ translation->z = mat.m14;
+
+ // Extract upper-left for determinant computation.
+ const float a = mat.m0;
+ const float b = mat.m4;
+ const float c = mat.m8;
+ const float d = mat.m1;
+ const float e = mat.m5;
+ const float f = mat.m9;
+ const float g = mat.m2;
+ const float h = mat.m6;
+ const float i = mat.m10;
+ const float A = e * i - f * h;
+ const float B = f * g - d * i;
+ const float C = d * h - e * g;
+
+ // Extract scale.
+ const float det = a * A + b * B + c * C;
+ float scalex = Vector3Length((Vector3) {a, b, c});
+ float scaley = Vector3Length((Vector3) {d, e, f});
+ float scalez = Vector3Length((Vector3) {g, h, i});
+ Vector3 s = {scalex, scaley, scalez};
+
+ if (det < 0) s = Vector3Negate(s);
+
+ *scale = s;
+
+ // Remove scale from the matrix if it is not close to zero.
+ Matrix clone = mat;
+ if (!FloatEquals(det, 0))
+ {
+ clone.m0 /= s.x;
+ clone.m5 /= s.y;
+ clone.m10 /= s.z;
+ // Extract rotation
+ *rotation = QuaternionFromMatrix(clone);
+ }
+ else
+ {
+ // Set to identity if close to zero
+ *rotation = QuaternionIdentity();
+ }
+}
+
#endif // RAYMATH_H