IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

GLUT Discussion :

Gestion d'une caméra


Sujet :

GLUT

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Mai 2011
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2011
    Messages : 21
    Par défaut Gestion d'une caméra
    Bonjour tout le monde,

    Je me bas depuis hier pour essayer de faire fonctionner correctement le déplacement de ma caméra sous OpenGL; J'ai volontairement choisi de ne pas suivre à la lettre les tutos trouvés sur le web, car je voulais que la solution vienne de moi.

    Je pense m'en être sorti en ce qui concerne le déplacement droit devant la caméra (même si celà reste à prouver), mais je galère vraiment pour la partie orientation avec la souris.En effet, je me retrouve avec des valeurs assez incohérentes, bien qu'ayant repris les calculs du tuto. Voici le code que j'ai réalisé:

    camera.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    36
    37
    38
    39
    40
    41
    42
    #ifndef CAMERA_H
    #define CAMERA_H
     
    #include <SDL/SDL.h>
     
    #include <gl/gl.h>
    #include <gl/glu.h>
     
    #include "math.h"
     
    class camera
    {
    private:
        int posX;       //position X
        int posY;       //position Y
        int posZ;       //position Z
        double viseX;      //Position où regarde la caméra X
        double viseY;      //Position où regarde la caméra Y
        double viseZ;      //Position où regarde la caméra Z
        float axeX;     //Angle de la caméra X
        float axeY;     //Angle de la caméra Y
        float axez;     //Angle de la caméra Z
     
        SDL_Event *event;
        int preX;
        int preY;
     
        float teta;
        float phi;
    public:
            camera(int unePosX, int unePosY, int unePosZ, int uneViseX, int uneViseY, int uneViseZ, float unAxeX, float unAxeY, float unAxeZ, SDL_Event *unEvent);
     
            //*****************************************************
            //*********** vitesse doit être différent de 1 ********   //D'ailleurs je sais pas pourquoi, je sais juste que ça ne marche pas
            //*****************************************************
            void deplacementLongitudinal(int vitesse);
            void deplacementLateral(int vitesse);
            void tournerCam(SDL_Event *event);
            virtual ~camera();
    };
     
    #endif // CAMERA_H
    camera.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    #include "camera.h"
     
    camera::camera(int unePosX,
                   int unePosY,
                   int unePosZ,
                   int uneViseX,
                   int uneViseY,
                   int uneViseZ,
                   float unAxeX,
                   float unAxeY,
                   float unAxeZ,
                   SDL_Event *unEvent)
    {
        //ctor
        posX = unePosX;
        posY = unePosY;
        posZ = unePosZ;
        viseX = uneViseX;
        viseY = uneViseY;
        viseZ = uneViseZ;
        axeX = unAxeX;
        axeY = unAxeY;
        axez = unAxeZ;
     
        event = unEvent;
        preX = event->motion.x;
        preY = event->motion.y;
     
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        gluLookAt(posX,posY,posZ,viseX,viseY,viseZ,0,0,1);
    }
     
    void camera::deplacementLongitudinal(int vitesse)
    {
        float angleX = 0;
        float angleY = 0;
        float angleZ = 0;
     
        angleX = atan((posZ-viseZ)/(posY-viseY));
        angleY = atan((posZ-viseZ)/(posX-viseX));
        angleZ = atan((posX-viseX)/(posY-viseY));
     
        posX=(int)(posX+vitesse*(sin(angleX)));
        posY=(int)(posY+vitesse*(sin(angleY)));
        posZ=(int)(posZ+vitesse*(sin(angleZ)));
     
        viseX=(int)(viseX+vitesse/2*(sin(angleX)));
        viseY=(int)(viseY+vitesse/2*(sin(angleY)));
        viseZ=(int)(viseZ+vitesse/2*(sin(angleZ)));
     
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        gluLookAt(posX,posY,posZ,viseX,viseY,viseZ,0,0,1);
    }
     
    void camera::deplacementLateral(int vitesse)
    {
        //Pas vraiment d'idées mais pas encore vraiment cherché...
    }
     
    void camera::tournerCam(SDL_Event *Event)
    {
        teta -= Event->motion.xrel;
        phi -= Event->motion.yrel;
     
        if(phi >= 90)
            phi = 90;
     
        else if(phi<=-90)
            phi = -90;
     
        fprintf(stderr, "phi = %f\n", phi);
        fprintf(stderr, "teta = %f\n", teta);
        fprintf(stderr, "phi*3.14/180 = %f\n", phi*3.14/180);
        fprintf(stderr, "teta*3.14/180 = %f\n", teta*3.14/180);
        fprintf(stderr, "cos(phi*3.14/180) = %f\n", cos(phi*3.14/180));
        fprintf(stderr, "cos(teta*3.14/180) = %f\n", cos(teta*3.14/180));
        fprintf(stderr, "viseX = %d\n\n", viseX);
     
        viseX = ((cos(phi*3.14/180))*(cos(teta*3.14/180)));
        viseY = ((cos(phi*3.14/180))*(sin(teta*3.14/180)));
        viseZ = (sin(phi*3.14/180));
     
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        gluLookAt(posX,posY,posZ,viseX,viseY,viseZ,0,0,1);
    }
     
     
    camera::~camera()
    {
        //dtor
    }
    le résultat de mes logs:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    ...
     
    phi = 60.000000
    teta = -206.000000
    phi*3.14/180 = 1.046667
    teta*3.14/180 = -3.593556
    cos(phi*3.14/180) = 0.500460
    cos(teta*3.14/180) = -0.899592
    viseX = -1696566979
     
    ...
    Le résultat est que l'orientation ne bouge quasiment pas (à peine visible) et si je met des coefficients multiplacateur à mes viseX, viseY et viseZ, je ne peux pas tourner à 360°...

    Si vous voulez d'avantages d'info. n'hésitez pas à demander, je ne sais pas exactement ce qui pourrait vous être utile...

    En vous remerciant!

  2. #2
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    27 129
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 27 129
    Billets dans le blog
    149
    Par défaut
    Bonjour,

    J'imagine que vous voulez faire une caméra FPS, du coup.
    Je vous conseille de penser en terme de vecteur et donc de dire que votre caméra a une orientation (un vecteur qui va vers devant elle).

    Ensuite, autour du point de la position de la caméra, imaginez une sphère.

    Vous avez deux angles (l'inclinaison et l'orientation). Ces deux changent suivant le déplacement de la souris. En Y l'inclinaison et en X l'orientation.
    Grâce à des calculs, vous pouvez retranscrire ces deux angles en un point sur la sphère autour de la caméra. C'est plutôt simple, il faut une feuille de papier, son cercle trigonométrique du collège et c'est. En fait, il suffit de faire quelques cosinus/sinus et le tour est joué.

    Ce point indique où la camera regarde. Pour la fonction gluLookAt, vous allez juste faire "position + point de regard (celui généré à partir de l'inclinaison/orientation)" et vous aurez le point où regarde la caméra.

    Je crois que j'ai tout dit. N'hésitez pas à m'en demander plus.
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Mai 2011
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2011
    Messages : 21
    Par défaut
    Merci LittleWhite!

    En faite, je pense que c'est exactement ce que j'ai fais. C'est vrai que je n'appelais pas ça vecteur, mais je pense qu'au final c'est ce que j'ai.
    Mon problème se situe justement au niveau de ces calculs. En effet, lorsque j'exécute mon programme, j'ai bien un monde qui bouge, mais sans me donner l'impression que je suis dans une sphère... :/
    ça ressemble d'avantages à du n'importe quoi! ^^"

    Donc si justement tu pouvais t'assurer de la véracité de mes calculs ce serait top! (même si d'après les exemples sur internet, ils me paraissent bon...) Ensuite, faudra peut être reparler du code!

    Merci de ton aide!

  4. #4
    Expert confirmé

    Profil pro
    Fabricant et casseur d'avions
    Inscrit en
    Avril 2004
    Messages
    3 817
    Détails du profil
    Informations personnelles :
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Fabricant et casseur d'avions
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2004
    Messages : 3 817
    Par défaut
    Salut

    Citation Envoyé par momo l'plus bô Voir le message
    Le résultat est que l'orientation ne bouge quasiment pas (à peine visible) et si je met des coefficients multiplacateur à mes viseX, viseY et viseZ, je ne peux pas tourner à 360°...
    ça, ça vient de là:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
        viseX = ((cos(phi*3.14/180))*(cos(teta*3.14/180)));
        viseY = ((cos(phi*3.14/180))*(sin(teta*3.14/180)));
        viseZ = (sin(phi*3.14/180));
    quoi que tu faaaaaaaaaaaasses, oùùùùùùùù que tu sois (oui, je fais du Goldman, je sais, mais c'est vendredi!), tes viseX/Y/Z seront toujours entre -1 et 1 (produits de cos/sin). Pas vraiment ce que tu cherches, vu que tu gères ta caméra avec un GluLookAt, la position de ta caméra et ton point de visée.
    Comme le suggère LittleWhite, pense avec des vecteurs. Ton point de visée c'est ta position, à laquelle tu ajoutes un vecteur, donc une distance multipliée par tes produits de cos/sin. Et pas directement tes produits de cos/sin.



    Citation Envoyé par momo l'plus bô Voir le message
    En faite, je pense que c'est exactement ce que j'ai fais.
    Pas tout à fait. Tu as exactement fait ça, mais en supposant que ta caméra reste bloquée sur l'origine. Hors là, elle bouge...
    "Errare humanum est, sed perseverare diabolicum"

    Ma page sur DVP.com

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Mai 2011
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2011
    Messages : 21
    Par défaut
    Merci plegat de ta réponse!

    tes viseX/Y/Z seront toujours entre -1 et 1
    Pour avoir donc un angle sur 360° j'ai finalement simplement multiplié le résultat de mon produit par 360, ce qui à l'air de fonctionner.
    Mais maintenant mon problème est sur la partie qui me semblait fonctionner correctement. En effet, le déplacement longitudinal ne se comporte pas normalement...
    Pas tout à fait. Tu as exactement fait ça, mais en supposant que ta caméra reste bloquée sur l'origine. Hors là, elle bouge...
    Je suppose que c'est de ça que tu parlais. Mais je ne vois pas comment adapter mon calcul. :/ Il est vrai que lorsque j'arrive au point (0,0,0), j'ai un sérieux bug (au lieu d'avancer, je pars à reculons...) Et je ne me déplace pas du tout dans la bonne direction! (du moins rarement et je pense que c'est des coups de chance ^^ )...

    Voici la dernière version de code que j'ai pour cette partie:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    void camera::deplacementLongitudinal(int vitesse)
    {
        float angleX = 0;
        float angleY = 0;
        float angleZ = 0;
     
        angleX = atan((saPosZ-sonViseZ)/(saPosY-sonViseY));
        angleY = atan((saPosZ-sonViseZ)/(saPosX-sonViseX));
        angleZ = atan((saPosX-sonViseX)/(saPosY-sonViseY));
     
        //if(sin(angleX)!=0 && sin(angleY)!=0 && sin(angleZ)!=0)
     
            saPosX=(int)(saPosX+vitesse*(sin(angleX)));
            saPosY=(int)(saPosY+vitesse*(sin(angleY)));
            saPosZ=(int)(saPosZ+vitesse*(sin(angleZ)));
     
            sonViseX=(int)(sonViseX+vitesse*(sin(angleX)));
            sonViseY=(int)(sonViseY+vitesse*(sin(angleY)));
            sonViseZ=(int)(sonViseZ+vitesse*(sin(angleZ)));
     
     
        #ifdef DEBUG
            fprintf(stderr, "vitesse = %d\n", vitesse);
            fprintf(stderr, "saPosX = %d, saPosY = %d, saPosZ = %d\n", saPosX, saPosY, saPosZ);
            fprintf(stderr, "sonViseX = %d, sonViseY = %d, sonViseZ = %d\n", sonViseX, sonViseY, sonViseZ);
            fprintf(stderr, "sin(angleX) = %d, sin(angleY) = %d, sin(angleZ) = %d\n\n", sin(angleX), sin(angleY), sin(angleZ));
        #endif // DEBUG
     
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        gluLookAt(saPosX,saPosY,saPosZ,sonViseX,sonViseY,sonViseZ,0,0,1);
    }
    Donc si quelqu'un a une petite idée concernant mon déplacement longitudinal, je suis preneur!

    Très cordialement!

  6. #6
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    27 129
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 27 129
    Billets dans le blog
    149
    Par défaut
    Il n'y a pas besoin de multiplier par 360 les valeurs normalisés de l'orientation.

    Sinon, sonVise ne prend toujours pas en compte la position du joueur et pour moi, saPos ne devrait pas dépendre d'un quelconque angle, car c'est une position absolue dans l'espace.
    Par contre ,le déplacement du joueur s'effectuera avec un sonVise normalisé : en l'ajoutant simplement à saPos.
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

Discussions similaires

  1. Gestion d'une liste box
    Par norwy dans le forum Windows
    Réponses: 6
    Dernier message: 01/11/2005, 12h51
  2. Gestion d'une file d'attente
    Par jesus144 dans le forum Algorithmes et structures de données
    Réponses: 2
    Dernier message: 22/09/2005, 19h58
  3. [Composite] Gestion d'une recherche avancée
    Par Loctar dans le forum Design Patterns
    Réponses: 12
    Dernier message: 23/06/2005, 18h32
  4. [Clavier] Gestion d'une invite de commandes
    Par Damian dans le forum Assembleur
    Réponses: 9
    Dernier message: 28/04/2005, 16h41
  5. gestion d'une erreur
    Par Jeannotc dans le forum Bases de données
    Réponses: 8
    Dernier message: 25/06/2004, 18h04

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo