// Author : Chris Tolley
// Date   : 7/06/2004
// matrix.cpp contains the class definition for a 4x4 matrix class which is 
// compatable with OpenGL

#include <math.h>

#include "matrix.h"

// Default Constructor
matrix::matrix()
{
	// Set all the values to zero
	memset( m_fMat, 0, 16 * sizeof( float ) );
}// End matrix::Default Constructor


// Constructor with arguments
matrix::matrix( const float* mat )
{
	m_fMat[0]  = mat[0];
	m_fMat[1]  = mat[1];
	m_fMat[2]  = mat[2];
	m_fMat[3]  = mat[3];
	m_fMat[4]  = mat[4];
	m_fMat[5]  = mat[5];
	m_fMat[6]  = mat[6];
	m_fMat[7]  = mat[7];
	m_fMat[8]  = mat[8];
	m_fMat[9]  = mat[9];
	m_fMat[10] = mat[10];
	m_fMat[11] = mat[11];
	m_fMat[12] = mat[12];
	m_fMat[13] = mat[13];
	m_fMat[14] = mat[14];
	m_fMat[15] = mat[15];
}// End matrix::Constructor with arguments


// Constructor with arguments
matrix::matrix( const float a, const float b, const float c, const float d,
				const float e, const float f, const float g, const float h,
				const float i, const float j, const float k, const float l,
				const float m, const float n, const float o, const float p )
{
	m_fMat[0]  = a;
	m_fMat[1]  = b;
	m_fMat[2]  = c;
	m_fMat[3]  = d;
	m_fMat[4]  = e;
	m_fMat[5]  = f;
	m_fMat[6]  = g;
	m_fMat[7]  = h;
	m_fMat[8]  = i;
	m_fMat[9]  = j;
	m_fMat[10] = k;
	m_fMat[11] = l;
	m_fMat[12] = m;
	m_fMat[13] = n;
	m_fMat[14] = o;
	m_fMat[15] = p;
}// End matrix::Constructor with arguments


// Copy Constructor
matrix::matrix( const matrix& rhs )
{
	m_fMat[0]  = rhs.m_fMat[0];
	m_fMat[1]  = rhs.m_fMat[1];
	m_fMat[2]  = rhs.m_fMat[2];
	m_fMat[3]  = rhs.m_fMat[3];
	m_fMat[4]  = rhs.m_fMat[4];
	m_fMat[5]  = rhs.m_fMat[5];
	m_fMat[6]  = rhs.m_fMat[6];
	m_fMat[7]  = rhs.m_fMat[7];
	m_fMat[8]  = rhs.m_fMat[8];
	m_fMat[9]  = rhs.m_fMat[9];
	m_fMat[10] = rhs.m_fMat[10];
	m_fMat[11] = rhs.m_fMat[11];
	m_fMat[12] = rhs.m_fMat[12];
	m_fMat[13] = rhs.m_fMat[13];
	m_fMat[14] = rhs.m_fMat[14];
	m_fMat[15] = rhs.m_fMat[15];
}// End matrix::Copy Constructor


// Destructor
matrix::~matrix()
{}


// Sets the matrix to the identity matrix
void matrix::LoadIdentity()
{
	// Zero out the matrix
	memset( m_fMat, 0, 16 * sizeof( float ) );

	// Set the diagonal column to zero
	m_fMat[0] = 1;
	m_fMat[5] = 1;
	m_fMat[10] = 1;
	m_fMat[15] = 1;
}// End matrix::LoadIdentity


// Zero's out all values in this matrix
void matrix::Zero()
{
	memset( m_fMat, 0, 16 * sizeof( float ) );
}// End matrix::Zero


// Returns true if the two matrices are equal
bool matrix::operator== ( const matrix& rhs ) const
{
	return m_fMat[0]  == rhs.m_fMat[0] &&
		   m_fMat[1]  == rhs.m_fMat[1] &&
		   m_fMat[2]  == rhs.m_fMat[2] &&
		   m_fMat[3]  == rhs.m_fMat[3] &&
		   m_fMat[4]  == rhs.m_fMat[4] &&
		   m_fMat[5]  == rhs.m_fMat[5] &&
		   m_fMat[6]  == rhs.m_fMat[6] &&
		   m_fMat[7]  == rhs.m_fMat[7] &&
		   m_fMat[8]  == rhs.m_fMat[8] &&
		   m_fMat[9]  == rhs.m_fMat[9] &&
		   m_fMat[10] == rhs.m_fMat[10] &&
		   m_fMat[11] == rhs.m_fMat[11] &&
		   m_fMat[12] == rhs.m_fMat[12] &&
		   m_fMat[13] == rhs.m_fMat[13] &&
		   m_fMat[14] == rhs.m_fMat[14] &&
		   m_fMat[15] == rhs.m_fMat[15];
}// End matrix::operator ==


