1use dreamwell_engine::input::VirtualKey;
5use dreamwell_fabric::FabricInput;
6use dreamwell_gpu::camera::Camera;
7use winit::event::{ElementState, KeyEvent, MouseButton, MouseScrollDelta};
8use winit::keyboard::{KeyCode, PhysicalKey};
9
10const SCROLL_DEAD_ZONE: f32 = 0.01;
11const CURSOR_DEAD_ZONE: f32 = 0.1;
12const PAN_SPEED: f32 = 0.5;
13const SCROLL_SENSITIVITY: f32 = 0.5;
14const PIXEL_SCROLL_SCALE: f32 = 0.01;
15
16const ORBIT_YAW_SENSITIVITY: f32 = 0.005;
18const ORBIT_PITCH_SENSITIVITY: f32 = 0.003;
20
21#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
24pub enum RuntimeAction {
25 MoveIntent,
27 LookIntent,
29 BurstStart,
31 BurstEnd,
32 SetFormCohere,
34 SetFormWave,
36 GatherStart,
38 GatherEnd,
39 PrimaryActionStart,
41 PrimaryActionEnd,
42 Interact,
44 Jump,
46 CameraRecenter,
48}
49
50pub struct InputState {
52 pub fabric: FabricInput,
53 scroll_raw: f32,
55 active_touches: std::collections::HashMap<u64, [f32; 2]>,
57 pub orbit_dx: f32,
59 pub orbit_dy: f32,
61 pub scroll_delta: f32,
63}
64
65impl InputState {
66 pub fn new() -> Self {
67 Self {
68 fabric: FabricInput::new(),
69 scroll_raw: 0.0,
70 active_touches: std::collections::HashMap::new(),
71 orbit_dx: 0.0,
72 orbit_dy: 0.0,
73 scroll_delta: 0.0,
74 }
75 }
76
77 pub fn handle_keyboard(&mut self, event: &KeyEvent) {
79 if let PhysicalKey::Code(code) = event.physical_key {
80 if let Some(vk) = winit_to_virtual_key(code) {
81 match event.state {
82 ElementState::Pressed => self.fabric.key_down(vk),
83 ElementState::Released => self.fabric.key_up(vk),
84 }
85 }
86 }
87 }
88
89 pub fn handle_mouse_button(&mut self, button: MouseButton, state: ElementState) {
91 let vk = match button {
92 MouseButton::Left => VirtualKey::MouseLeft,
93 MouseButton::Right => VirtualKey::MouseRight,
94 MouseButton::Middle => VirtualKey::MouseMiddle,
95 MouseButton::Back => VirtualKey::MouseButton4,
96 MouseButton::Forward => VirtualKey::MouseButton5,
97 _ => return,
98 };
99 match state {
100 ElementState::Pressed => self.fabric.key_down(vk),
101 ElementState::Released => self.fabric.key_up(vk),
102 }
103 }
104
105 pub fn handle_cursor_move(&mut self, x: f32, y: f32) {
107 self.fabric.cursor_moved(x, y);
108 }
109
110 pub fn handle_scroll(&mut self, delta: &MouseScrollDelta) {
112 let y = match delta {
113 MouseScrollDelta::LineDelta(_, y) => *y,
114 MouseScrollDelta::PixelDelta(pos) => pos.y as f32 * PIXEL_SCROLL_SCALE,
115 };
116 self.scroll_raw = y;
117 self.fabric.scroll(y);
118 }
119
120 pub fn apply_to_camera(&mut self, camera: &mut Camera, dt: f32) {
123 let frame = self.fabric.build_frame();
124 let dt_pan = PAN_SPEED * dt * 60.0; if self.scroll_raw.abs() > SCROLL_DEAD_ZONE {
128 camera.zoom(-self.scroll_raw * SCROLL_SENSITIVITY);
129 self.scroll_raw = 0.0;
130 }
131
132 if frame.has_action(dreamwell_engine::input::InputAction::CameraRotate) {
134 let [dx, dy] = frame.cursor_delta;
135 if dx.abs() > CURSOR_DEAD_ZONE || dy.abs() > CURSOR_DEAD_ZONE {
136 camera.rotate(dx, dy);
137 }
138 }
139
140 if frame.has_action(dreamwell_engine::input::InputAction::CameraPan) {
142 let [dx, dy] = frame.cursor_delta;
143 if dx.abs() > CURSOR_DEAD_ZONE || dy.abs() > CURSOR_DEAD_ZONE {
144 camera.pan(-dx, dy);
145 }
146 }
147
148 let [mx, my] = frame.movement;
150 if my > 0.0 {
151 camera.pan(0.0, dt_pan);
152 }
153 if my < 0.0 {
154 camera.pan(0.0, -dt_pan);
155 }
156 if mx < 0.0 {
157 camera.pan(dt_pan, 0.0);
158 }
159 if mx > 0.0 {
160 camera.pan(-dt_pan, 0.0);
161 }
162 }
163
164 pub fn apply_mouse_to_camera(&mut self, _camera: &mut Camera, _dt: f32) {
168 if self.scroll_raw.abs() > SCROLL_DEAD_ZONE {
170 self.scroll_delta += -self.scroll_raw * SCROLL_SENSITIVITY;
171 self.scroll_raw = 0.0;
172 }
173
174 let frame = self.fabric.build_frame();
176 if frame.has_action(dreamwell_engine::input::InputAction::CameraRotate) {
177 let [dx, dy] = frame.cursor_delta;
178 if dx.abs() > CURSOR_DEAD_ZONE {
179 self.orbit_dx += dx * ORBIT_YAW_SENSITIVITY;
180 }
181 if dy.abs() > CURSOR_DEAD_ZONE {
182 self.orbit_dy += dy * ORBIT_PITCH_SENSITIVITY;
183 }
184 }
185 }
186
187 #[cfg(feature = "gamepad")]
190 pub fn handle_gamepad(&mut self, gilrs: &mut gilrs::Gilrs, camera: &mut Camera) {
191 while let Some(event) = gilrs.next_event() {
192 let _ = event;
194 }
195 if let Some((_id, gamepad)) = gilrs.gamepads().next() {
197 let lx = gamepad.value(gilrs::Axis::LeftStickX);
198 let ly = gamepad.value(gilrs::Axis::LeftStickY);
199 let rx = gamepad.value(gilrs::Axis::RightStickX);
200 let ry = gamepad.value(gilrs::Axis::RightStickY);
201
202 const DEAD_ZONE: f32 = 0.15;
203
204 if lx.abs() > DEAD_ZONE || ly.abs() > DEAD_ZONE {
206 camera.pan(-lx * PAN_SPEED, ly * PAN_SPEED);
207 }
208
209 if rx.abs() > DEAD_ZONE || ry.abs() > DEAD_ZONE {
211 camera.rotate(rx * 2.0, ry * 2.0);
212 }
213
214 let lt = gamepad.value(gilrs::Axis::LeftZ);
216 let rt = gamepad.value(gilrs::Axis::RightZ);
217 let zoom_delta = rt - lt;
218 if zoom_delta.abs() > DEAD_ZONE {
219 camera.zoom(zoom_delta * SCROLL_SENSITIVITY);
220 }
221 }
222 }
223
224 pub fn handle_touch(&mut self, phase: TouchPhase, id: u64, x: f32, y: f32) {
227 match phase {
228 TouchPhase::Started => {
229 self.active_touches.insert(id, [x, y]);
230 }
231 TouchPhase::Moved => {
232 if let Some(prev) = self.active_touches.get_mut(&id) {
233 let dx = x - prev[0];
234 let dy = y - prev[1];
235 *prev = [x, y];
236
237 if self.active_touches.len() == 1 {
238 self.fabric.cursor_moved(dx, dy);
240 }
241 }
242 }
243 TouchPhase::Ended | TouchPhase::Cancelled => {
244 self.active_touches.remove(&id);
245 }
246 }
247 }
248
249 pub fn end_frame(&mut self) {
251 self.fabric.end_frame();
252 self.scroll_raw = 0.0;
253 self.orbit_dx = 0.0;
254 self.orbit_dy = 0.0;
255 self.scroll_delta = 0.0;
256 }
257}
258
259#[derive(Debug, Clone, Copy, PartialEq, Eq)]
261pub enum TouchPhase {
262 Started,
263 Moved,
264 Ended,
265 Cancelled,
266}
267
268impl Default for InputState {
269 fn default() -> Self {
270 Self::new()
271 }
272}
273
274fn winit_to_virtual_key(code: KeyCode) -> Option<VirtualKey> {
276 Some(match code {
277 KeyCode::KeyA => VirtualKey::A,
278 KeyCode::KeyB => VirtualKey::B,
279 KeyCode::KeyC => VirtualKey::C,
280 KeyCode::KeyD => VirtualKey::D,
281 KeyCode::KeyE => VirtualKey::E,
282 KeyCode::KeyF => VirtualKey::F,
283 KeyCode::KeyG => VirtualKey::G,
284 KeyCode::KeyH => VirtualKey::H,
285 KeyCode::KeyI => VirtualKey::I,
286 KeyCode::KeyJ => VirtualKey::J,
287 KeyCode::KeyK => VirtualKey::K,
288 KeyCode::KeyL => VirtualKey::L,
289 KeyCode::KeyM => VirtualKey::M,
290 KeyCode::KeyN => VirtualKey::N,
291 KeyCode::KeyO => VirtualKey::O,
292 KeyCode::KeyP => VirtualKey::P,
293 KeyCode::KeyQ => VirtualKey::Q,
294 KeyCode::KeyR => VirtualKey::R,
295 KeyCode::KeyS => VirtualKey::S,
296 KeyCode::KeyT => VirtualKey::T,
297 KeyCode::KeyU => VirtualKey::U,
298 KeyCode::KeyV => VirtualKey::V,
299 KeyCode::KeyW => VirtualKey::W,
300 KeyCode::KeyX => VirtualKey::X,
301 KeyCode::KeyY => VirtualKey::Y,
302 KeyCode::KeyZ => VirtualKey::Z,
303 KeyCode::Digit0 => VirtualKey::Num0,
304 KeyCode::Digit1 => VirtualKey::Num1,
305 KeyCode::Digit2 => VirtualKey::Num2,
306 KeyCode::Digit3 => VirtualKey::Num3,
307 KeyCode::Digit4 => VirtualKey::Num4,
308 KeyCode::Digit5 => VirtualKey::Num5,
309 KeyCode::Digit6 => VirtualKey::Num6,
310 KeyCode::Digit7 => VirtualKey::Num7,
311 KeyCode::Digit8 => VirtualKey::Num8,
312 KeyCode::Digit9 => VirtualKey::Num9,
313 KeyCode::ArrowUp => VirtualKey::ArrowUp,
314 KeyCode::ArrowDown => VirtualKey::ArrowDown,
315 KeyCode::ArrowLeft => VirtualKey::ArrowLeft,
316 KeyCode::ArrowRight => VirtualKey::ArrowRight,
317 KeyCode::ShiftLeft => VirtualKey::ShiftLeft,
318 KeyCode::ShiftRight => VirtualKey::ShiftRight,
319 KeyCode::ControlLeft => VirtualKey::CtrlLeft,
320 KeyCode::ControlRight => VirtualKey::CtrlRight,
321 KeyCode::AltLeft => VirtualKey::AltLeft,
322 KeyCode::AltRight => VirtualKey::AltRight,
323 KeyCode::Space => VirtualKey::Space,
324 KeyCode::Enter => VirtualKey::Enter,
325 KeyCode::Escape => VirtualKey::Escape,
326 KeyCode::Tab => VirtualKey::Tab,
327 KeyCode::Backspace => VirtualKey::Backspace,
328 KeyCode::Delete => VirtualKey::Delete,
329 KeyCode::Home => VirtualKey::Home,
330 KeyCode::End => VirtualKey::End,
331 KeyCode::PageUp => VirtualKey::PageUp,
332 KeyCode::PageDown => VirtualKey::PageDown,
333 KeyCode::F1 => VirtualKey::F1,
334 KeyCode::F2 => VirtualKey::F2,
335 KeyCode::F3 => VirtualKey::F3,
336 KeyCode::F4 => VirtualKey::F4,
337 KeyCode::F5 => VirtualKey::F5,
338 KeyCode::F6 => VirtualKey::F6,
339 KeyCode::F7 => VirtualKey::F7,
340 KeyCode::F8 => VirtualKey::F8,
341 KeyCode::F9 => VirtualKey::F9,
342 KeyCode::F10 => VirtualKey::F10,
343 KeyCode::F11 => VirtualKey::F11,
344 KeyCode::F12 => VirtualKey::F12,
345 _ => return None,
346 })
347}