7.2.5 Les fonctions propre aux matrices

Commençons par la fonction qui transforme la Matrice4 en matrice identité, et celle qui la transforme en matrice nulle :

1
2
3
4
5
6
7
8
9
10
11
12
void Matrice4::loadIdentity(){
	depiler();
	this->loadNull();
	p_mat[0] = 1;
	p_mat[5] = 1;
	p_mat[10] = 1;
	p_mat[15] = 1;
}

void Matrice4::loadNull(){
	for(unsigned int i(0); i < 16; i++) p_mat[i] = 0.0;
}

J'espère que pour le moment ça va.

Matrice de translation :

1
2
3
4
5
6
7
8
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;
}

Comme je vous l'ai dit, on créé une matrice, et on multiplie notre matrice par celle que l'on a créé, et ça nous translate le repère de la matrice si c'est modelview.

Matrice d'échelle :

1
2
3
4
5
6
7
8
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;
}

Même principe de précédemment.

Matrice de rotation :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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;
}

Même principe de précédemment.

Heu, comment ça se fait qu'on ne met pas les 0 des cases qui manquent ?

C'est un tour du constructeur par défaut, une matrice créée est une matrice nulle.

Matrice de rotation avec un angle en dégrées :

1
2
3
void Matrice4::rotateDeg(float angle, float x, float y, float z){
	rotateRad((angle*M_PI)/180.0, x, y, z);
}

Là on ne peut pas dire qu'on s'est foulé.

La matrice de perspective :

1
2
3
4
5
6
7
8
9
10
11
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;
}

La matrice de perspective avec un angle de vue en dégrées :

1
2
3
void Matrice4::perspectiveDeg(float angle, float ratio, float near, float far){
	perspectiveRad((angle*M_PI)/180.0, ratio, near, far);
}

On ne s'est encore pas trop foulé.

La fonction lookAt :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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;
	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;

	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);
}

Et voici ce qui se cachait derrière la fonction gluLookAt.