#include "ptmatrice4fc.h" ///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 produitVectorielPtMatrice4fcLocal(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 normaliseVecteurPtMatrice4fcLocal(float * x, float * y, float * z){ float norme = sqrtf((*x)*(*x) + (*y)*(*y) + (*z)*(*z)); if(norme != 0.0 && norme != 1.0){ *x /= norme; *y /= norme; *z /= norme; } } ///fonction qui initialise les valeurs des cases de la matrice4f passée en paramètre /** @param mat4f : matrice4f à modifier * @param x1 : coeficient en (0,0) * @param y1 : coeficient en (0,1) * @param z1 : coeficient en (0,2) * @param t1 : coeficient en (0,3) * @param x2 : coeficient en (1,0) * @param y2 : coeficient en (1,1) * @param z2 : coeficient en (1,2) * @param t2 : coeficient en (1,3) * @param x3 : coeficient en (2,0) * @param y3 : coeficient en (2,1) * @param z3 : coeficient en (2,2) * @param t3 : coeficient en (2,3) * @param x4 : coeficient en (3,0) * @param y4 : coeficient en (3,1) * @param z4 : coeficient en (3,2) * @param t4 : coeficient en (3,3) */ void setPtMat4f(PtMatrice4fc mat4f, 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){ mat4f[0] = x1; mat4f[1] = x2; mat4f[2] = x3; mat4f[3] = x4; mat4f[4] = y1; mat4f[5] = y2; mat4f[6] = y3; mat4f[7] = y4; mat4f[8] = z1; mat4f[9] = z2; mat4f[10] = z3; mat4f[11] = z4; mat4f[12] = t1; mat4f[13] = t2; mat4f[14] = t3; mat4f[15] = t4; } ///fonction qui initialise la n-ième composante de la matrice4f /** @param mat4f : matrice4f à initialisée * @param n : numéro de la composante à initialiser (0 <= n < 16) * @param value : valeur de la composante */ void setValueNPtMat4f(PtMatrice4fc mat4f, unsigned int n, float value){ mat4f[n] = value; } ///fonction qui initialise la n-ième composante de la matrice4f et test si n est correcte /** @param mat4f : matrice4f à initialisée * @param n : numéro de la composante à initialiser (0 <= n < 16) * @param value : valeur de la composante */ void setValueNTestPtMat4f(PtMatrice4fc mat4f, unsigned int n, float value){ if(n < 16) mat4f[n] = value; } ///fonction qui initialise la composante (j, i) (ligne, colone) de la matrice4f /** @param mat4f : matrice4f à initialisée * @param i : colone de la composante à initialiser (0 <= i < 4) * @param j : ligne de la composante à initialiser (0 <= j < 4) * @param value : valeur de la composante */ void setValueIJPtMat4f(PtMatrice4fc mat4f, unsigned int i, unsigned int j, float value){ mat4f[4*j + i] = value; } ///fonction qui initialise la composante (j, i) (ligne, colone) de la matrice4f et test si i et j sont correcte /** @param mat4f : matrice4f à initialisée * @param i : colone de la composante à initialiser (0 <= i < 4) * @param j : ligne de la composante à initialiser (0 <= j < 4) * @param value : valeur de la composante */ void setValueIJTestPtMat4f(PtMatrice4fc mat4f, unsigned int i, unsigned int j, float value){ if(i < 4 && j < 4) mat4f[4*j + i] = value; } ///fonction qui donne la même valeur à toutes les cases de la matrice /** @param mat4fInOut : matrice à modifier * @param value : valeur des cases de la matrice */ void fillPtMat4f(PtMatrice4fc mat4fInOut, float value){ int i; for(i = 0; i < 16; i++) mat4fInOut[i] = value; } ///fonction qui transforme la matrice en matrice identité /** @param mat4fInOut : matrice4f à modifier */ void loadIdentityPtMat4f(PtMatrice4fc mat4fInOut){ mat4fInOut[0] = 1.0; mat4fInOut[1] = 0.0; mat4fInOut[2] = 0.0; mat4fInOut[3] = 0.0; mat4fInOut[4] = 0.0; mat4fInOut[5] = 1.0; mat4fInOut[6] = 0.0; mat4fInOut[7] = 0.0; mat4fInOut[8] = 0.0; mat4fInOut[9] = 0.0; mat4fInOut[10] = 1.0; mat4fInOut[11] = 0.0; mat4fInOut[12] = 0.0; mat4fInOut[13] = 0.0; mat4fInOut[14] = 0.0; mat4fInOut[15] = 1.0; } ///fonction qui additionne deux matrice4f /** @param mat4fOut : resultat de l'addition (doit avoir été alouée au préalable) * @param mat4fIn1 : matrice4f * @param mat4fIn2 : matrice4f */ void addPtMat4f(PtMatrice4fc mat4fOut, const PtMatrice4fc mat4fIn1, const PtMatrice4fc mat4fIn2){ int i; for(i = 0; i < 16; i++) mat4fOut[i] = mat4fIn1[i] + mat4fIn2[i]; } ///fonction qui soustrait deux matrice4f /** @param mat4fOut : resultat de la soustraction (doit avoir été alouée au préalable) * @param mat4fIn1 : matrice4f * @param mat4fIn2 : matrice4f */ void subPtMat4f(PtMatrice4fc mat4fOut, const PtMatrice4fc mat4fIn1, const PtMatrice4fc mat4fIn2){ int i; for(i = 0; i < 16; i++) mat4fOut[i] = mat4fIn1[i] - mat4fIn2[i]; } ///fonction qui calcule la multiplication de deux matrices4f (mat4fOut = mat4fIn1*mat4fIn2) /** @param mat4fOut : resultat de la multiplucation des matrices (doit avoir été alouée au préalable) * @param mat4fIn1 : matrices4f * @param mat4fIn2 : matrices4f */ void multPtMat4fPtMat4f(PtMatrice4fc mat4fOut, const PtMatrice4fc mat4fIn1, const PtMatrice4fc mat4fIn2){ unsigned int i,j,k; float calcul; for(j = 0; j < 4; j++){ for(i = 0; i < 4; i++){ calcul = 0; for(k = 0; k < 4; k++){ calcul += mat4fIn1[4*j + k]*mat4fIn2[4*k + i]; } mat4fOut[4*j + i] = calcul; } } } ///fonction qui calcule la multiplication de deux matrices4f (mat4fInOut1 = mat4fInOut1*mat4fIn2) /** @param mat4fInOut1 : resultat de la multiplucation des matrices (doit avoir été alouée au préalable) * @param mat4fIn2 : matrices4f */ void multSelfPtMat4fPtMat4f(PtMatrice4fc mat4fInOut1, const PtMatrice4fc mat4fIn2){ PtMatrice4fc tmp; multPtMat4fPtMat4f(tmp, mat4fInOut1, mat4fIn2); memcpy(mat4fInOut1, tmp, sizeof(PtMatrice4fc)); } ///fonction qui calcule la multiplication entre une matrice3f et un vecteur3f /** @param vect4fOut : résultat de la multiplication (doit avoir été alouée au préalable) * @param mat4fIn : matrice4f * @param vect4fIn : vecteur4f */ void multPtMat4fVect4f(PtVect4fc vect4fOut, const PtMatrice4fc mat4fIn, const PtVect4fc vect4fIn){ unsigned int i,j; float calcul; for(i = 0; i < 4; i++){ calcul = 0.0; for(j = 0; j < 4; j++){ calcul += mat4fIn[4*i + j]*vect4fIn[j]; } vect4fOut[i] = calcul; } } ///fonction qui calcule la matrice de rotation d'axe Ox et d'angle angledeg en degré /** @param mat4InOut : matrice de rotation (doit avoir été alouée au préalable) * @param angledeg : angle de rotation autour de l'axe Ox en degré */ void setRotationPtMat4fXdeg(PtMatrice4fc mat4InOut, float angledeg){ setRotationPtMat4fXRad(mat4InOut, (angledeg*M_PI)/180.0); } ///fonction qui calcule la matrice de rotation d'axe Ox et d'angle anglerad en radian /** @param mat4InOut : matrice de rotation (doit avoir été alouée au préalable) * @param anglerad : angle de rotation autour de l'axe Ox en radian */ void setRotationPtMat4fXRad(PtMatrice4fc mat4InOut, float anglerad){ mat4InOut[0] = 1.0; mat4InOut[1] = 0.0; mat4InOut[2] = 0.0; mat4InOut[3] = 0.0; mat4InOut[4] = 0.0; mat4InOut[5] = cosf(anglerad); mat4InOut[6] = -sinf(anglerad); mat4InOut[7] = 0.0; mat4InOut[8] = 0.0; mat4InOut[9] = sinf(anglerad); mat4InOut[10] = cosf(anglerad); mat4InOut[11] = 0.0; mat4InOut[12] = 0.0; mat4InOut[13] = 0.0; mat4InOut[14] = 0.0; mat4InOut[15] = 1.0; } ///fonction qui calcule la matrice de rotation d'axe Oy et d'angle angledeg en degré /** @param mat4InOut : matrice de rotation (doit avoir été alouée au préalable) * @param angledeg : angle de rotation autour de l'axe Oy en degré */ void setRotationPtMat4fYdeg(PtMatrice4fc mat4InOut, float angledeg){ setRotationPtMat4fYRad(mat4InOut, (angledeg*M_PI)/180.0); } ///fonction qui calcule la matrice de rotation d'axe Oy et d'angle anglerad en radian /** @param mat4InOut : matrice de rotation (doit avoir été alouée au préalable) * @param anglerad : angle de rotation autour de l'axe Oy en radian */ void setRotationPtMat4fYRad(PtMatrice4fc mat4InOut, float anglerad){ mat4InOut[0] = cosf(anglerad); mat4InOut[1] = 0.0; mat4InOut[2] = sinf(anglerad); mat4InOut[3] = 0.0; mat4InOut[4] = 0.0; mat4InOut[5] = 1.0; mat4InOut[6] = 0.0; mat4InOut[7] = 0.0; mat4InOut[8] = -sinf(anglerad); mat4InOut[9] = 0.0; mat4InOut[10] = cosf(anglerad); mat4InOut[11] = 0.0; mat4InOut[12] = 0.0; mat4InOut[13] = 0.0; mat4InOut[14] = 0.0; mat4InOut[15] = 1.0; } ///fonction qui calcule la matrice de rotation d'axe Oz et d'angle angledeg en degré /** @param mat4InOut : matrice de rotation (doit avoir été alouée au préalable) * @param angledeg : angle de rotation autour de l'axe Oz en degré */ void setRotationPtMat4fZdeg(PtMatrice4fc mat4InOut, float angledeg){ setRotationPtMat4fZRad(mat4InOut, (angledeg*M_PI)/180.0); } ///fonction qui calcule la matrice de rotation d'axe Oz et d'angle anglerad en radian /** @param mat4InOut : matrice de rotation (doit avoir été alouée au préalable) * @param anglerad : angle de rotation autour de l'axe Oz en radian */ void setRotationPtMat4fZRad(PtMatrice4fc mat4InOut, float anglerad){ mat4InOut[0] = cosf(anglerad); mat4InOut[1] = -sinf(anglerad); mat4InOut[2] = 0.0; mat4InOut[3] = 0.0; mat4InOut[4] = sinf(anglerad); mat4InOut[5] = cosf(anglerad); mat4InOut[6] = 0.0; mat4InOut[7] = 0.0; mat4InOut[8] = 0.0; mat4InOut[9] = 0.0; mat4InOut[10] = 0.0; mat4InOut[11] = 0.0; mat4InOut[12] = 0.0; mat4InOut[13] = 0.0; mat4InOut[14] = 0.0; mat4InOut[15] = 1.0; } ///fonction qui calcule la matrice de rotation générale avec des angles en degré /** @param mat4InOut : matrice de rotation (doit avoir été alouée au préalable) * @param thetaDeg : angle de rotation par rapport à l'axe Ox de l'axe de rotation de la matrice en coodonnées polaires en degré * @param phiDeg : angle de rotation par rapport à l'axe Oz de l'axe de rotation de la matrice en coodonnées polaires en degré * @param rouliDeg : angle de rotation autour de l'axe de rotation définit par thetaDeg et phiDeg en degré */ void setRotationPtMat4fdeg(PtMatrice4fc mat4InOut, float thetaDeg, float phiDeg, float rouliDeg){ setRotationPtMat4fRad(mat4InOut, (thetaDeg*M_PI)/180.0, (phiDeg*M_PI)/180.0, (rouliDeg*M_PI)/180.0); } ///fonction qui calcule la matrice de rotation générale avec des angles en radian /** @param mat4InOut : matrice de rotation (doit avoir été alouée au préalable) * @param thetaRad : angle de rotation par rapport à l'axe Ox de l'axe de rotation de la matrice en coodonnées polaires en radian * @param phiRad : angle de rotation par rapport à l'axe Oz de l'axe de rotation de la matrice en coodonnées polaires en radian * @param rouliRad : angle de rotation autour de l'axe de rotation définit par thetaRad et phiRad en radian */ void setRotationPtMat4fRad(PtMatrice4fc mat4InOut, float thetaRad, float phiRad, float rouliRad){ float x = cos(thetaRad)*sin(phiRad); float y = sin(thetaRad)*sin(phiRad); float z = cos(phiRad); mat4InOut[0] = x*x + (1 - x*x)*cosf(rouliRad); mat4InOut[1] = x*y*(1 - cosf(rouliRad)) - z*sinf(rouliRad); mat4InOut[2] = x*z*(1 - cosf(rouliRad)) + y*sinf(rouliRad); mat4InOut[3] = 0.0; mat4InOut[4] = x*y*(1 - cosf(rouliRad)) + z*sinf(rouliRad); mat4InOut[5] = y*y + (1 - y*y)*cosf(rouliRad); mat4InOut[6] = y*z*(1 - cosf(rouliRad)) - x*sinf(rouliRad); mat4InOut[7] = 0.0; mat4InOut[8] = x*z*(1 - cosf(rouliRad)) - y*sinf(rouliRad); mat4InOut[9] = y*z*(1- cosf(rouliRad)) + x*sinf(rouliRad); mat4InOut[10] = z*z + (1 - z*z)*cosf(rouliRad); mat4InOut[11] = 0.0; mat4InOut[12] = 0.0; mat4InOut[13] = 0.0; mat4InOut[14] = 0.0; mat4InOut[15] = 1.0; } ///fonction qui affiche une matrice4f dans le terminal /** @param mat4f : matrice4f à afficher */ void printPtMat4f(const PtMatrice4fc mat4f){ int i; for(i = 0; i < 4; i++) printf("%f\t%f\t%f\t%f\n", mat4f[4*i], mat4f[4*i + 1], mat4f[4*i + 2], mat4f[4*i + 3]); } ///fonction qui transforme la matrice en matrice nulle /** @param mat4f : matrice4f à annuler */ void loadNullPtMat4f(PtMatrice4fc mat4f){ unsigned int i; for(i = 0; i < 16; i++) mat4f[i] = 0.0; } ///fonction qui permet de faire une translation de la matrice (si on s'en sert de matrice modelView) /** @param mat4f : PtMatrice4fc à modifier * @param x : translation en x * @param y : translation en y * @param z : translation en z */ void translatedPtMat4f(PtMatrice4fc mat4f, float x, float y, float z){ PtMatrice4fc translation; loadIdentityPtMat4f(translation); translation[3] = x; translation[7] = y; translation[11] = z; multSelfPtMat4fPtMat4f(mat4f, translation); } ///fonction qui permet de changer l'échelle de la matrice (si on s'en sert de matrice modelView) /** @param mat4f : PtMatrice4fc à modifier * @param x : échelle en x * @param y : échelle en y * @param z : échelle en z */ void scalePtMat4f(PtMatrice4fc mat4f, float x, float y, float z){ PtMatrice4fc scale; loadNullPtMat4f(scale); scale[0] = x; scale[5] = y; scale[10] = z; scale[15] = 1.0; multSelfPtMat4fPtMat4f(mat4f, scale); } ///fonction qui permet de créer une matrice de rotation /** @param mat4f : PtMatrice4fc à modifier * @param angleRad : 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 rotatePtMat4fRad(PtMatrice4fc mat4f, float angleRad, float x, float y, float z){ PtMatrice4fc rotation; loadNullPtMat4f(rotation); // Normalisation du vecteur axe float norme = sqrtf(x*x + y*y + z*z); if(norme != 0.0){ x /= norme; y /= norme; z /= norme; } rotation[0] = x*x + (1 - x*x)*cosf(angleRad); rotation[4] = x*y*(1 - cosf(angleRad)) + z*sinf(angleRad); rotation[8] =x*z*(1 - cosf(angleRad)) - y*sinf(angleRad); rotation[1] = x*y*(1 - cosf(angleRad)) - z*sinf(angleRad); rotation[5] = y*y + (1 - y*y)*cosf(angleRad); rotation[9] = y*z*(1- cosf(angleRad)) + x*sinf(angleRad); rotation[2] = x*z*(1 - cosf(angleRad)) + y*sinf(angleRad); rotation[6] = y*z*(1 - cosf(angleRad)) - x*sinf(angleRad); rotation[10] = z*z + (1 - z*z)*cosf(angleRad); rotation[15] = 1.0; multSelfPtMat4fPtMat4f(mat4f, rotation); } ///fonction qui permet de créer une matrice de rotation /** @param mat4f : PtMatrice4fc à modifier * @param angleDeg : 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 rotatePtMat4fDeg(PtMatrice4fc mat4f, float angleDeg, float x, float y, float z){ rotatePtMat4fRad(mat4f, (angleDeg*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 mat4f : PtMatrice4fc à modifier * @param angleRad : 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 perspectivePtMat4fRad(PtMatrice4fc mat4f, float angleRad, float ratio, float near, float far){ float f = (1.0/tan((angleRad/2.0))); PtMatrice4fc projection; loadNullPtMat4f(projection); projection[0] = f/ratio; projection[5] = f; projection[10] = (near + far)/(near - far); projection[11] = (2.0*near*far)/(near - far); projection[14] = -1.0; multSelfPtMat4fPtMat4f(mat4f, projection); } ///fonction qui initialise la perspective de la matrice (qui sera la matrice de projection du monde OpenGl 3.1) /** @param mat4f : PtMatrice4fc à modifier * @param angleDeg : 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 perspectivePtMat4fDeg(PtMatrice4fc mat4f, float angleDeg, float ratio, float near, float far){ perspectivePtMat4fRad(mat4f, (angleDeg*M_PI)/180.0, ratio, near, far); } ///fonction qui permet de dire où on veut regarder /** @param mat4f : PtMatrice4fc à modifier * @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 lookAtPtMat4f(PtMatrice4fc mat4f, 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; produitVectorielPtMatrice4fcLocal(&normaleX, &normaleY, &normaleZ, regardX, regardY, regardZ, upX, upY, upZ); produitVectorielPtMatrice4fcLocal(&newAxeX, &newAxeY, &newAxeZ, normaleX, normaleY, normaleZ, regardX, regardY, regardZ); normaliseVecteurPtMatrice4fcLocal(&normaleX, &normaleY, &normaleZ); normaliseVecteurPtMatrice4fcLocal(&newAxeX, &newAxeY, &newAxeZ); normaliseVecteurPtMatrice4fcLocal(®ardX, ®ardY, ®ardZ); PtMatrice4fc matrice; matrice[0] = normaleX; matrice[1] = normaleY; matrice[2] = normaleZ; matrice[3] = 0.0; matrice[4] = newAxeX; matrice[5] = newAxeY; matrice[6] = newAxeZ; matrice[7] = 0.0; matrice[8] = -regardX; matrice[9] = -regardY; matrice[10] = -regardZ; matrice[11] = 0.0; matrice[12] = 0.0; matrice[13] = 0.0; matrice[14] = 0.0; matrice[15] = 1.0; // Multiplication des matrices, puis translation de la matrice modelview multSelfPtMat4fPtMat4f(mat4f, matrice); translatedPtMat4f(mat4f, -eyeX, -eyeY, -eyeZ); } ///fonction qui permet de dire où on veut regarder /** @param mat4f : PtMatrice4fc à modifier * @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 viseeX : axe de visée de la caméra en x * @param viseeY : axe de visée de la caméra en y * @param viseeZ : axe de visée de la caméra en z * @param planDroitX : composante x du vecteur orthogonal à la visée et à up * @param planDroitY : composante y du vecteur orthogonal à la visée et à up * @param planDroitZ : composante z du vecteur orthogonal à la visée et à up * @param upX : composante x du vecteur vertical * @param upY : composante y du vecteur vertical * @param upZ : composante z du vecteur vertical */ void lookAtPtMat4fVisee(PtMatrice4fc mat4f, float eyeX, float eyeY, float eyeZ, float viseeX, float viseeY, float viseeZ, float planDroitX, float planDroitY, float planDroitZ, float upX, float upY, float upZ){ PtMatrice4fc matrice; matrice[0] = planDroitX; matrice[1] = planDroitY; matrice[2] = planDroitZ; matrice[3] = 0.0; matrice[4] = upX; matrice[5] = upY; matrice[6] = upZ; matrice[7] = 0.0; matrice[8] = -viseeX; matrice[9] = -viseeY; matrice[10] = -viseeZ; matrice[11] = 0.0; matrice[12] = 0.0; matrice[13] = 0.0; matrice[14] = 0.0; matrice[15] = 1.0; // Multiplication des matrices, puis translation de la matrice modelview multSelfPtMat4fPtMat4f(mat4f, matrice); translatedPtMat4f(mat4f, -eyeX, -eyeY, -eyeZ); }