-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[rcore] Initial position reported by GetMouseDelta()
incorrect
#4654
Comments
did you close the issue already, lol? |
@asdqwe have you tested the fix? I've tried, and it didn't resolve anything. Also, the issue seems to be unrelated to DisableCursor method: mouse delta should be appropriate when cursor is enabled as well! |
Yeah well I did exactly that, and there seems to be no difference on MacOS :(. Also as mentioned above, it seems that the fix should be unrelated to DisableCursor method. |
@asdqwe I've checked GLFW, it is a well known behaviour, see this example: https://learnopengl.com/Getting-started/Camera The solution is to ignore first mouse update: void mouse_callback(GLFWwindow* window, double xpos, double ypos)
{
if (firstMouse)
{
lastX = xpos;
lastY = ypos;
firstMouse = false;
}
...
} However, in rcore_desktop_glfw.c, there is no such logic in MouseCursorPosCallback, hence the result. I'm not sure where to put this temporary firstMouse variable, should be reviewed by somebody familiar with the library architecture. |
I don’t understand why do you claim that. When you have a cursor and the window appears, mouse delta should be continuous as well. |
I can confirm I see the same issue on Linux using the GLFW backend.
This appears to be correct. I have implemented this solution in my PR (#4663) and can confirm it fixes the camera jump on my machine. |
I can confirm that this PR fixes the issue for me as well as with enabled and disabled cursor! |
@asdqwe thanks for all the time put on reviewing this issue, definitely the target platform does not deserve it. @alexnivanov @ve-nt Am I understanding correctly that the solution to the issue is a macOS-platforn-specific-hack for first mouse input read, requiring a global variable to manage it? No way. |
I don't believe the issue is limited to macOS, as I'm seeing the same issue on Linux. I think the issue is in the GLFW backend in general. I have experienced this same issue when working with GLFW+OpenGL directly, in fact this issue is brought up and fixed as part of the LearnOpenGL book, using the same solution I've implemented in my PR. See Mouse Input section at: https://learnopengl.com/Getting-started/Camera Depends on your definition of "global variable" I guess. In my PR its a static local variable inside the callback. |
Afaik, the lifetime is since first run to the end of the program, so effectively it's a global variable that will require some bytes forever (while the program running). Still, I think this issue should be addressed at GLFW side, not hacked at raylib side. Thanks for reporting it's not macOS specific, I'm changing the title. |
GetMouseDelta()
incorrect
As per the details of the issue and the further clarification, it seems this issue is related to GLFW, so I'm afraid it should be addressed by GLFW, not hacked at raylib side. |
I'm not sure that the problem is in the GLFW side. As far as I can tell, its because the |
@ve-nt I see, can it be managed at user side in that case? Actually |
I have been trying to fix this on the user side but not had much luck so far. I'm open to any ideas and will keep you posted if I find a fix on the user side. |
I'm reopening for a closer look, in case of a better solution than proposed hack... |
@raysan5 I see the root cause in |
@asdqwe this is better, but if you call either |
I'm afraid I've tested it with It only jolts when the cursor is positioned inside the window from the start. There's no jolt if the cursor was outside the window when the window opened. Is this the same for you @alexnivanov? |
@ve-nt it does jolt for me not depending on initial cursor position being inside/outside of the window. Only removing |
So after a bit more digging, this bug is weirder than I thought at first. It appears that When my cursor is outside of the created window, it seems to work fine. But when the cursor is over the created window, GLFW does not actually move the cursor. This means that when This is what is leading to the spike in the mouse delta, and hence why I don't get a camera jolt unless my cursor is over the window when its opened. Its worth me reiterating that GLFW seems to be setting the cursor position fine if my cursor is not over the window. The coordinates reported from the first callback match up with where Perhaps this is a GLFW issue after all? |
@asdqwe thanks for the further review. Please, take it easy, no hurries at all. |
Please see my fix here: ve-nt@28975df This fixes the issue on my machine, although I don't quite understand why yet, hence why I haven't submitted it as a PR. Though it may help if others want to look. The thing I don't understand is why GLFW isn't setting its cursor position properly. I believe this is key to why our mouse deltas are wrong. Our |
This makes sense to me as |
Strange... It works on the outside left for me. Could you also print out the Also, from the GLFW header:
I get the feeling this might have something to do with it but I'm not sure yet. |
I'm seeing the same weird results with I'm tracing the reported values from Here's what I'm seeing with my cursor OUTSIDE and to the LEFT:
The inputs to Meanwhile, here's the output with my cursor INSIDE:
They match up great! Hence no jolt when my cursor is inside, but huge jolt when outside... I should mention that this is the same whether I |
Another hint from what I've just noticed: My |
Here's a standalone GLFW test:
Here's my current test (with the prints):
Conclusions so far:
Logs:Note: in all cases (GLFW_CURSOR_DISABLED, GLFW_CURSOR_NORMAL, outside, inside, bottom right, top left) the first frames use a different coord plot. On GLFW_CURSOR_NORMAL outside bottom right:
GLFW_CURSOR_NORMAL outside top left:
GLFW_CURSOR_NORMAL inside bottom right (ish) of the window area:
GLFW_CURSOR_NORMAL inside top left (ish) of the window area:
GLFW_CURSOR_DISABLED outside bottom right:
GLFW_CURSOR_DISABLED outside top left:
GLFW_CURSOR_DISABLED inside bottom right (ish) of the window area:
GLFW_CURSOR_DISABLED inside top left (ish) of the window area:
|
From what I'm seeing, it appears that https://github.com/raysan5/raylib/blob/fc29bc27fd1c6904143fc24fbcf5ca629ec491c6/src/external/glfw/src/input.c#L545C1-L553C2 only works when my cursor is outside of the window. When its inside, the cursor indeed reports that its centered, but the For context, this is me disabling all the cursor relocations that raylib is doing, and reporting the values from GLFW directly. I'll have a go with your isolated GLFW example when I've got some time later today. When INSIDE:
When OUTSIDE:
I'm also going to do a debugging session with GLFW later on to try and track down why this cursor pos isn't setting properly. Considering Raylib has the option of building its own GLFW, I think that correcting this issue on our end and pushing it upstream would be the best approach if we can manage it. Even if it takes GLFW a long time to take the patch upstream, Raylib will at least benefit from the fix in the meantime (when building GLFW itself at least). |
@asdqwe Ah sorry, didn't see you had updated your comment. Thats very interesting that the coord space is changing 5-7 frames in. I'm going to try and reproduce that on my machine and see if I get the same results, because this isn't something I've noticed so far (which doesn't mean it isnt happening). |
It appears I'm seeing the same thing you are @asdqwe Just from a quick test on the
With these two, I'm no longer getting any camera jolt at all. Whether my cursor is over the window or outside the window. Its not an exact science test as I don't have much time to check this right now, but figured I'd update with this for now. |
Oh! One thing which is making a difference is your code to initialize Raylib's stored mouse positions in I.E. your: double xpos, ypos;
glfwGetCursorPos(platform.handle, &xpos, &ypos);
CORE.Input.Mouse.previousPosition.x = (float)xpos;
CORE.Input.Mouse.previousPosition.y = (float)ypos;
CORE.Input.Mouse.currentPosition.x = (float)xpos;
CORE.Input.Mouse.currentPosition.y = (float)ypos; With this in place its working. I'll clean up my code and put together a branch of exact code thats working for me later on. Hopefully I've not missed anything important and you'll be able to reproduce. |
Okay screw it I'll just do it now. Here's my working code: ve-nt@fcf2a99 |
No sweat, take all the time you need. Thanks for looking into this. |
Status update (complementary to #4654 (comment)):
Logs:With disableCursor forced call and _glfwCenterCursorInContentArea unchanged:
With disableCursor forced call and _glfwCenterCursorInContentArea commented:
|
@asdqwe wow... really? definitely it seems an issue with GLFW or even the OS windowing system... be careful with that rabbit hole... EDIT: Afaik, @ColleagueRiley has been dealing with it for RGFW, any ideas? |
GLFW's handling of things tends to be far more complicated than RGFW's in most cases. RGFW shouldn't have this problem, so it should be easy to compare the two implementations and see what's different. I'm not really what information is relevant, so here are a few things: I also made an RGFW article on this issue, not sure if the code is outdated or not: https://github.com/ColleagueRiley/raw-mouse-input X11 and Windows both have a "raw mouse input mode" that must be enabled. When handling raw mouse input, you must handle specific events, X11: case GenericEvent: {
XGetEventData(display, &E.xcookie);
if (E.xcookie.evtype == XI_RawMotion) { X11 also requires you to handle ( GLFW should have simular boolean that can be checked) if ((win->_winArgs & RGFW_HOLD_MOUSE)) {
/* convert E.xmotion to raw input by subtracting the previous point */
win->event.point.x = win->_lastMousePoint.x - E.xmotion.x;
win->event.point.y = win->_lastMousePoint.y - E.xmotion.y;
} Windows: You only need to handle the For cocoa you only need to enable raw input, then you can get the raw mouse point from the usual mouse event. I'm not 100% sure if GLFW handles Cocoa events directly like this.
I'm not sure if any of this information is helpful, case NSEventTypeMouseMoved: {
NSPoint p;
if ((win->_flags & RGFW_HOLD_MOUSE)) {
p.x = ((CGFloat(*)(id, SEL))abi_objc_msgSend_fpret)(e, sel_registerName("deltaX"));
p.y = ((CGFloat(*)(id, SEL))abi_objc_msgSend_fpret)(e, sel_registerName("deltaY"));
} You could also achieve this with IOKit, but this way integrates better if you already use the Cocoa event system. I hope something here is helpful. |
@raysan5 @ve-nt @alexnivanov, I thought I had found a solution for it, but didn't work out. |
Issue description
I'm having an issue with camera update on MacOS: when the app starts, and I first move the mouse, GetMouseDelta() is very far away. After doing some experiments I figured out that it's assuming that the mouse is initially in the center of the screen. When I start the app having previously moved the mouse to the center of the screen, the behaviour is OK.
I've build from source core_3d_camera_free, and the issue is reproduced as described above.
Environment
MacBook M1 Pro, MacOS Sequoia 15.1.1, OpenGL Version: 4.1 Metal - 89.3.
Issue Screenshot
Just touched my mouse and got this:
Code Example
examples/core_3d_camera_free reproduces the issue.
The text was updated successfully, but these errors were encountered: