Skip to content

Commit 1941ff1

Browse files
committed
Add GamepadAxis2DEvent::direction
1 parent fb4a5ac commit 1941ff1

File tree

1 file changed

+50
-1
lines changed

1 file changed

+50
-1
lines changed

lighthouse-protocol/src/input/gamepad_axis_2d_event.rs

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use serde::{Deserialize, Serialize};
22

3-
use crate::Vec2;
3+
use crate::{Direction, Vec2};
44

55
/// A 2D axis event on a gamepad.
66
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
@@ -11,3 +11,52 @@ pub struct GamepadAxis2DEvent {
1111
/// The value of the axis (each component is between -1.0 and 1.0, modeled after the Web Gamepad API).
1212
pub value: Vec2<f64>,
1313
}
14+
15+
impl GamepadAxis2DEvent {
16+
/// The approximate direction (outside of a small deadzone).
17+
pub fn direction(&self) -> Option<Direction> {
18+
let deadzone_radius: f64 = 0.1;
19+
if self.value.length() < deadzone_radius {
20+
return None;
21+
}
22+
23+
// See https://www.desmos.com/calculator/472pdoxzqa for visualization
24+
// Note that the y-axis is flipped here, per computer graphics conventions,
25+
// hence the sign flip (-y instead of y).
26+
let Vec2 { x, y } = self.value;
27+
let left_or_up = x < -y;
28+
let right_or_up = -x < -y;
29+
Some(
30+
match (left_or_up, right_or_up) {
31+
(true, true) => Direction::Up,
32+
(true, false) => Direction::Left,
33+
(false, true) => Direction::Right,
34+
(false, false) => Direction::Down,
35+
}
36+
)
37+
}
38+
}
39+
40+
#[cfg(test)]
41+
mod tests {
42+
use crate::{Direction, Vec2, Zero};
43+
44+
use super::GamepadAxis2DEvent;
45+
46+
#[test]
47+
fn directions() {
48+
assert_eq!(event(Vec2::UP).direction(), Some(Direction::Up));
49+
assert_eq!(event(Vec2::DOWN).direction(), Some(Direction::Down));
50+
assert_eq!(event(Vec2::LEFT).direction(), Some(Direction::Left));
51+
assert_eq!(event(Vec2::RIGHT).direction(), Some(Direction::Right));
52+
assert_eq!(event(Vec2::ZERO).direction(), None);
53+
assert_eq!(event(Vec2::new(-0.05, 0.05)).direction(), None); // within deadzone
54+
}
55+
56+
fn event(value: Vec2<f64>) -> GamepadAxis2DEvent {
57+
GamepadAxis2DEvent {
58+
index: 0,
59+
value,
60+
}
61+
}
62+
}

0 commit comments

Comments
 (0)