So I'm trying to work with the origin, and it makes no sense to me at all. Here's some simple code I wrote to play around with the origin:
sf::RenderWindow window(sf::VideoMode(1200, 800), "Window");
sf::RectangleShape square(sf::Vector2f(200, 200));
square.setPosition(500, 600);
auto smallSquare = square;
smallSquare.move(0, -square.getSize().y);
smallSquare.setOrigin(0, square.getSize().y);
smallSquare.scale(0.5, 0.5);
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
window.draw(square);
window.draw(smallSquare);
window.display();
}
What I expect this to do is
1) Draw a 200x200 square at the center bottom of the screen
2) Make a copy of that square called smallSquare
3) Move the smallSquare upwards by the height of the square
4) Set smallSquare's origin to it's bottom left corner, instead of top left.
5) Scale the smallSquare to 0.5 around it's new origin
So the result should be a 200x200 square at the center bottom, with a 100x100 square on top of it on it's left side. Sort of like a blocky lowercase b shape.
Instead what I get is
(https://i.imgur.com/txmbCko.jpg)
Why is this happening? What's wrong with my assumptions of how the origin works?
I see. So to solve the first problem, always do moves and setPositions before changing the origin?
I don't know what "first" and "second" problems you refer to, but as I said these functions are just setters for position/rotation/scale variables, which are then combined at draw time, always in the same order. So chaning the origin after or before won't make any difference.
Is there a way to force apply the transformations immediately?
Yes. Bypass the entity's transform with your own transform (sf::Transform). sf::Transform is lower level, it's actually a thin wrapper on top of a 4x4 matrix so you can build whatever you want with it.
sf::Transform transform;
transform.translate(x, y); // first translate
transform.rotate(a); // then rotate
// ...
window.draw(entity, transform);
Then, remember that everything based on the entity's transform (local/global bounds for example) won't be right since it will use the entity's transform and not yours.
If you're setting the origin to the bottom of the smaller rectangle and want both origins to be in the same place (i.e. the bottom of the small one touching the top of the larger one) then both rectangles should have the same position.
I see. So let's say I want the same result, but the starting square has it's origin in the center. How would I go about doing it?
Is there a way to force apply the transformations immediately?
Yes. Bypass the entity's transform with your own transform (sf::Transform). sf::Transform is lower level, it's actually a thin wrapper on top of a 4x4 matrix so you can build whatever you want with it.
sf::Transform transform;
transform.translate(x, y); // first translate
transform.rotate(a); // then rotate
// ...
window.draw(entity, transform);
Then, remember that everything based on the entity's transform (local/global bounds for example) won't be right since it will use the entity's transform and not yours.
Thanks. Unfortunately I won't be able to use that method as I need to be able to use the entity's transform.