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}