/lib/ode/ode_source/OPCODE/Ice/IceMatrix4x4.cpp

http://narutortsproject.googlecode.com/ · C++ · 135 lines · 63 code · 16 blank · 56 comment · 1 complexity · 90595b10e8077df3cacb235d3f829d39 MD5 · raw file

  1. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2. /**
  3. * Contains code for 4x4 matrices.
  4. * \file IceMatrix4x4.cpp
  5. * \author Pierre Terdiman
  6. * \date April, 4, 2000
  7. */
  8. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  9. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  10. /**
  11. * 4x4 matrix.
  12. * DirectX-compliant, ie row-column order, ie m[Row][Col].
  13. * Same as:
  14. * m11 m12 m13 m14 first row.
  15. * m21 m22 m23 m24 second row.
  16. * m31 m32 m33 m34 third row.
  17. * m41 m42 m43 m44 fourth row.
  18. * Translation is (m41, m42, m43), (m14, m24, m34, m44) = (0, 0, 0, 1).
  19. * Stored in memory as m11 m12 m13 m14 m21...
  20. *
  21. * Multiplication rules:
  22. *
  23. * [x'y'z'1] = [xyz1][M]
  24. *
  25. * x' = x*m11 + y*m21 + z*m31 + m41
  26. * y' = x*m12 + y*m22 + z*m32 + m42
  27. * z' = x*m13 + y*m23 + z*m33 + m43
  28. * 1' = 0 + 0 + 0 + m44
  29. *
  30. * \class Matrix4x4
  31. * \author Pierre Terdiman
  32. * \version 1.0
  33. */
  34. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  35. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  36. // Precompiled Header
  37. #include "Stdafx.h"
  38. using namespace IceMaths;
  39. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  40. /**
  41. * Inverts a PR matrix. (which only contains a rotation and a translation)
  42. * This is faster and less subject to FPU errors than the generic inversion code.
  43. *
  44. * \relates Matrix4x4
  45. * \fn InvertPRMatrix(Matrix4x4& dest, const Matrix4x4& src)
  46. * \param dest [out] destination matrix
  47. * \param src [in] source matrix
  48. */
  49. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  50. ICEMATHS_API void IceMaths::InvertPRMatrix(Matrix4x4& dest, const Matrix4x4& src)
  51. {
  52. dest.m[0][0] = src.m[0][0];
  53. dest.m[1][0] = src.m[0][1];
  54. dest.m[2][0] = src.m[0][2];
  55. dest.m[3][0] = -(src.m[3][0]*src.m[0][0] + src.m[3][1]*src.m[0][1] + src.m[3][2]*src.m[0][2]);
  56. dest.m[0][1] = src.m[1][0];
  57. dest.m[1][1] = src.m[1][1];
  58. dest.m[2][1] = src.m[1][2];
  59. dest.m[3][1] = -(src.m[3][0]*src.m[1][0] + src.m[3][1]*src.m[1][1] + src.m[3][2]*src.m[1][2]);
  60. dest.m[0][2] = src.m[2][0];
  61. dest.m[1][2] = src.m[2][1];
  62. dest.m[2][2] = src.m[2][2];
  63. dest.m[3][2] = -(src.m[3][0]*src.m[2][0] + src.m[3][1]*src.m[2][1] + src.m[3][2]*src.m[2][2]);
  64. dest.m[0][3] = 0.0f;
  65. dest.m[1][3] = 0.0f;
  66. dest.m[2][3] = 0.0f;
  67. dest.m[3][3] = 1.0f;
  68. }
  69. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  70. // Compute the cofactor of the Matrix at a specified location
  71. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  72. float Matrix4x4::CoFactor(udword row, udword col) const
  73. {
  74. return (( m[(row+1)&3][(col+1)&3]*m[(row+2)&3][(col+2)&3]*m[(row+3)&3][(col+3)&3] +
  75. m[(row+1)&3][(col+2)&3]*m[(row+2)&3][(col+3)&3]*m[(row+3)&3][(col+1)&3] +
  76. m[(row+1)&3][(col+3)&3]*m[(row+2)&3][(col+1)&3]*m[(row+3)&3][(col+2)&3])
  77. - (m[(row+3)&3][(col+1)&3]*m[(row+2)&3][(col+2)&3]*m[(row+1)&3][(col+3)&3] +
  78. m[(row+3)&3][(col+2)&3]*m[(row+2)&3][(col+3)&3]*m[(row+1)&3][(col+1)&3] +
  79. m[(row+3)&3][(col+3)&3]*m[(row+2)&3][(col+1)&3]*m[(row+1)&3][(col+2)&3])) * ((row + col) & 1 ? -1.0f : +1.0f);
  80. }
  81. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  82. // Compute the determinant of the Matrix
  83. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  84. float Matrix4x4::Determinant() const
  85. {
  86. return m[0][0] * CoFactor(0, 0) +
  87. m[0][1] * CoFactor(0, 1) +
  88. m[0][2] * CoFactor(0, 2) +
  89. m[0][3] * CoFactor(0, 3);
  90. }
  91. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  92. // Compute the inverse of the matrix
  93. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  94. Matrix4x4& Matrix4x4::Invert()
  95. {
  96. float Det = Determinant();
  97. Matrix4x4 Temp;
  98. if(fabsf(Det) < MATRIX4X4_EPSILON)
  99. return *this; // The matrix is not invertible! Singular case!
  100. float IDet = 1.0f / Det;
  101. Temp.m[0][0] = CoFactor(0,0) * IDet;
  102. Temp.m[1][0] = CoFactor(0,1) * IDet;
  103. Temp.m[2][0] = CoFactor(0,2) * IDet;
  104. Temp.m[3][0] = CoFactor(0,3) * IDet;
  105. Temp.m[0][1] = CoFactor(1,0) * IDet;
  106. Temp.m[1][1] = CoFactor(1,1) * IDet;
  107. Temp.m[2][1] = CoFactor(1,2) * IDet;
  108. Temp.m[3][1] = CoFactor(1,3) * IDet;
  109. Temp.m[0][2] = CoFactor(2,0) * IDet;
  110. Temp.m[1][2] = CoFactor(2,1) * IDet;
  111. Temp.m[2][2] = CoFactor(2,2) * IDet;
  112. Temp.m[3][2] = CoFactor(2,3) * IDet;
  113. Temp.m[0][3] = CoFactor(3,0) * IDet;
  114. Temp.m[1][3] = CoFactor(3,1) * IDet;
  115. Temp.m[2][3] = CoFactor(3,2) * IDet;
  116. Temp.m[3][3] = CoFactor(3,3) * IDet;
  117. *this = Temp;
  118. return *this;
  119. }