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