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

Contribuez Discussion :

[Tuto] [3D] Moteur physique [En attente]


Sujet :

Contribuez

  1. #1
    Membre averti Avatar de Rafy
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    415
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 415
    Points : 417
    Points
    417
    Par défaut [Tuto] [3D] Moteur physique
    Le moteur physique dont nous allons voir les différents traits aura les caractéristiques suivantes :
    -> Moteur physique 3D, orienté vers DirectX car le moteur sera voué à travailler avec un moteur 3D basé sur Direct3D.
    -> Codage en C++
    -> Utilisation des types de base de DirectX (D3DXVECTOR4, D3DXMATRIX)
    -> Moteur de particules
    -> Gestion de rayons
    -> Gestion de rigid-body

    Caractéristiques du moteur de particules :
    -> Variation du nombre maximum de particule en runtime
    -> Optimisation de la gestion de nombreuses particules en les regroupant en emetteur
    -> Gestion des collisions avec tous les rigid-body du moteur

    Quelques remarques :
    -> La dépendance de DirectX est très faible, il est possible de s'en défaire sans trop de soucis, pour cela j'utiliserai les types Vector, et Matrix pour ceux qui souhaiteraient du code plutôt indépendant de DirectX.
    -> Les explications tentent le plus possible d'être structurées pour réaliser une certaine progression. Il est possible pour certains de penser que je m'attarde sur des détails, ils auront de l'importance plus tard...

    Les choix décisifs :
    -> Le moteur sera en Left-handed, car DirectX est en left-handed, les changements de repères seraient un facteur limitant les performances.
    -> L'ordre des transformations dans les changements de repères sont Y, X, Z. Car DirectX possède cet ordre. Le but final du moteur est de retourner la matrice de transformation du mesh qui modélise de Rigid-body, il faut absolument que l'ordre des transformations du moteur soit le même que celui de l'affichage... Donc celui de DirectX... Comme il est hors de question de gérer les rigid-body avec cet ordre et le reste du moteur avec un ordre différent, le moteur entier tournera en YXZ.

    La première chose quand on code un moteur physique c'est les bases. Les
    objets qui vont servir très souvent : les torseurs, les vecteurs, les matrices, les repères, les SmartVector. Ensuite on peut commencer à coder un moteur et les corps qu'il sera suceptible de gérer.

    Les vecteurs
    Les vecteurs sont de loin les objets les plus manipulés dans un moteur physique. Il permettent dans les torseurs de contenir des informations, dans les SmartVector de participer aux calculs.
    Il est possible d'utiliser une class faite maison, mais c'est assez lourd à coder, il y a des opérateurs partout, il faut optimiser pas mal de choses.
    Mon conseil est d'utiliser des class déjà faite (Les types de DirectX sont parfait, ils sont éprouvé, utilisations dans pas mal d'applications, s'il y avait des erreurs de codage, ça se saurai... )

    Les matrices
    Les matrices sont des éléments de calculs très important car elles modélisent aussi bien des transformations 3D que des opérations sur les vecteurs. Comme pour les vecteurs je préconise d'utiliser es types déjà codés.... Il y aura assez de boulot avec le moteur.

    Les torseurs
    Les torseurs sont les outils indispensables des calculs de la physique du solide.
    Voir la class de base des torseurs

    Les repères
    Les repères sont des outils de base avancés, car ils utilisent les vecteurs, les matrices. Ils permettent de rendre au codeurs du moteur une transparance dans l'utilisation des vecteurs et surtout de la gestions des corps non ponctuels.
    Voir la class de base des repères

    Les SmartVector
    Les SmartVector permettent de faire évoluer la class de base des vecteurs, et d'apporter des possibilités enormes de calculs et de transparence dans le codage du moteur, mais également pour l'utilisateur.
    Voir la class de base des SmartVector

  2. #2
    Membre averti Avatar de Rafy
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    415
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 415
    Points : 417
    Points
    417
    Par défaut
    Les repères :
    Un repère correspond en mathématique à une base. Ils permettent d'exprimer des grandeurs plus facilement car liées à ce qu'elles représentent.
    Il faut prendre avant tout un repère de référence... Ce repère c'est le repère absolut, ce repère c'est un repère qui va servir de référence à tous les autres repères, il est défini comme fixe. Au sens de la mécanique, c'est le bati. Nos calculs seront fait dans ce repère. Nos expliqueront pourquoi plus tard.
    Les repères sont donc, comme on l'a dit une base au sens mathématique. Qui dit base, dit changement de base. Car nous allons avoir des valeurs exprimées dans un repère et il va falloir les changer de repère. Les changements de base, en mathématiques, sont matérialisés par des matrices : les matrices de changement de base. Pour définir un repère il suffit d'avoir sa matrice de changement de base.
    Cette matrice se présente sous la forme d'une matrice 4x4.
    Pourquoi 4x4 ?
    Nous travaillons en 3D il nous faut, pour pouvoir faire des translations une dimension de plus. (Voir la définition et la manipulation des quaternions)
    Revenons à nos repères, une matrice nous suffit pour les définir : la matrice de changement de base du repère absolut vers notre repère.
    Il faut savoir que pour pouvoir faire des changement de base, il va nous falloir égallement la matrice inverse.
    On peut donc déjà débuter notre class :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    class CCoordinateSystem
    {
        public :
            CCoordinateSystem(void);
        protected :
        private :
            Matrix BaseChangingMatrix;    // Matrice du changement de base absolut -> notre repère
            Matrix BaseChangingMatrixInvert;    // Matrice du changement de base notre repère -> absolut
    };
    Edit and continu...

  3. #3
    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 : 40
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Très intéressant, et bravo pour la rapidité

    Ok, donc maintenant ce que l'on peut faire, c'est passer à l'étape suivante : je te donner accès aux outils de rédaction, et t'ouvrir un espace perso. Ainsi tu auras tout ce qu'il faut pour rédiger tes tutoriels au gabarit directement comme il faut.

    Contacte moi par MP pour m'indiquer d'une part si tu es OK, d'autre part le nom de domaine que tu souhaites avoir (de type xxx.developpez.com -- sans point ni espace ni underscore).


  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 : 40
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Ta boîte MP est pleine, je ne peux plus te contacter.

    Je voulais te dire qu'il me manque une chose : ton adresse e-mail, afin que l'on puisse t'enoyer les codes d'accès de ton domaine perso.

  5. #5
    Membre averti Avatar de Rafy
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    415
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 415
    Points : 417
    Points
    417
    Par défaut
    Mais un repère ne reste jamais fixe, il peut bouger, on doit donc pouvoir bouger se repère, en position et en orientation. Mais s'il on change ça position et son orientation alors il faut recalculer sa nouvelle matrice...
    On va introduire 4 Mutateurs sur 4 variables qu'on va introduire.
    Ces 4 variables vont stocker les 3 Angles qui vont nous permettre de créer la matrice de changement de base, et aussi la position du repère.
    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
    class CCoordinateSystem
    {
        public :
            CCoordinateSystem(void);
            CCoordinateSystem(const Vector& Position, float Yaw, float Pitch, float Roll);
     
        // Ils modifient la variable associé, et mettent MatrixComputed à false, mais ne modifient pas les matrices
            void SetYaw(float Yaw);                       
            void SetPitch(float Pitch);
            void SetRoll(float Roll);
            void SetPosition(const Vector& Position);
     
            const float& GetYaw(void) const;
            const float& GetPitch(void) const;
            const float& GetRoll(void) const;
            const float& GetPosition(void) const;
     
        protected :
        private :
            Vector Position;
            float Yaw;
            float Pitch;
            float Roll;
            bool MatrixComputed;
     
            void ComputeMatrix(void);      // Génère les deux matrices à partir des variables position, yaw, pitch, roll et met ComputedMatrix à true
            Matrix BaseChangingMatrix;    // Matrice du changement de base absolut -> notre repère
            Matrix BaseChangingMatrixInvert;    // Matrice du changement de base notre repère -> absolut
    };
    Maintenant on va passer à la chose la plus importante de cette class : les changements de repère.
    On va donc créer 4 méthodes dans notre class CCoordinateSystem :
    -> FromThisToAbsolut
    -> FromAbolutToThis
    -> FromThisToCoordinateSystem
    -> FromCoordinateSystemToThis

    FromThisToAbsolute
    Retourne les coordonnées de V dans le repère absolut (V exprimé dans notre repère)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    const Vector CCoordinateSystem::FromThisToAbsolute(const Vector& V)
    {
            Vector Result;
            if (!this->MatrixComputed)
                this->ComputeMatrix();
            Result = this->BaseChangingMatrix * V;
            return Result;
    }
    FromAbsoluteToThis
    Retourne les coordonnées de V dans notre repère (V exprimé dans le repère absolut)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    const Vector CCoordinateSystem::FromAbsoluteToThis(const Vector& V)
    {
            Vector Result;
            if (!this->MatrixComputed)
                this->ComputeMatrix();
            Result = this->BaseChangingMatrixInvert * V;
            return Result;
    }
    FromThisToCoordinateSystem
    Retourne les coordonnées de V dans le repère donné (V exprimé dans notre repère)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    const Vector CCoordinateSystem::FromThisToCoordinateSystem(const Vector& V, const boost::shared_ptr<CCoordinateSystem>& pCoordinateSystem)
    {
            Vector Result;
            Result = pCoordinateSystem->FromAbsoluteToThis(this->FromThisToAbsolute(V));
            return Result;
    }
    FromCoordinateSystemToThis
    Retourne les coordonnées de V dans notre repère (V exprimé dans le repère donné)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    const Vector CCoordinateSystem::FromCoordinateSystemToThis(const Vector& V, const boost::shared_ptr<CCoordinateSystem>& pCoordinateSystem)
    {
            Vector Result;
            Result = this->FromAbsoluteToThis(pCoordinateSystem->FromThisToAbsolute(V));
            return Result;
    }
    Remarque :
    Il est rare, dans un moteur physique, de faire un changement de repère d'un repère quelconque vers un autre repère que le repère absolut. Mais ça peut arriver...
    On remarque que les méthodes de changement de repère ou le repère absolut n'est ni le repère de départ ni celui d'arrivé sont plus lente. Mais très peu utilisées.

    Edit and Continu

  6. #6
    Membre averti Avatar de Rafy
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    415
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 415
    Points : 417
    Points
    417
    Par défaut
    J'ai volontairement pas donnée le code de la méthode CCoordinateSystem::ComputMatrix() car elle peut varier suivant ce que l'utilisateur décide :
    Je m'explique, il faut que l'utilisateur créé deux matrices, l'une l'inverse de l'autre.
    BaseChangingMatrix, est la matrice de changement de base qui va permettre de passer du repère absolut à notre repère.
    Voir la FAQ sur les matrices et les quaternions pour voir comment on créé une telle matrice...
    Avec DirectX il est possible d'utiliser D3DXMatrixYawPitchRoll() et d'insérer les 3 valeurs de la position.

    On remarque que si on donne aux méthodes de changement de repère un vecteur sous la forme (x, y, z, 0) alors seul la direction du vecteur change. Alors qu'avec un vecteur du type (x, y, z, 1) la direction change, mais la position de l'origine est modifiée également. (ça servira plus tard pour les vecteurs qui déterminent une direction)

  7. #7
    Membre averti Avatar de Rafy
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    415
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 415
    Points : 417
    Points
    417
    Par défaut
    Les repères serviront dans les applications suivantes :
    Ils seront liés à des entités et détermineront leurs orientations et leurs positions.




    Nous allons parler maintenant d'une class encore très importante : les SmartVector. Le moteur physique ferra bouger les entités, il ferra bouger les particules, mais quand on voudra attacher quelque chose à une entité (un emetteur de particules, un rayon, etc), il faudra alors l'utilisateur devra déplacer au point voulu, à chaque frame son objet (emetteur de particules, rayon, etc). Pour être plus précis, l'utilisateur devra faire à chaque frame un GetPosition sur l'entité, et un SetPosition sur son objet. (je parle la de la position mais ça peut être plein d'autre choses.)
    L'idée des SmartVector est de réaliser cette "liaison". Pour cela on a besoin des CCoordinateSystem. Un SmartVector est en fait un vecteur qui est exprimé dans un repère quelconque et qu'on lit dans un autre repère...
    Exemple :
    On a un vaisseau spacial, on fixe sur lui un emetteur de particule qui va représenter la trainé de son réacteur. Alors quand le vaisseau va se déplacer, il emènera notre emetteur avec lui... Pas besoin de le repositionner à chaque frame.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    class CSmartVector
    {
        public :
            CSmartVector(void);
            CSmartVector(const Vector& Vector, const boost::shared_ptr<CCoordinateSystem>& pCoordinateSystem);
     
        protected :
            Vector RelativeVector; // Vecteur
            boost::shared_ptr<CCoordinateSystem> pCoordinateSystem; // Repère dans lequel est exprimé RelativeVector
        private :
    };
    Pour l'instant pas grand chose de compliqué.

  8. #8
    Membre averti Avatar de Rafy
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    415
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 415
    Points : 417
    Points
    417
    Par défaut
    D'ici quelques mois un je vais créer un vrai tuto, ce ne sera plus une liste de poste, patience....

Discussions similaires

  1. [FAQ] [3D] Physique, moteur physique
    Par Rafy dans le forum Contribuez
    Réponses: 7
    Dernier message: 04/06/2006, 18h51
  2. Moteur Physique
    Par Jbx 2.0b dans le forum Physique
    Réponses: 6
    Dernier message: 11/03/2005, 13h29
  3. Moteur physique : comment l'implémenter ?
    Par haypo dans le forum Algorithmes et structures de données
    Réponses: 15
    Dernier message: 17/12/2003, 13h56

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