Browse Source

Added extraction of Euler angles from rotation matrix.

Extraction of Euler angles from rotation matrix for 11 sequences of rotation axes:
z-x-z, x-y-x, y-z-y, z-y-z, x-z-x, y-x-y, y-z-x, z-x-y, x-z-y, z-y-x, y-x-z.
Vitali Parkhomenko 7 years ago
parent
commit
15fb58aacb
2 changed files with 278 additions and 0 deletions
  1. 91 0
      glm/gtx/euler_angles.hpp
  2. 187 0
      glm/gtx/euler_angles.inl

+ 91 - 0
glm/gtx/euler_angles.hpp

@@ -9,6 +9,9 @@
 /// Include <glm/gtx/euler_angles.hpp> to use the features of this extension.
 ///
 /// Build matrices from Euler angles.
+///
+/// Extraction of Euler angles from rotation matrix.
+/// Based on the original paper 2014 Mike Day - Extracting Euler Angles from a Rotation Matrix.
 
 #pragma once
 
@@ -238,6 +241,94 @@ namespace glm
                                             T & t2,
                                             T & t3);
     
+	/// Extracts the (Y * X * Z) Euler angles from the rotation matrix M
+	/// @see gtx_euler_angles
+	template <typename T>
+	GLM_FUNC_DECL void extractEulerAngleYXZ(mat<4, 4, T, defaultp> const & M,
+											T & t1,
+											T & t2,
+											T & t3);
+
+	/// Extracts the (X * Z * X) Euler angles from the rotation matrix M
+	/// @see gtx_euler_angles
+	template <typename T>
+	GLM_FUNC_DECL void extractEulerAngleXZX(mat<4, 4, T, defaultp> const & M,
+											T & t1,
+											T & t2,
+											T & t3);
+
+	/// Extracts the (X * Y * X) Euler angles from the rotation matrix M
+	/// @see gtx_euler_angles
+	template <typename T>
+	GLM_FUNC_DECL void extractEulerAngleXYX(mat<4, 4, T, defaultp> const & M,
+											T & t1,
+											T & t2,
+											T & t3);
+
+	/// Extracts the (Y * X * Y) Euler angles from the rotation matrix M
+	/// @see gtx_euler_angles
+	template <typename T>
+	GLM_FUNC_DECL void extractEulerAngleYXY(mat<4, 4, T, defaultp> const & M,
+											T & t1,
+											T & t2,
+											T & t3);
+
+	/// Extracts the (Y * Z * Y) Euler angles from the rotation matrix M
+	/// @see gtx_euler_angles
+	template <typename T>
+	GLM_FUNC_DECL void extractEulerAngleYZY(mat<4, 4, T, defaultp> const & M,
+											T & t1,
+											T & t2,
+											T & t3);
+
+	/// Extracts the (Z * Y * Z) Euler angles from the rotation matrix M
+	/// @see gtx_euler_angles
+	template <typename T>
+	GLM_FUNC_DECL void extractEulerAngleZYZ(mat<4, 4, T, defaultp> const & M,
+											T & t1,
+											T & t2,
+											T & t3);
+
+	/// Extracts the (Z * X * Z) Euler angles from the rotation matrix M
+	/// @see gtx_euler_angles
+	template <typename T>
+	GLM_FUNC_DECL void extractEulerAngleZXZ(mat<4, 4, T, defaultp> const & M,
+											T & t1,
+											T & t2,
+											T & t3);
+
+	/// Extracts the (X * Z * Y) Euler angles from the rotation matrix M
+	/// @see gtx_euler_angles
+	template <typename T>
+	GLM_FUNC_DECL void extractEulerAngleXZY(mat<4, 4, T, defaultp> const & M,
+											T & t1,
+											T & t2,
+											T & t3);
+
+	/// Extracts the (Y * Z * X) Euler angles from the rotation matrix M
+	/// @see gtx_euler_angles
+	template <typename T>
+	GLM_FUNC_DECL void extractEulerAngleYZX(mat<4, 4, T, defaultp> const & M,
+											T & t1,
+											T & t2,
+											T & t3);
+
+	/// Extracts the (Z * Y * X) Euler angles from the rotation matrix M
+	/// @see gtx_euler_angles
+	template <typename T>
+	GLM_FUNC_DECL void extractEulerAngleZYX(mat<4, 4, T, defaultp> const & M,
+											T & t1,
+											T & t2,
+											T & t3);
+
+	/// Extracts the (Z * X * Y) Euler angles from the rotation matrix M
+	/// @see gtx_euler_angles
+	template <typename T>
+	GLM_FUNC_DECL void extractEulerAngleZXY(mat<4, 4, T, defaultp> const & M,
+											T & t1,
+											T & t2,
+											T & t3);
+
 	/// @}
 }//namespace glm
 

