Relative Mouse Mode

Smoothing Mouse Movement

Can relative motion data be smoothed for a better user experience?

Abstract art representing computer programming

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.

Answers to questions are automatically generated and may not have been reviewed.

sdl2-promo.jpg
Part of the course:

Game Dev with SDL2

Learn C++ and SDL development by creating hands on, practical projects inspired by classic retro games

Free, unlimited access

This course includes:

  • 62 Lessons
  • 100+ Code Samples
  • 91% Positive Reviews
  • Regularly Updated
  • Help and FAQ
Free, Unlimited Access

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Screenshot from Warhammer: Total War
Screenshot from Tomb Raider
Screenshot from Jedi: Fallen Order
Contact|Privacy Policy|Terms of Use
Copyright © 2024 - All Rights Reserved