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.

Questions & Answers

Answers are generated by AI models and may not have been reviewed. Be mindful when running any code on your device.

Handling SDL Relative Mode Failure
What happens if SDL_SetRelativeMouseMode() fails?
Common Relative Mode Failures
What are common reasons for relative mode to fail on some systems?
Center Mode Impact
How does SDL_HINT_MOUSE_RELATIVE_MODE_CENTER affect gameplay?
Handling Small Movements
Why might an application ignore small movements in relative mode?
Debugging Motion Issues
How do I debug incorrect relative motion readings?
SDL2 vs SDL3 Relative Mode
How does relative mode work differently in SDL2 vs. SDL3?
Or Ask your Own Question
Purchase the course to ask your own questions