/lib/ode/ode_source/OPCODE/Ice/IceMatrix3x3.h

http://narutortsproject.googlecode.com/ · C++ Header · 496 lines · 333 code · 67 blank · 96 comment · 14 complexity · d02cae97add75928ae7740b575351fcc MD5 · raw file

  1. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2. /**
  3. * Contains code for 3x3 matrices.
  4. * \file IceMatrix3x3.h
  5. * \author Pierre Terdiman
  6. * \date April, 4, 2000
  7. */
  8. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  9. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  10. // Include Guard
  11. #ifndef __ICEMATRIX3X3_H__
  12. #define __ICEMATRIX3X3_H__
  13. // Forward declarations
  14. class Quat;
  15. #define MATRIX3X3_EPSILON (1.0e-7f)
  16. class ICEMATHS_API Matrix3x3
  17. {
  18. public:
  19. //! Empty constructor
  20. inline_ Matrix3x3() {}
  21. //! Constructor from 9 values
  22. inline_ Matrix3x3(float m00, float m01, float m02, float m10, float m11, float m12, float m20, float m21, float m22)
  23. {
  24. m[0][0] = m00; m[0][1] = m01; m[0][2] = m02;
  25. m[1][0] = m10; m[1][1] = m11; m[1][2] = m12;
  26. m[2][0] = m20; m[2][1] = m21; m[2][2] = m22;
  27. }
  28. //! Copy constructor
  29. inline_ Matrix3x3(const Matrix3x3& mat) { CopyMemory(m, &mat.m, 9*sizeof(float)); }
  30. //! Destructor
  31. inline_ ~Matrix3x3() {}
  32. //! Assign values
  33. inline_ void Set(float m00, float m01, float m02, float m10, float m11, float m12, float m20, float m21, float m22)
  34. {
  35. m[0][0] = m00; m[0][1] = m01; m[0][2] = m02;
  36. m[1][0] = m10; m[1][1] = m11; m[1][2] = m12;
  37. m[2][0] = m20; m[2][1] = m21; m[2][2] = m22;
  38. }
  39. //! Sets the scale from a Point. The point is put on the diagonal.
  40. inline_ void SetScale(const Point& p) { m[0][0] = p.x; m[1][1] = p.y; m[2][2] = p.z; }
  41. //! Sets the scale from floats. Values are put on the diagonal.
  42. inline_ void SetScale(float sx, float sy, float sz) { m[0][0] = sx; m[1][1] = sy; m[2][2] = sz; }
  43. //! Scales from a Point. Each row is multiplied by a component.
  44. inline_ void Scale(const Point& p)
  45. {
  46. m[0][0] *= p.x; m[0][1] *= p.x; m[0][2] *= p.x;
  47. m[1][0] *= p.y; m[1][1] *= p.y; m[1][2] *= p.y;
  48. m[2][0] *= p.z; m[2][1] *= p.z; m[2][2] *= p.z;
  49. }
  50. //! Scales from floats. Each row is multiplied by a value.
  51. inline_ void Scale(float sx, float sy, float sz)
  52. {
  53. m[0][0] *= sx; m[0][1] *= sx; m[0][2] *= sx;
  54. m[1][0] *= sy; m[1][1] *= sy; m[1][2] *= sy;
  55. m[2][0] *= sz; m[2][1] *= sz; m[2][2] *= sz;
  56. }
  57. //! Copy from a Matrix3x3
  58. inline_ void Copy(const Matrix3x3& source) { CopyMemory(m, source.m, 9*sizeof(float)); }
  59. // Row-column access
  60. //! Returns a row.
  61. inline_ void GetRow(const udword r, Point& p) const { p.x = m[r][0]; p.y = m[r][1]; p.z = m[r][2]; }
  62. //! Returns a row.
  63. inline_ const Point& GetRow(const udword r) const { return *(const Point*)&m[r][0]; }
  64. //! Returns a row.
  65. inline_ Point& GetRow(const udword r) { return *(Point*)&m[r][0]; }
  66. //! Sets a row.
  67. inline_ void SetRow(const udword r, const Point& p) { m[r][0] = p.x; m[r][1] = p.y; m[r][2] = p.z; }
  68. //! Returns a column.
  69. inline_ void GetCol(const udword c, Point& p) const { p.x = m[0][c]; p.y = m[1][c]; p.z = m[2][c]; }
  70. //! Sets a column.
  71. inline_ void SetCol(const udword c, const Point& p) { m[0][c] = p.x; m[1][c] = p.y; m[2][c] = p.z; }
  72. //! Computes the trace. The trace is the sum of the 3 diagonal components.
  73. inline_ float Trace() const { return m[0][0] + m[1][1] + m[2][2]; }
  74. //! Clears the matrix.
  75. inline_ void Zero() { ZeroMemory(&m, sizeof(m)); }
  76. //! Sets the identity matrix.
  77. inline_ void Identity() { Zero(); m[0][0] = m[1][1] = m[2][2] = 1.0f; }
  78. //! Checks for identity
  79. inline_ bool IsIdentity() const
  80. {
  81. if(IR(m[0][0])!=IEEE_1_0) return false;
  82. if(IR(m[0][1])!=0) return false;
  83. if(IR(m[0][2])!=0) return false;
  84. if(IR(m[1][0])!=0) return false;
  85. if(IR(m[1][1])!=IEEE_1_0) return false;
  86. if(IR(m[1][2])!=0) return false;
  87. if(IR(m[2][0])!=0) return false;
  88. if(IR(m[2][1])!=0) return false;
  89. if(IR(m[2][2])!=IEEE_1_0) return false;
  90. return true;
  91. }
  92. //! Checks matrix validity
  93. inline_ BOOL IsValid() const
  94. {
  95. for(udword j=0;j<3;j++)
  96. {
  97. for(udword i=0;i<3;i++)
  98. {
  99. if(!IsValidFloat(m[j][i])) return FALSE;
  100. }
  101. }
  102. return TRUE;
  103. }
  104. //! Makes a skew-symmetric matrix (a.k.a. Star(*) Matrix)
  105. //! [ 0.0 -a.z a.y ]
  106. //! [ a.z 0.0 -a.x ]
  107. //! [ -a.y a.x 0.0 ]
  108. //! This is also called a "cross matrix" since for any vectors A and B,
  109. //! A^B = Skew(A) * B = - B * Skew(A);
  110. inline_ void SkewSymmetric(const Point& a)
  111. {
  112. m[0][0] = 0.0f;
  113. m[0][1] = -a.z;
  114. m[0][2] = a.y;
  115. m[1][0] = a.z;
  116. m[1][1] = 0.0f;
  117. m[1][2] = -a.x;
  118. m[2][0] = -a.y;
  119. m[2][1] = a.x;
  120. m[2][2] = 0.0f;
  121. }
  122. //! Negates the matrix
  123. inline_ void Neg()
  124. {
  125. m[0][0] = -m[0][0]; m[0][1] = -m[0][1]; m[0][2] = -m[0][2];
  126. m[1][0] = -m[1][0]; m[1][1] = -m[1][1]; m[1][2] = -m[1][2];
  127. m[2][0] = -m[2][0]; m[2][1] = -m[2][1]; m[2][2] = -m[2][2];
  128. }
  129. //! Neg from another matrix
  130. inline_ void Neg(const Matrix3x3& mat)
  131. {
  132. m[0][0] = -mat.m[0][0]; m[0][1] = -mat.m[0][1]; m[0][2] = -mat.m[0][2];
  133. m[1][0] = -mat.m[1][0]; m[1][1] = -mat.m[1][1]; m[1][2] = -mat.m[1][2];
  134. m[2][0] = -mat.m[2][0]; m[2][1] = -mat.m[2][1]; m[2][2] = -mat.m[2][2];
  135. }
  136. //! Add another matrix
  137. inline_ void Add(const Matrix3x3& mat)
  138. {
  139. m[0][0] += mat.m[0][0]; m[0][1] += mat.m[0][1]; m[0][2] += mat.m[0][2];
  140. m[1][0] += mat.m[1][0]; m[1][1] += mat.m[1][1]; m[1][2] += mat.m[1][2];
  141. m[2][0] += mat.m[2][0]; m[2][1] += mat.m[2][1]; m[2][2] += mat.m[2][2];
  142. }
  143. //! Sub another matrix
  144. inline_ void Sub(const Matrix3x3& mat)
  145. {
  146. m[0][0] -= mat.m[0][0]; m[0][1] -= mat.m[0][1]; m[0][2] -= mat.m[0][2];
  147. m[1][0] -= mat.m[1][0]; m[1][1] -= mat.m[1][1]; m[1][2] -= mat.m[1][2];
  148. m[2][0] -= mat.m[2][0]; m[2][1] -= mat.m[2][1]; m[2][2] -= mat.m[2][2];
  149. }
  150. //! Mac
  151. inline_ void Mac(const Matrix3x3& a, const Matrix3x3& b, float s)
  152. {
  153. m[0][0] = a.m[0][0] + b.m[0][0] * s;
  154. m[0][1] = a.m[0][1] + b.m[0][1] * s;
  155. m[0][2] = a.m[0][2] + b.m[0][2] * s;
  156. m[1][0] = a.m[1][0] + b.m[1][0] * s;
  157. m[1][1] = a.m[1][1] + b.m[1][1] * s;
  158. m[1][2] = a.m[1][2] + b.m[1][2] * s;
  159. m[2][0] = a.m[2][0] + b.m[2][0] * s;
  160. m[2][1] = a.m[2][1] + b.m[2][1] * s;
  161. m[2][2] = a.m[2][2] + b.m[2][2] * s;
  162. }
  163. //! Mac
  164. inline_ void Mac(const Matrix3x3& a, float s)
  165. {
  166. m[0][0] += a.m[0][0] * s; m[0][1] += a.m[0][1] * s; m[0][2] += a.m[0][2] * s;
  167. m[1][0] += a.m[1][0] * s; m[1][1] += a.m[1][1] * s; m[1][2] += a.m[1][2] * s;
  168. m[2][0] += a.m[2][0] * s; m[2][1] += a.m[2][1] * s; m[2][2] += a.m[2][2] * s;
  169. }
  170. //! this = A * s
  171. inline_ void Mult(const Matrix3x3& a, float s)
  172. {
  173. m[0][0] = a.m[0][0] * s; m[0][1] = a.m[0][1] * s; m[0][2] = a.m[0][2] * s;
  174. m[1][0] = a.m[1][0] * s; m[1][1] = a.m[1][1] * s; m[1][2] = a.m[1][2] * s;
  175. m[2][0] = a.m[2][0] * s; m[2][1] = a.m[2][1] * s; m[2][2] = a.m[2][2] * s;
  176. }
  177. inline_ void Add(const Matrix3x3& a, const Matrix3x3& b)
  178. {
  179. m[0][0] = a.m[0][0] + b.m[0][0]; m[0][1] = a.m[0][1] + b.m[0][1]; m[0][2] = a.m[0][2] + b.m[0][2];
  180. m[1][0] = a.m[1][0] + b.m[1][0]; m[1][1] = a.m[1][1] + b.m[1][1]; m[1][2] = a.m[1][2] + b.m[1][2];
  181. m[2][0] = a.m[2][0] + b.m[2][0]; m[2][1] = a.m[2][1] + b.m[2][1]; m[2][2] = a.m[2][2] + b.m[2][2];
  182. }
  183. inline_ void Sub(const Matrix3x3& a, const Matrix3x3& b)
  184. {
  185. m[0][0] = a.m[0][0] - b.m[0][0]; m[0][1] = a.m[0][1] - b.m[0][1]; m[0][2] = a.m[0][2] - b.m[0][2];
  186. m[1][0] = a.m[1][0] - b.m[1][0]; m[1][1] = a.m[1][1] - b.m[1][1]; m[1][2] = a.m[1][2] - b.m[1][2];
  187. m[2][0] = a.m[2][0] - b.m[2][0]; m[2][1] = a.m[2][1] - b.m[2][1]; m[2][2] = a.m[2][2] - b.m[2][2];
  188. }
  189. //! this = a * b
  190. inline_ void Mult(const Matrix3x3& a, const Matrix3x3& b)
  191. {
  192. m[0][0] = a.m[0][0] * b.m[0][0] + a.m[0][1] * b.m[1][0] + a.m[0][2] * b.m[2][0];
  193. m[0][1] = a.m[0][0] * b.m[0][1] + a.m[0][1] * b.m[1][1] + a.m[0][2] * b.m[2][1];
  194. m[0][2] = a.m[0][0] * b.m[0][2] + a.m[0][1] * b.m[1][2] + a.m[0][2] * b.m[2][2];
  195. m[1][0] = a.m[1][0] * b.m[0][0] + a.m[1][1] * b.m[1][0] + a.m[1][2] * b.m[2][0];
  196. m[1][1] = a.m[1][0] * b.m[0][1] + a.m[1][1] * b.m[1][1] + a.m[1][2] * b.m[2][1];
  197. m[1][2] = a.m[1][0] * b.m[0][2] + a.m[1][1] * b.m[1][2] + a.m[1][2] * b.m[2][2];
  198. m[2][0] = a.m[2][0] * b.m[0][0] + a.m[2][1] * b.m[1][0] + a.m[2][2] * b.m[2][0];
  199. m[2][1] = a.m[2][0] * b.m[0][1] + a.m[2][1] * b.m[1][1] + a.m[2][2] * b.m[2][1];
  200. m[2][2] = a.m[2][0] * b.m[0][2] + a.m[2][1] * b.m[1][2] + a.m[2][2] * b.m[2][2];
  201. }
  202. //! this = transpose(a) * b
  203. inline_ void MultAtB(const Matrix3x3& a, const Matrix3x3& b)
  204. {
  205. m[0][0] = a.m[0][0] * b.m[0][0] + a.m[1][0] * b.m[1][0] + a.m[2][0] * b.m[2][0];
  206. m[0][1] = a.m[0][0] * b.m[0][1] + a.m[1][0] * b.m[1][1] + a.m[2][0] * b.m[2][1];
  207. m[0][2] = a.m[0][0] * b.m[0][2] + a.m[1][0] * b.m[1][2] + a.m[2][0] * b.m[2][2];
  208. m[1][0] = a.m[0][1] * b.m[0][0] + a.m[1][1] * b.m[1][0] + a.m[2][1] * b.m[2][0];
  209. m[1][1] = a.m[0][1] * b.m[0][1] + a.m[1][1] * b.m[1][1] + a.m[2][1] * b.m[2][1];
  210. m[1][2] = a.m[0][1] * b.m[0][2] + a.m[1][1] * b.m[1][2] + a.m[2][1] * b.m[2][2];
  211. m[2][0] = a.m[0][2] * b.m[0][0] + a.m[1][2] * b.m[1][0] + a.m[2][2] * b.m[2][0];
  212. m[2][1] = a.m[0][2] * b.m[0][1] + a.m[1][2] * b.m[1][1] + a.m[2][2] * b.m[2][1];
  213. m[2][2] = a.m[0][2] * b.m[0][2] + a.m[1][2] * b.m[1][2] + a.m[2][2] * b.m[2][2];
  214. }
  215. //! this = a * transpose(b)
  216. inline_ void MultABt(const Matrix3x3& a, const Matrix3x3& b)
  217. {
  218. m[0][0] = a.m[0][0] * b.m[0][0] + a.m[0][1] * b.m[0][1] + a.m[0][2] * b.m[0][2];
  219. m[0][1] = a.m[0][0] * b.m[1][0] + a.m[0][1] * b.m[1][1] + a.m[0][2] * b.m[1][2];
  220. m[0][2] = a.m[0][0] * b.m[2][0] + a.m[0][1] * b.m[2][1] + a.m[0][2] * b.m[2][2];
  221. m[1][0] = a.m[1][0] * b.m[0][0] + a.m[1][1] * b.m[0][1] + a.m[1][2] * b.m[0][2];
  222. m[1][1] = a.m[1][0] * b.m[1][0] + a.m[1][1] * b.m[1][1] + a.m[1][2] * b.m[1][2];
  223. m[1][2] = a.m[1][0] * b.m[2][0] + a.m[1][1] * b.m[2][1] + a.m[1][2] * b.m[2][2];
  224. m[2][0] = a.m[2][0] * b.m[0][0] + a.m[2][1] * b.m[0][1] + a.m[2][2] * b.m[0][2];
  225. m[2][1] = a.m[2][0] * b.m[1][0] + a.m[2][1] * b.m[1][1] + a.m[2][2] * b.m[1][2];
  226. m[2][2] = a.m[2][0] * b.m[2][0] + a.m[2][1] * b.m[2][1] + a.m[2][2] * b.m[2][2];
  227. }
  228. //! Makes a rotation matrix mapping vector "from" to vector "to".
  229. Matrix3x3& FromTo(const Point& from, const Point& to);
  230. //! Set a rotation matrix around the X axis.
  231. //! 1 0 0
  232. //! RX = 0 cx sx
  233. //! 0 -sx cx
  234. void RotX(float angle);
  235. //! Set a rotation matrix around the Y axis.
  236. //! cy 0 -sy
  237. //! RY = 0 1 0
  238. //! sy 0 cy
  239. void RotY(float angle);
  240. //! Set a rotation matrix around the Z axis.
  241. //! cz sz 0
  242. //! RZ = -sz cz 0
  243. //! 0 0 1
  244. void RotZ(float angle);
  245. //! cy sx.sy -sy.cx
  246. //! RY.RX 0 cx sx
  247. //! sy -sx.cy cx.cy
  248. void RotYX(float y, float x);
  249. //! Make a rotation matrix about an arbitrary axis
  250. Matrix3x3& Rot(float angle, const Point& axis);
  251. //! Transpose the matrix.
  252. void Transpose()
  253. {
  254. IR(m[1][0]) ^= IR(m[0][1]); IR(m[0][1]) ^= IR(m[1][0]); IR(m[1][0]) ^= IR(m[0][1]);
  255. IR(m[2][0]) ^= IR(m[0][2]); IR(m[0][2]) ^= IR(m[2][0]); IR(m[2][0]) ^= IR(m[0][2]);
  256. IR(m[2][1]) ^= IR(m[1][2]); IR(m[1][2]) ^= IR(m[2][1]); IR(m[2][1]) ^= IR(m[1][2]);
  257. }
  258. //! this = Transpose(a)
  259. void Transpose(const Matrix3x3& a)
  260. {
  261. m[0][0] = a.m[0][0]; m[0][1] = a.m[1][0]; m[0][2] = a.m[2][0];
  262. m[1][0] = a.m[0][1]; m[1][1] = a.m[1][1]; m[1][2] = a.m[2][1];
  263. m[2][0] = a.m[0][2]; m[2][1] = a.m[1][2]; m[2][2] = a.m[2][2];
  264. }
  265. //! Compute the determinant of the matrix. We use the rule of Sarrus.
  266. float Determinant() const
  267. {
  268. return (m[0][0]*m[1][1]*m[2][2] + m[0][1]*m[1][2]*m[2][0] + m[0][2]*m[1][0]*m[2][1])
  269. - (m[2][0]*m[1][1]*m[0][2] + m[2][1]*m[1][2]*m[0][0] + m[2][2]*m[1][0]*m[0][1]);
  270. }
  271. /*
  272. //! Compute a cofactor. Used for matrix inversion.
  273. float CoFactor(ubyte row, ubyte column) const
  274. {
  275. static const sdword gIndex[3+2] = { 0, 1, 2, 0, 1 };
  276. return (m[gIndex[row+1]][gIndex[column+1]]*m[gIndex[row+2]][gIndex[column+2]] - m[gIndex[row+2]][gIndex[column+1]]*m[gIndex[row+1]][gIndex[column+2]]);
  277. }
  278. */
  279. //! Invert the matrix. Determinant must be different from zero, else matrix can't be inverted.
  280. Matrix3x3& Invert()
  281. {
  282. float Det = Determinant(); // Must be !=0
  283. float OneOverDet = 1.0f / Det;
  284. Matrix3x3 Temp;
  285. Temp.m[0][0] = +(m[1][1] * m[2][2] - m[2][1] * m[1][2]) * OneOverDet;
  286. Temp.m[1][0] = -(m[1][0] * m[2][2] - m[2][0] * m[1][2]) * OneOverDet;
  287. Temp.m[2][0] = +(m[1][0] * m[2][1] - m[2][0] * m[1][1]) * OneOverDet;
  288. Temp.m[0][1] = -(m[0][1] * m[2][2] - m[2][1] * m[0][2]) * OneOverDet;
  289. Temp.m[1][1] = +(m[0][0] * m[2][2] - m[2][0] * m[0][2]) * OneOverDet;
  290. Temp.m[2][1] = -(m[0][0] * m[2][1] - m[2][0] * m[0][1]) * OneOverDet;
  291. Temp.m[0][2] = +(m[0][1] * m[1][2] - m[1][1] * m[0][2]) * OneOverDet;
  292. Temp.m[1][2] = -(m[0][0] * m[1][2] - m[1][0] * m[0][2]) * OneOverDet;
  293. Temp.m[2][2] = +(m[0][0] * m[1][1] - m[1][0] * m[0][1]) * OneOverDet;
  294. *this = Temp;
  295. return *this;
  296. }
  297. Matrix3x3& Normalize();
  298. //! this = exp(a)
  299. Matrix3x3& Exp(const Matrix3x3& a);
  300. void FromQuat(const Quat &q);
  301. void FromQuatL2(const Quat &q, float l2);
  302. // Arithmetic operators
  303. //! Operator for Matrix3x3 Plus = Matrix3x3 + Matrix3x3;
  304. inline_ Matrix3x3 operator+(const Matrix3x3& mat) const
  305. {
  306. return Matrix3x3(
  307. m[0][0] + mat.m[0][0], m[0][1] + mat.m[0][1], m[0][2] + mat.m[0][2],
  308. m[1][0] + mat.m[1][0], m[1][1] + mat.m[1][1], m[1][2] + mat.m[1][2],
  309. m[2][0] + mat.m[2][0], m[2][1] + mat.m[2][1], m[2][2] + mat.m[2][2]);
  310. }
  311. //! Operator for Matrix3x3 Minus = Matrix3x3 - Matrix3x3;
  312. inline_ Matrix3x3 operator-(const Matrix3x3& mat) const
  313. {
  314. return Matrix3x3(
  315. m[0][0] - mat.m[0][0], m[0][1] - mat.m[0][1], m[0][2] - mat.m[0][2],
  316. m[1][0] - mat.m[1][0], m[1][1] - mat.m[1][1], m[1][2] - mat.m[1][2],
  317. m[2][0] - mat.m[2][0], m[2][1] - mat.m[2][1], m[2][2] - mat.m[2][2]);
  318. }
  319. //! Operator for Matrix3x3 Mul = Matrix3x3 * Matrix3x3;
  320. inline_ Matrix3x3 operator*(const Matrix3x3& mat) const
  321. {
  322. return Matrix3x3(
  323. m[0][0]*mat.m[0][0] + m[0][1]*mat.m[1][0] + m[0][2]*mat.m[2][0],
  324. m[0][0]*mat.m[0][1] + m[0][1]*mat.m[1][1] + m[0][2]*mat.m[2][1],
  325. m[0][0]*mat.m[0][2] + m[0][1]*mat.m[1][2] + m[0][2]*mat.m[2][2],
  326. m[1][0]*mat.m[0][0] + m[1][1]*mat.m[1][0] + m[1][2]*mat.m[2][0],
  327. m[1][0]*mat.m[0][1] + m[1][1]*mat.m[1][1] + m[1][2]*mat.m[2][1],
  328. m[1][0]*mat.m[0][2] + m[1][1]*mat.m[1][2] + m[1][2]*mat.m[2][2],
  329. m[2][0]*mat.m[0][0] + m[2][1]*mat.m[1][0] + m[2][2]*mat.m[2][0],
  330. m[2][0]*mat.m[0][1] + m[2][1]*mat.m[1][1] + m[2][2]*mat.m[2][1],
  331. m[2][0]*mat.m[0][2] + m[2][1]*mat.m[1][2] + m[2][2]*mat.m[2][2]);
  332. }
  333. //! Operator for Point Mul = Matrix3x3 * Point;
  334. inline_ Point operator*(const Point& v) const { return Point(GetRow(0)|v, GetRow(1)|v, GetRow(2)|v); }
  335. //! Operator for Matrix3x3 Mul = Matrix3x3 * float;
  336. inline_ Matrix3x3 operator*(float s) const
  337. {
  338. return Matrix3x3(
  339. m[0][0]*s, m[0][1]*s, m[0][2]*s,
  340. m[1][0]*s, m[1][1]*s, m[1][2]*s,
  341. m[2][0]*s, m[2][1]*s, m[2][2]*s);
  342. }
  343. //! Operator for Matrix3x3 Mul = float * Matrix3x3;
  344. inline_ friend Matrix3x3 operator*(float s, const Matrix3x3& mat)
  345. {
  346. return Matrix3x3(
  347. s*mat.m[0][0], s*mat.m[0][1], s*mat.m[0][2],
  348. s*mat.m[1][0], s*mat.m[1][1], s*mat.m[1][2],
  349. s*mat.m[2][0], s*mat.m[2][1], s*mat.m[2][2]);
  350. }
  351. //! Operator for Matrix3x3 Div = Matrix3x3 / float;
  352. inline_ Matrix3x3 operator/(float s) const
  353. {
  354. if (s) s = 1.0f / s;
  355. return Matrix3x3(
  356. m[0][0]*s, m[0][1]*s, m[0][2]*s,
  357. m[1][0]*s, m[1][1]*s, m[1][2]*s,
  358. m[2][0]*s, m[2][1]*s, m[2][2]*s);
  359. }
  360. //! Operator for Matrix3x3 Div = float / Matrix3x3;
  361. inline_ friend Matrix3x3 operator/(float s, const Matrix3x3& mat)
  362. {
  363. return Matrix3x3(
  364. s/mat.m[0][0], s/mat.m[0][1], s/mat.m[0][2],
  365. s/mat.m[1][0], s/mat.m[1][1], s/mat.m[1][2],
  366. s/mat.m[2][0], s/mat.m[2][1], s/mat.m[2][2]);
  367. }
  368. //! Operator for Matrix3x3 += Matrix3x3
  369. inline_ Matrix3x3& operator+=(const Matrix3x3& mat)
  370. {
  371. m[0][0] += mat.m[0][0]; m[0][1] += mat.m[0][1]; m[0][2] += mat.m[0][2];
  372. m[1][0] += mat.m[1][0]; m[1][1] += mat.m[1][1]; m[1][2] += mat.m[1][2];
  373. m[2][0] += mat.m[2][0]; m[2][1] += mat.m[2][1]; m[2][2] += mat.m[2][2];
  374. return *this;
  375. }
  376. //! Operator for Matrix3x3 -= Matrix3x3
  377. inline_ Matrix3x3& operator-=(const Matrix3x3& mat)
  378. {
  379. m[0][0] -= mat.m[0][0]; m[0][1] -= mat.m[0][1]; m[0][2] -= mat.m[0][2];
  380. m[1][0] -= mat.m[1][0]; m[1][1] -= mat.m[1][1]; m[1][2] -= mat.m[1][2];
  381. m[2][0] -= mat.m[2][0]; m[2][1] -= mat.m[2][1]; m[2][2] -= mat.m[2][2];
  382. return *this;
  383. }
  384. //! Operator for Matrix3x3 *= Matrix3x3
  385. inline_ Matrix3x3& operator*=(const Matrix3x3& mat)
  386. {
  387. Point TempRow;
  388. GetRow(0, TempRow);
  389. m[0][0] = TempRow.x*mat.m[0][0] + TempRow.y*mat.m[1][0] + TempRow.z*mat.m[2][0];
  390. m[0][1] = TempRow.x*mat.m[0][1] + TempRow.y*mat.m[1][1] + TempRow.z*mat.m[2][1];
  391. m[0][2] = TempRow.x*mat.m[0][2] + TempRow.y*mat.m[1][2] + TempRow.z*mat.m[2][2];
  392. GetRow(1, TempRow);
  393. m[1][0] = TempRow.x*mat.m[0][0] + TempRow.y*mat.m[1][0] + TempRow.z*mat.m[2][0];
  394. m[1][1] = TempRow.x*mat.m[0][1] + TempRow.y*mat.m[1][1] + TempRow.z*mat.m[2][1];
  395. m[1][2] = TempRow.x*mat.m[0][2] + TempRow.y*mat.m[1][2] + TempRow.z*mat.m[2][2];
  396. GetRow(2, TempRow);
  397. m[2][0] = TempRow.x*mat.m[0][0] + TempRow.y*mat.m[1][0] + TempRow.z*mat.m[2][0];
  398. m[2][1] = TempRow.x*mat.m[0][1] + TempRow.y*mat.m[1][1] + TempRow.z*mat.m[2][1];
  399. m[2][2] = TempRow.x*mat.m[0][2] + TempRow.y*mat.m[1][2] + TempRow.z*mat.m[2][2];
  400. return *this;
  401. }
  402. //! Operator for Matrix3x3 *= float
  403. inline_ Matrix3x3& operator*=(float s)
  404. {
  405. m[0][0] *= s; m[0][1] *= s; m[0][2] *= s;
  406. m[1][0] *= s; m[1][1] *= s; m[1][2] *= s;
  407. m[2][0] *= s; m[2][1] *= s; m[2][2] *= s;
  408. return *this;
  409. }
  410. //! Operator for Matrix3x3 /= float
  411. inline_ Matrix3x3& operator/=(float s)
  412. {
  413. if (s) s = 1.0f / s;
  414. m[0][0] *= s; m[0][1] *= s; m[0][2] *= s;
  415. m[1][0] *= s; m[1][1] *= s; m[1][2] *= s;
  416. m[2][0] *= s; m[2][1] *= s; m[2][2] *= s;
  417. return *this;
  418. }
  419. // Cast operators
  420. //! Cast a Matrix3x3 to a Matrix4x4.
  421. operator Matrix4x4() const;
  422. //! Cast a Matrix3x3 to a Quat.
  423. operator Quat() const;
  424. inline_ const Point& operator[](int row) const { return *(const Point*)&m[row][0]; }
  425. inline_ Point& operator[](int row) { return *(Point*)&m[row][0]; }
  426. public:
  427. float m[3][3];
  428. };
  429. #endif // __ICEMATRIX3X3_H__