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

Author Topic: Mouse capture/grab  (Read 56956 times)

0 Members and 5 Guests are viewing this topic.

cmc5788

  • Newbie
  • *
  • Posts: 11
    • View Profile
Mouse capture/grab
« Reply #30 on: March 30, 2011, 08:32:59 pm »
One more note on this topic:

Input's GetMouseX() and GetMouseY() functiosn are not accurate/quick enough to support the "snap to center screen every frame" method of mouselook.

I was wonder why my mouselook code was degenerating at lower FPS, and replacing these with Windows-specific code completely fixed the problem.  Not sure why this is, but in case anyone else is having trouble, you should definitely use platform-specific code for something as time-sensitive as getting and setting the mouse cursor location every frame.

Tank

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1486
    • View Profile
    • Blog
    • Email
Mouse capture/grab
« Reply #31 on: March 31, 2011, 01:25:31 am »
Well SFML does also use platform-specific code. :) The question is where's the difference? Maybe SFML can be enhanced in this case.

cmc5788

  • Newbie
  • *
  • Posts: 11
    • View Profile
Mouse capture/grab
« Reply #32 on: March 31, 2011, 01:30:13 am »
Quote from: "Tank"
Well SFML does also use platform-specific code. :) The question is where's the difference? Maybe SFML can be enhanced in this case.


I'm not sure where the difference is, I haven't had a good look at SFML's code.  I can just tell you for sure that there's significant lag in reporting between Input::GetMouseX() and the Windows-specific GetCursorPos (or perhaps the difference is between the cursor-position setting functions).

edit: --------

Having now looked at the SFML code a little bit, I can surmise that the lag has to do with Input::myMouseX and myMouseY only being updated on MouseMove events.  The Windows-specific equivalent immediately queries the mouse state as tracked by the operating system, and is likely independent of the event system.

Tank

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1486
    • View Profile
    • Blog
    • Email
Mouse capture/grab
« Reply #33 on: March 31, 2011, 01:41:26 am »
SFML uses its own event queue (sf::Event::MouseMoved), and those events are generated through Windows messages (WM_MOUSEMOVE). This might produce a delay.

A solution would be sf::Input's mouse methods using GetCursorPos() on Windows, instead. This needs modifications in the sf::Window implementations for the various platforms, I guess. Laurent has surely more details on this.

cmc5788

  • Newbie
  • *
  • Posts: 11
    • View Profile
Mouse capture/grab
« Reply #34 on: March 31, 2011, 01:43:41 am »
Just missed my edit, I reached the same conclusion.  I suppose it would be good if SFML had support for immediate querying via something like

Code: [Select]

POINT cursor_pos;
HWND sys_handle = window.GetSystemHandle();
GetCursorPos(&cursor_pos);
ScreenToClient(sys_handle, &cursor_pos);


which is what I used in my code to fix the delay.

e:  when I get a little farther on my project I'll compile the workarounds I've had to use into a separate feature request thread.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Mouse capture/grab
« Reply #35 on: March 31, 2011, 07:47:56 am »
Using OS functions to get the real-time mouse/keyboard state is not a good option. While it should be ok for mouse, for keyboard it doesn't take focus in account (ie. you can read the keyboard state from any window that doesn't have the focus, even hidden/minimized ones) so it may lead to strange behaviours.

But this could also solve problems (key released while out of the window are not notified to sf::Input, for example), so if we can find a satisfying design/implementation for this thing I'm open to discussion :)
Laurent Gomila - SFML developer

cmc5788

  • Newbie
  • *
  • Posts: 11
    • View Profile
Mouse capture/grab
« Reply #36 on: March 31, 2011, 09:15:38 am »
What's wrong with just implementing it for mouse?  With keyboard response I don't see it being an issue.  Or just keep the current system in-place but also implement an alternative "GetImmediate__" series of functions to clarify the difference.

Just bear in mind that supporting mouse look is fairly important for anything that can be used as an OpenGL context.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Mouse capture/grab
« Reply #37 on: March 31, 2011, 09:28:14 am »
Quote
What's wrong with just implementing it for mouse?

Inconsistent design.
And it works only for mouse position, everything else (mouse buttons, keyboard, joysticks, ...) would produce the kind of problems that I described in my previous posts.

Quote
Or just keep the current system in-place but also implement an alternative "GetImmediate__" series of functions to clarify the difference.

There's no point providing two different ways of doing the same thing. If I change this I'd rather end up with only one clean and efficient solution.

Quote
Just bear in mind that supporting mouse look is fairly important for anything that can be used as an OpenGL context.

That's right. I need to think more about this issue; providing mouse grab features would also be a solution.
Laurent Gomila - SFML developer

cmc5788

  • Newbie
  • *
  • Posts: 11
    • View Profile
Mouse capture/grab
« Reply #38 on: March 31, 2011, 02:54:40 pm »
Quote from: "Laurent"
Quote
What's wrong with just implementing it for mouse?

Inconsistent design.
And it works only for mouse position, everything else (mouse buttons, keyboard, joysticks, ...) would produce the kind of problems that I described in my previous posts.


I understand that the design would be slightly inconsistent, but I think that having an "elegantly designed" function that returns values other than those expected is orders of magnitude worse than having a single function whose design is inconsistent from others of the type for reasons of usability.

