Skip to content

Commit

Permalink
Add get_unclamped to Axis (#8871)
Browse files Browse the repository at this point in the history
# Objective

Add a get_unclamped method to
[Axis](https://docs.rs/bevy/0.10.1/bevy/input/struct.Axis.html) to allow
it to be used in cases where being able to get a precise relative
movement is important. For example, camera zoom with the mouse wheel.

This would make it possible for libraries like leafwing input manager to
leverage `Axis` for mouse motion and mouse wheel axis mapping. I tried
to use it my PR here
Leafwing-Studios/leafwing-input-manager#346 but
will likely have to revert that and read the mouse wheel events for now
which is what prompted this PR.

## Solution

Instead of clamping the axis value when it is set, it now stores the raw
value and clamps it in the `get` method. This allows a simple
get_unclamped method that just returns the raw value.


## Changelog

- Added a get_unclamped method to Axis that can return values outside of
-1.0 to 1.0
  • Loading branch information
paul-hansen authored Jun 19, 2023
1 parent 6440546 commit b4fa833
Showing 1 changed file with 22 additions and 6 deletions.
28 changes: 22 additions & 6 deletions crates/bevy_input/src/axis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ use std::hash::Hash;

/// Stores the position data of the input devices of type `T`.
///
/// The values are stored as `f32`s, which range from [`Axis::MIN`] to [`Axis::MAX`], inclusive.
/// The values are stored as `f32`s, using [`Axis::set`].
/// Use [`Axis::get`] to retrieve the value clamped between [`Axis::MIN`] and [`Axis::MAX`]
/// inclusive, or unclamped using [`Axis::get_unclamped`].
#[derive(Debug, Resource)]
pub struct Axis<T> {
/// The position data of the input devices.
Expand Down Expand Up @@ -34,20 +36,34 @@ where

/// Sets the position data of the `input_device` to `position_data`.
///
/// The `position_data` is clamped to be between [`Axis::MIN`] and [`Axis::MAX`], inclusive.
///
/// If the `input_device`:
/// - was present before, the position data is updated, and the old value is returned.
/// - wasn't present before, [None] is returned.
pub fn set(&mut self, input_device: T, position_data: f32) -> Option<f32> {
let new_position_data = position_data.clamp(Self::MIN, Self::MAX);
self.axis_data.insert(input_device, new_position_data)
self.axis_data.insert(input_device, position_data)
}

/// Returns a position data corresponding to the `input_device`.
/// Returns the position data of the provided `input_device`.
///
/// This will be clamped between [`Axis::MIN`] and [`Axis::MAX`] inclusive.
pub fn get(&self, input_device: T) -> Option<f32> {
self.axis_data
.get(&input_device)
.copied()
.map(|value| value.clamp(Self::MIN, Self::MAX))
}

/// Returns the unclamped position data of the provided `input_device`.
///
/// This value may be outside of the [`Axis::MIN`] and [`Axis::MAX`] range.
///
/// Use for things like camera zoom, where you want devices like mouse wheels to be able to
/// exceed the normal range. If being able to move faster on one input device
/// than another would give an unfair advantage, you should likely use [`Axis::get`] instead.
pub fn get_unclamped(&self, input_device: T) -> Option<f32> {
self.axis_data.get(&input_device).copied()
}

/// Removes the position data of the `input_device`, returning the position data if the input device was previously set.
pub fn remove(&mut self, input_device: T) -> Option<f32> {
self.axis_data.remove(&input_device)
Expand Down

0 comments on commit b4fa833

Please sign in to comment.