Several comments in blenderartists pointing out that using logic.mouse.position not center properly the cursor and this brings that the cursor drifts. Mouselook works well.
I have to check it yet.
I confirm. I've some problems with my mouselook scripts (in my python component templates) if I open them in certain versions of UPBGE + with certain screen resolution.
Most of the time it is due to an user error: if screen width is an odd number, there will be issues if not careful:
width = 5 # px
center = width / 2
# center = 2.5px, oops!
center = width // 2 # "truediv" operator
# center = 2px, good!
_(odd resolutions are common when running the BGE from Blender, where the viewport can be resized by hand to non-standard formats)_
On the other hand, if you set mouse.position to 0.5 (relative), it will land on a round pixel value, such as 2px, and not 2.5px. So when you do the delta to measure movement, you see a 0.5px movement, constantly.
In a nutshell, 0.5 (relative) is not always the center of the screen, because pixels cannot be split.
But it would need .blend files in order to be sure about the source of the problem.
Here the mouselook script that i use, it has drifting as well, and indeed using 0.5/0.5 as the center.
mouse drift demo.zip
Diff = (mousePos - center)
if diff.magnitude > threshold:
(tab)acceptMouseInput
On Fri, Oct 5, 2018, 7:03 AM Cotaks notifications@github.com wrote:
Here the mouselook script that i use, it has drifting as well, and indeed
using 0.5/0.5 as the center.
mouse drift demo.zip
https://github.com/UPBGE/blender/files/2450584/mouse.drift.demo.zip—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/UPBGE/blender/issues/865#issuecomment-427376780, or mute
the thread
https://github.com/notifications/unsubscribe-auth/AG25WX1RyLiCmt7KSvlPO28vqojB94r4ks5uh2augaJpZM4XHkts
.
@BluePrintRandom that is not fixing the issue.
@Cotaks I will take a look later today, but the test is simple:
mouse.position = (.5, .5)
assert(mouse.position == (.5, .5))
I expect that in some case the assertion is false, because the mouse will in fact be placed on a pixel which will be very slightly off the mathematical center.
@Cotaks thank you for the blend, here are the script and output:
screen = render.getWindowWidth(), render.getWindowHeight()
logic.mouse.position = .5, .5
print('screen format (pixels):', screen)
print('mouse position (relative):', logic.mouse.position)
print('mouse position (pixels):', tuple(map(lambda x, y: x * y, logic.mouse.position, screen)))
screen format (pixels): (1158, 398)
mouse position (relative): (0.49956783652305603, 0.498740553855896)
mouse position (pixels): (578.4995546936989, 198.4987404346466)
So turns out the resolution is not odd, and I can't find a reason for the displacement. When we get the position in pixels from where the mouse is and the size of the screen, it is outputting floating pixels...
Is it a precision issue from the datatype used in the BGE sources? @lordloki
Confirmed. The precision lost comes from function GetMouseNormalizedX()
mouse normalization use the maximum pixel not the number of pixels, so if you have 4 pixels width (maximum 3) the middle is the pixel 1.5 (3/2) and not 2 (4/2).
And as maximum pixel is number - 1, odd resolution succeed with 0.5 the test
screen = render.getWindowWidth(), render.getWindowHeight()
logic.mouse.position = .5, .5
print('screen format (pixels):', screen)
print('mouse position (relative):', logic.mouse.position)
print('mouse position (pixels):', tuple(map(lambda x, y: x * y, logic.mouse.position, screen)))
@panzergame Ok, so I accounted for what you said, that the mouse was normalized based on width - 1 and height - 1, but there's still is an issue.
This is what I had to do to fix the drifting from the blend sent by @Cotaks:
w, h = render.getWindowWidth() - 1, render.getWindowHeight() - 1
center_x = w / 2 / w
center_y = h / 2 / (h + 1)
x = center_x - logic.mouse.position[0]
y = center_y - logic.mouse.position[1]
Note the h + 1 that comes out of nowhere, but that seems needed, else we have a drift vertically. Horizontally it is fine on my side.
Turns out if I resize the viewport to weird dimensions, it breaks. So what I post doesn't even seem to work in all cases...
Ok, spamming again, but I just forgot that the mouse cannot be placed on floating pixels, so the fix right now for the code I posted earlier is the following:
w, h = render.getWindowWidth() - 1, render.getWindowHeight() - 1
center_x = w // 2 / w # truediv operation
center_y = h // 2 / h # truediv operation
x = center_x - logic.mouse.position[0]
y = center_y - logic.mouse.position[1]
Because in the case where w or h end up as odd numbers, when we try to get the center we need to ensure that the result is an integer.
After all, it seems to make sense the way it is. The tricky part is for people doing this to understand that the mouse position is normalized based on width - 1 and height - 1. But can anything be done about it in this case?
here is a patch to get logic.mouse.position with correct precision but it only can supply 2 decimals
https://gist.github.com/lordloki/1e2c1f5c07123b8e78d7c273b2608b5e


@lordloki I don't think we should round values, that's what I did before, and it turned out to not be a good idea.
The problem isn't even precision, but the values that were used.
Relative mouse position is computed with width - 1, when people used width alone.
When you account for that, no more drifting, numbers are exact without any rounding.
Blender might do the minus 1 because the mouse position on the system returns the nth pixel, starting at 0 I think. So if the screen is 4 pixels wide, starting at zero, the middle pixel index is 1, because (4 - 1) / 2 = 1.5 that we floor at 1 because indexes are integers.
Ahh ok I didn't read it :-).
Then maybe we should include a mouse look simple example with UPBGE won't take that into account
The code on this comment does take it into account, maybe just a matter of using better var names, but this has to be documented indeed :)
@marechal-p, @lordloki : Using size - 1 is the way to go as other components of the engine do the same (mouse actuator/look...).
This question is recurrent, would it worth doing a wiki on it ?
Ok, spamming again, but I just forgot that the mouse cannot be placed on floating pixels, so the fix right now for the code I posted earlier is the following:
w, h = render.getWindowWidth() - 1, render.getWindowHeight() - 1 center_x = w // 2 / w # truediv operation center_y = h // 2 / h # truediv operation x = center_x - logic.mouse.position[0] y = center_y - logic.mouse.position[1]Because in the case where
worhend up as odd numbers, when we try to get the center we need to ensure that the result is an integer.After all, it seems to make sense the way it is. The tricky part is for people doing this to understand that the mouse position is normalized based on
width - 1andheight - 1. But can anything be done about it in this case?
Works like a charm, thanks!