// Returns true if the two matrices are not equal
bool matrix::operator!= ( const matrix& rhs ) const
{
	return m_fMat[0]  != rhs.m_fMat[0] &&
		   m_fMat[1]  != rhs.m_fMat[1] &&
		   m_fMat[2]  != rhs.m_fMat[2] &&
		   m_fMat[3]  != rhs.m_fMat[3] &&
		   m_fMat[4]  != rhs.m_fMat[4] &&
		   m_fMat[5]  != rhs.m_fMat[5] &&
		   m_fMat[6]  != rhs.m_fMat[6] &&
		   m_fMat[7]  != rhs.m_fMat[7] &&
		   m_fMat[8]  != rhs.m_fMat[8] &&
		   m_fMat[9]  != rhs.m_fMat[9] &&
		   m_fMat[10] != rhs.m_fMat[10] &&
		   m_fMat[11] != rhs.m_fMat[11] &&
		   m_fMat[12] != rhs.m_fMat[12] &&
		   m_fMat[13] != rhs.m_fMat[13] &&
		   m_fMat[14] != rhs.m_fMat[14] &&
		   m_fMat[15] != rhs.m_fMat[15];
}// End matrix::operator !=


// Returns the product of this matrix and scalar
matrix matrix::operator* ( const int scalar ) const
{
	// Create and return a temp matrix to store the product
	return matrix(
		m_fMat[0] * scalar,
		m_fMat[1] * scalar,
		m_fMat[2] * scalar,
		m_fMat[3] * scalar,
		m_fMat[4] * scalar,
		m_fMat[5] * scalar,
		m_fMat[6] * scalar,
		m_fMat[7] * scalar,
		m_fMat[8] * scalar,
		m_fMat[9] * scalar,
		m_fMat[10] * scalar,
		m_fMat[11] * scalar,
		m_fMat[12] * scalar,
		m_fMat[13] * scalar,
		m_fMat[14] * scalar,
		m_fMat[15] * scalar );
}// End matrix::operator*


