Smoothing Mouse Movement
Can relative motion data be smoothed for a better user experience?
Yes, relative motion data can be smoothed to provide a better user experience. This is particularly important in games where jerky camera movement can be disorienting.
Here's a comprehensive approach to implementing motion smoothing:
#include <SDL.h>
#include <deque>
#include <numeric>
#include "Window.h"
class MotionSmoother {
public:
void AddSample(int x, int y) {
// Add new sample
Samples.push_back({x, y});
// Remove old samples if we exceed our window
while (Samples.size() > WindowSize) {
Samples.pop_front();
}
}
SDL_Point GetSmoothedMotion() {
if (Samples.empty()) { return {0, 0}; }
// Calculate moving average
int SumX{0};
int SumY{0};
for (const auto& Sample : Samples) {
SumX += Sample.x;
SumY += Sample.y;
}
return {
SumX / static_cast<int>(Samples.size()),
SumY / static_cast<int>(Samples.size())};
}
private:
static constexpr size_t WindowSize{5};
std::deque<SDL_Point> Samples;
};
class Camera {
public:
void Update(SDL_MouseMotionEvent& E) {
// Add new motion sample
Smoother.AddSample(E.xrel, E.yrel);
// Get smoothed motion
SDL_Point Motion{
Smoother.GetSmoothedMotion()};
// Apply smoothed motion
xRotation += Motion.x * Sensitivity;
yRotation += Motion.y * Sensitivity;
std::cout << "Raw input: " << E.xrel << ", "
<< E.yrel << '\n'
<< "Smoothed: " << Motion.x << ", "
<< Motion.y << '\n';
}
private:
MotionSmoother Smoother;
float xRotation{0.0f};
float yRotation{0.0f};
float Sensitivity{0.1f};
};
int main() {
SDL_Init(SDL_INIT_VIDEO);
Window GameWindow;
Camera Cam;
SDL_SetRelativeMouseMode(SDL_TRUE);
SDL_Event E;
while (true) {
while (SDL_PollEvent(&E)) {
if (E.type == SDL_MOUSEMOTION) {
Cam.Update(E.motion);
} else if (E.type == SDL_QUIT) {
SDL_Quit();
return 0;
}
}
GameWindow.Update();
GameWindow.Render();
}
}
This implementation uses a moving average to smooth the motion, but there are other approaches you might consider:
- Exponential moving average for more weight on recent samples
- Kalman filtering for more sophisticated noise reduction
- Bezier curve interpolation for smooth transitions
- Low-pass filtering to remove high-frequency jitter
The key is to find the right balance between responsiveness and smoothness for your specific application.
Relative Mouse Mode
Learn how to restrict cursor movement to a window whilst capturing mouse motion continuously.