+ 187 - 0
glm/gtx/euler_angles.inl

@@ -710,4 +710,191 @@ namespace glm
         t2 = -T2;
         t3 = -T3;
     }
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER void extractEulerAngleYXZ(mat<4, 4, T, defaultp> const & M,
+												 T & t1,
+												 T & t2,
+												 T & t3)
+	{
+		T T1 = glm::atan2<T, defaultp>(M[2][0], M[2][2]);
+		T C2 = glm::sqrt(M[0][1]*M[0][1] + M[1][1]*M[1][1]);
+		T T2 = glm::atan2<T, defaultp>(-M[2][1], C2);
+		T S1 = glm::sin(T1);
+		T C1 = glm::cos(T1);
+		T T3 = glm::atan2<T, defaultp>(S1*M[1][2] - C1*M[1][0], C1*M[0][0] - S1*M[0][2]);
+		t1 = T1;
+		t2 = T2;
+		t3 = T3;
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER void extractEulerAngleXZX(mat<4, 4, T, defaultp> const & M,
+												 T & t1,
+												 T & t2,
+												 T & t3)
+	{
+		T T1 = glm::atan2<T, defaultp>(M[0][2], M[0][1]);
+		T S2 = glm::sqrt(M[1][0]*M[1][0] + M[2][0]*M[2][0]);
+		T T2 = glm::atan2<T, defaultp>(S2, M[0][0]);
+		T S1 = glm::sin(T1);
+		T C1 = glm::cos(T1);
+		T T3 = glm::atan2<T, defaultp>(C1*M[1][2] - S1*M[1][1], C1*M[2][2] - S1*M[2][1]);
+		t1 = T1;
+		t2 = T2;
+		t3 = T3;
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER void extractEulerAngleXYX(mat<4, 4, T, defaultp> const & M,
+												 T & t1,
+												 T & t2,
+												 T & t3)
+	{
+		T T1 = glm::atan2<T, defaultp>(M[0][1], -M[0][2]);
+		T S2 = glm::sqrt(M[1][0]*M[1][0] + M[2][0]*M[2][0]);
+		T T2 = glm::atan2<T, defaultp>(S2, M[0][0]);
+		T S1 = glm::sin(T1);
+		T C1 = glm::cos(T1);
+		T T3 = glm::atan2<T, defaultp>(-C1*M[2][1] - S1*M[2][2], C1*M[1][1] + S1*M[1][2]);
+		t1 = T1;
+		t2 = T2;
+		t3 = T3;
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER void extractEulerAngleYXY(mat<4, 4, T, defaultp> const & M,
+												 T & t1,
+												 T & t2,
+												 T & t3)
+	{
+		T T1 = glm::atan2<T, defaultp>(M[1][0], M[1][2]);
+		T S2 = glm::sqrt(M[0][1]*M[0][1] + M[2][1]*M[2][1]);
+		T T2 = glm::atan2<T, defaultp>(S2, M[1][1]);
+		T S1 = glm::sin(T1);
+		T C1 = glm::cos(T1);
+		T T3 = glm::atan2<T, defaultp>(C1*M[2][0] - S1*M[2][2], C1*M[0][0] - S1*M[0][2]);
+		t1 = T1;
+		t2 = T2;
+		t3 = T3;
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER void extractEulerAngleYZY(mat<4, 4, T, defaultp> const & M,
+												 T & t1,
+												 T & t2,
+												 T & t3)
+	{
+		T T1 = glm::atan2<T, defaultp>(M[1][2], -M[1][0]);
+		T S2 = glm::sqrt(M[0][1]*M[0][1] + M[2][1]*M[2][1]);
+		T T2 = glm::atan2<T, defaultp>(S2, M[1][1]);
+		T S1 = glm::sin(T1);
+		T C1 = glm::cos(T1);
+		T T3 = glm::atan2<T, defaultp>(-S1*M[0][0] - C1*M[0][2], S1*M[2][0] + C1*M[2][2]);
+		t1 = T1;
+		t2 = T2;
+		t3 = T3;
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER void extractEulerAngleZYZ(mat<4, 4, T, defaultp> const & M,
+												 T & t1,
+												 T & t2,
+												 T & t3)
+	{
+		T T1 = glm::atan2<T, defaultp>(M[2][1], M[2][0]);
+		T S2 = glm::sqrt(M[0][2]*M[0][2] + M[1][2]*M[1][2]);
+		T T2 = glm::atan2<T, defaultp>(S2, M[2][2]);
+		T S1 = glm::sin(T1);
+		T C1 = glm::cos(T1);
+		T T3 = glm::atan2<T, defaultp>(C1*M[0][1] - S1*M[0][0], C1*M[1][1] - S1*M[1][0]);
+		t1 = T1;
+		t2 = T2;
+		t3 = T3;
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER void extractEulerAngleZXZ(mat<4, 4, T, defaultp> const & M,
+												 T & t1,
+												 T & t2,
+												 T & t3)
+	{
+		T T1 = glm::atan2<T, defaultp>(M[2][0], -M[2][1]);
+		T S2 = glm::sqrt(M[0][2]*M[0][2] + M[1][2]*M[1][2]);
+		T T2 = glm::atan2<T, defaultp>(S2, M[2][2]);
+		T S1 = glm::sin(T1);
+		T C1 = glm::cos(T1);
+		T T3 = glm::atan2<T, defaultp>(-C1*M[1][0] - S1*M[1][1], C1*M[0][0] + S1*M[0][1]);
+		t1 = T1;
+		t2 = T2;
+		t3 = T3;
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER void extractEulerAngleXZY(mat<4, 4, T, defaultp> const & M,
+												 T & t1,
+												 T & t2,
+												 T & t3)
+	{
+		T T1 = glm::atan2<T, defaultp>(M[1][2], M[1][1]);
+		T C2 = glm::sqrt(M[0][0]*M[0][0] + M[2][0]*M[2][0]);
+		T T2 = glm::atan2<T, defaultp>(-M[1][0], C2);
+		T S1 = glm::sin(T1);
+		T C1 = glm::cos(T1);
+		T T3 = glm::atan2<T, defaultp>(S1*M[0][1] - C1*M[0][2], C1*M[2][2] - S1*M[2][1]);
+		t1 = T1;
+		t2 = T2;
+		t3 = T3;
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER void extractEulerAngleYZX(mat<4, 4, T, defaultp> const & M,
+												 T & t1,
+												 T & t2,
+												 T & t3)
+	{
+		T T1 = glm::atan2<T, defaultp>(-M[0][2], M[0][0]);
+		T C2 = glm::sqrt(M[1][1]*M[1][1] + M[2][1]*M[2][1]);
+		T T2 = glm::atan2<T, defaultp>(M[0][1], C2);
+		T S1 = glm::sin(T1);
+		T C1 = glm::cos(T1);
+		T T3 = glm::atan2<T, defaultp>(S1*M[1][0] + C1*M[1][2], S1*M[2][0] + C1*M[2][2]);
+		t1 = T1;
+		t2 = T2;
+		t3 = T3;
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER void extractEulerAngleZYX(mat<4, 4, T, defaultp> const & M,
+												 T & t1,
+												 T & t2,
+												 T & t3)
+	{
+		T T1 = glm::atan2<T, defaultp>(M[0][1], M[0][0]);
+		T C2 = glm::sqrt(M[1][2]*M[1][2] + M[2][2]*M[2][2]);
+		T T2 = glm::atan2<T, defaultp>(-M[0][2], C2);
+		T S1 = glm::sin(T1);
+		T C1 = glm::cos(T1);
+		T T3 = glm::atan2<T, defaultp>(S1*M[2][0] - C1*M[2][1], C1*M[1][1] - S1*M[1][0]);
+		t1 = T1;
+		t2 = T2;
+		t3 = T3;
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER void extractEulerAngleZXY(mat<4, 4, T, defaultp> const & M,
+												 T & t1,
+												 T & t2,
+												 T & t3)
+	{
+		T T1 = glm::atan2<T, defaultp>(-M[1][0], M[1][1]);
+		T C2 = glm::sqrt(M[0][2]*M[0][2] + M[2][2]*M[2][2]);
+		T T2 = glm::atan2<T, defaultp>(M[1][2], C2);
+		T S1 = glm::sin(T1);
+		T C1 = glm::cos(T1);
+		T T3 = glm::atan2<T, defaultp>(C1*M[2][0] + S1*M[2][1], C1*M[0][0] + S1*M[0][1]);
+		t1 = T1;
+		t2 = T2;
+		t3 = T3;
+	}
 }//namespace glm