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

OpenGL Discussion :

Rotation d'un objet 3D sur lui-même


Sujet :

OpenGL

  1. #1
    Membre éprouvé
    Avatar de ABD-Z
    Homme Profil pro
    Ingé. webapps embarquées – Admin/mainteneur serveur/BDD – Formateur WordPress – Desiger : logo/site
    Inscrit en
    Septembre 2016
    Messages
    264
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Ingé. webapps embarquées – Admin/mainteneur serveur/BDD – Formateur WordPress – Desiger : logo/site

    Informations forums :
    Inscription : Septembre 2016
    Messages : 264
    Points : 945
    Points
    945
    Billets dans le blog
    2
    Par défaut Rotation d'un objet 3D sur lui-même
    Bonsoir,
    Je suis en train d'essayer d'implémenter les rotations sur les axes X, Y et Z d'un objet 3D.
    Je veux programmer la rotation sur le pitch, roll et yaw.
    Ce que j'ai fait dans un premier temps correspond à cela :
    -je remets l'objet au centre (0,0,0)
    -j'applique une rotation sur l'axe X, Y ou Z
    -puis enfin je le remets à sa place.
    Mais, cela est très limite quand on veut appliquer plusieurs rotations... Il faudra mettre à jour aussi les positions des axes qui subissent la rotation
    J'ai cherché partout sur internet pour implémenter cela notamment avec les formules trigonométriques, mais ça ne marche pas comme je veux...
    Voilà tout ce que j'ai pu faire :

    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
     
    if (current_event.key.keysym.sym == SDLK_u)
    {
    	t = physics[scene["mario"]]->getWorldTransform();
    	((btRigidBody *)physics[scene["mario"]])->setMotionState(new btDefaultMotionState(t));
     
     
    	scene["mario"]->translate(-x, -y, -z);
    	scene["mario"]->rotate(pitch, +0.05);
    	float oldy, oldz;
    	pitchAng += 0.05;
    	oldy = yaw.y; oldz = yaw.z;
    	yaw.y = oldy * cos(+0.05) - oldz * sin(+0.05);
    	yaw.z = oldy * sin(+0.05) + oldz * cos(+0.05);
     
    	oldy = roll.y; oldz = roll.z;
    	roll.y = oldy * cos(+0.05) - oldz * sin(+0.05);
    	roll.z = oldy * sin(+0.05) + oldz * cos(+0.05);
     
    	scene["mario"]->translate(x, y, z);
    	physics.setModelMatrix(scene["mario"]);
     
     
    	cout << " PITCH ANGLE " << pitchAng << endl;
    	cout << " YAW " << yaw.x << " " << yaw.y << " " << yaw.z << endl;
    	cout << " ROLL " << roll.x << " " << roll.y << " " << roll.z << endl;
    }
    if (current_event.key.keysym.sym == SDLK_i)
    {
    	btTransform t = physics[scene["mario"]]->getWorldTransform();
    	((btRigidBody *)physics[scene["mario"]])->setMotionState(new btDefaultMotionState(t));
     
     
    	scene["mario"]->translate(-x, -y, -z);
    	scene["mario"]->rotate(yaw, +0.05);
    	yawAng += 0.05;
    	float oldx, oldz;
    	oldx = roll.x; oldz = roll.z;
    	roll.x = oldx * cos(+0.05) + oldz * sin(+0.05);
    	roll.z = oldx * -sin(+0.05) + oldz * cos(+0.05);
     
    	oldx = pitch.x; oldz = pitch.z;
    	pitch.x = oldx * cos(+0.05) + oldz * sin(+0.05);
    	pitch.z = oldx * -sin(+0.05) + oldz * cos(+0.05);
     
    	scene["mario"]->translate(x, y, z);
    	physics.setModelMatrix(scene["mario"]);
     
    }
    if (current_event.key.keysym.sym == SDLK_o)
    {
    	btTransform t = physics[scene["mario"]]->getWorldTransform();
    	((btRigidBody *)physics[scene["mario"]])->setMotionState(new btDefaultMotionState(t));
     
     
    	scene["mario"]->translate(-x, -y, -z);
    	scene["mario"]->rotate(roll, +0.05);
    	rollAng += 0.05;
    	float oldx, oldy;
    	oldx = pitch.x; oldy = pitch.y;
    	pitch.x = oldx * cos(DegToRad(.05)) - oldy * sin(DegToRad(.05));
    	pitch.y = oldx * sin(+DegToRad(.05)) + oldy * cos(+DegToRad(.05));
     
    	oldx = yaw.x; oldy = yaw.y;
    	yaw.x = oldx * cos(+DegToRad(.05)) - oldy * sin(+DegToRad(.05));
    	yaw.y = oldx * sin(+DegToRad(.05)) + oldy * cos(+DegToRad(.05));
     
    	scene["mario"]->translate(x, y, z);
    	physics.setModelMatrix(scene["mario"]);
    }

    Est-ce que vous avez des pistes pour implémenter cela?
    Merci

  2. #2
    Expert éminent sénior
    Avatar de Kannagi
    Homme Profil pro
    cyber-paléontologue
    Inscrit en
    Mai 2010
    Messages
    3 214
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cyber-paléontologue

    Informations forums :
    Inscription : Mai 2010
    Messages : 3 214
    Points : 10 140
    Points
    10 140
    Par défaut
    J'ai un peu la flemme de lire ce code et de savoir où est l'erreur !

    Mais en 3D , on applique tout simplement une matrice de rotation et je conseille d'en faire autant
    (surtout que ce genre de calcul est souvent accélérer matériellement)

  3. #3
    Membre éprouvé
    Avatar de ABD-Z
    Homme Profil pro
    Ingé. webapps embarquées – Admin/mainteneur serveur/BDD – Formateur WordPress – Desiger : logo/site
    Inscrit en
    Septembre 2016
    Messages
    264
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Ingé. webapps embarquées – Admin/mainteneur serveur/BDD – Formateur WordPress – Desiger : logo/site

    Informations forums :
    Inscription : Septembre 2016
    Messages : 264
    Points : 945
    Points
    945
    Billets dans le blog
    2
    Par défaut
    Effectivement, il fallait appliquer une rotation aux vecteurs le multipliant par la rotation.
    Mais, apparemment dans glm, y a pas une fonction rotate qui retourne un vec3 après rotation.
    Du coup je me suis passé des matrices, et j'ai appliqué les formules trigonométriques comme dans ce lien : https://learnopengl.com/Getting-started/Transformations (voir plus bas)
    Mais ça marche pas...

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


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 860
    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 860
    Points : 219 062
    Points
    219 062
    Billets dans le blog
    120
    Par défaut
    Bonjour,

    Ce que je ferai, c'est pour chaque objet du jeu, je conserverai la rotation et la translation (soit, deux vector3, ou encore, directement les matrices de transformation). Et lorsque je veux afficher, je générerai la matrice pour placer l'objet (matrice du modèle), en faisant le classique mat_scale * mat_rotation * mat_translate. Ici (dans le code initial), le fait de replacer l'objet en 0,0,0 puis de le remettre là où il faut, c'est trop "pénible" (complexité pour rien).
    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 ABD-Z
    Homme Profil pro
    Ingé. webapps embarquées – Admin/mainteneur serveur/BDD – Formateur WordPress – Desiger : logo/site
    Inscrit en
    Septembre 2016
    Messages
    264
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Ingé. webapps embarquées – Admin/mainteneur serveur/BDD – Formateur WordPress – Desiger : logo/site

    Informations forums :
    Inscription : Septembre 2016
    Messages : 264
    Points : 945
    Points
    945
    Billets dans le blog
    2
    Par défaut
    C'est bon je viens de résoudre mon problème.
    Je vais quand même expliquer comment j'ai fait pour éventuellement aider d'autres personnes qui ont le même problème.
    J'ai utiliser cette fonction :
    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
    static void rotate(glm::vec3 & inputvec, glm::vec3 rotation_axis, float theta, bool tonormalize = false)
    {
    	const float cos_theta = cos(theta);
    	const float dot = glm::dot(inputvec, rotation_axis);
    	glm::vec3 cross = glm::cross(inputvec, rotation_axis);
     
    	inputvec.x *= cos_theta; inputvec.y *= cos_theta; inputvec.z *= cos_theta;
    	inputvec.x += rotation_axis.x * dot * static_cast<float>(1.0 - cos_theta);
    	inputvec.y += rotation_axis.y * dot * static_cast<float>(1.0 - cos_theta);
    	inputvec.z += rotation_axis.z * dot * static_cast<float>(1.0 - cos_theta);
     
    	inputvec.x -= cross.x * sin(theta);
    	inputvec.y -= cross.y * sin(theta);
    	inputvec.z -= cross.z * sin(theta);
     
    	if (tonormalize) inputvec = glm::normalize(inputvec);
    }
    Ainsi je veux appliquer une rotation sur le pitch (axe X) à un objet 3D, je dois également appliquer la même rotation aux axes yaw (Y) et roll (Z).
    Du coup je fais ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    scene["mario"]->rotate(pitch, +angle);
    rotate(roll, pitch, angle, true); //le paramètre true c'est pour la normalisation
    rotate(yaw, pitch, angle, true);
    Et ça marche

  6. #6
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    C'est quand même dommage d'utiliser glm uniquement pour stocker des coordonnées...

    Tu peux créer une matrice de rotation puis faire une simple multiplication.
    https://glm.g-truc.net/0.9.4/api/a00206.html

    Ou utiliser glm::rotate
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    glm::rotate(Model, rotation.x, glm::vec3(1.0f, 0.0f, 0.0f));
    glm::rotate(Model, rotation.y, glm::vec3(0.0f, 1.0f, 0.0f));
    glm::rotate(Model, rotation.z, glm::vec3(0.0f, 0.0f, 1.0f));
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

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

Discussions similaires

  1. Objet tournant sur lui-même
    Par ayla33 dans le forum Flash
    Réponses: 1
    Dernier message: 01/05/2012, 18h22
  2. [POO] Objet se renvoyant lui-même en php5
    Par stailer dans le forum Langage
    Réponses: 10
    Dernier message: 19/09/2007, 03h42
  3. PLPGSQL : Mon trigger boucle t'il sur lui même ?
    Par htristra dans le forum PostgreSQL
    Réponses: 2
    Dernier message: 08/09/2007, 19h27
  4. Rotation d'un objet sur lui-même
    Par Ninouw dans le forum OpenGL
    Réponses: 6
    Dernier message: 29/12/2006, 09h40
  5. [Rotation] Faire tourner un cube sur lui-même
    Par cyber_N dans le forum OpenGL
    Réponses: 4
    Dernier message: 14/07/2005, 21h29

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