summaryrefslogtreecommitdiffstats
path: root/external/include/glm/gtx/matrix_decompose.inl
diff options
context:
space:
mode:
Diffstat (limited to 'external/include/glm/gtx/matrix_decompose.inl')
-rw-r--r--external/include/glm/gtx/matrix_decompose.inl115
1 files changed, 54 insertions, 61 deletions
diff --git a/external/include/glm/gtx/matrix_decompose.inl b/external/include/glm/gtx/matrix_decompose.inl
index 7194e9d..02a5acc 100644
--- a/external/include/glm/gtx/matrix_decompose.inl
+++ b/external/include/glm/gtx/matrix_decompose.inl
@@ -1,22 +1,25 @@
/// @ref gtx_matrix_decompose
/// @file glm/gtx/matrix_decompose.inl
+#include "../gtc/constants.hpp"
+#include "../gtc/epsilon.hpp"
+
namespace glm{
namespace detail
{
/// Make a linear combination of two vectors and return the result.
// result = (a * ascl) + (b * bscl)
- template <typename T, precision P>
- GLM_FUNC_QUALIFIER tvec3<T, P> combine(
- tvec3<T, P> const & a,
- tvec3<T, P> const & b,
+ template<typename T, qualifier Q>
+ GLM_FUNC_QUALIFIER vec<3, T, Q> combine(
+ vec<3, T, Q> const& a,
+ vec<3, T, Q> const& b,
T ascl, T bscl)
{
return (a * ascl) + (b * bscl);
}
- template <typename T, precision P>
- GLM_FUNC_QUALIFIER tvec3<T, P> scale(tvec3<T, P> const& v, T desiredLength)
+ template<typename T, qualifier Q>
+ GLM_FUNC_QUALIFIER vec<3, T, Q> scale(vec<3, T, Q> const& v, T desiredLength)
{
return v * desiredLength / length(v);
}
@@ -26,13 +29,13 @@ namespace detail
// http://www.opensource.apple.com/source/WebCore/WebCore-514/platform/graphics/transforms/TransformationMatrix.cpp
// Decomposes the mode matrix to translations,rotation scale components
- template <typename T, precision P>
- GLM_FUNC_QUALIFIER bool decompose(tmat4x4<T, P> const & ModelMatrix, tvec3<T, P> & Scale, tquat<T, P> & Orientation, tvec3<T, P> & Translation, tvec3<T, P> & Skew, tvec4<T, P> & Perspective)
+ template<typename T, qualifier Q>
+ GLM_FUNC_QUALIFIER bool decompose(mat<4, 4, T, Q> const& ModelMatrix, vec<3, T, Q> & Scale, tquat<T, Q> & Orientation, vec<3, T, Q> & Translation, vec<3, T, Q> & Skew, vec<4, T, Q> & Perspective)
{
- tmat4x4<T, P> LocalMatrix(ModelMatrix);
+ mat<4, 4, T, Q> LocalMatrix(ModelMatrix);
// Normalize the matrix.
- if(LocalMatrix[3][3] == static_cast<T>(0))
+ if(epsilonEqual(LocalMatrix[3][3], static_cast<T>(0), epsilon<T>()))
return false;
for(length_t i = 0; i < 4; ++i)
@@ -41,21 +44,24 @@ namespace detail
// perspectiveMatrix is used to solve for perspective, but it also provides
// an easy way to test for singularity of the upper 3x3 component.
- tmat4x4<T, P> PerspectiveMatrix(LocalMatrix);
+ mat<4, 4, T, Q> PerspectiveMatrix(LocalMatrix);
for(length_t i = 0; i < 3; i++)
PerspectiveMatrix[i][3] = static_cast<T>(0);
PerspectiveMatrix[3][3] = static_cast<T>(1);
/// TODO: Fixme!
- if(determinant(PerspectiveMatrix) == static_cast<T>(0))
+ if(epsilonEqual(determinant(PerspectiveMatrix), static_cast<T>(0), epsilon<T>()))
return false;
// First, isolate perspective. This is the messiest.
- if(LocalMatrix[0][3] != static_cast<T>(0) || LocalMatrix[1][3] != static_cast<T>(0) || LocalMatrix[2][3] != static_cast<T>(0))
+ if(
+ epsilonNotEqual(LocalMatrix[0][3], static_cast<T>(0), epsilon<T>()) ||
+ epsilonNotEqual(LocalMatrix[1][3], static_cast<T>(0), epsilon<T>()) ||
+ epsilonNotEqual(LocalMatrix[2][3], static_cast<T>(0), epsilon<T>()))
{
// rightHandSide is the right hand side of the equation.
- tvec4<T, P> RightHandSide;
+ vec<4, T, Q> RightHandSide;
RightHandSide[0] = LocalMatrix[0][3];
RightHandSide[1] = LocalMatrix[1][3];
RightHandSide[2] = LocalMatrix[2][3];
@@ -64,8 +70,8 @@ namespace detail
// Solve the equation by inverting PerspectiveMatrix and multiplying
// rightHandSide by the inverse. (This is the easiest way, not
// necessarily the best.)
- tmat4x4<T, P> InversePerspectiveMatrix = glm::inverse(PerspectiveMatrix);// inverse(PerspectiveMatrix, inversePerspectiveMatrix);
- tmat4x4<T, P> TransposedInversePerspectiveMatrix = glm::transpose(InversePerspectiveMatrix);// transposeMatrix4(inversePerspectiveMatrix, transposedInversePerspectiveMatrix);
+ mat<4, 4, T, Q> InversePerspectiveMatrix = glm::inverse(PerspectiveMatrix);// inverse(PerspectiveMatrix, inversePerspectiveMatrix);
+ mat<4, 4, T, Q> TransposedInversePerspectiveMatrix = glm::transpose(InversePerspectiveMatrix);// transposeMatrix4(inversePerspectiveMatrix, transposedInversePerspectiveMatrix);
Perspective = TransposedInversePerspectiveMatrix * RightHandSide;
// v4MulPointByMatrix(rightHandSide, transposedInversePerspectiveMatrix, perspectivePoint);
@@ -77,19 +83,19 @@ namespace detail
else
{
// No perspective.
- Perspective = tvec4<T, P>(0, 0, 0, 1);
+ Perspective = vec<4, T, Q>(0, 0, 0, 1);
}
// Next take care of translation (easy).
- Translation = tvec3<T, P>(LocalMatrix[3]);
- LocalMatrix[3] = tvec4<T, P>(0, 0, 0, LocalMatrix[3].w);
+ Translation = vec<3, T, Q>(LocalMatrix[3]);
+ LocalMatrix[3] = vec<4, T, Q>(0, 0, 0, LocalMatrix[3].w);
- tvec3<T, P> Row[3], Pdum3;
+ vec<3, T, Q> Row[3], Pdum3;
// Now get scale and shear.
for(length_t i = 0; i < 3; ++i)
- for(int j = 0; j < 3; ++j)
- Row[i][j] = LocalMatrix[i][j];
+ for(length_t j = 0; j < 3; ++j)
+ Row[i][j] = LocalMatrix[i][j];
// Compute X scale factor and normalize first row.
Scale.x = length(Row[0]);// v3Length(Row[0]);
@@ -147,47 +153,34 @@ namespace detail
// ret.rotateZ = 0;
// }
- T s, t, x, y, z, w;
-
- t = Row[0][0] + Row[1][1] + Row[2][2] + static_cast<T>(1);
-
- if(t > static_cast<T>(1e-4))
+ int i, j, k = 0;
+ float root, trace = Row[0].x + Row[1].y + Row[2].z;
+ if(trace > static_cast<T>(0))
{
- s = static_cast<T>(0.5) / sqrt(t);
- w = static_cast<T>(0.25) / s;
- x = (Row[2][1] - Row[1][2]) * s;
- y = (Row[0][2] - Row[2][0]) * s;
- z = (Row[1][0] - Row[0][1]) * s;
- }
- else if(Row[0][0] > Row[1][1] && Row[0][0] > Row[2][2])
- {
- s = sqrt (static_cast<T>(1) + Row[0][0] - Row[1][1] - Row[2][2]) * static_cast<T>(2); // S=4*qx
- x = static_cast<T>(0.25) * s;
- y = (Row[0][1] + Row[1][0]) / s;
- z = (Row[0][2] + Row[2][0]) / s;
- w = (Row[2][1] - Row[1][2]) / s;
- }
- else if(Row[1][1] > Row[2][2])
- {
- s = sqrt (static_cast<T>(1) + Row[1][1] - Row[0][0] - Row[2][2]) * static_cast<T>(2); // S=4*qy
- x = (Row[0][1] + Row[1][0]) / s;
- y = static_cast<T>(0.25) * s;
- z = (Row[1][2] + Row[2][1]) / s;
- w = (Row[0][2] - Row[2][0]) / s;
- }
+ root = sqrt(trace + static_cast<T>(1.0));
+ Orientation.w = static_cast<T>(0.5) * root;
+ root = static_cast<T>(0.5) / root;
+ Orientation.x = root * (Row[1].z - Row[2].y);
+ Orientation.y = root * (Row[2].x - Row[0].z);
+ Orientation.z = root * (Row[0].y - Row[1].x);
+ } // End if > 0
else
- {
- s = sqrt(static_cast<T>(1) + Row[2][2] - Row[0][0] - Row[1][1]) * static_cast<T>(2); // S=4*qz
- x = (Row[0][2] + Row[2][0]) / s;
- y = (Row[1][2] + Row[2][1]) / s;
- z = static_cast<T>(0.25) * s;
- w = (Row[1][0] - Row[0][1]) / s;
- }
-
- Orientation.x = x;
- Orientation.y = y;
- Orientation.z = z;
- Orientation.w = w;
+ {
+ static int Next[3] = {1, 2, 0};
+ i = 0;
+ if(Row[1].y > Row[0].x) i = 1;
+ if(Row[2].z > Row[i][i]) i = 2;
+ j = Next[i];
+ k = Next[j];
+
+ root = sqrt(Row[i][i] - Row[j][j] - Row[k][k] + static_cast<T>(1.0));
+
+ Orientation[i] = static_cast<T>(0.5) * root;
+ root = static_cast<T>(0.5) / root;
+ Orientation[j] = root * (Row[i][j] + Row[j][i]);
+ Orientation[k] = root * (Row[i][k] + Row[k][i]);
+ Orientation.w = root * (Row[j][k] - Row[k][j]);
+ } // End if <= 0
return true;
}