math_matrix.h 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. /*
  2. ===========================================================================
  3. Copyright (C) 1999-2005 Id Software, Inc.
  4. This file is part of Quake III Arena source code.
  5. Quake III Arena source code is free software; you can redistribute it
  6. and/or modify it under the terms of the GNU General Public License as
  7. published by the Free Software Foundation; either version 2 of the License,
  8. or (at your option) any later version.
  9. Quake III Arena source code is distributed in the hope that it will be
  10. useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with Foobar; if not, write to the Free Software
  15. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16. ===========================================================================
  17. */
  18. #ifndef __MATH_MATRIX_H__
  19. #define __MATH_MATRIX_H__
  20. #include <string.h>
  21. #include "math_vector.h"
  22. #ifndef ID_INLINE
  23. #ifdef _WIN32
  24. #define ID_INLINE __inline
  25. #else
  26. #define ID_INLINE inline
  27. #endif
  28. #endif
  29. class quat_t;
  30. class angles_t;
  31. class mat3_t {
  32. public:
  33. idVec3_t mat[ 3 ];
  34. mat3_t();
  35. mat3_t( float src[ 3 ][ 3 ] );
  36. mat3_t( idVec3_t const &x, idVec3_t const &y, idVec3_t const &z );
  37. mat3_t( const float xx, const float xy, const float xz, const float yx, const float yy, const float yz, const float zx, const float zy, const float zz );
  38. friend void toMatrix( quat_t const &src, mat3_t &dst );
  39. friend void toMatrix( angles_t const &src, mat3_t &dst );
  40. friend void toMatrix( idVec3_t const &src, mat3_t &dst );
  41. idVec3_t operator[]( int index ) const;
  42. idVec3_t &operator[]( int index );
  43. idVec3_t operator*( const idVec3_t &vec ) const;
  44. mat3_t operator*( const mat3_t &a ) const;
  45. mat3_t operator*( float a ) const;
  46. mat3_t operator+( mat3_t const &a ) const;
  47. mat3_t operator-( mat3_t const &a ) const;
  48. friend idVec3_t operator*( const idVec3_t &vec, const mat3_t &mat );
  49. friend mat3_t operator*( float a, mat3_t const &b );
  50. mat3_t &operator*=( float a );
  51. mat3_t &operator+=( mat3_t const &a );
  52. mat3_t &operator-=( mat3_t const &a );
  53. void Clear( void );
  54. void ProjectVector( const idVec3_t &src, idVec3_t &dst ) const;
  55. void UnprojectVector( const idVec3_t &src, idVec3_t &dst ) const;
  56. void OrthoNormalize( void );
  57. void Transpose( mat3_t &matrix );
  58. void Transpose( void );
  59. mat3_t Inverse( void ) const;
  60. void Identity( void );
  61. friend void InverseMultiply( const mat3_t &inv, const mat3_t &b, mat3_t &dst );
  62. friend mat3_t SkewSymmetric( idVec3_t const &src );
  63. };
  64. ID_INLINE mat3_t::mat3_t() {
  65. }
  66. ID_INLINE mat3_t::mat3_t( float src[ 3 ][ 3 ] ) {
  67. memcpy( mat, src, sizeof( src ) );
  68. }
  69. ID_INLINE mat3_t::mat3_t( idVec3_t const &x, idVec3_t const &y, idVec3_t const &z ) {
  70. mat[ 0 ].x = x.x; mat[ 0 ].y = x.y; mat[ 0 ].z = x.z;
  71. mat[ 1 ].x = y.x; mat[ 1 ].y = y.y; mat[ 1 ].z = y.z;
  72. mat[ 2 ].x = z.x; mat[ 2 ].y = z.y; mat[ 2 ].z = z.z;
  73. }
  74. ID_INLINE mat3_t::mat3_t( const float xx, const float xy, const float xz, const float yx, const float yy, const float yz, const float zx, const float zy, const float zz ) {
  75. mat[ 0 ].x = xx; mat[ 0 ].y = xy; mat[ 0 ].z = xz;
  76. mat[ 1 ].x = yx; mat[ 1 ].y = yy; mat[ 1 ].z = yz;
  77. mat[ 2 ].x = zx; mat[ 2 ].y = zy; mat[ 2 ].z = zz;
  78. }
  79. ID_INLINE idVec3_t mat3_t::operator[]( int index ) const {
  80. assert( ( index >= 0 ) && ( index < 3 ) );
  81. return mat[ index ];
  82. }
  83. ID_INLINE idVec3_t& mat3_t::operator[]( int index ) {
  84. assert( ( index >= 0 ) && ( index < 3 ) );
  85. return mat[ index ];
  86. }
  87. ID_INLINE idVec3_t mat3_t::operator*( const idVec3_t &vec ) const {
  88. return idVec3_t(
  89. mat[ 0 ].x * vec.x + mat[ 1 ].x * vec.y + mat[ 2 ].x * vec.z,
  90. mat[ 0 ].y * vec.x + mat[ 1 ].y * vec.y + mat[ 2 ].y * vec.z,
  91. mat[ 0 ].z * vec.x + mat[ 1 ].z * vec.y + mat[ 2 ].z * vec.z );
  92. }
  93. ID_INLINE mat3_t mat3_t::operator*( const mat3_t &a ) const {
  94. return mat3_t(
  95. mat[0].x * a[0].x + mat[0].y * a[1].x + mat[0].z * a[2].x,
  96. mat[0].x * a[0].y + mat[0].y * a[1].y + mat[0].z * a[2].y,
  97. mat[0].x * a[0].z + mat[0].y * a[1].z + mat[0].z * a[2].z,
  98. mat[1].x * a[0].x + mat[1].y * a[1].x + mat[1].z * a[2].x,
  99. mat[1].x * a[0].y + mat[1].y * a[1].y + mat[1].z * a[2].y,
  100. mat[1].x * a[0].z + mat[1].y * a[1].z + mat[1].z * a[2].z,
  101. mat[2].x * a[0].x + mat[2].y * a[1].x + mat[2].z * a[2].x,
  102. mat[2].x * a[0].y + mat[2].y * a[1].y + mat[2].z * a[2].y,
  103. mat[2].x * a[0].z + mat[2].y * a[1].z + mat[2].z * a[2].z );
  104. }
  105. ID_INLINE mat3_t mat3_t::operator*( float a ) const {
  106. return mat3_t(
  107. mat[0].x * a, mat[0].y * a, mat[0].z * a,
  108. mat[1].x * a, mat[1].y * a, mat[1].z * a,
  109. mat[2].x * a, mat[2].y * a, mat[2].z * a );
  110. }
  111. ID_INLINE mat3_t mat3_t::operator+( mat3_t const &a ) const {
  112. return mat3_t(
  113. mat[0].x + a[0].x, mat[0].y + a[0].y, mat[0].z + a[0].z,
  114. mat[1].x + a[1].x, mat[1].y + a[1].y, mat[1].z + a[1].z,
  115. mat[2].x + a[2].x, mat[2].y + a[2].y, mat[2].z + a[2].z );
  116. }
  117. ID_INLINE mat3_t mat3_t::operator-( mat3_t const &a ) const {
  118. return mat3_t(
  119. mat[0].x - a[0].x, mat[0].y - a[0].y, mat[0].z - a[0].z,
  120. mat[1].x - a[1].x, mat[1].y - a[1].y, mat[1].z - a[1].z,
  121. mat[2].x - a[2].x, mat[2].y - a[2].y, mat[2].z - a[2].z );
  122. }
  123. ID_INLINE idVec3_t operator*( const idVec3_t &vec, const mat3_t &mat ) {
  124. return idVec3_t(
  125. mat[ 0 ].x * vec.x + mat[ 1 ].x * vec.y + mat[ 2 ].x * vec.z,
  126. mat[ 0 ].y * vec.x + mat[ 1 ].y * vec.y + mat[ 2 ].y * vec.z,
  127. mat[ 0 ].z * vec.x + mat[ 1 ].z * vec.y + mat[ 2 ].z * vec.z );
  128. }
  129. ID_INLINE mat3_t operator*( float a, mat3_t const &b ) {
  130. return mat3_t(
  131. b[0].x * a, b[0].y * a, b[0].z * a,
  132. b[1].x * a, b[1].y * a, b[1].z * a,
  133. b[2].x * a, b[2].y * a, b[2].z * a );
  134. }
  135. ID_INLINE mat3_t &mat3_t::operator*=( float a ) {
  136. mat[0].x *= a; mat[0].y *= a; mat[0].z *= a;
  137. mat[1].x *= a; mat[1].y *= a; mat[1].z *= a;
  138. mat[2].x *= a; mat[2].y *= a; mat[2].z *= a;
  139. return *this;
  140. }
  141. ID_INLINE mat3_t &mat3_t::operator+=( mat3_t const &a ) {
  142. mat[0].x += a[0].x; mat[0].y += a[0].y; mat[0].z += a[0].z;
  143. mat[1].x += a[1].x; mat[1].y += a[1].y; mat[1].z += a[1].z;
  144. mat[2].x += a[2].x; mat[2].y += a[2].y; mat[2].z += a[2].z;
  145. return *this;
  146. }
  147. ID_INLINE mat3_t &mat3_t::operator-=( mat3_t const &a ) {
  148. mat[0].x -= a[0].x; mat[0].y -= a[0].y; mat[0].z -= a[0].z;
  149. mat[1].x -= a[1].x; mat[1].y -= a[1].y; mat[1].z -= a[1].z;
  150. mat[2].x -= a[2].x; mat[2].y -= a[2].y; mat[2].z -= a[2].z;
  151. return *this;
  152. }
  153. ID_INLINE void mat3_t::OrthoNormalize( void ) {
  154. mat[ 0 ].Normalize();
  155. mat[ 2 ].Cross( mat[ 0 ], mat[ 1 ] );
  156. mat[ 2 ].Normalize();
  157. mat[ 1 ].Cross( mat[ 2 ], mat[ 0 ] );
  158. mat[ 1 ].Normalize();
  159. }
  160. ID_INLINE void mat3_t::Identity( void ) {
  161. mat[ 0 ].x = 1.f; mat[ 0 ].y = 0.f; mat[ 0 ].z = 0.f;
  162. mat[ 1 ].x = 0.f; mat[ 1 ].y = 1.f; mat[ 1 ].z = 0.f;
  163. mat[ 2 ].x = 0.f; mat[ 2 ].y = 0.f; mat[ 2 ].z = 1.f;
  164. }
  165. ID_INLINE void InverseMultiply( const mat3_t &inv, const mat3_t &b, mat3_t &dst ) {
  166. dst[0].x = inv[0].x * b[0].x + inv[1].x * b[1].x + inv[2].x * b[2].x;
  167. dst[0].y = inv[0].x * b[0].y + inv[1].x * b[1].y + inv[2].x * b[2].y;
  168. dst[0].z = inv[0].x * b[0].z + inv[1].x * b[1].z + inv[2].x * b[2].z;
  169. dst[1].x = inv[0].y * b[0].x + inv[1].y * b[1].x + inv[2].y * b[2].x;
  170. dst[1].y = inv[0].y * b[0].y + inv[1].y * b[1].y + inv[2].y * b[2].y;
  171. dst[1].z = inv[0].y * b[0].z + inv[1].y * b[1].z + inv[2].y * b[2].z;
  172. dst[2].x = inv[0].z * b[0].x + inv[1].z * b[1].x + inv[2].z * b[2].x;
  173. dst[2].y = inv[0].z * b[0].y + inv[1].z * b[1].y + inv[2].z * b[2].y;
  174. dst[2].z = inv[0].z * b[0].z + inv[1].z * b[1].z + inv[2].z * b[2].z;
  175. }
  176. ID_INLINE mat3_t SkewSymmetric( idVec3_t const &src ) {
  177. return mat3_t( 0.0f, -src.z, src.y, src.z, 0.0f, -src.x, -src.y, src.x, 0.0f );
  178. }
  179. extern mat3_t mat3_default;
  180. #endif /* !__MATH_MATRIX_H__ */