Relative Mouse Mode

Handling Small Movements

Why might an application ignore small movements in relative mode?

Abstract art representing computer programming

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

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