dreamwell_engine/input/
axis.rs1#[derive(Debug, Clone, Copy)]
6pub struct AxisValue {
7 raw: f32,
8 dead_zone: f32,
9}
10
11impl AxisValue {
12 pub fn new(dead_zone: f32) -> Self {
13 Self {
14 raw: 0.0,
15 dead_zone: dead_zone.abs(),
16 }
17 }
18
19 pub fn set(&mut self, value: f32) {
21 self.raw = value;
22 }
23
24 pub fn value(&self) -> f32 {
26 if self.raw.abs() <= self.dead_zone {
27 0.0
28 } else {
29 self.raw
30 }
31 }
32
33 pub fn raw(&self) -> f32 {
35 self.raw
36 }
37
38 pub fn active(&self) -> bool {
40 self.raw.abs() > self.dead_zone
41 }
42
43 pub fn reset(&mut self) {
45 self.raw = 0.0;
46 }
47}
48
49impl Default for AxisValue {
50 fn default() -> Self {
51 Self::new(0.0)
52 }
53}
54
55#[derive(Debug, Clone, Copy)]
57pub struct AxisPair {
58 pub x: AxisValue,
59 pub y: AxisValue,
60}
61
62impl AxisPair {
63 pub fn new(dead_zone: f32) -> Self {
64 Self {
65 x: AxisValue::new(dead_zone),
66 y: AxisValue::new(dead_zone),
67 }
68 }
69
70 pub fn set(&mut self, x: f32, y: f32) {
72 self.x.set(x);
73 self.y.set(y);
74 }
75
76 pub fn value(&self) -> [f32; 2] {
78 [self.x.value(), self.y.value()]
79 }
80
81 pub fn active(&self) -> bool {
83 self.x.active() || self.y.active()
84 }
85
86 pub fn magnitude_sq(&self) -> f32 {
88 let [x, y] = self.value();
89 x * x + y * y
90 }
91
92 pub fn normalized(&self) -> [f32; 2] {
94 let [x, y] = self.value();
95 let mag_sq = x * x + y * y;
96 if mag_sq < 1e-10 {
97 [0.0, 0.0]
98 } else {
99 let inv_mag = 1.0 / mag_sq.sqrt();
100 [x * inv_mag, y * inv_mag]
101 }
102 }
103
104 pub fn reset(&mut self) {
106 self.x.reset();
107 self.y.reset();
108 }
109}
110
111impl Default for AxisPair {
112 fn default() -> Self {
113 Self::new(0.0)
114 }
115}
116
117pub fn digital_axis(negative: bool, positive: bool) -> f32 {
120 match (negative, positive) {
121 (true, false) => -1.0,
122 (false, true) => 1.0,
123 _ => 0.0,
124 }
125}
126
127pub fn digital_axis_pair(left: bool, right: bool, down: bool, up: bool) -> [f32; 2] {
129 [digital_axis(left, right), digital_axis(down, up)]
130}
131
132#[cfg(test)]
133mod tests {
134 use super::*;
135
136 #[test]
137 fn axis_value_dead_zone() {
138 let mut axis = AxisValue::new(0.1);
139 axis.set(0.05);
140 assert_eq!(axis.value(), 0.0);
141 assert!(!axis.active());
142
143 axis.set(0.5);
144 assert_eq!(axis.value(), 0.5);
145 assert!(axis.active());
146 }
147
148 #[test]
149 fn axis_value_negative() {
150 let mut axis = AxisValue::new(0.1);
151 axis.set(-0.8);
152 assert_eq!(axis.value(), -0.8);
153 assert!(axis.active());
154 }
155
156 #[test]
157 fn axis_value_reset() {
158 let mut axis = AxisValue::new(0.0);
159 axis.set(1.0);
160 axis.reset();
161 assert_eq!(axis.value(), 0.0);
162 }
163
164 #[test]
165 fn axis_pair_basic() {
166 let mut pair = AxisPair::new(0.0);
167 pair.set(0.5, -0.3);
168 assert_eq!(pair.value(), [0.5, -0.3]);
169 assert!(pair.active());
170 }
171
172 #[test]
173 fn axis_pair_normalized() {
174 let mut pair = AxisPair::new(0.0);
175 pair.set(3.0, 4.0);
176 let [nx, ny] = pair.normalized();
177 assert!((nx - 0.6).abs() < 1e-5);
178 assert!((ny - 0.8).abs() < 1e-5);
179 }
180
181 #[test]
182 fn axis_pair_zero_normalized() {
183 let pair = AxisPair::new(0.0);
184 assert_eq!(pair.normalized(), [0.0, 0.0]);
185 }
186
187 #[test]
188 fn digital_axis_values() {
189 assert_eq!(digital_axis(false, false), 0.0);
190 assert_eq!(digital_axis(true, false), -1.0);
191 assert_eq!(digital_axis(false, true), 1.0);
192 assert_eq!(digital_axis(true, true), 0.0); }
194
195 #[test]
196 fn digital_axis_pair_wasd() {
197 let [x, y] = digital_axis_pair(true, false, false, true); assert_eq!(x, -1.0);
200 assert_eq!(y, 1.0);
201 }
202}