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

XNA/Monogame Discussion :

Probleme de camera


Sujet :

XNA/Monogame

  1. #1
    Futur Membre du Club
    Inscrit en
    Janvier 2010
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 8
    Points : 7
    Points
    7
    Par défaut Probleme de camera
    Bonjour,

    Developpant un jeu en 3D avec XNA je passe forcément par le développement d'une classe de camera. Cependant malgré un certains nombre de recherche je n'ai pas réussi à développer une classe de camera qui fasse ce que je souhaite. Le problème est nottement sur la rotation (la translation fonctionne).

    Donc j'en appel à votre aide pour m'aider.

    Voici ma classe de camera :

    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
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
     
    namespace Jeu.Moteur_Graphique.Camera
    {
        /// <summary>
        /// This is a game component that implements IUpdateable.
        /// </summary>
        public class Camera : Microsoft.Xna.Framework.GameComponent
        {
            public Vector3 CameraInitPosition;
            public Vector3 CameraPosition;
     
            public Vector3 CameraInitLookAt;
            public Vector3 CameraLookAt;
     
            public Matrix ViewMatrix;
     
            public Matrix ProjectionMatrix;
     
            Matrix CameraRotation;
     
            public float OffSetZ;
     
            public float OffSetY;
     
            public float OffSetX;
     
            private Vector3 CameraUpVector;
            private float Near;
            private int Far;
            private int AspectRatio;
     
            public Vector3 Dimension;
            public Matrix World;
            private int RotationX;
            private int RotationY;
            private int RotationZ;
     
            public Camera(Game game)
                : base(game)
            {
                CameraInitPosition = CameraPosition = new Vector3(0, 200, 0.0001f);
                CameraInitLookAt = CameraLookAt = new Vector3(0, -10, 0);
                ViewMatrix = Matrix.Identity;
                ProjectionMatrix = Matrix.Identity;
                CameraRotation = Matrix.Identity;
     
                OffSetX = 0;
                OffSetY = 0;
                OffSetZ = 0;
     
                RotationX = 0;
                RotationY = 0;
                RotationZ = 0;
     
                CameraUpVector = Vector3.Up;
     
                Near = 1.0F;
                Far = 2000;
     
                /*
                 * Dimension of the field view by the camera.
                 * The camera must not move outside the field
                 */
                Dimension = Vector3.Zero;
            }
     
            /// <summary>
            /// Allows the game component to perform any initialization it needs to before starting
            /// to run.  This is where it can query for any required services and load content.
            /// </summary>
            public override void Initialize()
            {
                // TODO: Add your initialization code here
                AspectRatio =
                    GLOBALS_GAME_RESSOURCES.VP_viewGame.Width /
                    GLOBALS_GAME_RESSOURCES.VP_viewGame.Height;
                base.Initialize();
            }
     
            /// <summary>
            /// Allows the game component to update itself.
            /// </summary>
            /// <param name="gameTime">Provides a snapshot of timing values.</param>
            public override void Update(GameTime gameTime)
            {
                //Recuperation du clavier
                KeyboardState kstate = Keyboard.GetState();
                if (kstate.IsKeyDown(Keys.Left) && !kstate.IsKeyDown(Keys.LeftAlt))
                {
                    OffSetX -= 10;
                    if (OffSetX <= 0)
                        OffSetX = 0;
                }
     
                if (kstate.IsKeyDown(Keys.Right) && !kstate.IsKeyDown(Keys.LeftAlt))
                {
                    OffSetX += 10;
                    if (OffSetX >= Dimension.X)
                        OffSetX = Dimension.X;
                }
     
                if (kstate.IsKeyDown(Keys.Down) && !kstate.IsKeyDown(Keys.LeftControl))
                {
                    OffSetZ -= 10;
                    if (OffSetZ <= 0)
                        OffSetZ = 0;
                }
     
                if (kstate.IsKeyDown(Keys.Up) && !kstate.IsKeyDown(Keys.LeftControl))
                {
                    OffSetZ += 10;
                    if (OffSetZ >= Dimension.Y)
                        OffSetZ = Dimension.Y;
                }
     
                if (kstate.IsKeyDown(Keys.Up) && kstate.IsKeyDown(Keys.LeftControl))
                {
                    OffSetY += 10;
                    if (OffSetY > 1800)
                        OffSetY = 1800;
                }
     
                if (kstate.IsKeyDown(Keys.Down) && kstate.IsKeyDown(Keys.LeftControl))
                {
                    OffSetY -= 10;
                    if (OffSetY <= Dimension.Z)
                        OffSetY = Dimension.Z;
                }
                if (kstate.IsKeyDown(Keys.Down) && kstate.IsKeyDown(Keys.LeftAlt))
                    RotationX += 2;
     
                if (kstate.IsKeyDown(Keys.Up) && kstate.IsKeyDown(Keys.LeftAlt))
                    RotationX -= 2;
     
                ///////////////////////////////////////////////////////////////////
     
                //Calcule des matrices
                CameraRotation = Matrix.CreateRotationX(MathHelper.ToRadians(RotationX));
     
                CameraPosition = Vector3.Transform(CameraInitPosition, CameraRotation);
     
                CameraPosition += new Vector3(OffSetX, OffSetY, OffSetZ);
     
                CameraLookAt = Vector3.Transform(CameraInitLookAt, CameraRotation);
     
                CameraLookAt += new Vector3(OffSetX, 0, OffSetZ);
     
                CameraUpVector = Vector3.Transform(CameraUpVector, CameraRotation);
     
                ViewMatrix = Matrix.CreateLookAt(CameraPosition, CameraLookAt, CameraUpVector);
     
                ProjectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, AspectRatio, Near, Far);
                base.Update(gameTime);
            }
        }
    }
    Et l'affichage d'un element par :

    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
     
     foreach (ModelMesh mesh in GLOBALS_GAME_RESSOURCES.Models[0].Meshes)
                {
                    // This is where the mesh orientation is set, as well
                    // as our camera and projection.
                    foreach (BasicEffect effect in mesh.Effects)
                    {
                        //effect.EnableDefaultLighting();
     
                        effect.TextureEnabled = true;
                        effect.World = transforms[mesh.ParentBone.Index]
                            * Matrix.CreateTranslation(new Vector3(32 * abs, 32 * hauteur, 32 * ord));
                        effect.View = Cam.ViewMatrix;
                        effect.Projection = Cam.ProjectionMatrix;
                    }
     
                    // Draw the mesh, using the effects set above.
                    mesh.Draw();
                }

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


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

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

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 859
    Points : 218 580
    Points
    218 580
    Billets dans le blog
    120
    Par défaut
    Bonjour,

    Pourriez vous mieux définir le problème. En effet, vous dites juste que vous avez un problème de rotation, certes, mais avec une meilleure description du problème on pourrait mieux deviner la source du problème.
    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
    Futur Membre du Club
    Inscrit en
    Janvier 2010
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 8
    Points : 7
    Points
    7
    Par défaut
    En effet, désolé pour cela.

    Normalement l'image devrait être fixe, or pour un angle différent de 0° l'image alterne entre 2 position.

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


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

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

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 859
    Points : 218 580
    Points
    218 580
    Billets dans le blog
    120
    Par défaut
    Alors, les quelques remarques que je vois pour le moment:

    La matrice de projection ne devrait pas etre calcule a chaque update.
    Y a trop de membres en public ...

    Votre lookAt en y ne bouge jamais ...

    Au fait, quel est le type de camera voulez vous ?

    Dans votre cas actuel, si vous mettez a jour les offset ... cela deplace le lookAt, mais en fait, cela ne va pas faire une vrais rotation...

    En theorie (je n'ai pas le code sous la main), le calcul d'une camera FPS, ce fait a partir de trois angles. Le joueur, de part ces mouvements de souris, va faire que ces angles changent.

    Maintenant, a quoi servent les angles, bah a calculer la direction de la camera.
    La direction, est un vecteur qui a pour source la position de la camera, et va selon les angles. (Tout le calcul se base sur des cosinus / sinus).

    Si la position change, l'emplacement change (car il faut changer la source du vecteur de direction).

    En esperant que cela aide.
    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.

  5. #5
    Membre éprouvé Avatar de oxyde356
    Homme Profil pro
    Ingénieur Recherche Imagerie
    Inscrit en
    Février 2006
    Messages
    797
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur Recherche Imagerie

    Informations forums :
    Inscription : Février 2006
    Messages : 797
    Points : 1 087
    Points
    1 087
    Par défaut
    Dans une vue FPS, les rotations doivent être appliquées successivement, d'abord rotation autour de l'axe Y puis rotation autour de l'axe X. Ces rotations ne doivent pas être accumulées dans une matrice frame après frame, sinon la rotation en Y va se répercuté sur une rotation de l'axe X précédent et en tournant votre caméra va commencer à rouler sur le côté (effet de roulis), bref vous tournerez autour de l'axe Z sans le vouloir petit à petit. Il faut donc que l'angle Y et l'angle X soit stockés et soient appliqués à une matrice que vous ne conserverez pas pour la frame d'après mais qui va vous servir à calculer le lookat (par contre le lookat conservez le si vous êtes sur que les angles de rotations n'ont pas changés autant ne pas le recalculer).
    Exemple de code :

    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
    // on copie la matrice de placement de notre camera
    tmpCameraModel = cameraModel;
     
    // on conserve la position de notre matrice
    vec4 position = tmpCameraModel.position();
     
    // on place la matrice au centre de notre repère global pour que le centre de la rotation soit le repère local de notre matrice
    tmpCameraModel.position(vec4(0.0, 0.0, 0.0, 1.0));
     
    // on créer les matrices de rotations
    mat4 rotY, rotX;
     
    // on applique la rotation sur l'axe Y
    rotY.rotate(angleY, tmpCameraModel.up());
    tmpCameraModel *= rotY;
    // on applique la rotation sur l'axe X
    // tmpCameraModel.right() a été modifié par la rotation précedente !
    rotX.rotate(angleX, tmpCameraModel.right());
    tmpCameraModel *= rotX;
     
    // on replace notre matrice à sa position initiale
    tmpCameraModel.position(position);
     
    // on calcul notre matrice lookat
    mat4 lookat = mat4::lookat(tmpCameraModel);
     
    // on l'applique si besoin
    glMatrixMode(GL_MODELVIEW);
    glLoadMatrixf(lookat);
    Sachant qu'une matrice de placement, enfin n'importe quel matrice, il faut la visualiser comme un repère, la première colonne c'est l'axe X local (right), la deuxième l'axe Y (up), la troisième l'axe Z (dir), et la quatrième le centre du repère (position). Dans la matrice de placement cameraModel vous ne conservez donc que la position de votre caméra. Si vous tournez cette matrice de 90° sur un axe votre plan de référence sera vertical et vous marchez sur les murs si on peut dire, si vous tournez de 180° vous marcherez au plafond.

    PS : mes manips sur la position de la matrice tmpCameraModel reviennent à effectuer une rotation autour d'un point précis.
    PS 2 : la matrice de placement de la caméra se calcul comme suit (chaque paramètre du constructeur est la n-ième colonne de la matrice) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    cameraModel = mat4(right, // produit vectoriel de "dir" et de "up" (dir ^ up)
                       up,
                       dir,
                       position);

  6. #6
    Futur Membre du Club
    Inscrit en
    Janvier 2010
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 8
    Points : 7
    Points
    7
    Par défaut
    Merci pour vos réponses qui m'ont bien aiguillées et permis de comprendre d'autres exemples. La principale erreure fut d'avoir un lookat en position plutôt qu'un vecteur.

    donc encore merci pour l'attention que vous avez porter à mon problème

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Probleme INTENT.Camera + Telephone HTC
    Par anto2b dans le forum Android
    Réponses: 1
    Dernier message: 10/03/2013, 12h15
  2. Réponses: 42
    Dernier message: 05/08/2008, 20h41
  3. probleme de gestion de la camera
    Par paquito dans le forum OpenGL
    Réponses: 1
    Dernier message: 01/05/2007, 16h30
  4. Réponses: 4
    Dernier message: 31/03/2005, 10h33
  5. Probleme gestion camera
    Par Fry dans le forum DirectX
    Réponses: 3
    Dernier message: 03/12/2004, 11h41

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