Bienvenue, Invité. Merci de vous connecter ou de vous inscrire.
Avez-vous perdu votre e-mail d'activation ?

Auteur Sujet: Une méthode get/setRect() pour tous les Drawable  (Lu 10775 fois)

0 Membres et 1 Invité sur ce sujet

L01man

  • Jr. Member
  • **
  • Messages: 69
    • Voir le profil
Une méthode get/setRect() pour tous les Drawable
« le: Mai 01, 2012, 01:55:59 pm »
C'est une chose bien pratique dans la SDL. On peut déjà utiliser getPosition() sur tous les Drawable, mais GetSize() ne fonctionne que sur Sprite, Texture et RectangleShape. Ce serait d'en faire une méthode virtuelle pure de Drawable et de pouvoir l'utiliser sur Text, Shape. L'avantage est que dans les trois que j'ai cités au début, la méthode renvoie simplement un attribut, mais que pour les autres le calcul pourrait être fait à la volée, à moins que Drawable ait un attribut Rect et plus de Position. Dans ce cas, on pourra même changer Left et Top par X et Y, étant donné que les Rect seront présents partout. Je viens juste de voir Text.getLocal/GlobalBounds, qui pourrait aussi être remplacé par un getLocat/Global/Rect. D'autre part, certaines fois je vois bounds et d'autre fois rect, quelle est la différence ?
Dans ce sujet du forum Anglais, ça serait utile avec ce que propose Tex Killer.
En ce qui me concerne, ça me permettrait par exemple de centrer un exemple sans utiliser des calculs sur getGlyph() approximatifs et d'implémenter une optimisation du Draw des éléments dans une View : seuls les éléments dont les Rect entrent en collision avec celui de la View seront affichés, alors qu'en ce moment je ne sais pas comment faire avec ma collection hétérogène :(. Sprite a une méthode setTextureRect(), mais tous les Drawable pourraient avoir ce setRect qui définirait la surface affichée !
Enfin, ça pourrait simplifier les calculs de collision et rendre sf::Rect::Intersects plus célèbre, du moins dans mon code ::).

Je me demande aussi si un tel attribut rect devrait appartenir à sf::Transformable ou sf::Drawable. Pour l'instant, le Vector2 de position est dans Transformable, donc il est logique qu'on y mette aussi le Size, et donc le Rect entier. Ca permettrait de séparer encore plus le visuel de la "logique".
« Modifié: Mai 01, 2012, 03:16:42 pm par Lolman »
http://metroidprime4.xooit.fr/

Un même visage, un même passé, deux destins différents ?
Metroid Prime : Némésis, fangame de la suite du célèbre Metroid Prime 3 : Corruption.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : Une méthode get/setRect() pour tous les Drawable
« Réponse #1 le: Mai 01, 2012, 06:59:05 pm »
getLocal/GlobalBounds est exactement ce que tu suggères. J'utilise "bounds" et non "rect" car ils renvoient le rectangle englobant -- c'est donc une approximation. De plus je trouve "bounds" plus expressif que "rect" : "bounds" véhicule bien l'idée de limite, alors que "rect" est plus vague, un rectangle peut représenter n'importe quoi (exemple : le texture rect).

Donc si j'ai bien suivi, tout ce qu'il manque c'est de rendre ces deux fonctions virtuelles dans sf::Transformable ou sf::Drawable, c'est ça ? C'est un peu compliqué à vrai dire :
- sf::Drawable n'a aucune notion de géometrie ni de transformation, donc elle n'a a priori aucun rapport avec le rectangle englobant
- sf::Transformable n'est pas qu'une classe de base, elle peut aussi être utilisée comme attribut (un genre de sf::Transform plus simple à manipuler), donc y coller une fonction virtuelle pure ne fonctionnerait pas

Au pire tu peux recréer toi-même l'abstraction qui va bien, via du type erasure. Ca a déjà été discuté il n'y a pas si longtemps que ça sur le forum français.
Laurent Gomila - SFML developer

L01man

  • Jr. Member
  • **
  • Messages: 69
    • Voir le profil
