#[derive(Debug, Clone, Copy)]
pub struct AxisValue {
raw: f32,
dead_zone: f32,
}
impl AxisValue {
pub fn new(dead_zone: f32) -> Self {
Self {
raw: 0.0,
dead_zone: dead_zone.abs(),
}
}
pub fn set(&mut self, value: f32) {
self.raw = value;
}
pub fn value(&self) -> f32 {
if self.raw.abs() <= self.dead_zone {
0.0
} else {
self.raw
}
}
pub fn raw(&self) -> f32 {
self.raw
}
pub fn active(&self) -> bool {
self.raw.abs() > self.dead_zone
}
pub fn reset(&mut self) {
self.raw = 0.0;
}
}
impl Default for AxisValue {
fn default() -> Self {
Self::new(0.0)
}
}
#[derive(Debug, Clone, Copy)]
pub struct AxisPair {
pub x: AxisValue,
pub y: AxisValue,
}
impl AxisPair {
pub fn new(dead_zone: f32) -> Self {
Self {
x: AxisValue::new(dead_zone),
y: AxisValue::new(dead_zone),
}
}
pub fn set(&mut self, x: f32, y: f32) {
self.x.set(x);
self.y.set(y);
}
pub fn value(&self) -> [f32; 2] {
[self.x.value(), self.y.value()]
}
pub fn active(&self) -> bool {
self.x.active() || self.y.active()
}
pub fn magnitude_sq(&self) -> f32 {
let [x, y] = self.value();
x * x + y * y
}
pub fn normalized(&self) -> [f32; 2] {
let [x, y] = self.value();
let mag_sq = x * x + y * y;
if mag_sq < 1e-10 {
[0.0, 0.0]
} else {
let inv_mag = 1.0 / mag_sq.sqrt();
[x * inv_mag, y * inv_mag]
}
}
pub fn reset(&mut self) {
self.x.reset();
self.y.reset();
}
}
impl Default for AxisPair {
fn default() -> Self {
Self::new(0.0)
}
}
pub fn digital_axis(negative: bool, positive: bool) -> f32 {
match (negative, positive) {
(true, false) => -1.0,
(false, true) => 1.0,
_ => 0.0,
}
}
pub fn digital_axis_pair(left: bool, right: bool, down: bool, up: bool) -> [f32; 2] {
[digital_axis(left, right), digital_axis(down, up)]
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn axis_value_dead_zone() {
let mut axis = AxisValue::new(0.1);
axis.set(0.05);
assert_eq!(axis.value(), 0.0);
assert!(!axis.active());
axis.set(0.5);
assert_eq!(axis.value(), 0.5);
assert!(axis.active());
}
#[test]
fn axis_value_negative() {
let mut axis = AxisValue::new(0.1);
axis.set(-0.8);
assert_eq!(axis.value(), -0.8);
assert!(axis.active());
}
#[test]
fn axis_value_reset() {
let mut axis = AxisValue::new(0.0);
axis.set(1.0);
axis.reset();
assert_eq!(axis.value(), 0.0);
}
#[test]
fn axis_pair_basic() {
let mut pair = AxisPair::new(0.0);
pair.set(0.5, -0.3);
assert_eq!(pair.value(), [0.5, -0.3]);
assert!(pair.active());
}
#[test]
fn axis_pair_normalized() {
let mut pair = AxisPair::new(0.0);
pair.set(3.0, 4.0);
let [nx, ny] = pair.normalized();
assert!((nx - 0.6).abs() < 1e-5);
assert!((ny - 0.8).abs() < 1e-5);
}
#[test]
fn axis_pair_zero_normalized() {
let pair = AxisPair::new(0.0);
assert_eq!(pair.normalized(), [0.0, 0.0]);
}
#[test]
fn digital_axis_values() {
assert_eq!(digital_axis(false, false), 0.0);
assert_eq!(digital_axis(true, false), -1.0);
assert_eq!(digital_axis(false, true), 1.0);
assert_eq!(digital_axis(true, true), 0.0); }
#[test]
fn digital_axis_pair_wasd() {
let [x, y] = digital_axis_pair(true, false, false, true); assert_eq!(x, -1.0);
assert_eq!(y, 1.0);
}
}