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