1/// @ref gtx_matrix_interpolation 2/// @file glm/gtx/matrix_interpolation.hpp 3 4namespace glm 5{ 6 template <typename T, precision P> 7 GLM_FUNC_QUALIFIER void axisAngle 8 ( 9 tmat4x4<T, P> const & mat, 10 tvec3<T, P> & axis, 11 T & angle 12 ) 13 { 14 T epsilon = (T)0.01; 15 T epsilon2 = (T)0.1; 16 17 if((abs(mat[1][0] - mat[0][1]) < epsilon) && (abs(mat[2][0] - mat[0][2]) < epsilon) && (abs(mat[2][1] - mat[1][2]) < epsilon)) 18 { 19 if ((abs(mat[1][0] + mat[0][1]) < epsilon2) && (abs(mat[2][0] + mat[0][2]) < epsilon2) && (abs(mat[2][1] + mat[1][2]) < epsilon2) && (abs(mat[0][0] + mat[1][1] + mat[2][2] - (T)3.0) < epsilon2)) 20 { 21 angle = (T)0.0; 22 axis.x = (T)1.0; 23 axis.y = (T)0.0; 24 axis.z = (T)0.0; 25 return; 26 } 27 angle = static_cast<T>(3.1415926535897932384626433832795); 28 T xx = (mat[0][0] + (T)1.0) / (T)2.0; 29 T yy = (mat[1][1] + (T)1.0) / (T)2.0; 30 T zz = (mat[2][2] + (T)1.0) / (T)2.0; 31 T xy = (mat[1][0] + mat[0][1]) / (T)4.0; 32 T xz = (mat[2][0] + mat[0][2]) / (T)4.0; 33 T yz = (mat[2][1] + mat[1][2]) / (T)4.0; 34 if((xx > yy) && (xx > zz)) 35 { 36 if (xx < epsilon) { 37 axis.x = (T)0.0; 38 axis.y = (T)0.7071; 39 axis.z = (T)0.7071; 40 } else { 41 axis.x = sqrt(xx); 42 axis.y = xy / axis.x; 43 axis.z = xz / axis.x; 44 } 45 } 46 else if (yy > zz) 47 { 48 if (yy < epsilon) { 49 axis.x = (T)0.7071; 50 axis.y = (T)0.0; 51 axis.z = (T)0.7071; 52 } else { 53 axis.y = sqrt(yy); 54 axis.x = xy / axis.y; 55 axis.z = yz / axis.y; 56 } 57 } 58 else 59 { 60 if (zz < epsilon) { 61 axis.x = (T)0.7071; 62 axis.y = (T)0.7071; 63 axis.z = (T)0.0; 64 } else { 65 axis.z = sqrt(zz); 66 axis.x = xz / axis.z; 67 axis.y = yz / axis.z; 68 } 69 } 70 return; 71 } 72 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])); 73 if (glm::abs(s) < T(0.001)) 74 s = (T)1.0; 75 angle = acos((mat[0][0] + mat[1][1] + mat[2][2] - (T)1.0) / (T)2.0); 76 axis.x = (mat[1][2] - mat[2][1]) / s; 77 axis.y = (mat[2][0] - mat[0][2]) / s; 78 axis.z = (mat[0][1] - mat[1][0]) / s; 79 } 80 81 template <typename T, precision P> 82 GLM_FUNC_QUALIFIER tmat4x4<T, P> axisAngleMatrix 83 ( 84 tvec3<T, P> const & axis, 85 T const angle 86 ) 87 { 88 T c = cos(angle); 89 T s = sin(angle); 90 T t = static_cast<T>(1) - c; 91 tvec3<T, P> n = normalize(axis); 92 93 return tmat4x4<T, P>( 94 t * n.x * n.x + c, t * n.x * n.y + n.z * s, t * n.x * n.z - n.y * s, T(0), 95 t * n.x * n.y - n.z * s, t * n.y * n.y + c, t * n.y * n.z + n.x * s, T(0), 96 t * n.x * n.z + n.y * s, t * n.y * n.z - n.x * s, t * n.z * n.z + c, T(0), 97 T(0), T(0), T(0), T(1) 98 ); 99 } 100 101 template <typename T, precision P> 102 GLM_FUNC_QUALIFIER tmat4x4<T, P> extractMatrixRotation 103 ( 104 tmat4x4<T, P> const & mat 105 ) 106 { 107 return tmat4x4<T, P>( 108 mat[0][0], mat[0][1], mat[0][2], 0.0, 109 mat[1][0], mat[1][1], mat[1][2], 0.0, 110 mat[2][0], mat[2][1], mat[2][2], 0.0, 111 0.0, 0.0, 0.0, 1.0 112 ); 113 } 114 115 template <typename T, precision P> 116 GLM_FUNC_QUALIFIER tmat4x4<T, P> interpolate 117 ( 118 tmat4x4<T, P> const & m1, 119 tmat4x4<T, P> const & m2, 120 T const delta 121 ) 122 { 123 tmat4x4<T, P> m1rot = extractMatrixRotation(m1); 124 tmat4x4<T, P> dltRotation = m2 * transpose(m1rot); 125 tvec3<T, P> dltAxis; 126 T dltAngle; 127 axisAngle(dltRotation, dltAxis, dltAngle); 128 tmat4x4<T, P> out = axisAngleMatrix(dltAxis, dltAngle * delta) * m1rot; 129 out[3][0] = m1[3][0] + delta * (m2[3][0] - m1[3][0]); 130 out[3][1] = m1[3][1] + delta * (m2[3][1] - m1[3][1]); 131 out[3][2] = m1[3][2] + delta * (m2[3][2] - m1[3][2]); 132 return out; 133 } 134}//namespace glm 135