www.pudn.com > zfxcengine-0.1.0.zip > ceMatrix.cpp


// $Id: ceMatrix.cpp,v 1.24 2005/08/10 20:13:08 kimmi Exp $  
#include  
#include  
#include   
 
 
#include "Math/ceMath.h" 
 
namespace ZFXCE { 
	//////////////////////////////////////////////////////////////////////////////// 
	using namespace std; 
	 
	//////////////////////////////////////////////////////////////////////////////// 
	ceMatrix::ceMatrix()  
	{ 
		Identity(); 
	} 
	//////////////////////////////////////////////////////////////////////////////// 
	void ceMatrix::Identity() 
	{ 
		memset (&_m[0], 0, sizeof(FLOAT) * 16); 
		_ms._11 = _ms._22 = _ms._33 = _ms._44 = 1.0f; 
	} 
	//////////////////////////////////////////////////////////////////////////////// 
	void ceMatrix::RotateAroundX(const FLOAT a) 
	{ 
		const FLOAT fCos = cosf(a); 
		const FLOAT fSin = sinf(a); 
 
		ceMatrix m;		 
		m._ms._22 = fCos; 
		m._ms._32 = fSin; 
		m._ms._23 = -fSin; 
		m._ms._33 = fCos; 
 
		Multiply(m); 
	} 
	//////////////////////////////////////////////////////////////////////////////// 
	void ceMatrix::RotateAroundY(const FLOAT a) 
	{ 
		const FLOAT fCos = cosf(a); 
		const FLOAT fSin = sinf(a); 
 
		ceMatrix m; 
		m._ms._11 =  fCos; 
		m._ms._31 = -fSin; 
		m._ms._13 =  fSin; 
		m._ms._33 =  fCos; 
		 
		Multiply(m); 
	} 
	//////////////////////////////////////////////////////////////////////////////// 
	void ceMatrix::RotateAroundZ(const FLOAT a) 
	{ 
		const FLOAT fCos = cosf(a); 
		const FLOAT fSin = sinf(a); 
		 
		ceMatrix m; 
		m._ms._11  =  fCos; 
		m._ms._21  =  fSin; 
		m._ms._12  = -fSin; 
		m._ms._22  =  fCos; 
		 
		Multiply(m); 
	} 
	//////////////////////////////////////////////////////////////////////////////// 
	void ceMatrix::ApplyInverseRotation(ceVec4f* pV) 
	{ 
		pV->x = pV->x * _ms._11 + pV->y * _ms._12 + pV->z * _ms._13; 
		pV->y = pV->x * _ms._21 + pV->y * _ms._22 + pV->z * _ms._23; 
		pV->z = pV->x * _ms._31 + pV->y * _ms._32 + pV->z * _ms._33; 
		pV->w = 1.0f; 
	} 
	//////////////////////////////////////////////////////////////////////////////// 
	void ceMatrix::RotateAround(const ceVec3f& v) 
	{ 
		const FLOAT sy = sinf( v.z ); 
		const FLOAT cy = cosf( v.z ); 
		const FLOAT sp = sinf( v.y ); 
		const FLOAT cp = cosf( v.y ); 
		const FLOAT sr = sinf( v.x ); 
		const FLOAT cr = cosf( v.x ); 
		 
		ceMatrix m; 
		m._ms._11 = cp*cy; 
		m._ms._21 = cp*sy; 
		m._ms._31 = -sp; 
		m._ms._12 = sr*sp*cy+cr*-sy; 
		m._ms._22 = sr*sp*sy+cr*cy; 
		m._ms._32 = sr*cp; 
		m._ms._13 = (cr*sp*cy+-sr*-sy); 
		m._ms._23 = (cr*sp*sy+-sr*cy); 
		m._ms._33 = cr*cp; 
		 
		Multiply(m); 
	} 
	//////////////////////////////////////////////////////////////////////////////// 
	void ceMatrix::SetTranslation(const ceVec3f &V, BOOL bEraseContent) 
	{ 
		if (bEraseContent) 
			Identity(); 
		 
		ceMatrix m; 
		m._ms._14 = V.x; 
		m._ms._24 = V.y; 
		m._ms._34 = V.z; 
		 
		Multiply(m); 
	} 
	//////////////////////////////////////////////////////////////////////////////// 
	void ceMatrix::SetTranslation(const ceVec4f &V, BOOL bEraseContent) 
	{	 
	if (bEraseContent) 
			Identity(); 
		 
		ceMatrix m; 
		m._ms._14 = V.x; 
		m._ms._24 = V.y; 
		m._ms._34 = V.z; 
		 
		Multiply(m); 
	} 
	//////////////////////////////////////////////////////////////////////////////// 
	ceVec4f ceMatrix::GetTranslation() const 
	{ 
		return ceVec4f(_ms._41, _ms._42, _ms._43, _ms._44); 
	} 
	//////////////////////////////////////////////////////////////////////////////// 
	void ceMatrix::Scale(ceVec3f &vScale) 
	{ 
		ceMatrix m; 
		m._ms._11 = vScale.x; 
		m._ms._22 = vScale.y; 
		m._ms._33 = vScale.z; 
		m._ms._44 = 1.0f; 
		Multiply(m); 
	} 
	//////////////////////////////////////////////////////////////////////////////// 
	void ceMatrix::RotateArbitrary(ceVec4f& vAxis, FLOAT a) 
	{ 
		const FLOAT fCos = cosf(a); 
		const FLOAT fSin = sinf(a); 
		const FLOAT fSum = 1.0f - fCos; 
 
		if (vAxis.GetSqrLength() != 1.0) 
			vAxis.Normalize(); 
 
		ceMatrix m; 
		m._ms._11 = (vAxis.x * vAxis.x) * fSum + fCos; 
		m._ms._21 = (vAxis.x * vAxis.y) * fSum - (vAxis.z * fSin); 
		m._ms._31 = (vAxis.x * vAxis.z) * fSum + (vAxis.y * fSin); 
 
		m._ms._12 = (vAxis.y * vAxis.x) * fSum + (vAxis.z * fSin); 
		m._ms._22 = (vAxis.y * vAxis.y) * fSum + fCos ; 
		m._ms._32 = (vAxis.y * vAxis.z) * fSum - (vAxis.x * fSin); 
 
		m._ms._13 = (vAxis.z * vAxis.x) * fSum - (vAxis.y * fSin); 
		m._ms._23 = (vAxis.z * vAxis.y) * fSum + (vAxis.x * fSin); 
		m._ms._33 = (vAxis.z * vAxis.z) * fSum + fCos; 
 
		Multiply(m); 
	} 
	//////////////////////////////////////////////////////////////////////////////// 
	void ceMatrix::RotateArbitrary(ceVec3f& vAxis, FLOAT a) 
	{ 
		ceVec4f V(vAxis.x, vAxis.y, vAxis.z, 1.0f); 
		RotateArbitrary(V, a); 
	} 
	//////////////////////////////////////////////////////////////////////////////// 
	void ceMatrix::Translate(const FLOAT dx, const FLOAT dy, const FLOAT dz) 
	{ 
		ceMatrix m; 
	 
		m._ms._14 = dx; 
		m._ms._24 = dy; 
		m._ms._34 = dz; 
 
		Multiply(m); 
	} 
	//////////////////////////////////////////////////////////////////////////////// 
	void ceMatrix::LookAt(ceVec4f vPos, ceVec4f vLookAt, ceVec4f vWorldUp) 
	{ 
		ceVec4f vDir = vLookAt - vPos; 
		ceVec4f vUp, vRight; 
 
		vDir.Normalize(); 
 
		FLOAT fAngle = vWorldUp * vDir; 
		vUp = vWorldUp - (vDir * fAngle); 
		vUp.Normalize(); 
		vRight.Cross(vUp, vDir); 
   
		_ms._11	= vRight.x;  
		_ms._12 = vUp.x;  
		_ms._13 = vDir.x; 
		_ms._21 = vRight.y; 
		_ms._22 = vUp.y;  
		_ms._23 = vDir.y; 
		_ms._31 = vRight.z;  
		_ms._32 = vUp.z;  
		_ms._33 = vDir.z; 
		_ms._14 = vPos.x; 
		_ms._24 = vPos.y; 
		_ms._34 = vPos.z; 
 
		_ms._14 = _ms._24 = _ms._34 = _ms._44 = 1.0f; 
	} 
	//////////////////////////////////////////////////////////////////////////////// 
	void ceMatrix::Multiply(const ceMatrix &m) 
	{	 
		ceMatrix m1; 
		m1._ms._11 = m._ms._11 * _ms._11 + m._ms._12 * _ms._21 + m._ms._13 * _ms._31 + m._ms._14 * _ms._41; 
		m1._ms._12 = m._ms._11 * _ms._12 + m._ms._12 * _ms._22 + m._ms._13 * _ms._32 + m._ms._14 * _ms._42; 
		m1._ms._13 = m._ms._11 * _ms._13 + m._ms._12 * _ms._23 + m._ms._13 * _ms._33 + m._ms._14 * _ms._43;  
		m1._ms._14 = m._ms._11 * _ms._14 + m._ms._12 * _ms._24 + m._ms._13 * _ms._34 + m._ms._14 * _ms._44; 
	 
		m1._ms._21 = m._ms._21 * _ms._11 + m._ms._22 * _ms._21 + m._ms._23 * _ms._31 + m._ms._24 * _ms._41; 
		m1._ms._22 = m._ms._21 * _ms._12 + m._ms._22 * _ms._22 + m._ms._23 * _ms._32 + m._ms._24 * _ms._42; 
		m1._ms._23 = m._ms._21 * _ms._13 + m._ms._22 * _ms._23 + m._ms._23 * _ms._33 + m._ms._24 * _ms._43;  
		m1._ms._24 = m._ms._21 * _ms._14 + m._ms._22 * _ms._24 + m._ms._23 * _ms._34 + m._ms._24 * _ms._44; 
 
		m1._ms._31 = m._ms._31 * _ms._11 + m._ms._32 * _ms._21 + m._ms._33 * _ms._31 + m._ms._34 * _ms._41; 
		m1._ms._32 = m._ms._31 * _ms._12 + m._ms._32 * _ms._22 + m._ms._33 * _ms._32 + m._ms._34 * _ms._42; 
		m1._ms._33 = m._ms._31 * _ms._13 + m._ms._32 * _ms._23 + m._ms._33 * _ms._33 + m._ms._34 * _ms._43;  
		m1._ms._34 = m._ms._31 * _ms._14 + m._ms._32 * _ms._24 + m._ms._33 * _ms._34 + m._ms._34 * _ms._44; 
 
		m1._ms._41 = m._ms._41 * _ms._11 + m._ms._42 * _ms._21 + m._ms._43 * _ms._31 + m._ms._44 * _ms._41; 
		m1._ms._42 = m._ms._41 * _ms._12 + m._ms._42 * _ms._22 + m._ms._43 * _ms._32 + m._ms._44 * _ms._42; 
		m1._ms._43 = m._ms._41 * _ms._13 + m._ms._42 * _ms._23 + m._ms._43 * _ms._33 + m._ms._44 * _ms._43;  
		m1._ms._44 = m._ms._41 * _ms._14 + m._ms._42 * _ms._24 + m._ms._43 * _ms._34 + m._ms._44 * _ms._44; 
		memcpy(&_ms, &m1._ms, sizeof(FLOAT) * 16); 
	} 
	//////////////////////////////////////////////////////////////////////////////// 
	void ceMatrix::Multiply(const ceMatrix *m) 
	{ 
		ceMatrix m1; 
		m1._ms._11 = m->_ms._11 * _ms._11 + m->_ms._12 * _ms._21 + m->_ms._13 * _ms._31 + m->_ms._14 * _ms._41; 
		m1._ms._12 = m->_ms._11 * _ms._12 + m->_ms._12 * _ms._22 + m->_ms._13 * _ms._32 + m->_ms._14 * _ms._42; 
		m1._ms._13 = m->_ms._11 * _ms._13 + m->_ms._12 * _ms._23 + m->_ms._13 * _ms._33 + m->_ms._14 * _ms._43;  
		m1._ms._14 = m->_ms._11 * _ms._14 + m->_ms._12 * _ms._24 + m->_ms._13 * _ms._34 + m->_ms._14 * _ms._44; 
	 
		m1._ms._21 = m->_ms._21 * _ms._11 + m->_ms._22 * _ms._21 + m->_ms._23 * _ms._31 + m->_ms._24 * _ms._41; 
		m1._ms._22 = m->_ms._21 * _ms._12 + m->_ms._22 * _ms._22 + m->_ms._23 * _ms._32 + m->_ms._24 * _ms._42; 
		m1._ms._23 = m->_ms._21 * _ms._13 + m->_ms._22 * _ms._23 + m->_ms._23 * _ms._33 + m->_ms._24 * _ms._43;  
		m1._ms._24 = m->_ms._21 * _ms._14 + m->_ms._22 * _ms._24 + m->_ms._23 * _ms._34 + m->_ms._24 * _ms._44; 
 
		m1._ms._31 = m->_ms._31 * _ms._11 + m->_ms._32 * _ms._21 + m->_ms._33 * _ms._31 + m->_ms._34 * _ms._41; 
		m1._ms._32 = m->_ms._31 * _ms._12 + m->_ms._32 * _ms._22 + m->_ms._33 * _ms._32 + m->_ms._34 * _ms._42; 
		m1._ms._33 = m->_ms._31 * _ms._13 + m->_ms._32 * _ms._23 + m->_ms._33 * _ms._33 + m->_ms._34 * _ms._43;  
		m1._ms._34 = m->_ms._31 * _ms._14 + m->_ms._32 * _ms._24 + m->_ms._33 * _ms._34 + m->_ms._34 * _ms._44; 
 
		m1._ms._41 = m->_ms._41 * _ms._11 + m->_ms._42 * _ms._21 + m->_ms._43 * _ms._31 + m->_ms._44 * _ms._41; 
		m1._ms._42 = m->_ms._41 * _ms._12 + m->_ms._42 * _ms._22 + m->_ms._43 * _ms._32 + m->_ms._44 * _ms._42; 
		m1._ms._43 = m->_ms._41 * _ms._13 + m->_ms._42 * _ms._23 + m->_ms._43 * _ms._33 + m->_ms._44 * _ms._43;  
		m1._ms._44 = m->_ms._41 * _ms._14 + m->_ms._42 * _ms._24 + m->_ms._43 * _ms._34 + m->_ms._44 * _ms._44; 
		 
		memcpy(&_ms, &m1._ms, sizeof(FLOAT) *16); 
	} 
	//////////////////////////////////////////////////////////////////////////////// 
	void ceMatrix::MakeBillboard(ceVec4f vPos, ceVec4f vDir, ceVec4f vWorldUp) 
	{ 
		const FLOAT fAngle = vWorldUp * vDir; 
		ceVec4f vUp = vWorldUp - (vDir * fAngle); 
		vUp.Normalize(); 
		ceVec4f vRight; 
		vRight.Cross(vUp,vDir); 
 
		_ms._11 = vRight.x;  
		_ms._12 = vUp.x;  
		_ms._13 = vDir.x; 
		_ms._21 = vRight.y;  
		_ms._22 = vUp.y;  
		_ms._23 = vDir.y; 
		_ms._31 = vRight.z;  
		_ms._32 = vUp.z;  
		_ms._33 = vDir.z; 
		_ms._14 = vPos.x; 
		_ms._24 = vPos.y; 
		_ms._34 = vPos.z; 
 
		_ms._14=0.0f; _ms._24=0.0f; _ms._34=0.0f; _ms._44=1.0f; 
	} 
	//////////////////////////////////////////////////////////////////////////////// 
	bool ceMatrix::operator== (const ceMatrix& m) const 
	{ 
		for (size_t iRow = 0; iRow < 3; iRow++) { 
            for (size_t iCol = 0; iCol < 3; iCol++) { 
				if (this->_m2[iRow][iCol] != m._m2[iRow][iCol]) { 
                    return false; 
				} 
            } 
        } 
 
        return true; 
	} 
	//////////////////////////////////////////////////////////////////////////////// 
	ceMatrix ceMatrix::operator * (const ceMatrix& m) const 
	{ 
		ceMatrix m1; 
		m1._ms._11 = m._ms._11 * _ms._11 + m._ms._12 * _ms._21 + m._ms._13 * _ms._31 + m._ms._14 * _ms._41; 
		m1._ms._12 = m._ms._11 * _ms._12 + m._ms._12 * _ms._22 + m._ms._13 * _ms._32 + m._ms._14 * _ms._42; 
		m1._ms._13 = m._ms._11 * _ms._13 + m._ms._12 * _ms._23 + m._ms._13 * _ms._33 + m._ms._14 * _ms._43;  
		m1._ms._14 = m._ms._11 * _ms._14 + m._ms._12 * _ms._24 + m._ms._13 * _ms._34 + m._ms._14 * _ms._44; 
	 
		m1._ms._21 = m._ms._21 * _ms._11 + m._ms._22 * _ms._21 + m._ms._23 * _ms._31 + m._ms._24 * _ms._41; 
		m1._ms._22 = m._ms._21 * _ms._12 + m._ms._22 * _ms._22 + m._ms._23 * _ms._32 + m._ms._24 * _ms._42; 
		m1._ms._23 = m._ms._21 * _ms._13 + m._ms._22 * _ms._23 + m._ms._23 * _ms._33 + m._ms._24 * _ms._43;  
		m1._ms._24 = m._ms._21 * _ms._14 + m._ms._22 * _ms._24 + m._ms._23 * _ms._34 + m._ms._24 * _ms._44; 
 
		m1._ms._31 = m._ms._31 * _ms._11 + m._ms._32 * _ms._21 + m._ms._33 * _ms._31 + m._ms._34 * _ms._41; 
		m1._ms._32 = m._ms._31 * _ms._12 + m._ms._32 * _ms._22 + m._ms._33 * _ms._32 + m._ms._34 * _ms._42; 
		m1._ms._33 = m._ms._31 * _ms._13 + m._ms._32 * _ms._23 + m._ms._33 * _ms._33 + m._ms._34 * _ms._43;  
		m1._ms._34 = m._ms._31 * _ms._14 + m._ms._32 * _ms._24 + m._ms._33 * _ms._34 + m._ms._34 * _ms._44; 
 
		m1._ms._41 = m._ms._41 * _ms._11 + m._ms._42 * _ms._21 + m._ms._43 * _ms._31 + m._ms._44 * _ms._41; 
		m1._ms._42 = m._ms._41 * _ms._12 + m._ms._42 * _ms._22 + m._ms._43 * _ms._32 + m._ms._44 * _ms._42; 
		m1._ms._43 = m._ms._41 * _ms._13 + m._ms._42 * _ms._23 + m._ms._43 * _ms._33 + m._ms._44 * _ms._43;  
		m1._ms._44 = m._ms._41 * _ms._14 + m._ms._42 * _ms._24 + m._ms._43 * _ms._34 + m._ms._44 * _ms._44; 
 
		return m1; 
	} 
	//////////////////////////////////////////////////////////////////////////////// 
	ceVec4f ceMatrix::operator * (const ceVec4f& v) const 
	{ 
		ceVec4f r; 
 
		const FLOAT fW = 1.0f / (_ms._41 * v.x + _ms._42 * v.y + _ms._43 * v.z + _ms._44); 
 
		r.x = ( _ms._11 * v.x + _ms._12 * v.y + _ms._13 * v.z + _ms._14 ) * fW; 
		r.y = ( _ms._21 * v.x + _ms._22 * v.y + _ms._23 * v.z + _ms._24 ) * fW; 
		r.z = ( _ms._31 * v.x + _ms._32 * v.y + _ms._33 * v.z + _ms._34 ) * fW; 
		r.w = 1.0f; 
 
		return r; 
	} 
	//////////////////////////////////////////////////////////////////////////////// 
	ceVec3f ceMatrix::operator * (const ceVec3f& v)const 
	{ 
		ceVec3f r; 
		const FLOAT fW = 1.0f / (_ms._41 * v.x + _ms._42 * v.y + _ms._43 * v.z + _ms._44); 
		r.x = ( _ms._11 * v.x + _ms._12 * v.y + _ms._13 * v.z + _ms._14 ) * fW; 
		r.y = ( _ms._21 * v.x + _ms._22 * v.y + _ms._23 * v.z + _ms._24 ) * fW; 
		r.z = ( _ms._31 * v.x + _ms._32 * v.y + _ms._33 * v.z + _ms._34 ) * fW; 
 
		return r; 
	} 
	//////////////////////////////////////////////////////////////////////////////// 
	void ceMatrix::Transpose() 
	{ 
		FLOAT m[16]; 
		memcpy(&m[0], this->GetAsArray(), sizeof(FLOAT)*16); 
		 
		_ms._11 = m[0]; 
		_ms._21 = m[4]; 
		_ms._31 = m[8]; 
		_ms._41 = m[12]; 
 
		_ms._12 = m[1]; 
		_ms._22 = m[5]; 
		_ms._32 = m[9]; 
		_ms._42 = m[13]; 
 
		_ms._13 = m[2]; 
		_ms._23 = m[6]; 
		_ms._33 = m[10]; 
		_ms._43 = m[14]; 
 
		_ms._14 = m[3]; 
		_ms._24 = m[7]; 
		_ms._34 = m[11]; 
		_ms._44 = m[15]; 
	} 
	//////////////////////////////////////////////////////////////////////////////// 
	void ceMatrix::CreateTransposeOf(const ceMatrix& m) 
	{ 
		FLOAT f[16]; 
		memcpy(&f[0], this->GetAsArray(), sizeof(FLOAT)*16); 
		f[0] = m._ms._11; 
		f[1] = m._ms._12; 
		f[2] = m._ms._13; 
		f[3] = m._ms._14; 
 
		f[4] = m._ms._21; 
		f[5] = m._ms._22; 
		f[6] = m._ms._23; 
		f[7] = m._ms._24; 
 
		f[8] = m._ms._31; 
		f[9] = m._ms._32; 
		f[10] = m._ms._33; 
		f[11] = m._ms._34; 
 
		f[12] = m._ms._41; 
		f[13] = m._ms._42; 
		f[14] = m._ms._43; 
		f[15] = m._ms._44; 
		memcpy(this->_m, f, sizeof(FLOAT) * 16); 
	} 
	//////////////////////////////////////////////////////////////////////////////// 
	void ceMatrix::CreateInverseOf(const ceMatrix& m) 
	{ 
		ceMatrix mTranspose; 
		float     fTemp[12], fDet; 
 
		mTranspose.CreateTransposeOf(m); 
 
		fTemp[0]  = mTranspose._ms._33 * mTranspose._ms._44; 
		fTemp[1]  = mTranspose._ms._34 * mTranspose._ms._43; 
		fTemp[2]  = mTranspose._ms._32 * mTranspose._ms._44; 
		fTemp[3]  = mTranspose._ms._34 * mTranspose._ms._42; 
		fTemp[4]  = mTranspose._ms._32 * mTranspose._ms._43; 
		fTemp[5]  = mTranspose._ms._33 * mTranspose._ms._42; 
		fTemp[6]  = mTranspose._ms._31 * mTranspose._ms._44; 
		fTemp[7]  = mTranspose._ms._34 * mTranspose._ms._41; 
		fTemp[8]  = mTranspose._ms._31 * mTranspose._ms._43; 
		fTemp[9]  = mTranspose._ms._33 * mTranspose._ms._41; 
		fTemp[10]  = mTranspose._ms._31 * mTranspose._ms._42; 
		fTemp[11]  = mTranspose._ms._32 * mTranspose._ms._41; 
 
		this->_ms._11  = fTemp[0]*mTranspose._ms._22 + fTemp[3]*mTranspose._ms._23 + fTemp[4] *mTranspose._ms._24; 
		this->_ms._11 -= fTemp[1]*mTranspose._ms._22 + fTemp[2]*mTranspose._ms._23 + fTemp[5] *mTranspose._ms._24; 
		this->_ms._12  = fTemp[1]*mTranspose._ms._21 + fTemp[6]*mTranspose._ms._23 + fTemp[9] *mTranspose._ms._24; 
		this->_ms._12 -= fTemp[0]*mTranspose._ms._21 + fTemp[7]*mTranspose._ms._23 + fTemp[8] *mTranspose._ms._24; 
		this->_ms._13  = fTemp[2]*mTranspose._ms._21 + fTemp[7]*mTranspose._ms._22 + fTemp[10]*mTranspose._ms._24; 
		this->_ms._13 -= fTemp[3]*mTranspose._ms._21 + fTemp[6]*mTranspose._ms._22 + fTemp[11]*mTranspose._ms._24; 
		this->_ms._14  = fTemp[5]*mTranspose._ms._21 + fTemp[8]*mTranspose._ms._22 + fTemp[11]*mTranspose._ms._23; 
		this->_ms._14 -= fTemp[4]*mTranspose._ms._21 + fTemp[9]*mTranspose._ms._22 + fTemp[10]*mTranspose._ms._23; 
		this->_ms._21  = fTemp[1]*mTranspose._ms._12 + fTemp[2]*mTranspose._ms._13 + fTemp[5] *mTranspose._ms._14; 
		this->_ms._21 -= fTemp[0]*mTranspose._ms._12 + fTemp[3]*mTranspose._ms._13 + fTemp[4] *mTranspose._ms._14; 
		this->_ms._22  = fTemp[0]*mTranspose._ms._11 + fTemp[7]*mTranspose._ms._13 + fTemp[8] *mTranspose._ms._14; 
		this->_ms._22 -= fTemp[1]*mTranspose._ms._11 + fTemp[6]*mTranspose._ms._13 + fTemp[9] *mTranspose._ms._14; 
		this->_ms._23  = fTemp[3]*mTranspose._ms._11 + fTemp[6]*mTranspose._ms._12 + fTemp[11]*mTranspose._ms._14; 
		this->_ms._23 -= fTemp[2]*mTranspose._ms._11 + fTemp[7]*mTranspose._ms._12 + fTemp[10]*mTranspose._ms._14; 
		this->_ms._24  = fTemp[4]*mTranspose._ms._11 + fTemp[9]*mTranspose._ms._12 + fTemp[10]*mTranspose._ms._13; 
		this->_ms._24 -= fTemp[5]*mTranspose._ms._11 + fTemp[8]*mTranspose._ms._12 + fTemp[11]*mTranspose._ms._13; 
 
		fTemp[0]  = mTranspose._ms._13 * mTranspose._ms._24; 
		fTemp[1]  = mTranspose._ms._14 * mTranspose._ms._23; 
		fTemp[2]  = mTranspose._ms._12 * mTranspose._ms._24; 
		fTemp[3]  = mTranspose._ms._14 * mTranspose._ms._22; 
		fTemp[4]  = mTranspose._ms._12 * mTranspose._ms._23; 
		fTemp[5]  = mTranspose._ms._13 * mTranspose._ms._22; 
		fTemp[6]  = mTranspose._ms._11 * mTranspose._ms._24; 
		fTemp[7]  = mTranspose._ms._14 * mTranspose._ms._21; 
		fTemp[8]  = mTranspose._ms._11 * mTranspose._ms._23; 
		fTemp[9]  = mTranspose._ms._13 * mTranspose._ms._21; 
		fTemp[10]  = mTranspose._ms._11 * mTranspose._ms._22; 
		fTemp[11]  = mTranspose._ms._12 * mTranspose._ms._21; 
 
		this->_ms._31  = fTemp[0] *mTranspose._ms._42 + fTemp[3] *mTranspose._ms._43 + fTemp[4] *mTranspose._ms._44; 
		this->_ms._31 -= fTemp[1] *mTranspose._ms._42 + fTemp[2] *mTranspose._ms._43 + fTemp[5] *mTranspose._ms._44; 
		this->_ms._32  = fTemp[1] *mTranspose._ms._41 + fTemp[6] *mTranspose._ms._43 + fTemp[9] *mTranspose._ms._44; 
		this->_ms._32 -= fTemp[0] *mTranspose._ms._41 + fTemp[7] *mTranspose._ms._43 + fTemp[8] *mTranspose._ms._44; 
		this->_ms._33  = fTemp[2] *mTranspose._ms._41 + fTemp[7] *mTranspose._ms._42 + fTemp[10]*mTranspose._ms._44; 
		this->_ms._33 -= fTemp[3] *mTranspose._ms._41 + fTemp[6] *mTranspose._ms._42 + fTemp[11]*mTranspose._ms._44; 
		this->_ms._34  = fTemp[5] *mTranspose._ms._41 + fTemp[8] *mTranspose._ms._42 + fTemp[11]*mTranspose._ms._43; 
		this->_ms._34 -= fTemp[4] *mTranspose._ms._41 + fTemp[9] *mTranspose._ms._42 + fTemp[10]*mTranspose._ms._43; 
		this->_ms._41  = fTemp[2] *mTranspose._ms._33 + fTemp[5] *mTranspose._ms._34 + fTemp[1] *mTranspose._ms._32; 
		this->_ms._41 -= fTemp[4] *mTranspose._ms._34 + fTemp[0] *mTranspose._ms._32 + fTemp[3] *mTranspose._ms._33; 
		this->_ms._42  = fTemp[8] *mTranspose._ms._34 + fTemp[0] *mTranspose._ms._31 + fTemp[7] *mTranspose._ms._33; 
		this->_ms._42 -= fTemp[6] *mTranspose._ms._33 + fTemp[9] *mTranspose._ms._34 + fTemp[1] *mTranspose._ms._31; 
		this->_ms._43  = fTemp[6] *mTranspose._ms._32 + fTemp[11]*mTranspose._ms._34 + fTemp[3] *mTranspose._ms._31; 
		this->_ms._43 -= fTemp[10]*mTranspose._ms._34 + fTemp[2] *mTranspose._ms._31 + fTemp[7] *mTranspose._ms._32; 
		this->_ms._44  = fTemp[10]*mTranspose._ms._33 + fTemp[4] *mTranspose._ms._31 + fTemp[9] *mTranspose._ms._32; 
		this->_ms._44 -= fTemp[8] *mTranspose._ms._32 + fTemp[11]*mTranspose._ms._33 + fTemp[5] *mTranspose._ms._31; 
 
		fDet = mTranspose._ms._11*this->_ms._11 + mTranspose._ms._12*this->_ms._12 +  
		         mTranspose._ms._13*this->_ms._13 + mTranspose._ms._14*this->_ms._14; 
 
		fDet = 1/fDet; 
 
		this->_ms._11 *= fDet;   
		this->_ms._12 *= fDet;   
		this->_ms._13 *= fDet;   
		this->_ms._14 *= fDet; 
 
		this->_ms._21 *= fDet;   
		this->_ms._22 *= fDet;   
		this->_ms._23 *= fDet;   
		this->_ms._24 *= fDet; 
 
		this->_ms._31 *= fDet;   
		this->_ms._32 *= fDet;   
		this->_ms._33 *= fDet;   
		this->_ms._34 *= fDet; 
 
		this->_ms._41 *= fDet;   
		this->_ms._42 *= fDet;   
		this->_ms._43 *= fDet;   
		this->_ms._44 *= fDet; 
	} 
	////////////////////////////////////////////////////////////////////////////////	 
	void ceMatrix::MakePerspectiveProjection(const FLOAT nearplane, const FLOAT farplane, const FLOAT theta,  
				const FLOAT ratio) 
	{ 
		const FLOAT top = nearplane * tan((theta * cePI) / 360.0f);	// top 
		const FLOAT bottom = -top;				// bottom 
		const FLOAT left = bottom * ratio;		// left 
		const FLOAT right = top * ratio;		// right 
		const FLOAT fVal = 1 / (farplane-nearplane); 
		const FLOAT fRL = 1 / (right-left); 
		const FLOAT fTB = 1 / (top - bottom); 
 
		const FLOAT a = (right+left) * fRL; 
		const FLOAT b = (top+bottom) * fTB; 
		const FLOAT c = -(farplane+nearplane) * fVal; 
		const FLOAT d = (-2.0f * farplane * nearplane ) * fVal; 
		const FLOAT x = (2.0f * nearplane) * fRL; 
		const FLOAT y = (2.0f * nearplane) * fTB; 
 
		_ms._11 = x;		 
		_ms._21 = 0.0f;	 
		_ms._31 = a;		 
		_ms._41 = 0.0f; 
			 
		_ms._12 = 0.0f;		 
		_ms._22 = y;	 
		_ms._32 = b; 
		_ms._42 = 0.0f; 
 
		_ms._13 = 0.0f;		 
		_ms._23 = 0.0f;	 
		_ms._33 = c;		 
		_ms._43 = d; 
 
		_ms._14 = 0.0f; 
		_ms._24 = 0.0f;	 
		_ms._34 = -1.0f;	 
		_ms._44 = 0.0f; 
	} 
	////////////////////////////////////////////////////////////////////////////////	 
	void ceMatrix::MakeOrthogonalProjection(FLOAT nearplane, FLOAT farplane, FLOAT theta,  
			FLOAT ratio) 
	{ 
		FLOAT top, bottom, right, left; 
		top = nearplane * tan((theta * cePI) / 360.0f);	// top 
		bottom = -top;				// bottom 
		left = bottom * ratio;		// left 
		right = top * ratio;		// right 
 
		const FLOAT x = 2.0f / (right-left); 
		const FLOAT y = 2.0f / (top - bottom); 
		const FLOAT a = -(right+left)/(right-left); 
		const FLOAT b = -(top+bottom)/(top-bottom); 
		const FLOAT c = -(farplane+nearplane)/(farplane-nearplane); 
		const FLOAT d = -2.0f/(farplane-nearplane); 
 
		_ms._11 = x;	 
		_ms._21 = 0.0f;	 
		_ms._31 = 0.0f; 
		_ms._41 = a; 
		_ms._12 = 0.0f;	 
		_ms._22 = y; 
		_ms._32 = 0.0f; 
		_ms._42 = b; 
		_ms._13 = 0.0f; 
		_ms._23 = 0.0f; 
		_ms._33 = d; 
		_ms._43 = c; 
		_ms._14 = 0.0f; 
		_ms._24 = 0.0f; 
		_ms._34 = 0.0f; 
		_ms._44 = 1.0f; 
	}	 
	//////////////////////////////////////////////////////////////////////////////// 
	void ceMatrix::Dump() 
	{ 
		std::cout << _ms._11 << " " << _ms._21 << " " << _ms._31 << " " << _ms._41 << std::endl; 
		std::cout << _ms._12 << " " << _ms._22 << " " << _ms._32 << " " << _ms._42 << std::endl; 
		std::cout << _ms._13 << " " << _ms._23 << " " << _ms._33 << " " << _ms._43 << std::endl; 
		std::cout << _ms._14 << " " << _ms._24 << " " << _ms._34 << " " << _ms._44 << std::endl; 
	} 
 
} // Namespace ZFXCE