use crate::Camera;
use super::action_frame::ActionFrame;
use super::context::ViewportContext;
use super::event::ViewportEvent;
use super::preset::{BindingPreset, viewport_all_bindings, viewport_primitives_bindings};
use super::viewport_input::ViewportInput;
pub struct OrbitCameraController {
input: ViewportInput,
pub orbit_sensitivity: f32,
pub zoom_sensitivity: f32,
viewport_size: [f32; 2],
}
impl OrbitCameraController {
pub const DEFAULT_ORBIT_SENSITIVITY: f32 = 0.005;
pub const DEFAULT_ZOOM_SENSITIVITY: f32 = 0.001;
pub fn new(preset: BindingPreset) -> Self {
let bindings = match preset {
BindingPreset::ViewportPrimitives => viewport_primitives_bindings(),
BindingPreset::ViewportAll => viewport_all_bindings(),
};
Self {
input: ViewportInput::new(bindings),
orbit_sensitivity: Self::DEFAULT_ORBIT_SENSITIVITY,
zoom_sensitivity: Self::DEFAULT_ZOOM_SENSITIVITY,
viewport_size: [1.0, 1.0],
}
}
pub fn viewport_primitives() -> Self {
Self::new(BindingPreset::ViewportPrimitives)
}
pub fn viewport_all() -> Self {
Self::new(BindingPreset::ViewportAll)
}
pub fn begin_frame(&mut self, ctx: ViewportContext) {
self.viewport_size = ctx.viewport_size;
self.input.begin_frame(ctx);
}
pub fn push_event(&mut self, event: ViewportEvent) {
self.input.push_event(event);
}
pub fn resolve(&self) -> ActionFrame {
self.input.resolve()
}
pub fn apply_to_camera(&self, camera: &mut Camera) -> ActionFrame {
let frame = self.input.resolve();
let nav = &frame.navigation;
let h = self.viewport_size[1];
if nav.orbit != glam::Vec2::ZERO {
camera.orbit(
nav.orbit.x * self.orbit_sensitivity,
nav.orbit.y * self.orbit_sensitivity,
);
}
if nav.pan != glam::Vec2::ZERO {
camera.pan_pixels(nav.pan, h);
}
if nav.zoom != 0.0 {
camera.zoom_by_factor(1.0 - nav.zoom * self.zoom_sensitivity);
}
frame
}
}