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