Browse Source

Added GLM_GTX_matrix_interpolation extension

Christophe Riccio 14 years ago
parent
commit
58053e5b89
3 changed files with 192 additions and 0 deletions
  1. 1 0
      glm/ext.hpp
  2. 73 0
      glm/gtx/matrix_interpolation.hpp
  3. 118 0
      glm/gtx/matrix_interpolation.inl

+ 1 - 0
glm/ext.hpp

@@ -48,6 +48,7 @@
 #include "./gtx/intersect.hpp"
 #include "./gtx/intersect.hpp"
 #include "./gtx/log_base.hpp"
 #include "./gtx/log_base.hpp"
 #include "./gtx/matrix_cross_product.hpp"
 #include "./gtx/matrix_cross_product.hpp"
+#include "./gtx/matrix_interpolation.hpp"
 #include "./gtx/matrix_major_storage.hpp"
 #include "./gtx/matrix_major_storage.hpp"
 #include "./gtx/matrix_operation.hpp"
 #include "./gtx/matrix_operation.hpp"
 #include "./gtx/matrix_query.hpp"
 #include "./gtx/matrix_query.hpp"

+ 73 - 0
glm/gtx/matrix_interpolation.hpp

@@ -0,0 +1,73 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2011-03-05
+// Updated : 2011-03-05
+// Licence : This source is under MIT License
+// File    : glm/gtx/matrix_interpolation.hpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+// - GLM_GTX_matric_interpolation
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// This extension has been written by Ghenadii Ursachi ([email protected])
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef glm_gtx_matrix_interpolation
+#define glm_gtx_matrix_interpolation
+
+// Dependency:
+//#include "../glm.hpp"
+
+#if(defined(GLM_MESSAGES) && !defined(glm_ext))
+#	pragma message("GLM: GLM_GTX_matrix_interpolation extension included")
+#endif
+
+namespace glm
+{
+	namespace test{
+		void main_gtx_transform();
+	}//namespace test
+
+	namespace gtx{
+	//! GLM_GTX_matrix_interpolation extension: Add transformation matrices
+	namespace matrix_interpolation
+	{
+		/// \addtogroup gtx_matrix_interpolation
+		///@{
+
+		//! Get the axis and angle of the rotation from a matrix.
+        //! From GLM_GTX_matrix_interpolation extension.
+		template <typename T>
+        void axisAngle(
+            detail::tmat4x4<T> const & mat,
+            detail::tvec3<T> & axis,
+            T & angle);
+
+        //! Build a matrix from axis and angle.
+        //! From GLM_GTX_matrix_interpolation extension.
+		template <typename T>
+        detail::tmat4x4<T> axisAngleMatrix(
+            detail::tvec3<T> const & axis,
+            T const angle);
+
+		//! Build a interpolation of 4 * 4 matrixes.
+        //! From GLM_GTX_matrix_interpolation extension.
+        //! Warning! works only with rotation and/or translation matrixes, scale will generate unexpected results.
+		template <typename T>
+        detail::tmat4x4<T> interpolate(
+            detail::tmat4x4<T> const & m1,
+            detail::tmat4x4<T> const & m2,
+            T const delta);
+
+		///@}
+
+	}//namespace matrix_interpolation
+	}//namespace gtx
+}//namespace glm
+
+#include "matrix_interpolation.inl"
+
+namespace glm{using namespace gtx::matrix_interpolation;}
+
+#endif//glm_gtx_transform

+ 118 - 0
glm/gtx/matrix_interpolation.inl

