icematrix3x3.h

来自「opcode是功能强大」· C头文件 代码 · 共 497 行 · 第 1/2 页

H
497
字号
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
 *	Contains code for 3x3 matrices.
 *	\file		IceMatrix3x3.h
 *	\author		Pierre Terdiman
 *	\date		April, 4, 2000
 */
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Include Guard
#ifndef __ICEMATRIX3X3_H__
#define __ICEMATRIX3X3_H__

	// Forward declarations
	class Quat;

	#define	MATRIX3X3_EPSILON		(1.0e-7f)

	class Matrix3x3
	{
		public:
		//! Empty constructor
		inline_					Matrix3x3()									{}
		//! Constructor from 9 values
		inline_					Matrix3x3(float m00, float m01, float m02, float m10, float m11, float m12, float m20, float m21, float m22)
								{
									m[0][0] = m00;	m[0][1] = m01;	m[0][2] = m02;
									m[1][0] = m10;	m[1][1] = m11;	m[1][2] = m12;
									m[2][0] = m20;	m[2][1] = m21;	m[2][2] = m22;
								}
		//! Copy constructor
		inline_					Matrix3x3(const Matrix3x3& mat)				{ CopyMemory(m, &mat.m, 9*sizeof(float));	}
		//! Destructor
		inline_					~Matrix3x3()								{}

		//! Assign values
		inline_	void			Set(float m00, float m01, float m02, float m10, float m11, float m12, float m20, float m21, float m22)
								{
									m[0][0] = m00;	m[0][1] = m01;	m[0][2] = m02;
									m[1][0] = m10;	m[1][1] = m11;	m[1][2] = m12;
									m[2][0] = m20;	m[2][1] = m21;	m[2][2] = m22;
								}

		//! Sets the scale from a Point. The point is put on the diagonal.
		inline_	void			SetScale(const Point& p)					{ m[0][0] = p.x;	m[1][1] = p.y;	m[2][2] = p.z;	}

		//! Sets the scale from floats. Values are put on the diagonal.
		inline_	void			SetScale(float sx, float sy, float sz)		{ m[0][0] = sx;		m[1][1] = sy;	m[2][2] = sz;	}

		//! Scales from a Point. Each row is multiplied by a component.
		inline_	void			Scale(const Point& p)
								{
									m[0][0] *= p.x;	m[0][1] *= p.x;	m[0][2] *= p.x;
									m[1][0] *= p.y;	m[1][1] *= p.y;	m[1][2] *= p.y;
									m[2][0] *= p.z;	m[2][1] *= p.z;	m[2][2] *= p.z;
								}

		//! Scales from floats. Each row is multiplied by a value.
		inline_	void			Scale(float sx, float sy, float sz)
								{
									m[0][0] *= sx;	m[0][1] *= sx;	m[0][2] *= sx;
									m[1][0] *= sy;	m[1][1] *= sy;	m[1][2] *= sy;
									m[2][0] *= sz;	m[2][1] *= sz;	m[2][2] *= sz;
								}

		//! Copy from a Matrix3x3
		inline_	void			Copy(const Matrix3x3& source)				{ CopyMemory(m, source.m, 9*sizeof(float));			}

		// Row-column access
		//! Returns a row.
		inline_	void			GetRow(const udword r, Point& p)	const	{ p.x = m[r][0];	p.y = m[r][1];	p.z = m[r][2];	}
		//! Returns a row.
		inline_	const Point&	GetRow(const udword r)				const	{ return *(const Point*)&m[r][0];	}
		//! Returns a row.
		inline_	Point&			GetRow(const udword r)						{ return *(Point*)&m[r][0];			}
		//! Sets a row.
		inline_	void			SetRow(const udword r, const Point& p)		{ m[r][0] = p.x;	m[r][1] = p.y;	m[r][2] = p.z;	}
		//! Returns a column.
		inline_	void			GetCol(const udword c, Point& p)	const	{ p.x = m[0][c];	p.y = m[1][c];	p.z = m[2][c];	}
		//! Sets a column.
		inline_	void			SetCol(const udword c, const Point& p)		{ m[0][c] = p.x;	m[1][c] = p.y;	m[2][c] = p.z;	}

		//! Computes the trace. The trace is the sum of the 3 diagonal components.
		inline_	float			Trace()					const				{ return m[0][0] + m[1][1] + m[2][2];				}
		//! Clears the matrix.
		inline_	void			Zero()										{ ZeroMemory(&m, sizeof(m));						}
		//! Sets the identity matrix.
		inline_	void			Identity()									{ Zero(); m[0][0] = m[1][1] = m[2][2] = 1.0f; 		}
		//! Checks for identity
		inline_	bool			IsIdentity()			const
								{
									if(IR(m[0][0])!=IEEE_1_0)	return false;
									if(IR(m[0][1])!=0)			return false;
									if(IR(m[0][2])!=0)			return false;

									if(IR(m[1][0])!=0)			return false;
									if(IR(m[1][1])!=IEEE_1_0)	return false;
									if(IR(m[1][2])!=0)			return false;

									if(IR(m[2][0])!=0)			return false;
									if(IR(m[2][1])!=0)			return false;
									if(IR(m[2][2])!=IEEE_1_0)	return false;

									return true;
								}

		//! Checks matrix validity
		inline_	BOOL			IsValid()				const
								{
									for(udword j=0;j<3;j++)
									{
										for(udword i=0;i<3;i++)
										{
											if(!IsValidFloat(m[j][i]))	return FALSE;
										}
									}
									return TRUE;
								}

		//! Makes a skew-symmetric matrix (a.k.a. Star(*) Matrix)
		//!	[  0.0  -a.z   a.y ]
		//!	[  a.z   0.0  -a.x ]
		//!	[ -a.y   a.x   0.0 ]
		//! This is also called a "cross matrix" since for any vectors A and B,
		//! A^B = Skew(A) * B = - B * Skew(A);
		inline_	void			SkewSymmetric(const Point& a)
								{
									m[0][0] = 0.0f;
									m[0][1] = -a.z;
									m[0][2] = a.y;

									m[1][0] = a.z;
									m[1][1] = 0.0f;
									m[1][2] = -a.x;

									m[2][0] = -a.y;
									m[2][1] = a.x;
									m[2][2] = 0.0f;
								}

		//! Negates the matrix
		inline_	void			Neg()
								{
									m[0][0] = -m[0][0];	m[0][1] = -m[0][1];	m[0][2] = -m[0][2];
									m[1][0] = -m[1][0];	m[1][1] = -m[1][1];	m[1][2] = -m[1][2];
									m[2][0] = -m[2][0];	m[2][1] = -m[2][1];	m[2][2] = -m[2][2];
								}

		//! Neg from another matrix
		inline_	void			Neg(const Matrix3x3& mat)
								{
									m[0][0] = -mat.m[0][0];	m[0][1] = -mat.m[0][1];	m[0][2] = -mat.m[0][2];
									m[1][0] = -mat.m[1][0];	m[1][1] = -mat.m[1][1];	m[1][2] = -mat.m[1][2];
									m[2][0] = -mat.m[2][0];	m[2][1] = -mat.m[2][1];	m[2][2] = -mat.m[2][2];
								}

		//! Add another matrix
		inline_	void			Add(const Matrix3x3& mat)
								{
									m[0][0] += mat.m[0][0];	m[0][1] += mat.m[0][1];	m[0][2] += mat.m[0][2];
									m[1][0] += mat.m[1][0];	m[1][1] += mat.m[1][1];	m[1][2] += mat.m[1][2];
									m[2][0] += mat.m[2][0];	m[2][1] += mat.m[2][1];	m[2][2] += mat.m[2][2];
								}

		//! Sub another matrix
		inline_	void			Sub(const Matrix3x3& mat)
								{
									m[0][0] -= mat.m[0][0];	m[0][1]	-= mat.m[0][1];	m[0][2] -= mat.m[0][2];
									m[1][0] -= mat.m[1][0];	m[1][1] -= mat.m[1][1];	m[1][2] -= mat.m[1][2];
									m[2][0] -= mat.m[2][0];	m[2][1] -= mat.m[2][1];	m[2][2] -= mat.m[2][2];
								}
		//! Mac
		inline_	void			Mac(const Matrix3x3& a, const Matrix3x3& b, float s)
								{
									m[0][0] = a.m[0][0] + b.m[0][0] * s;
									m[0][1] = a.m[0][1] + b.m[0][1] * s;
									m[0][2] = a.m[0][2] + b.m[0][2] * s;

									m[1][0] = a.m[1][0] + b.m[1][0] * s;
									m[1][1] = a.m[1][1] + b.m[1][1] * s;
									m[1][2] = a.m[1][2] + b.m[1][2] * s;

									m[2][0] = a.m[2][0] + b.m[2][0] * s;
									m[2][1] = a.m[2][1] + b.m[2][1] * s;
									m[2][2] = a.m[2][2] + b.m[2][2] * s;
								}
		//! Mac
		inline_	void			Mac(const Matrix3x3& a, float s)
								{
									m[0][0] += a.m[0][0] * s;	m[0][1] += a.m[0][1] * s;	m[0][2] += a.m[0][2] * s;
									m[1][0] += a.m[1][0] * s;	m[1][1] += a.m[1][1] * s;	m[1][2] += a.m[1][2] * s;
									m[2][0] += a.m[2][0] * s;	m[2][1] += a.m[2][1] * s;	m[2][2] += a.m[2][2] * s;
								}

		//! this = A * s
		inline_	void			Mult(const Matrix3x3& a, float s)
								{
									m[0][0] = a.m[0][0] * s;	m[0][1] = a.m[0][1] * s;	m[0][2] = a.m[0][2] * s;
									m[1][0] = a.m[1][0] * s;	m[1][1] = a.m[1][1] * s;	m[1][2] = a.m[1][2] * s;
									m[2][0] = a.m[2][0] * s;	m[2][1] = a.m[2][1] * s;	m[2][2] = a.m[2][2] * s;
								}

		inline_	void			Add(const Matrix3x3& a, const Matrix3x3& b)
								{
									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];
									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];
									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];
								}

		inline_	void			Sub(const Matrix3x3& a, const Matrix3x3& b)
								{
									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];
									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];
									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];
								}

		//! this = a * b
		inline_	void			Mult(const Matrix3x3& a, const Matrix3x3& b)
								{
									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];
									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];
									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];
									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];
									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];
									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];
									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];
									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];
									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];
								}

		//! this = transpose(a) * b
		inline_	void			MultAtB(const Matrix3x3& a, const Matrix3x3& b)
								{
									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];
									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];
									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];
									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];
									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];
									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];
									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];
									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];
									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];
								}

		//! this = a * transpose(b)
		inline_	void			MultABt(const Matrix3x3& a, const Matrix3x3& b)
								{
									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];

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?