IceMatrix3x3.h 20 KB

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