Muto 0.0.1
Cross-Platform Application Template
GitHub Repo | Muto Updates | Muto's Author
Loading...
Searching...
No Matches
Muto::Math Namespace Reference

Contains mathematical utility functions for the Vesper engine. More...

Functions

bool DecomposeTransform (const glm::mat4 &transform, glm::vec3 &translation, glm::vec3 &rotation, glm::vec3 &scale)
 Decomposes a transformation matrix into its translation, rotation, and scale components.
 

Detailed Description

Contains mathematical utility functions for the Vesper engine.

Function Documentation

◆ DecomposeTransform()

bool Muto::Math::DecomposeTransform ( const glm::mat4 &  transform,
glm::vec3 &  translation,
glm::vec3 &  rotation,
glm::vec3 &  scale 
)

Decomposes a transformation matrix into its translation, rotation, and scale components.

11 {
12 // From glm::decompose in matrix_decompose.inl
13
14 using namespace glm;
15 using T = float;
16
17 mat4 LocalMatrix(transform);
18
19 // Normalize the matrix.
20 if (epsilonEqual(LocalMatrix[3][3], static_cast<float>(0), epsilon<T>()))
21 return false;
22
23 // First, isolate perspective. This is the messiest.
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 // Clear the perspective partition
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 // Next take care of translation (easy).
35 translation = vec3(LocalMatrix[3]);
36 LocalMatrix[3] = vec4(0, 0, 0, LocalMatrix[3].w);
37
38 vec3 Row[3], Pdum3;
39
40 // Now get scale and shear.
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 // Compute X scale factor and normalize first row.
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 // At this point, the matrix (in rows[]) is orthonormal.
54 // Check for a coordinate system flip. If the determinant
55 // is -1, then negate the matrix and the scaling factors.
56#if 0
57 Pdum3 = cross(Row[1], Row[2]); // v3Cross(row[1], row[2], Pdum3);
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 }