diff --git a/src/renderer/control.rs b/src/renderer/control.rs index 71b93127..88310b2d 100644 --- a/src/renderer/control.rs +++ b/src/renderer/control.rs @@ -10,6 +10,10 @@ mod orbit_control; #[doc(inline)] pub use orbit_control::*; +mod free_orbit_control; +#[doc(inline)] +pub use free_orbit_control::*; + mod first_person_control; #[doc(inline)] pub use first_person_control::*; diff --git a/src/renderer/control/free_orbit_control.rs b/src/renderer/control/free_orbit_control.rs new file mode 100644 index 00000000..d67ba28d --- /dev/null +++ b/src/renderer/control/free_orbit_control.rs @@ -0,0 +1,44 @@ +use crate::renderer::*; + +/// +/// A control that makes the camera orbit around a target, with no fixed up direction. +/// +pub struct FreeOrbitControl { + control: CameraControl, +} + +impl FreeOrbitControl { + /// Creates a new free orbit control with the given target and minimum and maximum distance to the target. + pub fn new(target: Vec3, min_distance: f32, max_distance: f32) -> Self { + Self { + control: CameraControl { + left_drag_horizontal: CameraAction::FreeOrbitLeft { target, speed: 0.1 }, + left_drag_vertical: CameraAction::FreeOrbitUp { target, speed: 0.1 }, + scroll_vertical: CameraAction::Zoom { + min: min_distance, + max: max_distance, + speed: 0.1, + target, + }, + ..Default::default() + }, + } + } + + /// Handles the events. Must be called each frame. + pub fn handle_events(&mut self, camera: &mut Camera, events: &mut [Event]) -> bool { + if let CameraAction::Zoom { speed, target, .. } = &mut self.control.scroll_vertical { + let x = target.distance(*camera.position()); + *speed = 0.01 * x + 0.001; + } + if let CameraAction::FreeOrbitLeft { speed, target } = &mut self.control.left_drag_horizontal { + let x = target.distance(*camera.position()); + *speed = 0.01 * x + 0.001; + } + if let CameraAction::FreeOrbitUp { speed, target } = &mut self.control.left_drag_vertical { + let x = target.distance(*camera.position()); + *speed = 0.01 * x + 0.001; + } + self.control.handle_events(camera, events) + } +}