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

C++ Discussion :

Operateur de cast


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé Avatar de Robxley
    Homme Profil pro
    Docteur ingénieur traitement d'image
    Inscrit en
    Mai 2009
    Messages
    158
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Docteur ingénieur traitement d'image

    Informations forums :
    Inscription : Mai 2009
    Messages : 158
    Par défaut Operateur de cast
    Bonjour,

    Contexte :
    Je suis actuellement entrain de travailler sur un programme utilisant OpenGL. Avec les nouvelles spécificités OpenGL beaucoup de fonctions sont devenues dépréciées notamment toutes les fonctions concernant la manipulation des matrices Modelview et Projection.

    Pour me faciliter la gestion mathématique de mon programme et notamment tout ce qui touche aux matrices j'utilise la bibliothèque mathématique : OpenGL Mathematics (ou GLM, site : http://glm.g-truc.net/). Néanmoins cette bibliothèque ne propose pas la gestion des piles de matrices à la similitude des fonctions OpenGL glPushMatrix et glPopMatrix, fonctions dépréciées. J'ai donc par conséquent voulu reproduire ce type de fonction pour cela j'ai utilisé une classe du type :

    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
     
     
    class pile_matrix
    {
    public:
        //constructeur/destructeur
        pile_matrix(const glm::mat4& m);
        pile_matrix();
        ~pile_matrix();
     
        /*
        ....
          méthodes sur ma pile
        ....
        */
     
     
         operator glm::mat4&()  //cast qui ne va pas ou fait pas ce que je voudrai
        {
              return pile.back();
        }
    private:
    std::vector<mat4> pile;
     
    }
    Mon problème est que je voudrais utiliser de façon transparente un objet de ma classe pile_matrix comme étant un objet mat4. En gros avoir un cast automatique de ma classe pile_matrix en mat4 mais ce que je n'arrive pas à obtenir. Par exemple le code suivant ne fonctionne pas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    pile_matrix modelview, projection;
    glm::mat4 matriceA, matriceB;
    buffer = matriceA + modelview * projection * matriceB; //erreur lors de la compilation sur les operateurs
    Est-il nécessaire que je redéfinisse la globalité des opérateurs entre mat4 et pile_matrix ? ou une autre solution existe notamment au niveau du cast ? je fais une erreur quelque part ?


    (Je me suis permis de poster sur le forum c++ et non OpenGL étant donné que c'est plus un problème de langage que OpenGL, néanmoins si je me trompe de forum je déplacerai mon post)

  2. #2
    Membre très actif

    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2011
    Messages : 685
    Par défaut
    bonjour,

    tu as un message d'erreur à montrer ?


    bon je sais c'est toi qui demande de l'aide et c'est moi qui pose des questions,
    mais "l'opérateur de cast" il n'a pas de type de retour (d'accord pas de paramètre car il l'effectue sur this, mais pas de type retour non plus ça marche comment ? ) ?

    Edit : je n'ai rien dit

    sinon pourquoi dans ton attribut tu n'as pas besoin de spécifier le scope de tes mat4 alors que tu le fait partout ailleurs ?

    pour le cast, tu essaie de caster un élement en référence sur cet élément ?

  3. #3
    Membre éprouvé Avatar de Robxley
    Homme Profil pro
    Docteur ingénieur traitement d'image
    Inscrit en
    Mai 2009
    Messages
    158
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Docteur ingénieur traitement d'image

    Informations forums :
    Inscription : Mai 2009
    Messages : 158
    Par défaut
    Si bien sur.

    L'erreur donné par VS c++ express :

    1>main.cpp(95): error C2679: '*' binaire*: aucun opérateur trouvé qui accepte un opérande de partie droite de type 'pile_mat4' (ou il n'existe pas de conversion acceptable)
    1> c:\documents and settings\fresnel\bureau\opengl labo\rxenginegl3+\rxengine\ressources\glm-0.9.2.7\glm\core\type_mat4x4.inl(637): peut être 'glm::detail::tmat4x4<T> glm::detail::operator *<glm::core::type::precision::lowp_float>(const glm::detail::tmat4x4<T> &,const float &)' [trouvé à l'aide d'une recherche dépendante d'un argument]
    1> with
    1> [
    1> T=glm::core::type::precision::lowp_float
    1> ]
    1> c:\documents and settings\fresnel\bureau\opengl labo\rxenginegl3+\rxengine\ressources\glm-0.9.2.7\glm\core\type_mat4x4.inl(665): ou 'glm::detail::tvec4<T> glm::detail::operator *<glm::core::type::precision::lowp_float>(const glm::detail::tmat4x4<T> &,const glm::detail::tvec4<T> &)' [trouvé à l'aide d'une recherche dépendante d'un argument]
    1> with
    1> [
    1> T=glm::core::type::precision::mediump_float
    1> ]
    1> c:\documents and settings\fresnel\bureau\opengl labo\rxenginegl3+\rxengine\ressources\glm-0.9.2.7\glm\core\type_half.hpp(62): ou 'glm::detail::thalf glm::detail::operator *(const glm::detail::thalf &,const glm::detail::thalf &)' [trouvé à l'aide d'une recherche dépendante d'un argument]
    1> lors de la tentative de mise en correspondance de la liste des arguments '(glm::core::type::mat4, pile_mat4)'

    Dans mon programme la classe s'appelle pile_mat4 au lieu de pile_matrix et le log ici concerne que l'opérateur * mais cela le fait bien évidemment avec l'emploie d'un autre opérateur de la classe glm::mat4.

    Dans le log ce qui me chagrine c'est la remarque : "(ou il n'existe pas de conversion acceptable)".
    Ma méthode operator mat4&() n'est pas acceptable ? et pourquoi ?

    Edit :
    Pour info la class mat4 est un typedef float de la meta classe tmat4x4<T> :
    mat4 <=> tmat4x4<float>

    J'ai le morceau de code suivant qui marche :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    pile_mat4 pile;
    mat4 m = pile;
    mais toujours pas un truc du type :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    mat4 m,n;
    pile_mat4 pile;
    m = n*pile;

  4. #4
    Membre très actif

    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2011
    Messages : 685
    Par défaut
    je ne pensais pas que l'on puisse convertir un élément en référence sur cet élément directement.

    Je ne sais pas si c'est lié à ton problème, mais dans le code que tu montre, ton attribut de type std::vector<T> contient mat4, et pas glm::mat4. A part le fait que je ne comprend pas comment il peut compiler (à part si tu es sous le 2003), tu ne lui dis pas le scope dans lequel se trouvent tes mat4 (apparemment dans le namespace glm).

    Ensuite,
    buffer = matriceA + modelview * projection * matriceB
    tu l'utilises quand ton opérateur de cast ? parce que le compilo te précise qu'il ne peut pas faire ce genre de truc avec une opérande à droite de type "pile_mat4" mais il ne parle pas de "pile_mat4&" c'est donc que la conversion implicite n'est pas passée.

    Edit : Du coup, rien ne dit que ton cast soit le problème. Mais bon moi je dis plus rien les pros sont arrivés...

  5. #5
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Par défaut
    Au pire, tu utilises un fonction libre, par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    typedef std::stack<glm::mat4> mat4stack;
    glm::mat4& top(mat4stack& s) { return s.top(); }
    glm::mat4 const& top(mat4stack const& s) { return s.top(); }
     
    buffer = matriceA + top(modelview) * top(projection) * matriceB;

  6. #6
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Par défaut
    Bonjour

    Hum... problème de NIH ?
    Il existe déjà une classe stack qui fait ce que tu souhaites : std::stack.
    Ensuite, d'un point de vue sémantique, une pile n'est pas une matrice et ne devrait pas pourvoir être convertir implicitement en matrice.

  7. #7
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Par défaut
    Citation Envoyé par Robxley Voir le message
    Bonjour,

    Contexte :
    Je suis actuellement entrain de travailler sur un programme utilisant Opengl. Avec les nouvelles spécificités Opengl beaucoup de fonctions sont devenues dépréciées notamment toutes les fonctions concernant la manipulation des matrices Modelview et Projection.

    Pour me faciliter la gestion mathématique de mon programme et notamment tout ce qui touche aux matrices j'utilise la librairie mathématique : OpenGL Mathematics (ou GLM, site : http://glm.g-truc.net/). Néanmoins cette librairie ne propose pas la gestion des piles de matrices à la similitude des fonctions OpenGL glPushMatrix et glPopMatrix, fonctions dépréciées. J'ai donc par conséquent voulu reproduire ce type de fonction pour cela j'ai utilisé une classe du type :

    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
     
     
    class pile_matrix
    {
    public:
        //constructeur/destructeur
        pile_matrix(const glm::mat4& m);
        pile_matrix();
        ~pile_matrix();
     
        /*
        ....
          méthodes sur ma pile
        ....
        */
     
     
         operator glm::mat4&()  //cast qui ne va pas ou fait pas ce que je voudrai
        {
              return pile.back();
        }
    private:
    std::vector<mat4> pile;
     
    }
    Mon problème est que je voudrais utiliser de façon transparente un objet de ma class pile_matrix comme étant un objet mat4. En gros avoir un cast automatique de ma classe pile_matrix en mat4 mais ce que je n'arrive pas à obtenir. Par exemple le code suivant ne fonctionne pas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    pile_matrix modelview, projection;
    glm::mat4 matriceA, matriceB;
    buffer = matriceA + modelview * projection * matriceB; //erreur lors de la compilation sur les operateurs
    Est-il nécessaire que je redéfinisse la globalité des opérateurs entre mat4 et pile_matrix ? ou une autre solution existe notamment au niveau du cast ? je fais une erreur quelque part ?


    (Je me suis permis de poster sur le forum c++ et non opengl étant donné que c'est plus un problème de langage que Opengl, néanmoins si je me trompe de forum je déplacerai mon post)
    Non, pas de cast implicite. Il est beaucoup plus sage de redéfinir les opérateurs de manière à accepter des objets pile_matrice et des objets mat4 (ça ne fait pas beaucoup de travail, quand même).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    pile_matrice operator*(const pile_matrice& pm, const mat4& m);
    pile_matrice operator*(const mat4& m, const pile_matrice& pm);
    pile_matrice operator+(const pile_matrice& pm, const mat4& m);
    pile_matrice operator+(const mat4& m, const pile_matrice& pm);
    pile_matrice operator-(const pile_matrice& pm, const mat4& m);
    pile_matrice operator-(const mat4& m, const pile_matrice& pm);
    // vs. scalaires
    pile_matrice operator*(const pile_matrice& pm, float f);
    pile_matrice operator*(float f, const pile_matrice& pm);
    pile_matrice operator/(const pile_matrice& pm, float f);
    Ne pas oublier +=, -=, *= et /* (avec un float).

    Il va rester un problème léger : toutes les fonctions qui prennent en paramètre un mat4 pour le modifier ou créer un nouvel objet mat4 devront peut-être êtres surchargées pour travailler sur des pile_matrice.

    Au delà de ça, je me demande quand même si c'est une idée judicieuse au niveau du design. Une pile_matrice n'est pas une matrice, et son but n'est pas le même.
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  8. #8
    Membre éprouvé Avatar de Robxley
    Homme Profil pro
    Docteur ingénieur traitement d'image
    Inscrit en
    Mai 2009
    Messages
    158
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Docteur ingénieur traitement d'image

    Informations forums :
    Inscription : Mai 2009
    Messages : 158
    Par défaut
    Merci pour vos réponses :

    @Kaamui :
    c'est bien un vector<glm::mat4> et non un vector<mat4>, un simple oublie durant l'écriture du post (y a pas de debugger sur le post ).
    tu l'utilises quand ton opérateur de cast ? parce que le compilo te précise qu'il ne peut pas faire ce genre de truc avec une opérande à droite de type "pile_mat4" mais il ne parle pas de "pile_mat4&" c'est donc que la conversion implicite n'est pas passée.
    C'était plus ou moins ma question, si mon cast était correct pour ce que je souhaite faire ^^

    @gbdivers
    Ensuite, d'un point de vue sémantique, une pile n'est pas une matrice et ne devrait pas pourvoir être convertir implicitement en matrice.
    Je comprends bien et c'est pour cela qu'au départ j'avais une méthode :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    glm::mat4& pile_mat4::getActive()
    {
        return pile.back();
    }
    Et alors je faisais mes opérations de la façon suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    pile_mat4 modelView, projection;
    glm::mat4 m, rotation;
    m =projection.getActive()*modelView.getActive()*rotation
    mais c'est relativement long comme écriture et beaucoup moins lisible que :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    m =projection*modelView*rotation
    Et je préfère utiliser une structure vector que stack car avec vector via la méthode reserve tu peux allouer une partie de la mémoire avant même l'utilisation de l'objet vector, ce qui évite lors de multi push_back, pop_back de allouer/libérer indéfiniment de l'espace mémoire. Mais possible que je me trompe sur le réel intérêt.

    @Emmanuel Deloget
    Au delà de ça, je me demande quand même si c'est une idée judicieuse au niveau du design. Une pile_matrice n'est pas une matrice, et son but n'est pas le même.
    Même réponse qu'a gbdivers, c'est plus pour une question de visibilité de lecture mathématique que de niveau du design.


    Je ne suis toujours pas décidé vers quoi je vais me tourner si je garde la syntaxe lourde avec la méthode getActive...ou la surcharge d'opérateur mentionné par Emmanuel Deloget.

    Edit (post entre mon post) :
    @Emmanuel Deloget
    Effectivement c'est ce que je faisais auparavant avec mon getActive, je vais peut etre le raccourcir le nom pour une meilleur lisibilité. Un truc du genre pile_mat4::top

  9. #9
    Membre très actif

    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2011
    Messages : 685
    Par défaut
    si c'est juste que tu trouves ça trop long alors encapsule tes opérations comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    //m =projection*modelView*rotation à remplacer par...
     
    m = x(&projetction,&modelView,&rotation); //là tu garde une taille raisonnable
     
    //...avec : 
     
    glm::mat4 x(const pile_mat4& p, const pile_mat4& m, const glm::mat4& r) const
    {
        return (p.GetActive() * m.GetActive() * r);
    }
    mais c'est sur que c'est moins joli que ton instruction de départ

  10. #10
    Membre éprouvé Avatar de Robxley
    Homme Profil pro
    Docteur ingénieur traitement d'image
    Inscrit en
    Mai 2009
    Messages
    158
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Docteur ingénieur traitement d'image

    Informations forums :
    Inscription : Mai 2009
    Messages : 158
    Par défaut
    La méthode que tu proposes Kaamui est très peu flexible.

    Ca va dans le cas des exemples exposées pour mes questions, cependant les opérations matricielles de mon programme ne se limitent pas forcement à l'utilisation des matrices projection, modelview et une matrice de transformation mais plusieurs autres matrices, ainsi que l’utilisation de vecteurs. En effet avec la surcharge d'opérateur de glm tu peux effectuer des opérations du type :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    vec4 v,w,r;
    mat4 T1,T2; //matrices de transformation;
    r = projection.top()* modelview.top*T1*v - projection.top()* modelview.top*T2*w;


    Non mais, si non c'est pas très grave je vais m'en tenir à l'utilisation d'une méthode interne qui renvoie l'éléments du dessus de ma pile et puis c'est tout. Ma question était plus par curiosité pour voir s'il n'existait pas un opérateur de cast ou autre pour simplifier l'écriture. Ca aurait été idiot de pas en profiter par peur de poser la question.
    Je vais laisser comme c'est et utiliser une fonction top()

  11. #11
    Membre très actif

    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2011
    Messages : 685
    Par défaut
    En effet cela ne s'applique que dans ce cas précis.

    Dans cas la meilleure solution reste alors la proposition de Emmanuel Deloget.


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

Discussions similaires

  1. operateur de cast et tableau
    Par Awakening dans le forum Langage
    Réponses: 12
    Dernier message: 27/02/2014, 16h31
  2. Réponses: 2
    Dernier message: 16/07/2007, 15h34
  3. CAST DATETIME ----> SMALLDATETIME
    Par Guizz dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 26/06/2003, 12h07
  4. [langage] l'operateur tr///
    Par March' dans le forum Langage
    Réponses: 4
    Dernier message: 03/03/2003, 21h57
  5. traduction en delphi "reinterpreted cast"
    Par Chupakabra dans le forum Langage
    Réponses: 3
    Dernier message: 13/02/2003, 15h49

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