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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
use crate::math::*;
use crate::camera::*;
use crate::core::Error;
pub struct CameraControl {
camera: Camera
}
impl CameraControl {
pub fn new(camera: Camera) -> Self {
Self {camera}
}
pub fn translate(&mut self, change: &Vec3) -> Result<(), Error>
{
let position = *self.position();
let target = *self.target();
let up = *self.up();
self.set_view(position + change, target + change, up)?;
Ok(())
}
pub fn rotate(&mut self, x: f32, y: f32) -> Result<(), Error>
{
let target = *self.target();
let mut direction = self.target() - self.position();
let zoom = direction.magnitude();
direction /= zoom;
let right = direction.cross(*self.up());
let up = right.cross(direction);
let new_pos = self.position() + (-right * x + up * y) * 0.1;
let new_dir = (self.target() - new_pos).normalize();
self.set_view(target - new_dir * zoom, target, up)?;
Ok(())
}
pub fn rotate_around_up(&mut self, x: f32, y: f32) -> Result<(), Error>
{
let target = *self.target();
let up = *self.up();
let mut direction = target - self.position();
let zoom = direction.magnitude();
direction /= zoom;
let right = direction.cross(up);
let new_pos = self.position() + (-right * x + right.cross(direction) * y) * 0.1;
let new_dir = (self.target() - new_pos).normalize();
if new_dir.dot(up).abs() < 0.999 {
self.set_view(target - new_dir * zoom, target, up)?;
}
Ok(())
}
pub fn pan(&mut self, x: f32, y: f32) -> Result<(), Error>
{
let position = *self.position();
let target = *self.target();
let up = *self.up();
let mut direction = target - position;
let zoom = direction.magnitude();
direction /= zoom;
let right = direction.cross(up);
let delta = (-right * x + right.cross(direction) * y) * zoom * 0.005;
self.set_view(position + delta, target + delta, up)?;
Ok(())
}
pub fn zoom(&mut self, wheel: f32) -> Result<(), Error>
{
match self.projection_type() {
ProjectionType::Orthographic {width, height, depth} => {
let h = (height - wheel).max(0.001);
let w = h * width / height;
let d = *depth;
self.set_orthographic_projection(w, h, d)?;
},
ProjectionType::Perspective {..} => {
let position = *self.position();
let target = *self.target();
let up = *self.up();
let mut direction = target - position;
let mut zoom = direction.magnitude();
direction /= zoom;
zoom += wheel;
zoom = zoom.max(1.0);
self.set_view(target - direction * zoom, target, up)?;
}
}
Ok(())
}
}
impl std::ops::Deref for CameraControl {
type Target = Camera;
fn deref(&self) -> &Self::Target {
&self.camera
}
}
impl std::ops::DerefMut for CameraControl {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.camera
}
}