// Returns the product of these two matrices
matrix matrix::operator* ( const matrix& rhs ) const
{
	// Create a temp matrix to store the results in
	matrix temp;

	// Do the math, no loops here.
	temp.m_fMat[0] = m_fMat[0] * rhs.m_fMat[0] + m_fMat[1] * rhs.m_fMat[4] + 
					 m_fMat[2] * rhs.m_fMat[8] + m_fMat[3] * rhs.m_fMat[12];

	temp.m_fMat[1] = m_fMat[0] * rhs.m_fMat[1] + m_fMat[1] * rhs.m_fMat[5] + 
				   	 m_fMat[2] * rhs.m_fMat[9] + m_fMat[3] * rhs.m_fMat[13];

	temp.m_fMat[2] = m_fMat[0] * rhs.m_fMat[2] + m_fMat[1] * rhs.m_fMat[6] + 
					 m_fMat[2] * rhs.m_fMat[10] + m_fMat[3] * rhs.m_fMat[14];

	temp.m_fMat[3] = m_fMat[0] * rhs.m_fMat[3] + m_fMat[1] * rhs.m_fMat[7] + 
					 m_fMat[2] * rhs.m_fMat[11] + m_fMat[3] * rhs.m_fMat[15];

	temp.m_fMat[4] = m_fMat[4] * rhs.m_fMat[0] + m_fMat[5] * rhs.m_fMat[4] + 
					 m_fMat[6] * rhs.m_fMat[8] + m_fMat[7] * rhs.m_fMat[12];

	temp.m_fMat[5] = m_fMat[4] * rhs.m_fMat[1] + m_fMat[5] * rhs.m_fMat[5] + 
					 m_fMat[6] * rhs.m_fMat[9] + m_fMat[7] * rhs.m_fMat[13];

	temp.m_fMat[6] = m_fMat[4] * rhs.m_fMat[2] + m_fMat[5] * rhs.m_fMat[6] + 
				 	 m_fMat[6] * rhs.m_fMat[10] + m_fMat[7] * rhs.m_fMat[14];

	temp.m_fMat[7] = m_fMat[4] * rhs.m_fMat[3] + m_fMat[5] * rhs.m_fMat[7] + 
					 m_fMat[6] * rhs.m_fMat[11] + m_fMat[7] * rhs.m_fMat[15];

	temp.m_fMat[8] = m_fMat[8] * rhs.m_fMat[0] + m_fMat[9] * rhs.m_fMat[4] + 
					 m_fMat[10] * rhs.m_fMat[8] + m_fMat[11] * rhs.m_fMat[12];

	temp.m_fMat[9] = m_fMat[8] * rhs.m_fMat[1] + m_fMat[9] * rhs.m_fMat[5] + 
					 m_fMat[10] * rhs.m_fMat[9] + m_fMat[11] * rhs.m_fMat[13];

	temp.m_fMat[10] = m_fMat[8] * rhs.m_fMat[2] + m_fMat[9] * rhs.m_fMat[6] + 
  				     m_fMat[10] * rhs.m_fMat[10] + m_fMat[11] * rhs.m_fMat[14];

	temp.m_fMat[11] = m_fMat[8] * rhs.m_fMat[3] + m_fMat[9] * rhs.m_fMat[7] + 
					 m_fMat[10] * rhs.m_fMat[11] + m_fMat[11] * rhs.m_fMat[15];

	temp.m_fMat[12] = m_fMat[12] * rhs.m_fMat[0] + m_fMat[13] * rhs.m_fMat[4] + 
					  m_fMat[14] * rhs.m_fMat[8] + m_fMat[15] * rhs.m_fMat[12];

	temp.m_fMat[13] = m_fMat[12] * rhs.m_fMat[1] + m_fMat[13] * rhs.m_fMat[5] +
					  m_fMat[14] * rhs.m_fMat[9] + m_fMat[15] * rhs.m_fMat[13];

	temp.m_fMat[14] = m_fMat[12] * rhs.m_fMat[2] + m_fMat[13] * rhs.m_fMat[6] + 
					m_fMat[14] * rhs.m_fMat[10] + m_fMat[15] * rhs.m_fMat[14];

	temp.m_fMat[15] = m_fMat[12] * rhs.m_fMat[3] + m_fMat[13] * rhs.m_fMat[7] + 
					  m_fMat[14] * rhs.m_fMat[11] + m_fMat[15] * rhs.m_fMat[15];

	// Return the temp matrix
	return temp;
}// End matrix::operator*