Re : Une méthode get/setRect() pour tous les Drawable
« Réponse #2 le: Mai 01, 2012, 07:23:46 pm »
Citer
sf::Drawable n'a aucune notion de géometrie ni de transformation, donc elle n'a a priori aucun rapport avec le rectangle englobant
Oui, ces méthodes : getLocal/GlobalRect/Bounds, setRect/Bounds auraient plus leur place dans Transformable, puisque cette classe possède déjà l'attribut de position, soit le premier point de ce Rect.
En fait, ces méthodes ne seraient pas virtuelles pures : elles retourneraient simplement l'attribut Transformable.bounds de type Rect. Elles ne seraient même pas virtuelles du tout : c'est à chaque classe de faire un setBounds : quand on fait un setTexture(Texture, true) dans Sprite, quand on ajoute un point dans ConvexShape. Dans certains cas, comme getSize(), qui serait directement implémenté dans Transformable, car il correspond au deuxième point de l'attribut Transformable.bounds, les classes enfant n'auraient même rien à faire. Donc on pourrait instancier Transformable.
En bref, je propose d'implémenter la Surface présente dans SDL. Elle est déjà à moitié présente : setTextureRect() par exemple réduit la surface d'affichage, ou create() pour Image/Texture/Sprite, et ce utile qu'elle le soit partout : ça permettrait de réduire la taille d'affichage d'un Text, ou d'appliquer des méthodes d'alignement en fonction de son attribut bounds comme je l'ai vu proposé sur le forum anglais. Ca permet aussi de conditionner l'affichage de Drawable autres que Sprite en vérifiant si leur bounds intersects() avec le bounds de la View.

EDIT : Je viens de voir que les méthodes getLocal/GlobalBounds sont implémentées partout, désolé, je ne l'avais pas bien compris. Est-ce qu'il serait possible de la déclarer dans Transformable pour les collections hétérogènes.

Je vais voir ce qu'offre le type erasure, mais peut-être que cette suggestion est assez bonne pour être implémentée.
« Modifié: Mai 01, 2012, 07:28:22 pm par Lolman »
http://metroidprime4.xooit.fr/

Un même visage, un même passé, deux destins différents ?
Metroid Prime : Némésis, fangame de la suite du célèbre Metroid Prime 3 : Corruption.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : Une méthode get/setRect() pour tous les Drawable
« Réponse #3 le: Mai 01, 2012, 07:40:18 pm »
Citer
En fait, ces méthodes ne seraient pas virtuelles pures : elles retourneraient simplement l'attribut Transformable.bounds de type Rect. Elles ne seraient même pas virtuelles du tout : c'est à chaque classe de faire un setBounds
Ok, mais ça ne change pas grand chose : un sf::Transformable instancié directement n'aurait aucune taille, l'information et donc la fonction seraient inutiles, voire hors de propos dans ce cas.

Citer
En bref, je propose d'implémenter la Surface présente dans SDL.
Mauvaise approche. SFML aborde les choses autrement, mais ça n'empêche que quelque soit ton cas d'utilisation, tu peux toujours reproduire un équivalent avec SFML.

Citer
ça permettrait de réduire la taille d'affichage d'un Text
Ca c'est beaucoup plus complexe, ce sera implémenté comme une nouvelle fonctionnalité à part : les masques de rendu (il y a une tâche dans le tracker pour ça).
Laurent Gomila - SFML developer

L01man

  • Jr. Member
  • **
  • Messages: 69
    • Voir le profil
