use crate::*;
use super::*;
use crate::ui::*;
use crate::rs_math3d::*;
use crate::renderer::*;
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum NavigationMode {
Pan,
Orbit,
}
pub struct View3D {
camera : Camera,
nav_mode : NavigationMode,
dimension : Dimensioni,
scroll : f32,
bounds : Box3f,
pvm : Mat4f,
pointer_state : pointer::State,
}
impl View3D {
pub fn new(camera: Camera, dimension: Dimensioni, bounds: Box3f) -> Self {
Self {
camera : camera,
nav_mode : NavigationMode::Orbit,
dimension : dimension,
scroll : 0.0,
bounds : bounds,
pvm : Mat4f::identity(),
pointer_state : pointer::State::new(),
}
}
fn update(&mut self) {
match (&self.nav_mode, self.pointer_state.event()) {
(NavigationMode::Orbit, pointer::Event::Drag(prev, _, curr, _)) => {
let p = Vec2f::new(prev.x, prev.y);
let c = Vec2f::new(curr.x, curr.y);
self.camera = self.camera.tracball_rotate(self.dimension, &p, &c);
},
(NavigationMode::Pan, pointer::Event::Drag(prev, _, curr, _)) => {
let p = Vec2f::new(prev.x, prev.y);
let c = Vec2f::new(curr.x, curr.y);
self.camera = self.camera.pan(self.dimension, &p, &c);
},
(_, pointer::Event::Scroll(v)) => {
self.scroll += v as f32 / 128.0;
self.scroll = f32::max(0.1, self.scroll);
let distance = self.scroll + self.bounds.extent().length() ;
let aspect = (self.dimension.width as f32) / (self.dimension.height as f32);
self.camera = Camera::new(self.bounds.center(), distance, self.camera.rotation(), std::f32::consts::PI * 0.25, aspect, 0.1, self.bounds.extent().length() * 100.0);
}
_ => ()
}
self.pvm = self.camera.projection_matrix() * self.camera.view_matrix();
}
pub fn set_pointer(&mut self, pos: Vec2f, st: pointer::ButtonState) {
self.pointer_state.update(pos, st);
self.update();
}
pub fn set_dimension(&mut self, dimension: Dimensioni) {
self.dimension = dimension;
let aspect = (self.dimension.width as f32) / (self.dimension.height as f32);
self.camera = self.camera.with_aspect(aspect);
self.update();
}
pub fn get_navigation_mode(&self) -> NavigationMode { self.nav_mode }
pub fn set_navigation_mode(&mut self, nav_mode: NavigationMode) {
if nav_mode != self.nav_mode {
self.nav_mode = nav_mode;
self.pointer_state = pointer::State::new();
self.update(); }
}
pub fn pointer_event(&self) -> pointer::Event { self.pointer_state.event() }
pub fn pvm(&self) -> Mat4f { self.pvm }
pub fn projection_matrix(&self) -> Mat4f {
self.camera.projection_matrix()
}
pub fn view_matrix(&self) -> Mat4f {
self.camera.view_matrix()
}
}