// Stores the result of multipling this matrix with rhs
matrix& matrix::operator*= ( const matrix& rhs )
{
	// Create a temp matrix to store the results in
	matrix temp;

	// Do the math, no loops here.
	temp.m_fMat[0] = m_fMat[0] * rhs.m_fMat[0] + m_fMat[1] * rhs.m_fMat[4] + 
					 m_fMat[2] * rhs.m_fMat[8] + m_fMat[3] * rhs.m_fMat[12];

	temp.m_fMat[1] = m_fMat[0] * rhs.m_fMat[1] + m_fMat[1] * rhs.m_fMat[5] + 
				   	 m_fMat[2] * rhs.m_fMat[9] + m_fMat[3] * rhs.m_fMat[13];

	temp.m_fMat[2] = m_fMat[0] * rhs.m_fMat[2] + m_fMat[1] * rhs.m_fMat[6] + 
					 m_fMat[2] * rhs.m_fMat[10] + m_fMat[3] * rhs.m_fMat[14];

	temp.m_fMat[3] = m_fMat[0] * rhs.m_fMat[3] + m_fMat[1] * rhs.m_fMat[7] + 
					 m_fMat[2] * rhs.m_fMat[11] + m_fMat[3] * rhs.m_fMat[15];

	temp.m_fMat[4] = m_fMat[4] * rhs.m_fMat[0] + m_fMat[5] * rhs.m_fMat[4] + 
					 m_fMat[6] * rhs.m_fMat[8] + m_fMat[7] * rhs.m_fMat[12];

	temp.m_fMat[5] = m_fMat[4] * rhs.m_fMat[1] + m_fMat[5] * rhs.m_fMat[5] + 
					 m_fMat[6] * rhs.m_fMat[9] + m_fMat[7] * rhs.m_fMat[13];

	temp.m_fMat[6] = m_fMat[4] * rhs.m_fMat[2] + m_fMat[5] * rhs.m_fMat[6] + 
				 	 m_fMat[6] * rhs.m_fMat[10] + m_fMat[7] * rhs.m_fMat[14];

	temp.m_fMat[7] = m_fMat[4] * rhs.m_fMat[3] + m_fMat[5] * rhs.m_fMat[7] + 
					 m_fMat[6] * rhs.m_fMat[11] + m_fMat[7] * rhs.m_fMat[15];

	temp.m_fMat[8] = m_fMat[8] * rhs.m_fMat[0] + m_fMat[9] * rhs.m_fMat[4] + 
					 m_fMat[10] * rhs.m_fMat[8] + m_fMat[11] * rhs.m_fMat[12];

	temp.m_fMat[9] = m_fMat[8] * rhs.m_fMat[1] + m_fMat[9] * rhs.m_fMat[5] + 
					 m_fMat[10] * rhs.m_fMat[9] + m_fMat[11] * rhs.m_fMat[13];

	temp.m_fMat[10] = m_fMat[8] * rhs.m_fMat[2] + m_fMat[9] * rhs.m_fMat[6] + 
  				     m_fMat[10] * rhs.m_fMat[10] + m_fMat[11] * rhs.m_fMat[14];

	temp.m_fMat[11] = m_fMat[8] * rhs.m_fMat[3] + m_fMat[9] * rhs.m_fMat[7] + 
					 m_fMat[10] * rhs.m_fMat[11] + m_fMat[11] * rhs.m_fMat[15];

	temp.m_fMat[12] = m_fMat[12] * rhs.m_fMat[0] + m_fMat[13] * rhs.m_fMat[4] + 
					  m_fMat[14] * rhs.m_fMat[8] + m_fMat[15] * rhs.m_fMat[12];

	temp.m_fMat[13] = m_fMat[12] * rhs.m_fMat[1] + m_fMat[13] * rhs.m_fMat[5] +
					  m_fMat[14] * rhs.m_fMat[9] + m_fMat[15] * rhs.m_fMat[13];

	temp.m_fMat[14] = m_fMat[12] * rhs.m_fMat[2] + m_fMat[13] * rhs.m_fMat[6] + 
					m_fMat[14] * rhs.m_fMat[10] + m_fMat[15] * rhs.m_fMat[14];

	temp.m_fMat[15] = m_fMat[12] * rhs.m_fMat[3] + m_fMat[13] * rhs.m_fMat[7] + 
					  m_fMat[14] * rhs.m_fMat[11] + m_fMat[15] * rhs.m_fMat[15];

	*this = temp;
	return *this;
}// End matrix::operator*=


// Returns the result of dividing this matrix with scalar
matrix matrix::operator/ ( const int scalar ) const
{
	// Create and return a temp matrix to store the result
	return matrix( 
		m_fMat[0] / scalar,
		m_fMat[1] / scalar,
		m_fMat[2] / scalar,
		m_fMat[3] / scalar,
		m_fMat[4] / scalar,
		m_fMat[5] / scalar,
		m_fMat[6] / scalar,
		m_fMat[7] / scalar,
		m_fMat[8] / scalar,
		m_fMat[9] / scalar,
		m_fMat[10] / scalar,
		m_fMat[11] / scalar,
		m_fMat[12] / scalar,
		m_fMat[13] / scalar,
		m_fMat[14] / scalar,
		m_fMat[15] / scalar );
}// End matrix::operator/


// Returns the result of dividing this matrix with another
matrix matrix::operator/ ( const matrix& rhs ) const
{
	// Create and return a temp matrix to store the result
	return matrix(
		m_fMat[0]  / rhs.m_fMat[0],
		m_fMat[1]  / rhs.m_fMat[1],
		m_fMat[2]  / rhs.m_fMat[2],
		m_fMat[3]  / rhs.m_fMat[3],
		m_fMat[4]  / rhs.m_fMat[4],
		m_fMat[5]  / rhs.m_fMat[5],
		m_fMat[6]  / rhs.m_fMat[6],
		m_fMat[7]  / rhs.m_fMat[7],
		m_fMat[8]  / rhs.m_fMat[8],
		m_fMat[9]  / rhs.m_fMat[9],
		m_fMat[10] / rhs.m_fMat[10],
		m_fMat[11] / rhs.m_fMat[11],
		m_fMat[12] / rhs.m_fMat[12],
		m_fMat[13] / rhs.m_fMat[13],
		m_fMat[14] / rhs.m_fMat[14],
		m_fMat[15] / rhs.m_fMat[15] );
}// End matrix::operator/


