Decomposes a transformation matrix into its translation, rotation, and scale components.
11 {
12
13
14 using namespace glm;
15 using T = float;
16
17 mat4 LocalMatrix(transform);
18
19
20 if (epsilonEqual(LocalMatrix[3][3], static_cast<float>(0), epsilon<T>()))
21 return false;
22
23
24 if (
25 epsilonNotEqual(LocalMatrix[0][3], static_cast<T>(0), epsilon<T>()) ||
26 epsilonNotEqual(LocalMatrix[1][3], static_cast<T>(0), epsilon<T>()) ||
27 epsilonNotEqual(LocalMatrix[2][3], static_cast<T>(0), epsilon<T>()))
28 {
29
30 LocalMatrix[0][3] = LocalMatrix[1][3] = LocalMatrix[2][3] = static_cast<T>(0);
31 LocalMatrix[3][3] = static_cast<T>(1);
32 }
33
34
35 translation = vec3(LocalMatrix[3]);
36 LocalMatrix[3] = vec4(0, 0, 0, LocalMatrix[3].w);
37
38 vec3 Row[3], Pdum3;
39
40
41 for (length_t i = 0; i < 3; ++i)
42 for (length_t j = 0; j < 3; ++j)
43 Row[i][j] = LocalMatrix[i][j];
44
45
46 scale.x = length(Row[0]);
47 Row[0] = detail::scale(Row[0], static_cast<T>(1));
48 scale.y = length(Row[1]);
49 Row[1] = detail::scale(Row[1], static_cast<T>(1));
50 scale.z = length(Row[2]);
51 Row[2] = detail::scale(Row[2], static_cast<T>(1));
52
53
54
55
56#if 0
57 Pdum3 = cross(Row[1], Row[2]);
58 if (dot(Row[0], Pdum3) < 0)
59 {
60 for (length_t i = 0; i < 3; i++)
61 {
62 scale[i] *= static_cast<T>(-1);
63 Row[i] *= static_cast<T>(-1);
64 }
65 }
66#endif
67
68 rotation.y = asin(-Row[0][2]);
69 if (cos(rotation.y) != 0) {
70 rotation.x = atan2(Row[1][2], Row[2][2]);
71 rotation.z = atan2(Row[0][1], Row[0][0]);
72 }
73 else {
74 rotation.x = atan2(-Row[2][0], Row[1][1]);
75 rotation.z = 0;
76 }
77
78
79 return true;
80 }