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

Moteurs 3D Discussion :

Problème d'angle, dans un programme 3D


Sujet :

Moteurs 3D

  1. #1
    Futur Membre du Club
    Inscrit en
    Mars 2006
    Messages
    19
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 19
    Points : 6
    Points
    6
    Par défaut Problème d'angle, dans un programme 3D
    Bonjour,

    J'ai posté ce message dans un autre forum de Développez.com d'abord, petite erreur qu'un membre m'a gentillement fait remarquer, désolé, donc je reposte ici

    ************************************
    Bonjour,

    J'ai commencé il y a peu à m'intéresser à la 3D avec Delphi. Je n'ai actuellement aucun projet très particulier en tête, je préfère déjà voir ce que j'arrive à faire lol

    J'ai votre version de Delphi 2005 sur laquelle j'ai installé les composants Asphyre, d'après ce que j'ai cru comprendre il y a des chances pour que ce choix de librairie 3D soit avantageux ? bref.

    J'ai donc créé un monde tout simple : juste un plan ! mdr, mais ça suffit pour tester les premières fonctions.

    J'ai ajouté un objet sous forme de "matrix" que j'ai appelé persogol (un personnage bien gogol fait à la va-vite avec anim8or (logiciel pour créer facilement des objet 3D en plusieurs formats, notament le .3ds qui peut être converti ensuite en .mesh pour être utilisable par Asphyre. Téléchargeable sur www.anim8or.com)
    Je déclare les coordonnées de ce personnage avec ces variables globales :
    // Coordonnées
    PersoX := 0;
    PersoY := 25;
    PersoZ := 0;
    // Angle
    PersoAX := 0;
    PersoAY := 0;
    PersoAZ := 0;

    Je place devant lui un curseur (invisible lol, je n'ai pas réussi à afficher mon PNG) à une distance de 50 (50 quoi ? Pixel ?? je ne sais pas vraiment)
    // On initialise les coordonnées du curseur :
    CurseurD := 50;
    CurseurX := PersoX + CurseurD*sin(PersoAY) + CurseurD*cos(PersoAZ);
    CurseurY := PersoY + CurseurD*cos(PersoAX) + CurseurD*sin(PersoAZ);
    CurseurZ := PersoZ + CurseurD*sin(PersoAX) + CurseurD*cos(PersoAY);

    Je créé ensuite une caméra dont les coordonnées suivent celles du personnage et orientée vers le curseur (qui n'est ni plus ni moins qu'une coordonnée 3D finalement)


    J'ai ajouter un clavier et une sourie asphyre.
    Les touches :
    W : avancer
    S : reculer
    A : gauche (sans rotation)
    D : droite (sans rotation)
    La sourie gère la rotation autour de l'axe horizontal (donc vue vers le haut ou le bas) et autour de l'axe vertical (donc gauche ou droite)



    Actuellement, mon personnage peut se déplacer et tourner donc.
    Par contre j'ai deux soucis que je n'arrive pas à résoudre, ça fait des heures et des heures que je tourne en rond.
    Lorsque je déplace la sourie sur les côtés le curseur suit bien (pas le curseur que vous avez en lisant ce message, mon fameux curseur invisible qui devrait toujours être au centre de l'écran... comme un viseur en fait ! lol), le personnage tourne (par contre on ne le voit plus, étant donné que la caméra est "en lui" il fallait que je désactive l'affiche du perso) donc la caméra est bien accès vers ce fameux cuseur.
    Le premier hic est là... ça ne fonctionne pas sur lorsque je déplace la sourie en avant ou en arrière. Ma "formule" est incorrecte et je ne suis pas assez calé en trigo pour résoudre ça, j'ai fait énormément d'essaies mais pas le bon apparement.

    le deuxième hic, c'est pour le déplacement avec le clavier. le personnage se déplace, le curseur suit le mouvement mais le déplacement du perso ne prend pas en compte l'angle dans lequel il se trouve depuis que j'ai bougé ma sourie sur les côtés ! La cata, le personnage ne se déplace donc pas dans le sens du curseur....

    Voila mes deux soucis actuels (d'autres viendront c'est sûr )

    Pour info :

    Pour détecter les mouvements de la sourie :
    // Axe horizontal
    MouseDisplace := AsphyreMouse.displace;
    if MouseDisplace.X < -1 then DeplacementAX := -1;
    if MouseDisplace.X > 1 then DeplacementAX := 1;
    // Axe vertical
    DeplacementAY := MouseDisplace.Y;
    if MouseDisplace.Y < -1 then DeplacementAY := 1;
    if MouseDisplace.Y > 1 then DeplacementAY := -1;

    Pour détecter les touches du clavier :
    if AsphyreKeyboard.Key[DIK_A] then DeplacementX := -2;
    if AsphyreKeyboard.Key[DIK_D] then DeplacementX := 2;
    if AsphyreKeyboard.Key[DIK_S] then DeplacementZ := -2;
    if AsphyreKeyboard.Key[DIK_W] then DeplacementZ := 2;
    if AsphyreKeyboard.Key[DIK_SPACE] then DeplacementY := 2;
    if AsphyreKeyboard.Key[DIK_C] then DeplacementY := -2;

    Le calcul des angles de rotation :
    PersoAX := PersoAX + 0.1*DeplacementAZ;
    if PersoAX > 360 then PersoAX := PersoAX - 360;
    if PersoAX < 0 then PersoAX := PersoAX + 360;
    PersoAY := PersoAY + 0.1*DeplacementAX;
    if PersoAY > 360 then PersoAY := PersoAY - 360;
    if PersoAY < 0 then PersoAY := PersoAY + 360;
    PersoAZ := PersoAZ + 0.1*DeplacementAY;
    if PersoAZ > 360 then PersoAZ := PersoAZ - 360;
    if PersoAZ < 0 then PersoAZ := PersoAZ + 360;

    Déplacement du perso :
    if DeplacementX <> 0 then PersoX := PersoX + DeplacementX + 2*sin(PersoAY);
    if DeplacementZ <> 0 then PersoZ := PersoZ + DeplacementZ + 2*cos(PersoAY);

    (2 * le cos ou sin parce que pour le déplacement par clavier la valeur est de 2, alors qu'avec la sourie j'ai mit 1 pour que ça ne tourne pas trop vite)

    Et enfin le nouvel emplacement du curseur après un déplacement ou une rotation :

    CurseurX := PersoX
    + CurseurD*sin(PersoAY)
    + CurseurD*cos(PersoAZ)
    ;
    CurseurY := PersoY
    + CurseurD*sin(PersoAX)
    + CurseurD*cos(PersoAZ)
    ;
    CurseurZ := PersoZ
    + CurseurD*sin(PersoAX)
    + CurseurD*cos(PersoAY)
    ;

    (CurseurD est la distance séparant le curseur du perso, le curseur se déplaçant donc sur une sphère de diamètre 100 dans mon cas, autour du personnage)


    J'ignore si pour vous tout ce que j'écris là est bien compréhensible, moi j'ai écris tout ce code donc je sais ce que chaque élément doit représenté donc si quelque chose doit être éclairci n'hésitez pas à me le dire.

    Merci beaucoup à quiconque saura me mettre sur la voie. Personnellement je pense que les deux problèmes viennent de mes calculs de rotation, lorsque je bouge la sourie. Dure dure ... si j'avais su j'aurai sans doute plus bossé ma trigo à l'école lol

    PS : pour ma "formule" je me suis basé sur ça :
    x = r * cos(D)
    y = r * sin(D)
    Est-ce une bonne formule ou celle-ci n'est appliquable que pour le 2D, ce qui expliquerait en partie mes soucis dans la 3D ?

  2. #2
    Membre actif Avatar de Sixissor
    Étudiant
    Inscrit en
    Février 2006
    Messages
    206
    Détails du profil
    Informations personnelles :
    Âge : 37

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2006
    Messages : 206
    Points : 242
    Points
    242
    Par défaut
    Salut

    j'ai installé les composants Asphyre, d'après ce que j'ai cru comprendre il y a des chances pour que ce choix de librairie 3D soit avantageux ?
    Perso jamais entendu parler...
    Avec Delphi je sais qu'il y a GLScene, mais c'est comme GLUT (l'ancien GLUT): bien pour quelques applis vite fait mais pas un vrai prog.
    Et si tu veux aller plus loin y'a GLFW. Sinon tu bourrines avec OpenGL et l'API Win32

    un personnage bien gogol fait à la va-vite avec anim8or (logiciel pour créer facilement des objet 3D en plusieurs formats, notament le .3ds qui peut être converti ensuite en .mesh pour être utilisable
    J'ai déjà utilisé Anim8or et bien qu'on ait pas le confort d'un 3DS MAX ou de Maya, j'ai eu les résultats les plus rapides avec ce petit modeleur (+ autres...) très bien fait, et gratuit en plus.

    Je place devant lui un curseur (invisible lol, je n'ai pas réussi à afficher mon PNG) à une distance de 50 (50 quoi ? Pixel ?? je ne sais pas vraiment)
    // On initialise les coordonnées du curseur :
    {...}
    Je créé ensuite une caméra dont les coordonnées suivent celles du personnage et orientée vers le curseur (qui n'est ni plus ni moins qu'une coordonnée 3D finalement)
    NON ! Très mauvaise méthode !!!
    1 - Cherche libPNG sur Sourceforge
    2 - Ton curseur doit se situer sur un autre plan que celui que tu as en 3D, je m'explique: tu dois toujours avoir au moins une matrice PROJECTION et une matrice MODELVIEW, et pour la vue 3D, tu définis une projection en perspective par exemple + un point de vue de la scène. Pour ton curseur, tu dois recréer les matrices de projection mais en vue orthogonale cette fois et remettre à zéro ta matrice qui permet d'avoir un point de vue de la scène.
    En gros:

    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
     
    /*  2D    */
     
    Appel de la matrice de projection
    Mise à zéro
    Initialisation (mode de vue orthogonal)
     
    Appel de la matrice de "vue"
    Mise à zéro
    //Pas besoin d'initialisation si tu n'utilises pas l'axe en profondeur
     
    // Dessin de ton curseur ICI
     
     
    /*  3D  */
     
    Appel de la matrice de projection
    Mise à zéro
    Initialisation (perspective, etc.)
     
    Appel de la matrice de "vue"
    Mise à zéro
    Point de vue (+ autres...)
     
    // Dessin de ta scène 3D là

    En ce qui concerne le problème de rotations, translations, ... et caméra en général... C'est chiant je l'avoue
    Mai va voir sur Sulaco ou sur Nehe, y'a des projets qui utilisent des caméras et sont bien fait. Tu comprendras

    ++
    • Awesome dude ! R0FLC0PT3R !!!!11!ONE!!!
    • There's no place like 127.0.0.1

  3. #3
    Futur Membre du Club
    Inscrit en
    Mars 2006
    Messages
    19
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 19
    Points : 6
    Points
    6
    Par défaut
    Re,

    Merci pour les conseils, je vais voir les liens que tu me proposes. Pour Asphyre y'a un "tutau" sur Developpez.net :
    http://pedro.developpez.com/articles/delphi/3d/asphyre/

    Le soucis c'est que ce tutau explique ce qu'est Asphyre, en donnant quelques détails qui doivent pouvoir être compris par ceux qui nagent déjà dans la 3D, mais il n'y a pas de véritable "tutoriel" expliquant bien comment faire diverse chose. Je me suis servit de sources trouvés sur un site en anglais :
    http://www.afterwarp.net/forum/


    Pour le PNG Asphyre a un composant TAsphyreImages qui permet de charger les images contenues dans une archive (.asdb, conçue pour Asphyre uniquement apparement). Puis des fonctions d'un composant TAsphyreCanvas servent à afficher ces images en 2D. Il n'y a normalement pas besoin d'autre librairie pour ça, enfin si j'ai bien comprit lol


    Et enfin pour les soucis d'angles, j'ai continué un peu à faire des recherches de tutaux ou autres. Il semblerait que ma méthode ne soit pas la bonne du tout, plutôt que de déplacer des coordonnées et de définir l'angle dans lequel il se trouve pour jouer sur sa direction il faut créer une matrice qui a son propre repère XYZ, ainsi pour aller vers l'avant pas besoin de calculer un angle par rapport à la scène mais par rapport à l'objet lui-même.... là par contre il faut que je comprenne comme on fait pour indiquer au programme de déplacer une matrice en se servant de son repère plutôt que de celui de la scène... dure dure...

    Ah oui pour le curseur, tu me parle d'une projection... mais si la caméra suit ce curseur qui est à l'origine au centre de l'écran, il suffit de le dessiner toujours au centre non ? Je ne suis pas sûr de bien comprendre, la projection est le seul moyen de dessiner l'objet 2D dans un monde 3D, avec les librairies que tu connais ? (je dis bien que tu connais parce que sauf erreur de ma part, ce qui peut arriver souvent, Asphyre permet de faire ça sans projection avec les canvas)

    En tout cas merci de m'aider !

    ***************************************************
    Edit : Aïïeee... les deux sites que tu me conseille sont en anglais ça ne va pas être évident lol.... on va essayer quand même, mais demain matin..

  4. #4
    Futur Membre du Club
    Inscrit en
    Mars 2006
    Messages
    19
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 19
    Points : 6
    Points
    6
    Par défaut
    Hello,

    Voila, mes messages étant un peu haut je fait un nouveau au lieu d"éditer.

    C'est grâce à des explications de trigo que j'ai finalement réussi à faire bouger correctement ma caméra. Je suis resté dans mon obtique de déplacer le viseur (qui s'affiche bien en PNG maintenant, avec le Canvas, toujours au centre de l'écran) autour de l'objet du personnage.
    Le seul "inconvénient" c'est que la formule du site est basé sur la trigo en général, donc j'ai supposé que mes calculs étaient bons avec des °, mais finalement il faut mesurer les angles en radians, quand on a pas l'habitude c'est un peu gênant. Bref, pour info :


    CurseurX := CurseurD * cos(CurseurV) * sin(CurseurH);
    CurseurZ := CurseurD * cos(CurseurV) * cos(CurseurH);
    CurseurY := CurseurD * sin(CurseurV);

    CurseurX, CurseurZ et CurseurY sont des réels (Real) qui représente l'emplacement 3D du curseur. CurseurD est la distance entre la caméra et le curseur. CurseurH est l'angle en radian qui augmente et diminue lorsque l'on déplace la sourie sur les côtés et CurseurV lorsque l'on déplace la sourie en avant ou en arrière :

    // Rotation avec sourie
    if MouseDisplace.X < -1 then
    begin
    CurseurH := CurseurH - 0.1;
    if CurseurH < 0 then CurseurH := CurseurH + 2*Pi;
    end;
    if MouseDisplace.X > 1 then
    begin
    CurseurH := CurseurH + 0.1;
    if CurseurH > 2*Pi then CurseurH := CurseurH - 2*Pi;
    end;
    if MouseDisplace.Y < -1 then
    CurseurV := min(0.47*Pi,CurseurV + 0.05);
    if MouseDisplace.Y > 1 then
    CurseurV := max(-0.47*Pi,CurseurV - 0.05);

    Puis... et là ce n'est pas parfait, il y a encore un léger décalage de temps à autre, on calcul le déplacement avec le clavier en fonction de l'angle CurseurH :

    Gauche :
    DepX := -3 * cos(CurseurH);
    DepZ := 3 * sin(CurseurH);

    Droite :
    DepX := 3 * cos(CurseurH);
    DepZ := -3 * sin(CurseurH);

    Avant :
    DepZ := 3 * cos(CurseurH);
    DepX := 3 * sin(CurseurH);

    Arrière :
    DepZ := -3 * cos(CurseurH);
    DepX := -3 * sin(CurseurH);


    La valeur "3" juste au dessus est la vitesse de déplacement. DepX et DepZ sont des réels qu'il faut additionner au valeur PersoX et PersoY pour le déplacement de l'objet Perso.

    Voili voila, en espérant que je trouverai ce qui cause mon léger décalage entre l'orientation du personnage (ou de ses mouvements) et l'orientation de la caméra

Discussions similaires

  1. Problème d'éxecution dans mon programme
    Par mouchT8 dans le forum C
    Réponses: 8
    Dernier message: 16/05/2008, 01h36
  2. [Débutant] Problème de boucle dans un programme
    Par Nicolampion dans le forum MATLAB
    Réponses: 3
    Dernier message: 24/04/2008, 18h57
  3. Problème de sortie dans un programme.
    Par IDE dans le forum C
    Réponses: 8
    Dernier message: 20/05/2007, 18h21
  4. Réponses: 8
    Dernier message: 23/03/2006, 19h30
  5. [Debutant] Problème de fraction dans un programme
    Par SAKDOSS dans le forum Débuter
    Réponses: 4
    Dernier message: 22/10/2005, 18h38

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