Skip to main content

editor/
fly_camera.rs

1use libdqg::camera::Camera;
2use libdqg::glam;
3use libdqg::input::{InputState, MouseState};
4use libdqg::types::KeyCode;
5
6/// WASD + middle-mouse-drag look + wheel zoom, orbiting `target` at a fixed distance rather than
7/// flying freely — simplest thing that lets you look at a spawned entity from any angle.
8pub struct FlyCamera {
9    yaw: f32,
10    pitch: f32,
11    /// Orbit pivot. `Camera` itself only stores position + yaw/pitch, not a target, so this has
12    /// to live here instead.
13    target: glam::Vec3,
14    distance: f32,
15    move_speed: f32,
16    look_speed: f32,
17    zoom_speed: f32,
18}
19
20impl FlyCamera {
21    pub fn new(distance: f32) -> Self {
22        Self {
23            yaw: -90.0_f32.to_radians(),
24            pitch: -20.0_f32.to_radians(),
25            target: glam::Vec3::ZERO,
26            distance,
27            move_speed: 4.0,
28            look_speed: 0.005,
29            zoom_speed: 0.5,
30        }
31    }
32
33    pub fn update(&mut self, delta_time: f32, input: &InputState, mouse: &MouseState, camera: &mut Camera, mouse_delta: (f32, f32)) {
34        if mouse.is_button_held(winit::event::MouseButton::Middle) {
35            self.yaw += mouse_delta.0 * self.look_speed;
36            self.pitch = (self.pitch - mouse_delta.1 * self.look_speed).clamp(-1.5, 1.5);
37        }
38
39        self.distance = (self.distance - mouse.wheel_delta() * self.zoom_speed).max(0.5);
40
41        camera.yaw = self.yaw;
42        camera.pitch = self.pitch;
43        let forward = camera.forward();
44        let right = forward.cross(glam::Vec3::Y).normalize();
45
46        let mut move_delta = glam::Vec3::ZERO;
47        if input.is_key_held(KeyCode::KeyW) {
48            move_delta += forward;
49        }
50        if input.is_key_held(KeyCode::KeyS) {
51            move_delta -= forward;
52        }
53        if input.is_key_held(KeyCode::KeyA) {
54            move_delta -= right;
55        }
56        if input.is_key_held(KeyCode::KeyD) {
57            move_delta += right;
58        }
59        if move_delta != glam::Vec3::ZERO {
60            self.target += move_delta.normalize() * self.move_speed * delta_time;
61        }
62
63        camera.position = self.target - forward * self.distance;
64    }
65}