Oddities with base.win.get_pointer() and base.win.move_pointer()

First oddity is get_pointer() returns a float, even though the value is pixel position. While move_pointer() expects an integer. What’s up with this?

Second issue looks so bizzare I didn’t even know how to explain it, so I made a video showing the result of the below code snippet:


from panda3d.core import *
from direct.showbase.ShowBase import ShowBase
from direct.task import Task

base = ShowBase()

previous_x = 0
previous_y = 0

def my_task(task):
	global previous_x
	global previous_y
	x = base.win.get_pointer(0).get_x()
	y = base.win.get_pointer(0).get_y()
	base.win.move_pointer(0, int(previous_x), int(previous_y))
	previous_x = x
	previous_y = y
	return task.cont
base.taskMgr.add(my_task, "my_task")


I’d assume this code would continuously move the cursor back to its initial position, but instead we have the cursor jumping between two positions, even when mouse cursor is not moving. This seems to hint that values used by win.get_pointer() and base.win.move_pointer() aren’t quite the same.

I’ll respond in more detail later, could you just add what OS you are observing this on, and your precise Panda version, please?


Windows 10 64bit,

Panda3D 1.10.12-x64.

Because mouse positions have nothing to do with pixels on screen in relative mode. But even in absolute mode some back-end APIs may use fractional mouse positions, since after all, the mouse input data may have much higher precision than pixels on screen). DPI scaling can also result in fractional mouse positions.

But, all the platform APIs we have for setting the mouse positions on every OS take integers. Different APIs deal differently with subpixel mouse data. On Windows, subpixel data is retained, so if the mouse is at x=100.5, setting the x to 200 actually sets it to 200.5. On Linux, the subpixel data is thrown away entirely, which means precision is lost, so that’s why you need relative mouse mode to get smooth mouse look on Linux.

No, because you overwrite previous_x and previous_y in the task. So you are always switching rapidly back and forth between the previous and the current mouse position.

Regarding Windows 10, the mouse positions dumped don’t contain any subpixel data, they are always whole numbers, or floats with 0 in decimal points, at least according to the API Pandas uses dumps.

Because mouse positions have nothing to do with pixels on screen in relative mode.

What do you mean. Using relative mode and dumping the mouse positions we see values in pixels, with top-left being (0.0, 0.0) and bottom-right being (800.0,600.0) with default settings.
Should the ranges have been 0 to 1 of -1 to 1? Because they’re not right now.

As for my code, my bad.

Correct, Windows does not expose the subpixel component of the cursor position. But such a component does exist, otherwise FPS-style mouse look control would not work, since resetting the mouse cursor would otherwise erase any small movements.

In relative mode, the mouse positions reported no longer have anything to do with the position of the cursor on screen, they just represent the integration of all the mouse deltas that have occurred (without acceleration applied). So, the reported cursor position is no longer bounded to the window dimensions.

I still don’t know what you mean by “no longer bounded to the window dimensions”. It provides the position of the cursor on the WIndow in pixel values.

But where? Where can I access it?

You said you were on Windows. As pointed out in the other thread, the relative mouse mode is not implemented on Windows in Panda3D 1.10. Therefore, you are seeing the results of absolute mode. If you were to query base.win.rejected_properties, you would probably see your mouse mode request in there.

If you were to use Linux or macOS, or a development build of Panda3D 1.11, you would see the reported values of the mouse cursor increase beyond the limits of the window/screen boundaries. This is what “relative” mode means.

To my knowledge, this is not possible.