use crate::event::WindowEvent;
use crate::window::Canvas;
use glamx::{Mat4, Pose3, Vec2, Vec3, Vec4, Vec4Swizzles};
pub trait Camera3d {
fn handle_event(&mut self, canvas: &Canvas, event: &WindowEvent);
fn eye(&self) -> Vec3;
fn view_transform(&self) -> Pose3;
fn transformation(&self) -> Mat4;
fn inverse_transformation(&self) -> Mat4;
fn clip_planes(&self) -> (f32, f32);
fn update(&mut self, canvas: &Canvas);
fn view_transform_pair(&self, pass: usize) -> (Pose3, Mat4);
#[inline]
fn num_passes(&self) -> usize {
1usize
}
#[inline]
fn start_pass(&self, _pass: usize, _canvas: &Canvas) {}
#[inline]
fn render_complete(&self, _canvas: &Canvas) {}
fn project(&self, world_coord: Vec3, size: Vec2) -> Vec2 {
let h_world_coord = world_coord.extend(1.0);
let h_normalized_coord = self.transformation() * h_world_coord;
let normalized_coord = h_normalized_coord.xyz() / h_normalized_coord.w;
Vec2::new(
(1.0 + normalized_coord.x) * size.x / 2.0,
(1.0 + normalized_coord.y) * size.y / 2.0,
)
}
fn unproject(&self, window_coord: Vec2, size: Vec2) -> (Vec3, Vec3) {
let normalized_coord = Vec2::new(
2.0 * window_coord.x / size.x - 1.0,
2.0 * -window_coord.y / size.y + 1.0,
);
let normalized_begin = Vec4::new(normalized_coord.x, normalized_coord.y, -1.0, 1.0);
let normalized_end = Vec4::new(normalized_coord.x, normalized_coord.y, 1.0, 1.0);
let cam = self.inverse_transformation();
let h_unprojected_begin = cam * normalized_begin;
let h_unprojected_end = cam * normalized_end;
let unprojected_begin = h_unprojected_begin.xyz() / h_unprojected_begin.w;
let unprojected_end = h_unprojected_end.xyz() / h_unprojected_end.w;
(
unprojected_begin,
(unprojected_end - unprojected_begin).normalize(),
)
}
}