Vesper 0.5.1
Vesper is short form for the Latin word for "Bat", as Vesper is designed to be small, lightweight, and easily handle things like particles and flocking behaviors in accordance with the nature of bats. \n It is meant to be a particle simulation, VFX editor, and CAN be used secondarily as a small game engine.
GitHub | Vesper Updates | Creator
Loading...
Searching...
No Matches
Vesper::Math Namespace Reference

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.

Function Documentation

◆ DecomposeTransform()

bool Vesper::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 }