Re : Une méthode get/setRect() pour tous les Drawable
« Réponse #4 le: Mai 01, 2012, 08:29:31 pm »
Citer
un sf::Transformable instancié directement n'aurait aucune taille, l'information et donc la fonction seraient inutiles, voire hors de propos dans ce cas.
Un sf::Transformable instancié directement n'a aussi aucune position, aucune rotation, etc. En fait, un sf::Transformable vide, quels que soient ses attributs, n'a aucun sens : il faut le remplir d'information. Qu'est-ce qui est gênant ? De la même manière qu'on indique l'échelle, on indique la place prise par l'objet. C'est une information utile, et tous les dignes héritiers de Transformable peuvent la remplir. Une réduction de la surface, de bounds, est aussi une transformation.
Citer
Mauvaise approche. SFML aborde les choses autrement, mais ça n'empêche que quelque soit ton cas d'utilisation, tu peux toujours reproduire un équivalent avec SFML.
Oui, je propose juste en complément. La fonction existe sous le même nom dans  toutes les classes filles, mais pas dans la classe mère ! Ca me paraît une excellente occasion de "remonter", et sinon ça pourrait indiquer une autre faiblesse.
Les Rendering Masks ne pourraient-ils justement pas être ce paramètre de transformation, sous un nom différent ?
http://metroidprime4.xooit.fr/

Un même visage, un même passé, deux destins différents ?
Metroid Prime : Némésis, fangame de la suite du célèbre Metroid Prime 3 : Corruption.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : Une méthode get/setRect() pour tous les Drawable
« Réponse #5 le: Mai 01, 2012, 09:41:18 pm »
Citer
Un sf::Transformable instancié directement n'a aussi aucune position, aucune rotation, etc. En fait, un sf::Transformable vide, quels que soient ses attributs, n'a aucun sens : il faut le remplir d'information.
C'est faux : c'est une transformation, qui peut ensuite être appliquée à n'importe quelle entité. Et ses attributs sont très précisément une position, une rotation, etc.
Mais en tant que transformation, càd fonction mathématique, il n'y a pas de taille.
Laurent Gomila - SFML developer

L01man

  • Jr. Member
  • **
  • Messages: 69
    • Voir le profil
Re : Une méthode get/setRect() pour tous les Drawable
« Réponse #6 le: Mai 01, 2012, 09:44:53 pm »
Quand je voulais dire qu'il n'avait pas de rotation, etc. je voulais dire que leur valeur était à 0, ce qui est aussi le cas pour la taille. Est-ce que les agrandissements et les réductions sont des transformations ?
http://metroidprime4.xooit.fr/

Un même visage, un même passé, deux destins différents ?
Metroid Prime : Némésis, fangame de la suite du célèbre Metroid Prime 3 : Corruption.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : Une méthode get/setRect() pour tous les Drawable
« Réponse #7 le: Mai 01, 2012, 10:38:20 pm »
Citer
Quand je voulais dire qu'il n'avait pas de rotation, etc. je voulais dire que leur valeur était à 0
Je ne comprends pas. La valeur de rotation est celle que tu passes à setRotation. Pareil pour le reste. Pourquoi 0 ?

Citer
Est-ce que les agrandissements et les réductions sont des transformations ?
Oui, via le facteur de mise à l'échelle (setScale).
Laurent Gomila - SFML developer

L01man

  • Jr. Member
  • **
  • Messages: 69
    • Voir le profil
Re : Une méthode get/setRect() pour tous les Drawable
« Réponse #8 le: Mai 01, 2012, 11:09:45 pm »
Quand on crée un Transform avec le constructeur par défaut, je suppose que tous les attribtus sont à 0, aussi bien rotation que le serait bounds.
Dans l'implémentation actuelle de Transform, il y a des attributs comme la position. Très bien. Pourquoi ne peut-il pas y avoir la taille, Size ? Ce sont tous les deux des points. Et a ce moment-là, Position et Size formeraient un Rect. scale peut très bien s'appliquer sur un Rect, rotate aussi, etc., comme on le voit avec getGlobalBounds().
http://metroidprime4.xooit.fr/

Un même visage, un même passé, deux destins différents ?
Metroid Prime : Némésis, fangame de la suite du célèbre Metroid Prime 3 : Corruption.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : Une méthode get/setRect() pour tous les Drawable
« Réponse #9 le: Mai 01, 2012, 11:11:27 pm »
Mais la taille n'est pas une propriété que tu peux changer comme la rotation, c'est une donnée que tu demandes à l'entité, et qui dépend de son contenu. La taille d'un sprite correspond à son TextureRect, celle d'un texte à la séquence de ses glyphes, etc.