// Returns the sum of this matrix and scalar
matrix matrix::operator+ ( const int scalar ) const
{
	// Create a temp matrix to store the sum in
	return matrix(
		m_fMat[0]  + scalar,
		m_fMat[1]  + scalar,
		m_fMat[2]  + scalar,
		m_fMat[3]  + scalar,
		m_fMat[4]  + scalar,
		m_fMat[5]  + scalar,
		m_fMat[6]  + scalar,
		m_fMat[7]  + scalar,
		m_fMat[8]  + scalar,
		m_fMat[9]  + scalar,
		m_fMat[10] + scalar,
		m_fMat[11] + scalar,
		m_fMat[12] + scalar,
		m_fMat[13] + scalar,
		m_fMat[14] + scalar,
		m_fMat[15] + scalar );
}// End matrix::operator+


// Returns the sum of this matrix and rhs
matrix matrix::operator+ ( const matrix& rhs ) const
{
	// Create and return a temp matrix to store the product in
	return matrix( 
		m_fMat[0]  + rhs.m_fMat[0],
		m_fMat[1]  + rhs.m_fMat[1],
		m_fMat[2]  + rhs.m_fMat[2],
		m_fMat[3]  + rhs.m_fMat[3],
		m_fMat[4]  + rhs.m_fMat[4],
		m_fMat[5]  + rhs.m_fMat[5],
		m_fMat[6]  + rhs.m_fMat[6],
		m_fMat[7]  + rhs.m_fMat[7],
		m_fMat[8]  + rhs.m_fMat[8],
		m_fMat[9]  + rhs.m_fMat[9],
		m_fMat[10] + rhs.m_fMat[10],
		m_fMat[11] + rhs.m_fMat[11],
		m_fMat[12] + rhs.m_fMat[12],
		m_fMat[13] + rhs.m_fMat[13],
		m_fMat[14] + rhs.m_fMat[14],
		m_fMat[15] + rhs.m_fMat[15] );
}// End matrix::operator+


// Stores the sum of the two matrices
matrix matrix::operator+= ( const matrix& rhs )
{
	// Create a temp matrix to store the sum in
	matrix temp(
		m_fMat[0]  + rhs.m_fMat[0],
		m_fMat[1]  + rhs.m_fMat[1],
		m_fMat[2]  + rhs.m_fMat[2],
		m_fMat[3]  + rhs.m_fMat[3],
		m_fMat[4]  + rhs.m_fMat[4],
		m_fMat[5]  + rhs.m_fMat[5],
		m_fMat[6]  + rhs.m_fMat[6],
		m_fMat[7]  + rhs.m_fMat[7],
		m_fMat[8]  + rhs.m_fMat[8],
		m_fMat[9]  + rhs.m_fMat[9],
		m_fMat[10] + rhs.m_fMat[10],
		m_fMat[11] + rhs.m_fMat[11],
		m_fMat[12] + rhs.m_fMat[12],
		m_fMat[13] + rhs.m_fMat[13],
		m_fMat[14] + rhs.m_fMat[14],
		m_fMat[15] + rhs.m_fMat[15] );

	*this = temp;
	return *this;
}// End matrix::operator+=


// Return the difference between this matrix and scalar
matrix matrix::operator- ( const int scalar ) const
{
	// Create a temp matrix to store the difference in
	return matrix(
		m_fMat[0]  - scalar,
		m_fMat[1]  - scalar,
		m_fMat[2]  - scalar,
		m_fMat[3]  - scalar,
		m_fMat[4]  - scalar,
		m_fMat[5]  - scalar,
		m_fMat[6]  - scalar,
		m_fMat[7]  - scalar,
		m_fMat[8]  - scalar,
		m_fMat[9]  - scalar,
		m_fMat[10] - scalar,
		m_fMat[11] - scalar,
		m_fMat[12] - scalar,
		m_fMat[13] - scalar,
		m_fMat[14] - scalar,
		m_fMat[15] - scalar );
}// End matrix::operator-


