use std::rc::Rc; use tracker::track; use super::transforms::trackball::TrackballModel; use super::{AttaWithProgram, AttachWithIO}; use crate::camera::{self, Camera}; use crate::errors::*; use crate::pg::layout_type::ViewPort; use crate::ui::operation::Projection; use glow::HasContext; use nalgebra_glm::{Mat4, Vec3}; #[derive(Clone)] pub struct Trackball { trackball: TrackballModel, } impl Trackball { pub fn new(aspect: f32, z_near: f32, z_far: f32, fov: f32) -> Result { let trackball = TrackballModel::new(0.0, 90.0, 20.0); Ok(Self { trackball }) } } impl Default for Trackball { fn default() -> Self { Self::new(16.0 / 9.0, 0.1, 1000.0, 45.0).unwrap() } } impl AttaWithProgram for Trackball { fn attach_with_program( &self, gl: &glow::Context, program: &crate::components::Program, ) -> Result<()> { self.trackball.attach_with_program(gl, program); Ok(()) } } impl AttachWithIO for Trackball { type State = super::MouseState; fn attach_with_mouse( &mut self, state: &Self::State, camera: &mut Camera, projection: &mut Projection, viewport: &ViewPort, ) -> bool { match state { &super::MouseState::Wheel(delta) => { projection.set_fov((projection.fov() - delta).clamp(15.0, 120.0)); true } super::MouseState::Drag { from, delta } => { self.trackball.drag_to(from[0], from[1], delta[0], delta[1]); true } _ => false, } } fn reset(&mut self) { self.trackball.set_phi(90.0); self.trackball.set_theta(0.0); } fn init_camera(&self) -> Camera { Camera::new( Vec3::new(0.0, 30.0, 10.0), Vec3::new(0.0, 1.0, 0.0), Vec3::new(0.0, 0.0, 0.0), ) } }