Handling Small Movements

Why might an application ignore small movements in relative mode?

Applications often need to ignore small movements in relative mode to handle various real-world issues like sensor noise, user tremors, or imprecise input devices. Here's a comprehensive approach to handling small movements:

#include <SDL.h>
#include <cmath>
#include "Window.h"

class MotionFilter {
public:
  struct FilteredMotion {
    float x;
    float y;
    bool SignificantMotion;
  };

  FilteredMotion Filter(int RawX, int RawY) {
    // Convert to floating point for
    // precise calculations
    float X{static_cast<float>(RawX)};
    float Y{static_cast<float>(RawY)};

    // Calculate magnitude of movement
    float Magnitude{std::sqrt(X * X + Y * Y)};

    // Check if movement exceeds dead zone
    bool IsSignificant{Magnitude > DeadZone};

    if (!IsSignificant) {
      return {0.0f, 0.0f, false};
    }

    // Apply scaling to significant movements
    float Scale{
      (Magnitude - DeadZone) / Magnitude};
    return {X * Scale, Y * Scale, true};
  }

  void SetDeadZone(float NewDeadZone) {
    DeadZone = NewDeadZone;
  }

private:
  float DeadZone{2.0f};
};

class Camera {
public:
  void Update(SDL_MouseMotionEvent& E) {
    auto Filtered{
      Filter.Filter(E.xrel, E.yrel)};

    if (Filtered.SignificantMotion) {
      Rotation.x += Filtered.x * Sensitivity;
      Rotation.y += Filtered.y * Sensitivity;

      std::cout << "\nRaw input: "
        << E.xrel << ", " << E.yrel
        << "\nFiltered: " << Filtered.x << ", "
        << Filtered.y
        << "\nRotation: " << Rotation.x << ", "
        << Rotation.y;
    }
  }

private:
  MotionFilter Filter;
  SDL_FPoint Rotation{0.0f, 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();
  }
}

Key reasons for filtering small movements:

  • Eliminate jitter from mouse sensor noise
  • Prevent unintended micro-movements from affecting gameplay
  • Improve precision for tasks requiring fine control
  • Compensate for user hand tremors
  • Reduce the impact of low-quality input devices

The dead zone approach shown above is just one method. Other techniques include:

  • Exponential scaling for more precise control
  • Averaging over time to detect intentional movement
  • Direction-based filtering for different sensitivity on each axis
  • Adaptive filtering based on movement speed

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?
Smoothing Mouse Movement
Can relative motion data be smoothed for a better user experience?
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?
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