// Returns the difference between the two matrices
matrix matrix::operator- ( const matrix& rhs ) const
{
	// Create a temp matrix to store the difference in
	return matrix( 
		m_fMat[0]  - rhs.m_fMat[0],
		m_fMat[1]  - rhs.m_fMat[1],
		m_fMat[2]  - rhs.m_fMat[2],
		m_fMat[3]  - rhs.m_fMat[3],
		m_fMat[4]  - rhs.m_fMat[4],
		m_fMat[5]  - rhs.m_fMat[5],
		m_fMat[6]  - rhs.m_fMat[6],
		m_fMat[7]  - rhs.m_fMat[7],
		m_fMat[8]  - rhs.m_fMat[8],
		m_fMat[9]  - rhs.m_fMat[9],
		m_fMat[10] - rhs.m_fMat[10],
		m_fMat[11] - rhs.m_fMat[11],
		m_fMat[12] - rhs.m_fMat[12],
		m_fMat[13] - rhs.m_fMat[13],
		m_fMat[14] - rhs.m_fMat[14],
		m_fMat[15] - rhs.m_fMat[15] );
}// End matrix::operator-

// Stores the difference between the two matrices
matrix matrix::operator-= ( const matrix& rhs )
{
	// Create a temp matrix to store the difference in
	matrix temp( 
		m_fMat[0]  - rhs.m_fMat[0],
		m_fMat[1]  - rhs.m_fMat[1],
		m_fMat[2]  - rhs.m_fMat[2],
		m_fMat[3]  - rhs.m_fMat[3],
		m_fMat[4]  - rhs.m_fMat[4],
		m_fMat[5]  - rhs.m_fMat[5],
		m_fMat[6]  - rhs.m_fMat[6],
		m_fMat[7]  - rhs.m_fMat[7],
		m_fMat[8]  - rhs.m_fMat[8],
		m_fMat[9]  - rhs.m_fMat[9],
		m_fMat[10] - rhs.m_fMat[10],
		m_fMat[11] - rhs.m_fMat[11],
		m_fMat[12] - rhs.m_fMat[12],
		m_fMat[13] - rhs.m_fMat[13],
		m_fMat[14] - rhs.m_fMat[14],
		m_fMat[15] - rhs.m_fMat[15] );

	*this = temp;
	return *this;
}// End matrix::operator -=


// Sets the rotational values
void matrix::Rotate( const float x, const float y, const float z )
{
	// Create a matrix to hold the rotational matrix in
	matrix rot;
	rot.LoadIdentity();

	// Some variables to make this nicer
	double cx = cos( x );
	double sx = sin( x );
	double cy = cos( y );
	double sy = sin( y );
	double cz = cos( z );
	double sz = sin( z );

	rot[0] = ( float )( cy * cz );
	rot[1] = ( float )( cy * sz );
	rot[2] = ( float )( -sy );

	rot[4] = ( float )( sx * sy * cz - cx * sz );
	rot[5] = ( float )( sx * sy * sz + cx * cz );
	rot[6] = ( float )( sx * cy );

	rot[8] = ( float )( cx * sy * cz + sx * sz );
	rot[9] = ( float )( cx * sy * sz - sx * cz );
	rot[10] = ( float )( cx * cy );

	rot[15] = 1.0f;

	rot *= *this;
	*this = rot;
}// End matrix::Rotate


