Partage
  • Partager sur Facebook
  • Partager sur Twitter

[openGL] Faire tourner un objet

problème de trigo visiblement

    11 octobre 2006 à 18:10:21

    Bonsoir à toutes et à tous,

    J'ai suivi les cours d'openGL de Kayl, et pour m'améliorer un peu, j'ai voulu m'essayer à quelque chose qui n'était pas dans le cours; faire pivoter un objet. Mais pas comme dans le TP avec la terre dans lequel ça consiste juste à augmenter x, y ou z. Pas vis-à-vis d'un repère fixe, mais d'après lui-même (c'est peut-être pas forcément clair, mais une fois que vous aurez vu mon essai vous comprendrez).

    Vu que je n'avais pas trop d'idée, j'ai essayé d'y aller tête baissé, mais le résultat n'est pas très convaincant. Je me demandais aussi si ça avait un rapport avec la matrice de rotations présentée par kayl dans son cours.

    Enfin bon, voilà déjà ce à quoi je suis arrivé:

    >>Téléchargement de mon projet ici<<
    (executable et source du projet Code::Blocks)
    (au cas où, c'est les touches k et i pour l'axe y, j et l pour l'axe x, u et o pour z. J'aurais voulu prendre une configuration plus conventionnelle, mais ayant un clavier qwertz, je pense que ça aurait plus été pénalisant qu'autre chose, le joystick fonctionne aussi, j'en avais profité pour m'y essayer ^^ ).


    Mais en fait, le seul fichier qui me fait vraiment défaud, c'est celui ci:

    rotation.c :
    #include "fonctionsMath.h"
    #include "struct.h"
    #include <SDL/SDL.h>

    #define ROTATE_SPEED 50 // vitesse de rotation en deg/sec

    #define bool char
    #define true 1
    #define false 0

    /*
    Ces fonctions permettent de faire tourner l'objet sur ses 3 dimensions
    Dans le nom des fonctions, le X, Y ou Z marque quel axe on veut faire tourner
    quand au "p" ou "n" qui suivent, cela signifie simple "positif" ou "négatif"
    par rapport à quel sens on tourne.

    Quant au booléen "realiste", si il faut 0 (ou false), l'objet doit tourner d'après
    un repère fixe (qui ne tourne pas avec l'objet lui même).
    A l'inverse du cas ou il vaut 1 (ou true), on essaie de faire tourner l'objet
    d'après lui-même et non d'un point fixe.
    */


    void RotateXp(Uint32 temps, Rotation* rotate, bool realiste)
    {
        if(!realiste)rotate->x = rotate->x + ((double)temps/1000 * ROTATE_SPEED);
        else
        {
            /*rotate->y = rotate->y - (sinusDeg(rotate->z) * (((double)temps/1000) * ROTATE_SPEED));
            rotate->x = rotate->x + (cosinusDeg(rotate->z) * (((double)temps/1000) * ROTATE_SPEED));
            rotate->z = rotate->z + (sinusDeg(rotate->z+90) * sinusDeg(rotate->y) * ((double)temps/1000) * ROTATE_SPEED);*/


            //r(x, y, z)=(x, cos(a)*y-sin(a)*z, sin(a)*y+cos(a)*z)
            rotate->y = (cosinusDeg((double)temps/1000 * ROTATE_SPEED) * rotate->y) - (sinusDeg((double)temps/1000 * ROTATE_SPEED) * rotate->x);
            rotate->x = (sinusDeg((double)temps/1000 * ROTATE_SPEED) * rotate->y) + (cosinusDeg((double)temps/1000 * ROTATE_SPEED) * rotate->x);
        }
    }

    void RotateXn(Uint32 temps, Rotation* rotate, bool realiste)
    {
        if(!realiste)rotate->x = rotate->x - ((double)temps/1000 * ROTATE_SPEED);
        else
        {
            /*rotate->y = rotate->y + (sinusDeg(rotate->z) * (((double)temps/1000) * ROTATE_SPEED));
            rotate->x = rotate->x - (cosinusDeg(rotate->z) * (((double)temps/1000) * ROTATE_SPEED));
            rotate->z = rotate->z + (sinusDeg(rotate->z-90) * sinusDeg(rotate->y) * ((double)temps/1000) * ROTATE_SPEED);*/


            rotate->y = (cosinusDeg(-((double)temps/1000 * ROTATE_SPEED)) * rotate->y) - (sinusDeg(-((double)temps/1000 * ROTATE_SPEED)) * rotate->x);
            rotate->x = (sinusDeg(-((double)temps/1000 * ROTATE_SPEED)) * rotate->y) + (cosinusDeg(-((double)temps/1000 * ROTATE_SPEED)) * rotate->x);
        }
    }

    void RotateYp(Uint32 temps, Rotation* rotate, bool realiste)
    {
        if(!realiste)rotate->y = rotate->y + ((double)temps/1000 * ROTATE_SPEED);
        else
        {
            rotate->y = rotate->y + (cosinusDeg(rotate->z) * (((double)temps/1000) * ROTATE_SPEED));
            rotate->x = rotate->x + (sinusDeg(rotate->z) * (((double)temps/1000) * ROTATE_SPEED));
            rotate->z = rotate->z + (sinusDeg(rotate->z) * sinusDeg(rotate->y) * ((double)temps/1000) * ROTATE_SPEED);
        }
    }

    void RotateYn(Uint32 temps, Rotation* rotate, bool realiste)
    {
        if(!realiste)rotate->y = rotate->y - ((double)temps/1000 * ROTATE_SPEED);
        else
        {
            rotate->y = rotate->y - (cosinusDeg(rotate->z) * (((double)temps/1000) * ROTATE_SPEED));
            rotate->x = rotate->x - (sinusDeg(rotate->z) * (((double)temps/1000) * ROTATE_SPEED));
            rotate->z = rotate->z - (sinusDeg(rotate->z) * sinusDeg(rotate->y) * ((double)temps/1000) * ROTATE_SPEED);
        }
    }

    void RotateZp(Uint32 temps, Rotation* rotate, bool realiste)
    {
        rotate->z = rotate->z + ((double)temps/1000 * ROTATE_SPEED);
    }

    void RotateZn(Uint32 temps, Rotation* rotate, bool realiste)
    {
        rotate->z = rotate->z - ((double)temps/1000 * ROTATE_SPEED);
    }

    /*
    Cette fonction "redresse" simplement les valeurs des angles entre 0 et 360
    afin d'éviter qu'à force de tourner, le programme arrive à des valeurs qu'il
    ne puisse plus gérer correctement
    */

    void redresser(Rotation* rotate)
    {
        while(rotate->x < 0) rotate->x += 360;
        while(rotate->x >= 360) rotate->x -= 360;

        while(rotate->y < 0) rotate->y += 360;
        while(rotate->y >= 360) rotate->y -= 360;

        while(rotate->z < 0) rotate->z += 360;
        while(rotate->z >= 360) rotate->z -= 360;
    }




    (La structure rotate est juste composée des trois angles, x y et z).

    Je pense que vous l'aurez remarqué, tant que y n'est pas trop élevé, c'est presque bon, mais plus il augmente des "pôles" (à savoir 90 et 270 degrés), sa trajectoire se déforme beaucoup trop et je ne sais pas comment corriger cela.

    Donc voilà, je pense qu'il me manque quelques connaissances trigonométriques pour cela, et j'aimerais un petit coup de main s'il-vous-plaît.

    Merci d'avance et bonne fin de soirée
    • Partager sur Facebook
    • Partager sur Twitter
      11 octobre 2006 à 19:23:14

      Tu sais qu'il existe une fonction OpenGL très pratique :

      glRotate*(axe, theta);

      T'as bien lu TOUT le cours de Kayl ?
      • Partager sur Facebook
      • Partager sur Twitter
        11 octobre 2006 à 19:38:24

        Citation : Yno

        Tu sais qu'il existe une fonction OpenGL très pratique :

        glRotate*(axe, theta);

        T'as bien lu TOUT le cours de Kayl ?



        Lol, oui, le problème n'est pas l'afficher (si tu avais regardé les sources que j'ai fournises tu aurais vu que j'utilise cette fonction justement pour ce point ;) , le souci, c'est comment enregistrer les rotations).

        Visiblement, on a de la peine a comprendre quel est exactement mon problème, j'édite sous peu pour essayer d'être davantage clair.

        [EDIT] :
        Exemple :

        J'ai fait pivoté l'objet sur sa gauche sur son axe Z (en rouge).

        Image utilisateur

        A présent, j'aimerais le faire pivoter, le redresser, sur son axe Y (en vert), mais si je ne fais que bêtement augmenter la valeur d'Y, voilà ce qui arrive :

        Image utilisateur

        Le repère Y est fixe. Donc le sens de son mouvement, quelque soit le sens de l'objet lui-même, sera toujours le même.

        Hors voilà ce à quoi je veux arriver :

        Image utilisateur

        C'est presque ça, mais il y a de méchantes déformations aux "pôles".

        C'est plus clair?
        • Partager sur Facebook
        • Partager sur Twitter
          11 octobre 2006 à 21:53:34

          Jai pas bien compris le fonctionnement de tes rotations, mais si tu veux enregistrer dans le sens ou je comprends, utilise glMatrixPush et glMatrixPop
          • Partager sur Facebook
          • Partager sur Twitter
            11 octobre 2006 à 22:11:03

            Tu enregistres dans une matrice...

            C'est comme ça que fait OpenGL en tout cas, peut-être même qu'il existe une fontion opengl qui retourne la matrice actuelle, je sais pas, regarde dans la doc.
            Et si tu veux apprendre à bien te servir des matrices, tiens cadeau :
            http://jeux.developpez.com/faq/matquat/

            A+ :)
            • Partager sur Facebook
            • Partager sur Twitter

            [openGL] Faire tourner un objet

            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
            • Editeur
            • Markdown