I’m currently stuck with this. I’ve got some idea how to do it, but it seems I’m doing something wrong. If anyone could look at the code and see if I’m overlooking something silly. Basically I am trying to drag the camera around with the middle mouse button. Please note that the camera has the Perspective projection type.

```
pub struct EditorCameraMovementSystem {
dragging: bool,
drag_start: Option<Point3<f32>>,
}
fn run(&mut self, (mut transforms, camera, input, dims): Self::SystemData) {
if let Some((mut t, cam)) = (&mut transforms,&camera).join().next() {
if let Some((x,y)) = input.mouse_position() {
// All the logic needs be here.
// We get the middle mouse button input ( true / false).
let is_mouse_middle = input.mouse_button_is_down(MouseButton::Middle);
// If the dragging has not started yet but the middle
// mouse button is pressed, that means that the dragging
// has started, and we acquire the starting point.
if !self.dragging && is_mouse_middle {
// Now we need to tell the system that the dragging has started
// so it has it in mind, we do not want to keep writing the
// starting point everytime the mouse moves. Hence self.dragging = true.
self.dragging = true;
let ray = cam.projection().screen_ray(
Point2::new(x, y),
Vector2::new(dims.width(), dims.height()),
t,
);
// Here we are storing the starting point into our struct field.
if let Some(distance) = ray.intersect_plane(&Plane::with_z(0f32)) {
self.drag_start = Some(ray.at_distance(distance));
}
} else if let Some(p) = self.drag_start {
if is_mouse_middle {
// Here we will get the current point of the mouse
// but in world space. The same way as we got the
// drag starting position.
let ray = cam.projection().screen_ray(
Point2::new(x, y),
Vector2::new(dims.width(), dims.height()),
t,
);
if let Some(distance) = ray.intersect_plane(&Plane::with_z(0f32)) {
let d = ray.at_distance(distance);
// Inversing the dragging.
let x = -(d.x - p.x);
let y = -(d.y - p.y);
t.set_translation(Vector3::new(x, y, t.translation().z));
}
} else {
// Reset the values
self.dragging = false;
self.drag_start = None;
}
}
}
}
}
```