Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: sf::Transformable::setAnchor() method to complement setOrigin()  (Read 6708 times)

0 Members and 1 Guest are viewing this topic.

psSch

  • Newbie
  • *
  • Posts: 3
    • View Profile
I was using the SFML just now and attempting to center a sf::Text object at the top of the screen, which was accomplished with the following:

text.setString("SFML");
text.setOrigin(text.getLocalBounds().width / 2, text.getLocalBounds().height / 2);
text.setPosition(WindowWidth / 2, WindowHeight / 10);
 

This was simple enough, but it's not very good if my text happens to change size, as the origin is no longer relevant for its intended purposes.

This left me wondering is why SFML's sf::Transformable objects do not have something along the lines of a setAnchor() method, which would be able to set a relative point instead of an absolute for object manipulations. This way, users would be able to accomplish cleaner code that works for something like this:

// Anchor the text to it's center, then center the text.
// (0, 0) would be considered top-left, and (1, 1) bottom-right.
text.setString("SFML");
text.setAnchor(0.5, 0.5);
text.setPosition(WindowWidth / 2, WindowHeight / 10);

// The text's string changed, but the text is still centered at the top of the screen.
// In the first example, this would result in the text stretching off to the right.
text.setString("Hello, World!");
 

This method of manipulation is seen in other APIs such as Apple's SpriteKit. Would any of the authors know why this design decision was made, or if we could possible see features like this in the future?

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: sf::Transformable::setAnchor() method to complement setOrigin()
« Reply #1 on: July 20, 2015, 09:20:25 pm »
I came up with this idea a while ago: http://en.sfml-dev.org/forums/index.php?topic=9100
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

psSch

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: sf::Transformable::setAnchor() method to complement setOrigin()
« Reply #2 on: July 20, 2015, 09:52:57 pm »
It's good to know that I'm not the only one who has considered this.

I noticed in your post that Laurent mentioned that this change couldn't be made to SFML. I'm assuming this meant he couldn't change the functionality of setOrigin() itself, which is very understandable.

I can see how this would be a very desirable feature, but I'm also having a difficult time coming up with an implementation that could provide this behavior and not break old code.

My first reaction would be to add setAnchor() alongside setOrigin(), and make m_Anchor a stored property. But then, methods such as setPosition() wouldn't know which member to base their manipulation off of.

My second would be to make m_Origin a computed property, but this would break old code because now everything is based on the origin, and my first snippet wouldn't behave the same if i was to change the string afterwards.

And finally, making m_Anchor a computed property puts us back at square one with nothing really different.

Hmm...

psSch

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: sf::Transformable::setAnchor() method to complement setOrigin()
« Reply #3 on: July 20, 2015, 10:02:00 pm »
Or possibly?

union m_Origin {
    Vector2f absolute;
    enum {
        TopLeft,
        TopCenter,
        TopRight,
        MidLeft,
        ...
    } relative;
};

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: sf::Transformable::setAnchor() method to complement setOrigin()
« Reply #4 on: July 20, 2015, 10:33:27 pm »
Breaking code before SFML 3 is not an option.

An anchor that would directly modify the origin is not a meaningful addition (see my link above for explanation). The only possible way I see is as follows:
class Transformable
{
public:
   void setOrigin(Vector2f origin)
   {
      m_origin = origin;
      m_useAnchor = false;
   }

   void setAnchor(Vector2f anchor)
   {
      m_origin = anchor;
      m_useAnchor = true;
   }

   // everywhere else: case differentiations

private:
   Vector2f m_origin;
   bool     m_useAnchor;
};

