Collection of DPF-based plugins for packaging
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

131 lines
4.3KB

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