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;
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;
*this = *this * matrice;
translated(-eyeX, -eyeY, -eyeZ);
}
|
Et voici ce qui se cachait derrière la fonction gluLookAt.
|