mirror of
https://github.com/guilhermewerner/wgpu-renderer
synced 2025-06-15 05:14:20 +00:00
106 lines
3.4 KiB
Rust
106 lines
3.4 KiB
Rust
use super::Camera;
|
|
use winit::event::*;
|
|
|
|
pub struct CameraController {
|
|
pub speed: f32,
|
|
pub is_up_pressed: bool,
|
|
pub is_down_pressed: bool,
|
|
pub is_forward_pressed: bool,
|
|
pub is_backward_pressed: bool,
|
|
pub is_left_pressed: bool,
|
|
pub is_right_pressed: bool,
|
|
}
|
|
|
|
impl CameraController {
|
|
pub fn New(speed: f32) -> Self {
|
|
Self {
|
|
speed,
|
|
is_up_pressed: false,
|
|
is_down_pressed: false,
|
|
is_forward_pressed: false,
|
|
is_backward_pressed: false,
|
|
is_left_pressed: false,
|
|
is_right_pressed: false,
|
|
}
|
|
}
|
|
|
|
pub fn ProcessEvents(&mut self, event: &WindowEvent) -> bool {
|
|
match event {
|
|
WindowEvent::KeyboardInput {
|
|
input:
|
|
KeyboardInput {
|
|
state,
|
|
virtual_keycode: Some(keycode),
|
|
..
|
|
},
|
|
..
|
|
} => {
|
|
let is_pressed = *state == ElementState::Pressed;
|
|
match keycode {
|
|
VirtualKeyCode::Space => {
|
|
self.is_up_pressed = is_pressed;
|
|
true
|
|
}
|
|
VirtualKeyCode::LShift => {
|
|
self.is_down_pressed = is_pressed;
|
|
true
|
|
}
|
|
VirtualKeyCode::W | VirtualKeyCode::Up => {
|
|
self.is_forward_pressed = is_pressed;
|
|
true
|
|
}
|
|
VirtualKeyCode::A | VirtualKeyCode::Left => {
|
|
self.is_left_pressed = is_pressed;
|
|
true
|
|
}
|
|
VirtualKeyCode::S | VirtualKeyCode::Down => {
|
|
self.is_backward_pressed = is_pressed;
|
|
true
|
|
}
|
|
VirtualKeyCode::D | VirtualKeyCode::Right => {
|
|
self.is_right_pressed = is_pressed;
|
|
true
|
|
}
|
|
_ => false,
|
|
}
|
|
}
|
|
_ => false,
|
|
}
|
|
}
|
|
|
|
pub fn UpdateCamera(&self, camera: &mut Camera) {
|
|
use cgmath::InnerSpace;
|
|
|
|
let forward = camera.target - camera.eye;
|
|
let forward_norm = forward.normalize();
|
|
let forward_mag = forward.magnitude();
|
|
|
|
// Prevents glitching when camera gets too close to the
|
|
// center of the scene.
|
|
if self.is_forward_pressed && forward_mag > self.speed {
|
|
camera.eye += forward_norm * self.speed;
|
|
}
|
|
|
|
if self.is_backward_pressed {
|
|
camera.eye -= forward_norm * self.speed;
|
|
}
|
|
|
|
let right = forward_norm.cross(camera.up);
|
|
|
|
// Redo radius calc in case the up/ down is pressed.
|
|
let forward = camera.target - camera.eye;
|
|
let forward_mag = forward.magnitude();
|
|
|
|
if self.is_right_pressed {
|
|
// Rescale the distance between the target and eye so
|
|
// that it doesn't change. The eye therefore still
|
|
// lies on the circle made by the target and eye.
|
|
camera.eye = camera.target - (forward + right * self.speed).normalize() * forward_mag;
|
|
}
|
|
|
|
if self.is_left_pressed {
|
|
camera.eye = camera.target - (forward - right * self.speed).normalize() * forward_mag;
|
|
}
|
|
}
|
|
}
|