However, the API is going to be rather unintuitive if both origin (absolute) and anchor (relative) are coexisting attributes of sf::Transformable. It would introduce additional state and thus complexity, furthermore the case differentiations will come with decent overhead.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: sf::Transformable::setAnchor() method to complement setOrigin()
« Reply #5 on: July 20, 2015, 10:36:11 pm »
And don't forget that sf::Transformable knows nothing about the size of the derived class. So the anchor is useless at this level.
Laurent Gomila - SFML developer

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: sf::Transformable::setAnchor() method to complement setOrigin()
« Reply #6 on: July 20, 2015, 11:28:02 pm »
The anchor itself is independent from the size (that's the whole point). The anchor is a normalized scale where the interval [0, 1] is "inside the object". It would then be multiplied with the actual size when needed, in a place where the size is accessible -- but you're right that it may require a slightly different API.

The independence allows for very nice features like right-aligning sprites before their size is known, or keeping texts centered even when the string changes.
« Last Edit: July 20, 2015, 11:33:10 pm by Nexus »
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

dabbertorres

  • Hero Member
  • *****
  • Posts: 505
    • View Profile
    • website/blog
Re: sf::Transformable::setAnchor() method to complement setOrigin()
« Reply #7 on: July 21, 2015, 05:56:46 am »
Through using Unity at work, I've come to really like their anchor feature, it's quite handy.

As a comparison to an already existing feature in SFML, sf::View and its viewport is fairly similar to what an anchor would do (from my experience).

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: sf::Transformable::setAnchor() method to complement setOrigin()
« Reply #8 on: July 21, 2015, 07:31:48 am »
It would need a totally different API ;)

When you set an anchor, you need to know the size in order to interpret it.
When the size changes, you need to know the anchors to potentially update the position.

So basically you need to merge features that are currently split between the base class and the derived. And don't forget that sf::Transformable is designed to be self-contained, i.e. you can use it directly rather than as a base class; so adding virtual functions (for example) would break this design.
Laurent Gomila - SFML developer

Tank

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1486
    • View Profile
    • Blog
    • Email
Re: sf::Transformable::setAnchor() method to complement setOrigin()
« Reply #9 on: July 21, 2015, 01:02:18 pm »
@Laurent
Quote from: Nexus
The anchor itself is independent from the size (that's the whole point).

The time the size has to be known is, for example, in the render() implementation of sf::Drawables. So that's fair enough IMHO.

I like the idea.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: sf::Transformable::setAnchor() method to complement setOrigin()
« Reply #10 on: July 21, 2015, 01:10:54 pm »
When you set an anchor, you need to know the size in order to interpret it.
When the size changes, you need to know the anchors to potentially update the position.
No, this mutual dependency is exactly what I'm trying to avoid ;)

When you set an anchor, you set it and that's it.
When the size changes, anchors are left unchanged, as they're only ratios which still apply.

They need to be combined at some point, namely when you need the absolute origin in pixels. But you're probably correct that the API changes might be bigger than I thought...
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

shadowmouse

  • Sr. Member
  • ****
  • Posts: 302
    • View Profile
Re: sf::Transformable::setAnchor() method to complement setOrigin()
« Reply #11 on: July 21, 2015, 01:46:35 pm »
Might I suggest from a purely semantic point of view (ignoring whether or not the implementation is possible/good), that setAnchor() alongside setOrigin() makes it sound like setAnchor() is changing something that is not the origin. Even if in the implementation it does, the point that the object transforms around is its origin and the name setAnchor() would suggest to me that you are changing something other than the point around which the object transforms. Aside from this, it seems like a good idea. Personally, I'd suggest something like
sf::Transformable::setRelativeOrigin()
« Last Edit: July 21, 2015, 01:55:48 pm by shadowmouse »

SeriousITGuy

  • Full Member
  • ***
  • Posts: 123
  • Still learning...
    • View Profile
Re: sf::Transformable::setAnchor() method to complement setOrigin()
« Reply #12 on: July 30, 2015, 09:27:49 am »
Good to see this discussion about a feature I requested over a year ago already ;)
Maybe in some future version this is added. I would really appreciate it.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: sf::Transformable::setAnchor() method to complement setOrigin()
« Reply #13 on: July 30, 2015, 12:30:06 pm »
Maybe in some future version this is added. I would really appreciate it.
It won't be added magically as long as the above-mentioned issues aren't resolved :P
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development: