slam_viewer/window/camera/
controller.rs1use super::super::event::WindowEventState;
5use super::base::Camera;
6
7use nalgebra::Vector2;
8use slam_cv::Number;
9use winit::event::*;
10
11pub struct CameraControllerConfig<N>
12where
13 N: Number,
14{
15 pub mouse_left_speed: N,
16 pub mouse_right_speed: N,
17 pub scroll_speed: N,
18 pub keyboard_speed: N,
19}
20
21impl<N> Into<CameraController<N>> for CameraControllerConfig<N>
22where
23 N: Number,
24{
25 fn into(self) -> CameraController<N> {
26 CameraController {
27 config: self,
28
29 window_size: Vector2::zeros(),
30
31 cursor_d: Vector2::zeros(),
32 cursor_pos: None,
33 mouse_wheel_d: N::zero(),
34
35 is_left_mouse_pressed: false,
36 is_right_mouse_pressed: false,
37
38 is_left_key_pressed: false,
39 is_right_key_pressed: false,
40 is_up_key_pressed: false,
41 is_down_key_pressed: false,
42 }
43 }
44}
45
46pub struct CameraController<N>
47where
48 N: Number,
49{
50 config: CameraControllerConfig<N>,
51
52 cursor_d: Vector2<N>,
53 cursor_pos: Option<Vector2<N>>,
54 mouse_wheel_d: N,
55
56 pub(crate) window_size: Vector2<N>,
57
58 is_left_mouse_pressed: bool,
59 is_right_mouse_pressed: bool,
60
61 is_left_key_pressed: bool,
62 is_right_key_pressed: bool,
63 is_up_key_pressed: bool,
64 is_down_key_pressed: bool,
65}
66
67impl<N> CameraController<N>
68where
69 N: Number,
70{
71 pub fn process_events(&mut self, event: &WindowEvent) -> WindowEventState {
72 match event {
73 WindowEvent::Resized(size) => {
74 self.window_size.x = N::from(size.width).unwrap();
75 self.window_size.y = N::from(size.height).unwrap();
76 WindowEventState::Unused
77 }
78 WindowEvent::KeyboardInput {
79 input:
80 KeyboardInput {
81 state,
82 virtual_keycode: Some(keycode),
83 ..
84 },
85 ..
86 } => {
87 let is_pressed = *state == ElementState::Pressed;
88 match keycode {
89 VirtualKeyCode::A | VirtualKeyCode::Left => {
90 self.is_left_key_pressed = is_pressed;
91 WindowEventState::Consumed
92 }
93 VirtualKeyCode::D | VirtualKeyCode::Right => {
94 self.is_right_key_pressed = is_pressed;
95 WindowEventState::Consumed
96 }
97 VirtualKeyCode::W | VirtualKeyCode::Up => {
98 self.is_up_key_pressed = is_pressed;
99 WindowEventState::Consumed
100 }
101 VirtualKeyCode::S | VirtualKeyCode::Down => {
102 self.is_down_key_pressed = is_pressed;
103 WindowEventState::Consumed
104 }
105 _ => WindowEventState::Unused,
106 }
107 }
108 WindowEvent::MouseInput { state, button, .. } => {
109 self.cursor_pos = None;
110
111 let is_pressed = *state == ElementState::Pressed;
112 match button {
113 MouseButton::Left => {
114 self.is_left_mouse_pressed = is_pressed;
115 WindowEventState::Consumed
116 }
117 MouseButton::Right => {
118 self.is_right_mouse_pressed = is_pressed;
119 WindowEventState::Consumed
120 }
121 _ => WindowEventState::Unused,
122 }
123 }
124 WindowEvent::CursorMoved { position, .. } => {
126 if self.is_left_mouse_pressed || self.is_right_mouse_pressed {
127 let position =
128 Vector2::new(N::from(position.x).unwrap(), N::from(position.y).unwrap());
129
130 if let Some(cursor_pos) = self.cursor_pos {
131 let delta = position - cursor_pos;
132 self.cursor_d += delta;
133 }
134
135 self.cursor_pos = Some(position);
136 WindowEventState::Consumed
137 } else {
138 WindowEventState::Unused
139 }
140 }
141 WindowEvent::MouseWheel { delta, .. } => {
142 self.mouse_wheel_d += match delta {
143 MouseScrollDelta::LineDelta(_, ny) => N::from(*ny).unwrap(),
144 MouseScrollDelta::PixelDelta(dp) => N::from(dp.x.max(dp.y)).unwrap(),
146 };
147 WindowEventState::Consumed
148 }
149 _ => WindowEventState::Unused,
150 }
151 }
152
153 pub fn update_camera(&mut self, camera: &mut Camera<N>) {
154 self.cursor_d.x /= self.window_size.x;
155 self.cursor_d.y /= self.window_size.y;
156
157 if self.is_left_mouse_pressed {
159 camera.handle_left_button_displacement(self.cursor_d * self.config.mouse_left_speed);
160 }
161 if self.is_right_mouse_pressed {
162 camera.handle_right_button_displacement(self.cursor_d * self.config.mouse_right_speed);
163 }
164 self.cursor_d = Vector2::zeros();
165
166 camera.handle_scroll(self.mouse_wheel_d * self.config.scroll_speed);
168 self.mouse_wheel_d = N::zero();
169
170 let mut dkey = Vector2::<N>::zeros();
172 if self.is_left_key_pressed {
173 dkey.x -= N::one();
174 }
175 if self.is_right_key_pressed {
176 dkey.x += N::one();
177 }
178 if self.is_up_key_pressed {
179 dkey.y += N::one();
180 }
181 if self.is_down_key_pressed {
182 dkey.y -= N::one();
183 }
184 dkey *= self.config.keyboard_speed;
185
186 camera.handle_keyboard(dkey);
187 }
188}