radar-g/gi/src/graphics/threed.rs
2024-08-23 16:12:27 +08:00

78 lines
1.9 KiB
Rust

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<Self> {
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),
)
}
}