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.2 KiB

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