mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 09:52:27 -04:00
display: improve mouselook smoothness significantly, esp if low FPS
This problem occurs when movePointer is used to reset the mouse back to the center every frame, a very common way to implement mouselook on Windows (which has no relative mouse mode). Any movement between the last event loop run and the call to movePointer is destroyed, resulting in quite choppy mouselook in most implementations. The solution is for getPointer to always return the latest mouse cursor position. This goes a long way but is not 100% perfect; see the discussion in #359 for other solutions. Fixes #359
This commit is contained in:
parent
927fcda817
commit
29a08932ea
@ -93,7 +93,7 @@ PUBLISHED:
|
||||
void enable_pointer_mode(int device, double speed);
|
||||
void disable_pointer_mode(int device);
|
||||
|
||||
MouseData get_pointer(int device) const;
|
||||
virtual MouseData get_pointer(int device) const;
|
||||
virtual bool move_pointer(int device, int x, int y);
|
||||
virtual void close_ime();
|
||||
|
||||
|
@ -120,6 +120,34 @@ WinGraphicsWindow::
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the MouseData associated with the nth input device's pointer.
|
||||
*/
|
||||
MouseData WinGraphicsWindow::
|
||||
get_pointer(int device) const {
|
||||
MouseData result;
|
||||
{
|
||||
LightMutexHolder holder(_input_lock);
|
||||
nassertr(device >= 0 && device < (int)_input_devices.size(), MouseData());
|
||||
|
||||
result = _input_devices[device].get_pointer();
|
||||
|
||||
// We recheck this immediately to get the most up-to-date value.
|
||||
POINT cpos;
|
||||
if (device == 0 && GetCursorPos(&cpos) && ScreenToClient(_hWnd, &cpos)) {
|
||||
double time = ClockObject::get_global_clock()->get_real_time();
|
||||
RECT view_rect;
|
||||
if (GetClientRect(_hWnd, &view_rect)) {
|
||||
result._in_window = PtInRect(&view_rect, cpos);
|
||||
result._xpos = cpos.x;
|
||||
result._ypos = cpos.y;
|
||||
((GraphicsWindowInputDevice &)_input_devices[0]).set_pointer(result._in_window, result._xpos, result._ypos, time);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Forces the pointer to the indicated position within the window, if
|
||||
* possible.
|
||||
|
@ -72,6 +72,7 @@ public:
|
||||
GraphicsOutput *host);
|
||||
virtual ~WinGraphicsWindow();
|
||||
|
||||
virtual MouseData get_pointer(int device) const;
|
||||
virtual bool move_pointer(int device, int x, int y);
|
||||
|
||||
virtual void close_ime();
|
||||
|
@ -143,6 +143,36 @@ x11GraphicsWindow::
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the MouseData associated with the nth input device's pointer. This
|
||||
* is deprecated; use get_pointer_device().get_pointer() instead, or for raw
|
||||
* mice, use the InputDeviceManager interface.
|
||||
*/
|
||||
MouseData x11GraphicsWindow::
|
||||
get_pointer(int device) const {
|
||||
MouseData result;
|
||||
{
|
||||
LightMutexHolder holder(_input_lock);
|
||||
nassertr(device >= 0 && device < (int)_input_devices.size(), MouseData());
|
||||
|
||||
result = _input_devices[device].get_pointer();
|
||||
|
||||
// We recheck this immediately to get the most up-to-date value.
|
||||
if (device == 0 && !_dga_mouse_enabled && result._in_window) {
|
||||
XEvent event;
|
||||
if (XQueryPointer(_display, _xwindow, &event.xbutton.root,
|
||||
&event.xbutton.window, &event.xbutton.x_root, &event.xbutton.y_root,
|
||||
&event.xbutton.x, &event.xbutton.y, &event.xbutton.state)) {
|
||||
double time = ClockObject::get_global_clock()->get_real_time();
|
||||
result._xpos = event.xbutton.x;
|
||||
result._ypos = event.xbutton.y;
|
||||
((GraphicsWindowInputDevice &)_input_devices[0]).set_pointer(result._in_window, result._xpos, result._ypos, time);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Forces the pointer to the indicated position within the window, if
|
||||
* possible.
|
||||
|
@ -34,6 +34,7 @@ public:
|
||||
GraphicsOutput *host);
|
||||
virtual ~x11GraphicsWindow();
|
||||
|
||||
virtual MouseData get_pointer(int device) const;
|
||||
virtual bool move_pointer(int device, int x, int y);
|
||||
virtual bool begin_frame(FrameMode mode, Thread *current_thread);
|
||||
virtual void end_frame(FrameMode mode, Thread *current_thread);
|
||||
|
Loading…
x
Reference in New Issue
Block a user