three_d/renderer/control/free_orbit_control.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
use crate::renderer::*;
///
/// A control that makes the camera orbit around a target, with no fixed up direction.
///
#[derive(Clone, Copy, Debug)]
pub struct FreeOrbitControl {
/// The target point to orbit around.
pub target: Vec3,
/// The minimum distance to the target point.
pub min_distance: f32,
/// The maximum distance to the target point.
pub max_distance: f32,
}
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 {
target,
min_distance,
max_distance,
}
}
/// Handles the events. Must be called each frame.
pub fn handle_events(&mut self, camera: &mut Camera, events: &mut [Event]) -> bool {
let mut change = false;
for event in events.iter_mut() {
match event {
Event::MouseMotion {
delta,
button,
handled,
..
} => {
if !*handled {
if Some(MouseButton::Left) == *button {
let speed = 0.01 * self.target.distance(camera.position()) + 0.001;
camera.rotate_around(self.target, speed * delta.0, speed * delta.1);
*handled = true;
change = true;
}
}
}
Event::MouseWheel { delta, handled, .. } => {
if !*handled {
let speed = 0.01 * self.target.distance(camera.position()) + 0.001;
camera.zoom_towards(
self.target,
speed * delta.1,
self.min_distance,
self.max_distance,
);
*handled = true;
change = true;
}
}
Event::PinchGesture { delta, handled, .. } => {
if !*handled {
let speed = self.target.distance(camera.position()) + 0.1;
camera.zoom_towards(
self.target,
speed * *delta,
self.min_distance,
self.max_distance,
);
*handled = true;
change = true;
}
}
_ => {}
}
}
change
}
}