// Sets the rotational values
void matrix::Rotate( const float* rota )
{
	// Create a matrix to hold the rotational matrix in
	matrix rot;
	rot.LoadIdentity();

	// Some variables to make this nicer
	double cx = cos( rota[0] );
	double sx = sin( rota[0] );
	double cy = cos( rota[1] );
	double sy = sin( rota[1] );
	double cz = cos( rota[2] );
	double sz = sin( rota[2] );

	rot[0] = ( float )( cy * cz );
	rot[1] = ( float )( cy * sz );
	rot[2] = ( float )( -sy );

	rot[4] = ( float )( sx * sy * cz - cx * sz );
	rot[5] = ( float )( sx * sy * sz + cx * cz );
	rot[6] = ( float )( sx * cy );

	rot[8] = ( float )( cx * sy * cz + sx * sz );
	rot[9] = ( float )( cx * sy * sz - sx * cz );
	rot[10] = ( float )( cx * cy );

	rot[15] = 1.0f;

	rot *= *this;
	*this = rot;
/*	double cx = cos( rot[0] );
	double sx = sin( rot[0] );
	double cy = cos( rot[1] );
	double sy = sin( rot[1] );
	double cz = cos( rot[2] );
	double sz = sin( rot[2] );

	m_fMat[0] = ( float )( cy * cz );
	m_fMat[1] = ( float )( cy * sz );
	m_fMat[2] = ( float )( -sy );

	m_fMat[4] = ( float )( sx * sy * cz - cx * sz );
	m_fMat[5] = ( float )( sx * sy * sz + cx * cz );
	m_fMat[6] = ( float )( sx * cy );

	m_fMat[8] = ( float )( cx * sy * cz + sx * sz );
	m_fMat[9] = ( float )( cx * sy * sz - sx * cz );
	m_fMat[10] = ( float )( cx * cy );

	m_fMat[15] = 1.0f;
	*/
}// End matrix::Rotate


// Sets a translation
void matrix::Translate( const float x, const float y, const float z )
{
	// Create a translation matrix
	matrix trans(
		1, 0, 0, 0,
		0, 1, 0, 0,
		0, 0, 1, 0,
		x, y, z, 1 );

	// Multiple this matrix by the translation matrix and store the results
	trans *= *this;
	*this = trans;

//	m_fMat[12] = x;
//	m_fMat[13] = y;
//	m_fMat[14] = z;
}// End matrix::Translate


// Sets a translation
void matrix::Translate( const float* tran )
{
	// Create a translation matrix
	matrix trans(
		1, 0, 0, 0,
		0, 1, 0, 0,
		0, 0, 1, 0,
		tran[0], tran[1], tran[2], 1 );

	// Multiple this matrix by the translation matrix and store the results
	trans *= *this;
	*this = trans;

//	m_fMat[12] = tran[0];
//	m_fMat[13] = tran[1];
//	m_fMat[14] = tran[2];
}// End matrix::Translate


// Sets the scale values
void matrix::Scale( const float x, const float y, const float z )
{
	// Create a scaling matrix
	matrix scale( x, 0, 0, 0,
				  0, y, 0, 0,
				  0, 0, z, 0,
				  0, 0, 0, 1 );

	scale *= *this;
	*this = scale;
}// End matrix::Scale


// Sets the scale values
void matrix::Scale( const float* sca )
{
	// Create a scaling matrix
	matrix scale( sca[0], 0,      0,      0,
				  0,      sca[1], 0,      0,
				  0,      0,      sca[2], 0,
				  0,      0,      0,      1 );

	scale *= *this;
	*this = scale;
}// End matrix::Scale


/*
// Transforms these three points by the model's local coordinate system
void matrix::Transform( float& x, float& y, float& z ) const
{
	// Calculate the transformations
	float nx = ( x * m_fMat[0] + y * m_fMat[4] + 
				 z * m_fMat[ 8] + 1 * m_fMat[12] );

	float ny = ( x * m_fMat[1] + y * m_fMat[5] + 
				 z * m_fMat[ 9] + 1 * m_fMat[13] );
	
	float nz = ( x * m_fMat[2] + y * m_fMat[6] + 
				 z * m_fMat[10] + 1 * m_fMat[14] );

	// Set the transformations
	x = nx;
	y = ny;
	z = nz;
}// End matrix::Transform


// Transforms these three points by the model's local coordinate system
void matrix::Transform( float* pos ) const
{
	// Make this function a little easier
	float x = pos[0];
	float y = pos[1];
	float z = pos[2];

	// Calculate the transformations
	float nx = ( x * m_fMat[0] + y * m_fMat[4] + 
				 z * m_fMat[ 8] + 1 * m_fMat[12] );

	float ny = ( x * m_fMat[1] + y * m_fMat[5] + 
				 z * m_fMat[ 9] + 1 * m_fMat[13] );
	
	float nz = ( x * m_fMat[2] + y * m_fMat[6] + 
				 z * m_fMat[10] + 1 * m_fMat[14] );

	// Set the transformations
	pos[0] = nx;
	pos[1] = ny;
	pos[2] = nz;
}// End matrix::Transform
*/