Browse Source

Limit mouse sampling to reduce jitter at extreme framerates

Marko Pintera 11 years ago
parent
commit
25e7c861ca

+ 13 - 0
BansheeOISInput/Include/BsInputHandlerOIS.h

@@ -150,6 +150,19 @@ namespace BansheeEngine
 		 */
 		static const float MOUSE_MAX_TIME;
 
+		/**
+		 * @brief	Minimum number of milliseconds that need to pass before mouse axes are updated again.
+		 *			
+		 * @note	At extremely high frame rates sampling the mouse too often will introduce jitter. This is because
+		 *			mouse will be sampled by the application faster than the hardware reports the samples. This means some
+		 *			of the samples will be reported as 0, while in truth mouse could be moving but it just hasn't been sampled.
+		 *			So we cannot tell if mouse is actually still, or moving but sample hasn't been updated, and must assume mouse
+		 *			is still, which causes jitter as one frame reports mouse as moving and another as still.
+		 *
+		 *			We could get around this if we knew the exact hardware sampling rate, but we don't.
+		 */
+		static const float MOUSE_MAX_SAMPLING_RATE;
+
 		OIS::InputManager* mInputManager;
 		OIS::Mouse*	mMouse;
 		OIS::Keyboard* mKeyboard;

+ 4 - 6
BansheeOISInput/Source/BsInputHandlerOIS.cpp

@@ -11,6 +11,7 @@ namespace BansheeEngine
 	const UINT32 InputHandlerOIS::MOUSE_DPI = 800;
 	const float InputHandlerOIS::MOUSE_MAX = 0.05f;
 	const float InputHandlerOIS::MOUSE_MAX_TIME = 0.020f; // 20 ms
+	const float InputHandlerOIS::MOUSE_MAX_SAMPLING_RATE = 0.006f; // 6ms
 
 	GamepadEventListener::GamepadEventListener(InputHandlerOIS* parentHandler, UINT32 joystickIdx)
 		:mParentHandler(parentHandler), mGamepadIdx(joystickIdx)
@@ -193,11 +194,10 @@ namespace BansheeEngine
 			gamepadData.gamepad->capture();
 		}
 
-		// We limit mouse sampling to at least 6ms interval because lower values might cause
-		// incorrect 0-sized samples to be introduced as DirectInput is not able to sample
-		// the mouse quick enough, which might cause jitter in the movement.
+		// Limit mouse sampling to a certain rate to avoid jitter at extremely high frame rates.
+		// (As the application might request samples faster than they are produced)
 		mMouseSampleCounter += gTime().getFrameDelta();
-		if (mMouseSampleCounter < 0.006f)
+		if (mMouseSampleCounter < MOUSE_MAX_SAMPLING_RATE)
 			return;
 
 		float rawXValue = 0.0f;
@@ -228,8 +228,6 @@ namespace BansheeEngine
 		xState.rel = -Math::clamp(rawXValue / axisScale, -1.0f, 1.0f);
 		xState.abs = xState.rel; // Abs value irrelevant for mouse
 
-		LOGWRN(toString(xState.rel));
-
 		onAxisMoved(0, xState, (UINT32)InputAxis::MouseX);
 
 		RawAxisState yState;