Anecdotally, I spent a solid off-day of programming time trying to figure out why my mouse look was degrading precisely because "GetMouseX" sounds as though it should return, with as much precision as possible, the X value of the mouse.  As a client of the library, my application expects the function to work as-advertised, not to be consistent with its own internal state.  One major benefit of separating interface from implementation is that, as a user, I shouldn't CARE about inconsistent implementation so long as results are consistent with expectations.  In that way, I would make the argument that changing it is more elegant design.

As far as I can tell, -only- mouse coordinates would need to be changed in this way since they tend to be used for very time-sensitive tasks, none of the other variables that would produce problems would need to even be touched.

Quote
Quote
Just bear in mind that supporting mouse look is fairly important for anything that can be used as an OpenGL context.

That's right. I need to think more about this issue; providing mouse grab features would also be a solution.


Actually that isn't a solution, that's only part of the solution.  Mouse grab only confines the cursor to the window area; you still need a way of resetting the cursor every-so-often so that it doesn't wind up sticking to the borders.  The most-common way of doing this involves resetting it every frame to the center of the screen.  Mouse grab simply ensures that at low FPS your cursor won't "flicker" off-screen before it's reset.  You still need to ensure that it's reset to center (or some other location sufficiently far from the window borders) so that mouselook works properly.

If you were to provide mouse grab for mouse look support, you would also need to include an an abstracted way of returning an accurate mouse velocity per-frame.  If you can think of a good way to do this without resorting to cursor reset, then you're better than me.  (I also tried "wrapping" the mouse from the right border back around to the left, and top to bottom, etc., but that introduces its own set of problems)

edit:  Sorry for the mild rant, and thank you for your responses ;)

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Mouse capture/grab
« Reply #39 on: March 31, 2011, 03:23:52 pm »
Quote
I understand that the design would be slightly inconsistent, but I think that having an "elegantly designed" function that returns values other than those expected is orders of magnitude worse than having a single function whose design is inconsistent from others of the type for reasons of usability.

I was not comparing it to the current code. I just said that as a user, seeing an API with two functions that do the same thing is not consistent/elegant/whatever.

So I didn't mean to keep the current function unchanged, but rather than fixing it with something that I don't like, I prefer trying to find a solution which is globally better (even if it means redesigning half of the window module).

I think the first thing to do is to examinate this "lag" problem before throwing away the whole event-based implementation; just to be sure, you know ;)

Would be very cool if you could provide a minimal code that shows the problem (with low FPS simulated) so that I can test it myself and use it as a starting point for improving mouse handling.
Laurent Gomila - SFML developer

cmc5788

  • Newbie
  • *
  • Posts: 11
    • View Profile
Mouse capture/grab
« Reply #40 on: March 31, 2011, 03:38:29 pm »
Quote from: "Laurent"
Quote
I understand that the design would be slightly inconsistent, but I think that having an "elegantly designed" function that returns values other than those expected is orders of magnitude worse than having a single function whose design is inconsistent from others of the type for reasons of usability.

I was not comparing it to the current code. I just said that as a user, seeing an API with two functions that do the same thing is not consistent/elegant/whatever.

So I didn't mean to keep the current function unchanged, but rather than fixing it with something that I don't like, I prefer trying to find a solution which is globally better (even if it means redesigning half of the window module).

I think the first thing to do is to examinate this "lag" problem before throwing away the whole event-based implementation; just to be sure, you know ;)

Would be very cool if you could provide a minimal code that shows the problem (with low FPS simulated) so that I can test it myself and use it as a starting point for improving mouse handling.


I can do that very easily, I'll just set a #define in my current code to toggle between SFML GetMouseX/Y and the Windows code.  I'll post it soon.

Tank

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1486
    • View Profile
    • Blog
    • Email
Mouse capture/grab
« Reply #41 on: March 31, 2011, 09:23:03 pm »
Quote from: "cmc5788"
I can do that very easily, I'll just set a #define in my current code to toggle between SFML GetMouseX/Y and the Windows code

Sorry for being off-topic, but that is just hilarious. :D What it's called, "ENABLE_BUG"? ;)

cmc5788

  • Newbie
  • *
  • Posts: 11
    • View Profile
Mouse capture/grab
« Reply #42 on: March 31, 2011, 09:34:25 pm »
Quote from: "Tank"
Quote from: "cmc5788"
I can do that very easily, I'll just set a #define in my current code to toggle between SFML GetMouseX/Y and the Windows code

Sorry for being off-topic, but that is just hilarious. :D What it's called, "ENABLE_BUG"? ;)


Now that you mentioned it, I think I -will- call it that.

cmc5788

  • Newbie
  • *
  • Posts: 11
    • View Profile
Mouse capture/grab
« Reply #43 on: April 01, 2011, 07:07:47 pm »
Well, as embarrassing as this is, it looks like I jumped the gun a bit on blaming SFML.  I rewrote my code in simplified form to submit, and the bug disappeared.  I don't know what was causing it, and I'm not sure if I'll ever find out.

By way of apology, I'll submit a nice tutorial on implementing smoothed mouse look using the weighted mean of velocities to the wiki.

P.S. -- we still want cursor grabbing ;)

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Mouse capture/grab
« Reply #44 on: April 01, 2011, 07:32:15 pm »
Hehe :)

Quote
By way of apology, I'll submit a nice tutorial on implementing smoothed mouse look using the weighted mean of velocities to the wiki.

That's a very good idea, thanks.
Laurent Gomila - SFML developer