@@ -0,0 +1,118 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2011-03-05
+// Updated : 2011-03-05
+// Licence : This source is under MIT License
+// File    : glm/gtx/matrix_interpolation.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm{
+namespace gtx{
+namespace matrix_interpolation
+{
+
+    template <typename T>
+    inline void axisAngle(
+        detail::tmat4x4<T> const & mat,
+        detail::tvec3<T> & axis,
+        T & angle)
+    {
+        T epsilon = (T)0.01;
+        T epsilon2 = (T)0.1;
+
+        if ((fabs(mat[1][0] - mat[0][1]) < epsilon) && (fabs(mat[2][0] - mat[0][2]) < epsilon) && (fabs(mat[2][1] - mat[1][2]) < epsilon)) {
+            if ((fabs(mat[1][0] + mat[0][1]) < epsilon2) && (fabs(mat[2][0] + mat[0][2]) < epsilon2) && (fabs(mat[2][1] + mat[1][2]) < epsilon2) && (fabs(mat[0][0] + mat[1][1] + mat[2][2] - (T)3.0) < epsilon2)) {
+                angle = (T)0.0;
+                axis.x = (T)1.0;
+                axis.y = (T)0.0;
+                axis.z = (T)0.0;
+                return;
+            }
+            angle = M_1_PI;
+            T xx = (mat[0][0] + (T)1.0) / (T)2.0;
+            T yy = (mat[1][1] + (T)1.0) / (T)2.0;
+            T zz = (mat[2][2] + (T)1.0) / (T)2.0;
+            T xy = (mat[1][0] + mat[0][1]) / (T)4.0;
+            T xz = (mat[2][0] + mat[0][2]) / (T)4.0;
+            T yz = (mat[2][1] + mat[1][2]) / (T)4.0;
+            if ((xx > yy) && (xx > zz)) {
+                if (xx < epsilon) {
+                    axis.x = (T)0.0;
+                    axis.y = (T)0.7071;
+                    axis.z = (T)0.7071;
+                } else {
+                    axis.x = sqrt(xx);
+                    axis.y = xy / axis.x;
+                    axis.z = xz / axis.x;
+                }
+            } else if (yy > zz) {
+                if (yy < epsilon) {
+                    axis.x = (T)0.7071;
+                    axis.y = (T)0.0;
+                    axis.z = (T)0.7071;
+                } else {
+                    axis.y = sqrt(yy);
+                    axis.x = xy / axis.y;
+                    axis.z = yz / axis.y;
+                }
+            } else {
+                if (zz < epsilon) {
+                    axis.x = (T)0.7071;
+                    axis.y = (T)0.7071;
+                    axis.z = (T)0.0;
+                } else {
+                    axis.z = sqrt(zz);
+                    axis.x = xz / axis.z;
+                    axis.y = yz / axis.z;
+                }
+            }
+            return;
+        }
+        T s = sqrt((mat[2][1] - mat[1][2]) * (mat[2][1] - mat[1][2]) + (mat[2][0] - mat[0][2]) * (mat[2][0] - mat[0][2]) + (mat[1][0] - mat[0][1]) * (mat[1][0] - mat[0][1]));
+        if (fabs(s) < 0.001)
+            s = (T)1.0;
+        angle = acos((mat[0][0] + mat[1][1] + mat[2][2] - (T)1.0) / (T)2.0);
+        axis.x = (mat[1][2] - mat[2][1]) / s;
+        axis.y = (mat[2][0] - mat[0][2]) / s;
+        axis.z = (mat[0][1] - mat[1][0]) / s;
+    }
+
+    template <typename T>
+    inline detail::tmat4x4<T> axisAngleMatrix(
+		detail::tvec3<T> const & axis,
+		T const angle)
+    {
+        T c = cos(angle);
+        T s = sin(angle);
+        T t = 1.0 - c;
+        detail::tvec3<T> n = normalize(axis);
+
+        return detail::tmat4x4<T>(
+            t * n.x * n.x + c,          t * n.x * n.y + n.z * s,    t * n.x * n.z - n.y * s,    0.0,
+            t * n.x * n.y - n.z * s,    t * n.y * n.y + c,          t * n.y * n.z + n.x * s,    0.0,
+            t * n.x * n.z + n.y * s,    t * n.y * n.z - n.x * s,    t * n.z * n.z + c,          0.0,
+            0.0,                        0.0,                        0.0,                        1.0
+        );
+    }
+
+    template <typename T>
+    inline detail::tmat4x4<T> interpolate(
+		detail::tmat4x4<T> const & m1,
+		detail::tmat4x4<T> const & m2,
+		T const delta)
+    {
+		detail::tmat4x4<T> dltRotation = m2 * transpose(m1);
+		detail::tvec3<T> dltAxis;
+		T dltAngle;
+		axisAngle(dltRotation, dltAxis, dltAngle);
+		detail::tmat4x4<T> out = axisAngleMatrix(dltAxis, dltAngle * delta) * rotationMatrix(m1);
+		out[3][0] = m1[3][0] + delta * (m2[3][0] - m1[3][0]);
+		out[3][1] = m1[3][1] + delta * (m2[3][1] - m1[3][1]);
+		out[3][2] = m1[3][2] + delta * (m2[3][2] - m1[3][2]);
+		return out;
+    }
+
+}//namespace transform
+}//namespace gtx
+}//namespace glm