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

Author Topic: Dragging whole scene  (Read 1015 times)

0 Members and 1 Guest are viewing this topic.

Nical

  • Jr. Member
  • **
  • Posts: 58
    • View Profile
Dragging whole scene
« on: May 20, 2020, 11:58:38 am »
Hi all,

I'm trying to implement a scene drag functionality. When the middle mouse button is pressed, I want to translate all my scene positions from the exact amount of pixel the mouse traveled.

Here is a POC of what I did. I represented the scene graph by a simple rectangle.

int main(int argc, char* argv[])
{
  sf::RenderWindow window(sf::VideoMode(400, 400), "Drag world");

  sf::Vector2f sceneOrigin(100., 100.);
  sf::RectangleShape scene({50., 50.});

  bool isDragging = false;
  sf::Vector2i lastMousePosition = sf::Mouse::getPosition(window);
  sf::Transform transform;

  while (window.isOpen())
  {
    sf::Event event;

    while (window.pollEvent(event))
    {
      if (event.type == sf::Event::MouseButtonPressed)
      {
        if (event.mouseButton.button == sf::Mouse::Middle)
          isDragging = true;
      }
      else if (event.type == sf::Event::MouseButtonReleased)
      {
        if (event.mouseButton.button == sf::Mouse::Middle)
          isDragging = false;
      }
      else if (event.type == sf::Event::MouseMoved and isDragging)
      {
        auto mouseDelta =
          window.mapPixelToCoords(sf::Vector2i(event.mouseMove.x, event.mouseMove.y))
          - window.mapPixelToCoords(lastMousePosition)
        ;

        transform.translate(mouseDelta);
      }
      else if (event.type == sf::Event::Resized)
      {
        window.setView(sf::View(sf::FloatRect(0., 0., event.size.width, event.size.height)));
      }
    }

    lastMousePosition = sf::Mouse::getPosition(window);

    scene.setPosition(transform.transformPoint(sceneOrigin));

    window.clear(sf::Color::Black);
    window.draw(scene);
    window.display();
  }

  return EXIT_SUCCESS;
}
 

When I test it, the rectangle (scene) is moved, but faster than the mouse cursor. It seems that my mouse delta is too high.
I tried the same thing raw mouse position (without the call to mapPixelToCoords), but the result is the same.

I don't understand what I missed here. Any help ?
« Last Edit: May 20, 2020, 12:05:10 pm by Nical »

Athenian Hoplite

  • Newbie
  • *
  • Posts: 19
  • Nenikikamen !
    • View Profile
Re: Dragging whole scene
« Reply #1 on: May 20, 2020, 12:52:39 pm »
Never a good idea to mix real time input with event based input just as a caution you should initialize sf::Vector2i lastMousePosition with event.mouseButton.x and event.mouseButton.y when sf::Event::MouseButtonPressed as the starting position.

If I'm not mistaken for calculating a mouse delta for movement no conversion is needed just raw position in this scenario. I've never used transform.translate but I've implemented this kind of behaviour exactly as I have described by using sf::Transformable::move(offset) meaning in this case scene.move(mouseDelta). In a case where you would need this to propagate further down a hierarchy you could implement that by overloading the move method and calling it on children or simply by passing the appropriate states to child draw calls.
« Last Edit: May 20, 2020, 01:02:47 pm by Athenian Hoplite »
"By will of the Athenian People be it resolved:
If anyone rises up against the people for tyranny or join in establishing the tyranny or overthrow the People of the Athenians and the democracy in Athens, whoever kills him who does these things shall be blameless." - Athenian Law 337 BC

Nical

  • Jr. Member
  • **
  • Posts: 58
    • View Profile
Re: Dragging whole scene
« Reply #2 on: May 20, 2020, 01:18:48 pm »
This worked like a charm, thanks a lot :)

 

anything