Quel sens aurait une fonction setSize, par rapport à tout ça ?
Laurent Gomila - SFML developer

L01man

  • Jr. Member
  • **
  • Messages: 69
    • Voir le profil
Re : Une méthode get/setRect() pour tous les Drawable
« Réponse #10 le: Mai 01, 2012, 11:52:25 pm »
setSize est à size ce que setPosition est à position, et de même avec setRotation et rotation, et tous les autres. En fait, en prenant cette règle, qui est la seule "règle des mutateurs", on pourrait en venir à mettre setColor et color. C'est pourquoi la deuxième règle est que l'élément doit correspondre à une donnée euh... mathématique disons. Il se trouve que position et origin sont des points. Et size est aussi un point.
Vu de cette façon, size semble avoir sa place. J'ai envie de dire... que changer la taille est une transformation de la zone prise par l'élément. Qu'en dis-tu ?
http://metroidprime4.xooit.fr/

Un même visage, un même passé, deux destins différents ?
Metroid Prime : Némésis, fangame de la suite du célèbre Metroid Prime 3 : Corruption.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : Une méthode get/setRect() pour tous les Drawable
« Réponse #11 le: Mai 02, 2012, 08:21:49 am »
Dans ce cas c'est scale dont tu parles.

Et les "setters" pour la taille sont déjà là, ils sont juste un peu cachés : setTextureRect, setCharacterSize/setString, etc.
Laurent Gomila - SFML developer

L01man

  • Jr. Member
  • **
  • Messages: 69
    • Voir le profil
Re : Une méthode get/setRect() pour tous les Drawable
« Réponse #12 le: Mai 02, 2012, 10:38:31 am »
Citer
Dans ce cas c'est scale dont tu parles.
Oui, c'est un scale, mais qui prend des coordonnées absolues. D'ailleurs, s'il y a un attribut scale, il faut aussi un attribut size, parce-que sinon ce scale n'opère sur rien dans l'objet Transformable ;).
Citer
Et les "setters" pour la taille sont déjà là, ils sont juste un peu cachés : setTextureRect, setCharacterSize/setString, etc.
Justement, pourquoi les "cacher" ? Ces méthodes sont en quelques sortes dupliquées inutilement dans les enfants.
Transformable {
  //rien
}
Sprite {
  setTextureRect
}
Text {
  //la fonction manque à cette classe
}
RectangleShape {
  setSize //un nom différent
}
http://metroidprime4.xooit.fr/

Un même visage, un même passé, deux destins différents ?
Metroid Prime : Némésis, fangame de la suite du célèbre Metroid Prime 3 : Corruption.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : Une méthode get/setRect() pour tous les Drawable
« Réponse #13 le: Mai 02, 2012, 11:22:50 am »
On tourne en rond là. Pour moi c'est très clair, il y a d'un côté la géometrie définie dans son espace local, et de l'autre une transformation qu'on lui applique pour la faire passer dans l'espace global. Pour toi j'ai l'impression que ce n'est pas aussi clair et que tu mélanges (à tord) des attributs de ces deux choses qui sont pourtant bien distinctes.

Et pour setSize tu n'as pas non plus compris, j'ai l'impression, comment ça fonctionnait. On construit une entité avec certaines propriétés qui lui sont propres, et au final cette entité prend une certaine taille une fois qu'elle est construite. Je pense que tu n'as pas assez de recul sur tout ça pour comprendre mes arguments.
Laurent Gomila - SFML developer

L01man

  • Jr. Member
  • **
  • Messages: 69
    • Voir le profil
Re : Une méthode get/setRect() pour tous les Drawable
« Réponse #14 le: Mai 03, 2012, 03:06:19 pm »
Oui, c'est vrai que ça n'a pas trop de sens. C'est peut-être mieux de répéter certaines méthodes.
http://metroidprime4.xooit.fr/

Un même visage, un même passé, deux destins différents ?
Metroid Prime : Némésis, fangame de la suite du célèbre Metroid Prime 3 : Corruption.