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

DirectX Discussion :

Quaternion, petite aide DirectX/C++


Sujet :

DirectX

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 33
    Par défaut Quaternion, petite aide DirectX/C++
    Bonjour,
    J'ai lu la FAQ sur les quaternion, et il y a pas mal de chose que je ne comprend pas et que j'aimerais comprendre =(

    Je vous explique mon problème.

    J'ai une sphère, représentant une petite planète
    et J'ai un joueur (pour l'instant un cube) qui tourne autour de cette sphère (a altitude constante), qui peut se diriger à sa guise, je me suis rendu fou sur un algorithme pour pouvoir le bouger efficacement, maintenant c'est fait.
    Donc pour l'instant le cube tourne correctement autour de la planète, mais ne tourne pas, normal puisque mon algo définit juste la position (x,y,z) dans le repère de base.

    Mon joueur est une classe à part.
    Pour vous en dire un peu plus, car ça serviras peut être pour ma question, en interne mon joueur à un vecteur directeur, un vecteur up (collièaire au vecteur partant du centre de la sphère et arrivant à la position du joueur, mais normalisé), c'est 2 vecteurs sont perpendiculaire (désolé je ne sais plus le mot pour des vecteur), donc avec le produit vectoriel, cela forme un joli repère locale pour mon joueur.

    je voudrais maintenant utiliser les quaternions, pour que le joueur tourne lorsqu'on avance ou lorsqu'on change de direction.

    Je peux connaitre l'angle de rotation dans le repère local du joueur, lorsq'on avance et se dirige également puisque je calcule la future position grace aux angles, mais à la main, cependant je connait l'angle exact.

    Comment faire alors?
    mon code de transformation actuel ressemble à ça :
    J'ai essayer d'implémenter l'idée ci dessus :

    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
     
    void Player::SetTransform(LPDIRECT3DDEVICE9 pDEV){
    		D3DXMATRIX matWorld;
    		D3DXMATRIX matTranslation;
    		D3DXMATRIX matRotation;
     
    	//Translate OK
    		D3DXMatrixTranslation( &matTranslation, x, y, z );
     
     
    	//Rotate en cours ....
     
    		D3DXVECTOR3	vCross;
    		D3DXVec3Cross(&vCross,&Vdir,&Vup);
    		D3DXVec3Normalize(&vCross,&vCross);
     
    		D3DXQUATERNION qx, qy, qz, qt, QRot;
     
    	//Construction des Quat avec le repere locale et les angles locaux
    		qx=D3DXQUATERNION(Vdir.x, Vdir.y, Vdir.z, 0.0f);
    		qy=D3DXQUATERNION(vCross.x, vCross.y, vCross.z, rotAvance);
    		qz=D3DXQUATERNION(Vup.x, Vup.y, Vup.z, rotDirection);
     
    		D3DXQuaternionMultiply(&qt, &qx, &qy);
    		D3DXQuaternionMultiply(&QRot, &qt, &qz);
     
    	//Conversion en Matrice
    		D3DXMatrixRotationQuaternion( &matRotation, &QRot );
     
     
    	//Calcul MatriceWorld
    		matWorld =matRotation * matTranslation;
     
    		pDEV->SetTransform( D3DTS_WORLD, &matWorld );
    	}
    En fesant comme ça, le mesh se déforme, et tourne 2 fois trop vite.
    rotDirection est l'angle qu'il fait en se dirigeant (autour de Vup)
    rotAvance est l'angle qu'il fait en avançant, (autour de Vcross)

    Merci pour votre aide


    Ryan

  2. #2
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 33
    Par défaut
    J'ai trouvé le bug,
    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
     
    	void Player::SetTransform(LPDIRECT3DDEVICE9 pDEV){
    		D3DXMATRIX matWorld;
    		D3DXMATRIX matTranslation;
    		D3DXMATRIX matRotation;
     
    	//Translate OK
    		D3DXMatrixTranslation( &matTranslation, x, y, z );
     
     
    	//Rotate en cours ....
     
    		D3DXVECTOR3	vCross;
    		D3DXVec3Cross(&vCross,&Vdir,&Vup);
     
    		D3DXVec3Normalize(&vCross,&vCross);
    		D3DXVec3Normalize(&Vdir,&Vdir);
    		D3DXVec3Normalize(&Vup,&Vup);
     
    		D3DXQUATERNION qx, qy, qz, qt, QRot;
     
    	//Construction des Quat avec le repere locale et les angles locaux
    		//qx=D3DXQUATERNION(Vdir.x, Vdir.y, Vdir.z, 0.0f);
    		//qy=D3DXQUATERNION(vCross.x, vCross.y, vCross.z, rotAvance);
    		//qz=D3DXQUATERNION(Vup.x, Vup.y, Vup.z, rotDirection);
     
    		D3DXQuaternionRotationAxis(&qx,&Vdir,0.0f);
    		D3DXQuaternionRotationAxis(&qy,&vCross,rotAvance);
    		D3DXQuaternionRotationAxis(&qz,&Vup,-rotDirection);
     
    		D3DXQuaternionNormalize(&qx,&qx);
    		D3DXQuaternionNormalize(&qy,&qy);
    		D3DXQuaternionNormalize(&qz,&qz);
     
    		D3DXQuaternionMultiply(&qt, &qx, &qy);
    		D3DXQuaternionNormalize(&qt,&qt);
    		D3DXQuaternionMultiply(&QRot, &qt, &qz);
    		D3DXQuaternionNormalize(&QRot,&QRot);
     
    	//Conversion en Matrice
    		D3DXMatrixRotationQuaternion(&matRotation, &QRot);
     
    	//Calcul MatriceWorld
    		matWorld =matRotation * matTranslation;
     
    		pDEV->SetTransform( D3DTS_WORLD, &matWorld );
    	}
    La construction d'un quaternion directement avec l'angle et les paramètres du vecteur était foireuse...
    en utilisant D3DXQuaternionRotationAxis ça marche mieux, il y a encore des bug dans la rotation je ne voit pas trop d'où viens le problème...
    peut être de
    D3DXQuaternionRotationAxis(&qx,&Vdir,0.0f); avec un angle de 0, mais je ne vois pas comment trouver un angle ??...
    je me rend fou ^^

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 33
    Par défaut
    Arfle je ne comprend vraiment pas pourquoi ma technique si dessus ne fonctionne pas

    Je reformule ma question puisqu'elle as changée car j'ai une autre approche en tête :

    J'ai les coordonnées de 3 vecteurs qui forment un repère orthonormé local à un objet,
    Ce que je voudrais maintenant, c'est connaitre la matrice de rotation (par les angles d'euler ou peu importe) qui permet de passer du repère global au repère local, sachant que je connais les coordonnées des 6 vecteurs (3 par repères..).

    Je sèche complètement

  4. #4
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    Question bête (j'ai peut-être mal compris ton problème) : si tu as les 3 vecteurs formant la base locale de ton joueur, plus sa position, alors tu as immédiatement sa matrice de transformation, pourquoi cherches-tu à en extraire une rotation ?

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 33
    Par défaut
    Salut,
    non j'ai les 3 coordonnées des vecteurs locaux de mon objet plus l'origine de mon objet, il ne manque plus qu'à tourner l'objet pour su'il se cale bien dans le repère local.

    Puisque ce repère je l'ai calculé un peu à la main, je ne suis pas très familier des matrices.
    N'y as t-il pas un moyen de calculer une matrice de rotation à partir de mes 3 coordonnées de vecteurs ?
    Ou bien un moyen d'extraire de façon mathématique les 3 angles qui permetten de passer du repère global au repère local, pour après créer la matrice ?

    Vois-tu mon problème ?

  6. #6
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    Ce que je voulais dire, c'est qu'avec tes 3 vecteurs tu as déjà la matrice de transformation.

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 33
    Par défaut
    Ce que je voulais dire, c'est qu'avec tes 3 vecteurs tu as déjà la matrice de transformation.

    Je ne comprend vraiment pas, ou peut être est ce toi ^^, mais je m'en sors pas, pitié de l'aide :
    Mon code de transformation :

    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
     
    	void Player::SetTransform(LPDIRECT3DDEVICE9 pDEV){
    		D3DXMATRIX matWorld;
    		D3DXMATRIX matTranslation;
    		D3DXMATRIX matRotation;
     
    	//Translate OK
    		D3DXMatrixTranslation( &matTranslation, x, y, z );
     
     
    	//Rotate en cours ....
     
    		D3DXVECTOR3	vCross;
     
    		D3DXVec3Cross(&vCross,&Vdir,&Vup);
     
    		D3DXVec3Normalize(&vCross,&vCross);
    		D3DXVec3Normalize(&Vdir,&Vdir);
    		D3DXVec3Normalize(&Vup,&Vup);
     
    		D3DXQUATERNION qx, qy, qz, qt;
     
    	//Construction des Quat avec le repere locale et les angles locaux
     
    		D3DXQuaternionRotationAxis(&qx,&tmpVdir,0.0f);
    		D3DXQuaternionRotationAxis(&qy,&vCross,rotAvance);
    		D3DXQuaternionRotationAxis(&qz,&Vup,-rotDirection);
    		D3DXQuaternionNormalize(&qx,&qx);
    		D3DXQuaternionNormalize(&qy,&qy);
    		D3DXQuaternionNormalize(&qz,&qz);
     
    		D3DXQuaternionMultiply(&qt, &qx, &qy);
    		D3DXQuaternionNormalize(&qt,&qt);
    		D3DXQuaternionMultiply(&QRot, &qt, &qz);
    		D3DXQuaternionNormalize(&QRot,&QRot);
     
     
    	//Conversion en Matrice
    		D3DXMatrixRotationQuaternion(&matRotation, &QRot);
     
     
     
    	//Calcul MatriceWorld
    		matWorld =matRotation * matTranslation;
     
    		pDEV->SetTransform( D3DTS_WORLD, &matWorld );
    	}
    je calcul x,y et z grace au vecteurs que je crée qui forment mon repère local, mais à ce moment là, l'objet n'est pas tourné correctement ce qui est normal, donc je veux calculer la matrice de rotation qui permet le passage du repère global au repère local.

    Edit : la méthode que j'ai mise ci dessus pour la rotation ne marche pas, mais à ce moment j'ai les coordonnées de mon repère local que j'ai calculé en interne, mais je n'ai pas la matrice de rotation, vois tu?


    Edit 2 : petit schéma en attachement
    Images attachées Images attachées  

  8. #8
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    Je crois qu'on ne se comprend pas...

    Deux hypothèses, dis moi laquelle est la bonne :

    1/ J'ai mal compris ton problème, et tu ne connais que la translation de ton objet
    (mais alors pourquoi parles-tu toujours du repère local qui serait connu lui aussi ?).

    2/ Tu as bien ton repère local connu, avec ses 3 axes, mais tu te compliques la vie à vouloir extraire translation et position alors qu'il suffit de placer ces 3 vecteurs en tant que colonnes de ta matrice pour avoir la transformation finale.

    ?

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 33
    Par défaut
    aa
    voila peut être la solution, en fait je suis un gros boulet, ok? on part de là ^^

    Je me suis rendu fou au début pour pouvoir trouver une solution à mon problème de "base", ce problème était de trouver un moyen pour pouvoir se diriger corectement autour d'une sphère, les solutions de coordonnées sphèriques ne me convennait pas, puisque ça posait des problèmes aux pôles et des problèmes de direction également.

    Donc la solution à été de matérialiser 3 vecteurs dans mon objets
    L'idée était d'imaginer un cercle autour de la sphère à chaque fois qu'on avance, pour que l'objet tourne(edit : avance) correctement, ce 'cercle de trajectoire' est donc placé dans un autre repère :
    déterminé par 3vecteurs:
    Vecteur Vup : vecteur entre l'origine du repère global (= origine de la sphère) et la position de l'objet.
    Vecteur Vdir : initialisé à (1,0,0)
    Vecteur Vdir*Vup.

    Enfin bref ces 3 vecteurs me permettent de calculer la position de l'objet, et en même temps je veux que cet objet tourne de manière à rester toujours "droit" à ce repère.
    Vois tu ?

    2/ Tu as bien ton repère local connu, avec ses 3 axes, mais tu te compliques la vie à vouloir extraire translation et position alors qu'il suffit de placer ces 3 vecteurs en tant que colonnes de ta matrice pour avoir la transformation finale.
    donc c'est ça la solution?
    mais la translation n'est pas "enregistrée dans mes vecteurs... étant données que j'ai la translation, c'est comme si mon repère était maintenant à l'origine. il me manque plus qu'à "tourner" le mesh pour qu'il se "cale" (encore une fois ^^) sur le "repère"

  10. #10
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    mais la translation n'est pas "enregistrée dans mes vecteurs...
    Ca tombe bien : il reste une colonne à remplir dans la matrice (la 4ème), et bien c'est justement la translation

    Je pense que tu prends le problème à l'envers. Pour positionner un objet il faut connaître son repère local. Repère, matrice de passage, c'est la même chose : comme je te l'ai dit on peut passer de l'un à l'autre instantanément lorsqu'on sait que les 3 premières colonnes sont les 3 axes du repère, et la 4ème est la position. D'ailleurs si tu extrais des rotations pour reconstruire une matrice, tu t'apercevras que les colonnes de celle-ci ne sont rien d'autre que tes 3 vecteurs de départ...

    Est-ce que c'est plus clair comme ça ?

  11. #11
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 33
    Par défaut
    Voui m'sieur je pense avoir pigé, en fait mon problème était simple et je le savais mais je suis vraiment nulle niveaux matrice

    Donc ma matrice de transformation finale ressembe à ça :

    Sachant que
    Vdir est "associée" à (1,0,0) (dans mon repère global)
    Vup à (0,1,0)
    Vcross à (0,0,1)

    la matrice de transformation finales est :
    Vdir.x Vup.x Vcross.x x
    Vdir.y Vup.y Vcross.y y
    Vdir.z Vup.z Vcross.z z

    C'est bien ça?
    et la dernière ligne c'est quoi?
    ques des 1 ou que des 0, ou bien un mix ^^

    Merci pour ton attention en tout cas

    edit : x y et z sont les même que ceux dans mon code, à savoir la position de l'objet dans le repère global

  12. #12
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 33
    Par défaut
    Meeeeerciiiiiiiiiii

    Du fond du coeur, je suis trop heureux
    ça marche niquel hop là content de cliquer sur résolu, merci merci et merci encore Laurent

  13. #13
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    Content de t'avoir aidé

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

Discussions similaires

  1. petite aide sur les transactions et triggers SVP
    Par CharleLéo dans le forum Débuter
    Réponses: 4
    Dernier message: 15/11/2004, 20h43
  2. Petite aide pour gros problème : libstdc++
    Par Info-Rital dans le forum Linux
    Réponses: 5
    Dernier message: 30/08/2004, 19h17
  3. Petite aide sur les triggers ?
    Par krimson dans le forum PostgreSQL
    Réponses: 3
    Dernier message: 16/04/2004, 16h28
  4. Une petite aide pour les API ?
    Par Yop dans le forum Windows
    Réponses: 2
    Dernier message: 04/04/2002, 21h45

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