#include "Matrice4.h"

const Matrice4 MAT4_NULL(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
const Matrice4 MAT4_ID(1.0, 0.0, 0.0, 0.0,
		       0.0, 1.0, 0.0, 0.0,
		       0.0, 0.0, 1.0, 0.0,
		       0.0, 0.0, 0.0, 1.0);

///fonction qui fait un produit vectoriel
/**	@param x : composante x du produit vectoriel
 * 	@param y : composante y du produit vectoriel
 * 	@param z : composante z du produit vectoriel
 * 	@param x1 : x du premier vecteur
 * 	@param y1 : y du premier vecteur
 * 	@param z1 : z du premier vecteur
 * 	@param x2 : x du deuxième vecteur
 * 	@param y2 : y du deuxième vecteur
 * 	@param z2 : z du deuxième vecteur
*/
void produitVectoriel(float & x, float & y, float & z,float x1, float y1, float z1, float x2, float y2, float z2){
	x = (y1*z2 - y2*z1);
	y = (x2*z1 - x1*z2);
	z = (x1*y2 - x2*y1);
}

///fonction qui normalise un vecteur
/**	@param x : composante x du vecteur à normaliser (sera la composante x normalisée)
 * 	@param y : composante y du vecteur à normaliser (sera la composante y normalisée)
 * 	@param z : composante z du vecteur à normaliser (sera la composante z normalisée)
*/
void normaliseVecteur(float & x, float & y, float & z){
	float norme(sqrt(x*x + y*y + z*z));
	if(norme != 0.0 && norme != 1.0){
		x /= norme;
		y /= norme;
		z /= norme;
	}
}

///////////////////////////////////////////////////
//                                               //
//   Fonctions publiques de la classe Matrice4   //
//                                               //
///////////////////////////////////////////////////


///Constructeur par défaut de Matrice4
Matrice4::Matrice4(){
	p_mat = NULL;
	initialisationMatrice4(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
}

///constructeur de Matrice4
/**	@param v1 : Vecteur4
 * 	@param v2 : Vecteur4
 * 	@param v3 : Vecteur4
 * 	@param v4 : Vecteur4
*/
Matrice4::Matrice4(const Vecteur4 & v1, const Vecteur4 & v2, const Vecteur4 & v3, const Vecteur4 & v4){
	p_mat = NULL;
	this->initialisationMatrice4(v1, v2, v3, v4);
}


Matrice4::Matrice4(float x1, float y1, float z1, float t1,
	float x2, float y2, float z2, float t2,
	float x3, float y3, float z3, float t3,
	float x4, float y4, float z4, float t4)
{
	p_mat = NULL;
	initialisationMatrice4(x1, y1, z1, t1, x2, y2, z2, t2, x3, y3, z3, t3, x4, y4, z4, t4);
}

///Constructeur de copier de Matrice4
/**	@param other : Matrice4 à copier
*/
Matrice4::Matrice4(const Matrice4 & other){
	p_mat = NULL;
	this->copyMatrice4(other);
}

///Destructeur de Matrice4
Matrice4::~Matrice4(){
	depiler();
	if(p_mat != NULL) delete [] p_mat;
}

///fonction d'initialisation de Matrice4
/**	@param v1 : Vecteur4
 * 	@param v2 : Vecteur4
 * 	@param v3 : Vecteur4
 * 	@param v4 : Vecteur4
*/
void Matrice4::setMatrice4(const Vecteur4 & v1, const Vecteur4 & v2, const Vecteur4 & v3, const Vecteur4 & v4){
	this->initialisationMatrice4(v1, v2, v3, v4);
}


void Matrice4::setMatrice4(float x1, float y1, float z1, float t1,
			float x2, float y2, float z2, float t2,
			float x3, float y3, float z3, float t3,
			float x4, float y4, float z4, float t4)
{
	initialisationMatrice4(x1, y1, z1, t1, x2, y2, z2, t2, x3, y3, z3, t3, x4, y4, z4, t4);
}

///fonction qui transforme la matrice en matrice identité
void Matrice4::loadIdentity(){
	depiler();
	this->loadNull();
	p_mat[0] = 1;
	p_mat[5] = 1;
	p_mat[10] = 1;
	p_mat[15] = 1;
}

///fonction qui transforme la matrice en matrice nulle
void Matrice4::loadNull(){
	for(unsigned int i(0); i < 16; i++) p_mat[i] = 0.0;
}

///fonction qui permet de faire une translation de la matrice (si on s'en sert de matrice de projection)
/**	@param x translation en x
 * 	@param y translation en z
 * 	@param y translation en z
*/
void Matrice4::translated(float x, float y, float z){
	Matrice4 translation;
	translation.loadIdentity();
	translation.p_mat[3] = x;
	translation.p_mat[7] = y;
	translation.p_mat[11] = z;
	*this *= translation;
}

///fonction qui permet de changer l'échelle de la matrice (si on s'en sert de matrice de projection)
/**	@param x translation en x
 * 	@param y translation en z
 * 	@param y translation en z
*/
void Matrice4::scale(float x, float y, float z){
	Matrice4 scale;
	scale.p_mat[0] = x;
	scale.p_mat[5] = y;
	scale.p_mat[10] = z;
	scale.p_mat[15] = 1.0;
	*this *= scale;
}

///fonction qui permet de créer une matrice de rotation
/**	@param angle : angle de rotation (en radian)
 * 	@param x : composante x de l'axe de rotation
 * 	@param y : composante y de l'axe de rotation
 * 	@param z : composante z de l'axe de rotation
*/
void Matrice4::rotateRad(float angleRad, float x, float y, float z){
	Matrice4 rotation;
	// Normalisation du vecteur axe
	float norme(sqrt(x*x + y*y + z*z));
	if(norme != 0.0){
		x /= norme;
		y /= norme;
		z /= norme;
	}
	
	rotation.p_mat[0] = x*x + (1 - x*x)*cos(angleRad);
	rotation.p_mat[4] = x*y*(1 - cos(angleRad)) + z*sin(angleRad);
	rotation.p_mat[8] =x*z*(1 - cos(angleRad)) - y*sin(angleRad);
	
	rotation.p_mat[1] = x*y*(1 - cos(angleRad)) - z*sin(angleRad);
	rotation.p_mat[5] = y*y + (1 - y*y)*cos(angleRad);
	rotation.p_mat[9] = y*z*(1- cos(angleRad)) + x*sin(angleRad);
	
	rotation.p_mat[2] = x*z*(1 - cos(angleRad)) + y*sin(angleRad);
	rotation.p_mat[6] = y*z*(1 - cos(angleRad)) - x*sin(angleRad);
	rotation.p_mat[10] = z*z + (1 - z*z)*cos(angleRad);

	rotation.p_mat[15] = 1.0;
	*this *= rotation;
}

///fonction qui permet de créer une matrice de rotation
/**	@param angle : angle de rotation (en degré)
 * 	@param x : composante x de l'axe de rotation
 * 	@param y : composante y de l'axe de rotation
 * 	@param z : composante z de l'axe de rotation
*/
void Matrice4::rotateDeg(float angle, float x, float y, float z){
	rotateRad((angle*M_PI)/180.0, x, y, z);
}

///fonction qui initialise la perspective de la matrice (qui sera la matrice de projection du monde OpenGl 3.1)
/**	@param angle : angle de vue (en radian 70*M_PI/180.0)
 * 	@param ratio : ratio de l'écran
 * 	@param near : position la plus proche que l'on peut afficher
 * 	@param far : position la plus lointaine que l'on peut afficher
*/
void Matrice4::perspectiveRad(float angle, float ratio, float near, float far){
	float f(1/tan((angle/2.0)));
	Matrice4 projection;
	projection.p_mat[0] = f/ratio;
	projection.p_mat[5] = f;
	projection.p_mat[10] = (near + far)/(near - far);
	projection.p_mat[11] = (2.0*near*far)/(near - far);
	projection.p_mat[14] = -1.0;
	
	*this *= projection;
}

///fonction qui initialise la perspective de la matrice (qui sera la matrice de projection du monde OpenGl 3.1)
/**	@param angle : angle de vue (en degré 70°)
 * 	@param ratio : ratio de l'écran
 * 	@param near : position la plus proche que l'on peut afficher
 * 	@param far : position la plus lointaine que l'on peut afficher
*/
void Matrice4::perspectiveDeg(float angle, float ratio, float near, float far){
	perspectiveRad((angle*M_PI)/180.0, ratio, near, far);
}

//si vous vous amnusez à commenter la ligne qui suit, vous aller voir ce qu'est une matrice de projection qui ne fait pas son boulôt correctement
#define CALCUL_DE_BASE
///fonction qui permet de dire où on veut regarder
/**	@param eyeX : position en x de l'endroit d'où on regarde
 * 	@param eyeY : position en y de l'endroit d'où on regarde
 * 	@param eyeZ : position en z de l'endroit d'où on regarde
 * 	@param centerX : position en x de l'object que l'on regarde
 * 	@param centerY : position en y de l'object que l'on regarde
 * 	@param centerZ : position en z de l'object que l'on regarde
 * 	@param upX : composante x du vecteur vertical
 * 	@param upY : composante y du vecteur vertical
 * 	@param upZ : composante z du vecteur vertical
*/
void Matrice4::lookAt(float eyeX, float eyeY, float eyeZ, float centerX, float centerY, float centerZ, float upX, float upY, float upZ){
	float regardX(centerX - eyeX), regardY(centerY - eyeY), regardZ(centerZ - eyeZ);
	float normaleX, normaleY, normaleZ, newAxeX,newAxeY, newAxeZ;
	
	produitVectoriel(normaleX, normaleY, normaleZ, regardX, regardY, regardZ, upX, upY, upZ);
	produitVectoriel(newAxeX,newAxeY, newAxeZ, normaleX, normaleY, normaleZ, regardX, regardY, regardZ);
	
	normaliseVecteur(normaleX, normaleY, normaleZ);
	normaliseVecteur(newAxeX,newAxeY, newAxeZ);
	normaliseVecteur(regardX, regardY, regardZ);
	Matrice4 matrice;
#ifdef CALCUL_DE_BASE
	matrice.p_mat[0] = normaleX;
	matrice.p_mat[1] = normaleY;
	matrice.p_mat[2] = normaleZ;
	matrice.p_mat[3] = 0.0;
	
	matrice.p_mat[4] = newAxeX;
	matrice.p_mat[5] = newAxeY;
	matrice.p_mat[6] = newAxeZ;
	matrice.p_mat[7] = 0.0;

	matrice.p_mat[8] = -regardX;
	matrice.p_mat[9] = -regardY;
	matrice.p_mat[10] = -regardZ;
	matrice.p_mat[11] = 0.0;
#else
	matrice.p_mat[0] = normaleX;
	matrice.p_mat[1] = newAxeX;
	matrice.p_mat[2] = -regardX;
	matrice.p_mat[3] = 0.0;
	
	matrice.p_mat[4] = normaleY;
	matrice.p_mat[5] = newAxeY;
	matrice.p_mat[6] = -regardY;
	matrice.p_mat[7] = 0.0;

	matrice.p_mat[8] = normaleZ;
	matrice.p_mat[9] = newAxeZ;
	matrice.p_mat[10] = -regardZ;
	matrice.p_mat[11] = 0.0;
#endif
	matrice.p_mat[12] = 0.0;
	matrice.p_mat[13] = 0.0;
	matrice.p_mat[14] = 0.0;
	matrice.p_mat[15] = 1.0;

	
	// Multiplication des matrices, puis translation de la matrice modelview
	*this = *this * matrice;
	translated(-eyeX, -eyeY, -eyeZ);
}

///fonction qui permet de dire où on veut regarder
/**	@param eye : position de l'endroit d'où on regarde
 * 	@param center : position de l'object que l'on regarde
 * 	@param up : vecteur vertical
*/
void Matrice4::lookAt(const Vecteur3f & eye, const Vecteur3f & center, const Vecteur3f & up){
	lookAt(eye.getx(), eye.gety(), eye.getz(), center.getx(), center.gety(), center.getz(), up.getx(), up.gety(), up.getz());
}

///fonction qui permet à la matrice de faire pointer la caméra vers l'endroit désiré
/**	@param position : position de la caméra
 * 	@param visee : direction dans laquelle la caméra doit regarder
 * 	@param planDroit : vecteur qui désigne la direction pour aller à droite
 *	@param up : vecteur qui donne la verticale de la caméra 
*/
void Matrice4::lookAt(const Vecteur3f & position, const Vecteur3f & visee, const Vecteur3f & planDroit, const Vecteur3f & up){
	Matrice4 matrice;
	
	matrice.p_mat[0] = planDroit.getx();
	matrice.p_mat[1] = planDroit.gety();
	matrice.p_mat[2] = planDroit.getz();
	matrice.p_mat[3] = 0.0;
	
	matrice.p_mat[4] = up.getx();
	matrice.p_mat[5] = up.gety();
	matrice.p_mat[6] = up.getz();
	matrice.p_mat[7] = 0.0;

	matrice.p_mat[8] = -visee.getx();
	matrice.p_mat[9] = -visee.gety();
	matrice.p_mat[10] = -visee.getz();
	matrice.p_mat[11] = 0.0;
	
	matrice.p_mat[12] = 0.0;
	matrice.p_mat[13] = 0.0;
	matrice.p_mat[14] = 0.0;
	matrice.p_mat[15] = 1.0;
	
// 	*this = *this * matrice;
	*this *= matrice;
	
	translated(-position.getx(), -position.gety(), -position.getz());
}

///fonction qui sauvegarde la matrice courante
/**	@return true si la fonction à réussie, false sinon
*/
bool Matrice4::push(){
	Matrice4 *newCase = new Matrice4;
	// Si l'allocation réussit
	if(newCase != 0){
		// Copie des valeurs dans la nouvelle case
		*newCase = *this;
		// On pointe sur la sauvegarde précédente
		newCase->p_sauvegardePrecedente = p_sauvegardePrecedente;
		// Redéfinition du sommet de la pile
		p_sauvegardePrecedente = newCase;
		return true;
	}else return false;
}

///fonction qui dégomme la sauvegarde précédente
/**	@return true si la fonction à réussie, false sinon
*/
bool Matrice4::pop(){
	Matrice4 *matriceTmp = p_sauvegardePrecedente;
	// Si la pile existe toujours
	if(matriceTmp != 0){
		// Copie des valeurs depuis la sauvegarde
		*this = *matriceTmp;
		// Redéfinition du sommet de la pile
		p_sauvegardePrecedente = matriceTmp->p_sauvegardePrecedente;
		matriceTmp->p_sauvegardePrecedente = 0;
		delete matriceTmp;
		return true;
	}else return false;
}

///fonction qui dégomme toutes les sauvegardes de matrices précédentes
void Matrice4::depiler(){
	while(pop() != false);
}

///fonction qui renvoie la valeur de la matrice (enfin le tableau quoi)
/**	@return valeur de la matrice
*/
float * Matrice4::getValue() const{
	return p_mat;
}

///////////////////////////////////////////////
//                                           //
//   Les opérateurs de la classe Matrice4   //
//                                           //
///////////////////////////////////////////////


///Définition de l'opérateur = de Matrice4
/**	@param other : Matrice4 à copier
 * 	@return Matrice4 copiée
*/
Matrice4 & Matrice4::operator = (const Matrice4 & other){
	this->copyMatrice4(other);
	return *this;
}

///Définition de l'opérateur - de la classe Matrice4
Matrice4 & Matrice4::operator - (){
	for(unsigned int i(0); i < 16; i++){
		p_mat[i] = -p_mat[i];
	}
	return *this;
}

///Définition de l'opérateur -= de la classe Matrice4
/**	@param other : Matrice4
 * 	@return Matrice4
*/
Matrice4 & Matrice4::operator -= (const Matrice4 & other){
	for(unsigned int i(0); i < 16; i++){
		p_mat[i] -= other.p_mat[i];
	}
	return *this;
}

///Définition de l'opérateur += de la classe Matrice4
/**	@param other : Matrice4
 * 	@return Matrice4
*/
Matrice4 & Matrice4::operator += (const Matrice4 & other){
	for(unsigned int i(0); i < 16; i++){
		p_mat[i] += other.p_mat[i];
	}
	return *this;
}

///Définition de l'opérateur *= de la classe Matrice4
/**	@param other : Matrice4
 * 	@return Matrice4
*/
Matrice4 & Matrice4::operator *= (const Matrice4 & other){
	Matrice4 matrice;
	float calcul(0);
	int i,j,k;
	for(j = 0; j < 4; j++){
		for(i = 0; i < 4; i++){
			calcul = 0;
			for(k = 0; k < 4; k++){
				calcul +=  p_mat[4*j + k]*other.p_mat[4*k + i];
			}
			matrice.p_mat[4*j + i] = calcul;
		}
	}
	this->copyMatrice4(matrice);
	return *this;
}

///Définition de l'opérateur *= de la classe Matrice4
/**	@param nb : nombre
 * 	@return Matrice4
*/
Matrice4 & Matrice4::operator *= (float nb){
	for(unsigned int i(0); i < 16; i++){
		p_mat[i] *= nb;
	}
	return *this;
}

///Définition de l'opérateur /= de la classe Matrice4
/**	@param nb : nombre
 * 	@return Matrice4
*/
Matrice4 & Matrice4::operator /= (float nb){
	for(unsigned int i(0); i < 16; i++){
		p_mat[i] /= nb;
	}
	return *this;
}

////////////////////////////////////////////////////
//                                                //
//   Les opérateurs amis de la classe Matrice4    //
//                                                //
////////////////////////////////////////////////////


///Définition de l'opérateur ami == de la classe Matrice4
/**	@param other1 : Matrice4
 * 	@param other2 : Matrice4
 * 	@return true si other1 et other2 sont égaux, false sinonMatrice4
*/
bool operator == (const Matrice4 & other1, const Matrice4 & other2){
	unsigned int i(0);
	while(i < 16){
		if(other1.p_mat[i] != other2.p_mat[i]) return false;
		i++;
	}
	return true;
}

///Définition de l'opérateur ami != de la classe Matrice4
/**	@param other1 : Matrice4
 * 	@param other2 : Matrice4
 * 	@return false si other1 et other2 sont égaux, true sinon
*/
bool operator != (const Matrice4 & other1, const Matrice4 & other2){
	unsigned int i(0);
	while(i < 16){
		if(other1.p_mat[i] != other2.p_mat[i]) return true;
		i++;
	}
	return false;
}

///Définition de l'opérateur ami + de la classe Matrice4
/**	@param other1 : Matrice4
 * 	@param other2 : Matrice4
 * 	@return Matrice4
*/
Matrice4 operator + (const Matrice4 & other1, const Matrice4 & other2){
	Matrice4 matrice;
	for(unsigned int i(0); i < 16; i++){
		matrice.p_mat[i] = other1.p_mat[i] + other2.p_mat[i];
	}
	return matrice;
}

///Définition de l'opérateur ami - de la classe Matrice4
/**	@param other1 : Matrice4
 * 	@param other2 : Matrice4
 * 	@return Matrice4
*/
Matrice4 operator - (const Matrice4 & other1, const Matrice4 & other2){
	Matrice4 matrice;
	for(unsigned int i(0); i < 16; i++){
		matrice.p_mat[i] = other1.p_mat[i] - other2.p_mat[i];
	}
	return matrice;
}

///définition de la multiplication à gauche par un scalaire
/**	@param nb : nombre
 * 	@param other1 : Matrice4
 * 	@return Matrice4
*/
Matrice4 operator * (float nb, const Matrice4 & other1){
	Matrice4 matrice;
	for(unsigned int i(0); i < 16; i++){
		matrice.p_mat[i] = other1.p_mat[i]*nb;
	}
	return matrice;
}

///définition de la multiplication à droite par un scalaire
/**	@param other1 : Matrice4
 * 	@param nb : nombre
 * 	@return Matrice4
*/
Matrice4 operator * (const Matrice4 & other1, float nb){
	Matrice4 matrice;
	for(unsigned int i(0); i < 16; i++){
		matrice.p_mat[i] = other1.p_mat[i]*nb;
	}
	return matrice;
}

///Définition de l'opérateur ami * de la classe Matrice4
/**	@param other1 : Matrice4
 * 	@param other2 : Matrice4
 * 	@return Matrice4
*/
Matrice4 operator * (const Matrice4 & other1, const Matrice4 & other2){
	Matrice4 matrice;
	float calcul(0);
	unsigned int i,j,k;
	for(j = 0; j < 4; j++){
		for(i = 0; i < 4; i++){
			calcul = 0;
			for(k = 0; k < 4; k++){
				calcul +=  other1.p_mat[4*j + k]*other2.p_mat[4*k + i];
			}
			matrice.p_mat[4*j + i] = calcul;
		}
	}
	return matrice;
}

///définition de la multiplication d'une matrice par un Vecteur4
/**	@param matrice : Matrice4
 * 	@param vecteur : Vecteur4
 * 	@return Vecteur4
*/
Vecteur4 operator * (const Matrice4 & matrice, const Vecteur4 & vecteur){
	float x(vecteur.getX()), y(vecteur.getY()), z(vecteur.getZ()), t(vecteur.getT());
	Vecteur4 vect(matrice.p_mat[0]*x + matrice.p_mat[1]*y + matrice.p_mat[2]*z + matrice.p_mat[3]*t,
		     matrice.p_mat[4]*x + matrice.p_mat[5]*y + matrice.p_mat[6]*z + matrice.p_mat[7]*t,
		     matrice.p_mat[8]*x + matrice.p_mat[9]*y + matrice.p_mat[10]*z + matrice.p_mat[11]*t,
		      matrice.p_mat[12]*x + matrice.p_mat[13]*y + matrice.p_mat[14]*z + matrice.p_mat[15]*t);
	return vect;
}

///Définition de l'opérateur ami / de la classe Matrice4
/**	@param other1 : Matrice4
 * 	@param nb : nombre
 * 	@return Matrice4
*/
Matrice4 operator / (const Matrice4 & other1, float nb){
	Matrice4 matrice;
	for(unsigned int i(0); i < 16; i++){
		matrice.p_mat[i] = other1.p_mat[i]/nb;
	}
	return matrice;
}

///fonction qui permet d'afficher la Matrice4
/**	@param out : flux de sortie sortie (genre cout)
 *	@param  matrice : Matrice4 à afficher
 * 	@return flux contenant la matrice
*/
std::ostream & operator << (std::ostream & out, const Matrice4 & matrice){
	if(matrice.p_mat == NULL){
		out << "Pointeur NULL de matrice" << std::endl;
	}else{
		for(unsigned int k(0); k < 4; k++){
			out << "| ";
			for(unsigned int i(0); i < 4; i++){
				out << " " << matrice.p_mat[4*k + i] << " ";
			}
			out << "| " << std::endl;
		}
	}
	return out;
}

/////////////////////////////////////////////////
//                                             //
//   Fonctions private de la classe Matrice4   //
//                                             //
/////////////////////////////////////////////////


///Fonction d'initialisation de la classe Matrice4
/**	@param v1 : Vecteur4
 * 	@param v2 : Vecteur4
 * 	@param v3 : Vecteur4
 * 	@param v4 : Vecteur4
*/
void Matrice4::initialisationMatrice4(const Vecteur4& v1, const Vecteur4& v2, const Vecteur4& v3, const Vecteur4& v4){
	createMatrice4();
	p_mat[0] = v1.getX(); p_mat[1] = v2.getX(); p_mat[2] = v3.getX(); p_mat[3] = v4.getX();
	p_mat[4] = v1.getY(); p_mat[5] = v2.getY(); p_mat[6] = v3.getY(); p_mat[7] = v4.getY();
	p_mat[8] = v1.getZ(); p_mat[9] = v2.getZ(); p_mat[10] = v3.getZ();p_mat[11] = v4.getZ();
	p_mat[12] = v1.getT();p_mat[13] = v2.getT();p_mat[14] = v3.getT();p_mat[15] = v4.getT();
	p_sauvegardePrecedente = NULL;
}


void Matrice4::initialisationMatrice4(float x1, float y1, float z1, float t1,
				float x2, float y2, float z2, float t2,
				float x3, float y3, float z3, float t3,
				float x4, float y4, float z4, float t4){
	createMatrice4();
	p_mat[0] = x1; p_mat[1] = x2; p_mat[2] = x3; p_mat[3] = x4;
	p_mat[4] = y1; p_mat[5] = y2; p_mat[6] = y3; p_mat[7] = y4;
	p_mat[8] = z1; p_mat[9] = z2; p_mat[10] = z3;p_mat[11] = z4;
	p_mat[12] = t1;p_mat[13] = t2;p_mat[14] = t3;p_mat[15] = t4;
	p_sauvegardePrecedente = NULL;
}

///fonction qui alloue le tableau de la matrice
void Matrice4::createMatrice4(){
	if(p_mat == NULL) p_mat = new float[16];
}

///Fonction de copie de la classe Matrice4
/**	@param other : Matrice4 à copier
*/
void Matrice4::copyMatrice4(const Matrice4 & other){
	createMatrice4();
	for(unsigned int i(0); i < 16; i++){
		p_mat[i] = other.p_mat[i];
	}
}

