110 lines
2.6 KiB
Rust
110 lines
2.6 KiB
Rust
use crate::prelude::{cgmath::*, *};
|
|
use anyhow::Result;
|
|
use context::prelude::cgmath::num_traits::clamp;
|
|
|
|
struct HoldInfo {
|
|
roll: Deg<f32>,
|
|
pitch: Deg<f32>,
|
|
yaw: Deg<f32>,
|
|
|
|
mouse_position: (u32, u32),
|
|
}
|
|
|
|
impl<'a> From<&'a FreeCameraControl> for HoldInfo {
|
|
fn from(value: &'a FreeCameraControl) -> Self {
|
|
Self {
|
|
roll: value.roll,
|
|
pitch: value.pitch,
|
|
yaw: value.yaw,
|
|
|
|
mouse_position: value.mouse_position,
|
|
}
|
|
}
|
|
}
|
|
|
|
pub struct FreeCameraControl {
|
|
roll: Deg<f32>,
|
|
pitch: Deg<f32>,
|
|
yaw: Deg<f32>,
|
|
|
|
mouse_position: (u32, u32),
|
|
|
|
hold_info: Option<HoldInfo>,
|
|
}
|
|
|
|
impl FreeCameraControl {
|
|
const SCALE: f32 = 0.3;
|
|
const DEFAULT_DIR: Vector3<f32> = vec3(0.0, 1.0, 0.0);
|
|
|
|
pub fn new(view: &mut View) -> Result<Self> {
|
|
view.camera_mut().look_at(false);
|
|
view.camera_mut().set_eye_dir(Self::DEFAULT_DIR);
|
|
view.update_buffer()?;
|
|
|
|
Ok(Self {
|
|
roll: Deg(0.0),
|
|
pitch: Deg(0.0),
|
|
yaw: Deg(0.0),
|
|
|
|
mouse_position: (0, 0),
|
|
|
|
hold_info: None,
|
|
})
|
|
}
|
|
|
|
pub fn roll(&mut self, _view: &mut View) -> Result<()> {
|
|
todo!()
|
|
}
|
|
|
|
pub fn pitch(&mut self, _view: &mut View) -> Result<()> {
|
|
todo!()
|
|
}
|
|
|
|
pub fn yaw(&mut self, _view: &mut View) -> Result<()> {
|
|
todo!()
|
|
}
|
|
|
|
pub fn mouse_down(&mut self) {
|
|
self.hold_info = Some((&*self).into());
|
|
}
|
|
|
|
pub fn mouse_release(&mut self) {
|
|
self.hold_info = None;
|
|
}
|
|
|
|
pub fn mouse_move(&mut self, x: u32, y: u32, view: &mut View) -> Result<()> {
|
|
self.mouse_position = (x, y);
|
|
|
|
if let Some(hold_info) = &self.hold_info {
|
|
let x_diff = (hold_info.mouse_position.0 as i32 - x as i32) as f32 * Self::SCALE;
|
|
let y_diff = (hold_info.mouse_position.1 as i32 - y as i32) as f32 * Self::SCALE;
|
|
|
|
self.yaw = Deg((hold_info.yaw.0 + x_diff) % 360.0);
|
|
self.roll = Deg(clamp(hold_info.roll.0 + y_diff, -89.0, 89.0));
|
|
|
|
self.update_camera(view)?;
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
pub fn forward_back(&mut self, _view: &mut View) -> Result<()> {
|
|
todo!()
|
|
}
|
|
|
|
pub fn left_right(&mut self, _view: &mut View) -> Result<()> {
|
|
todo!()
|
|
}
|
|
|
|
pub fn up_down(&mut self, _view: &mut View) -> Result<()> {
|
|
todo!()
|
|
}
|
|
|
|
fn update_camera(&self, view: &mut View) -> Result<()> {
|
|
view.camera_mut().set_eye_dir(
|
|
Matrix3::from_angle_z(self.yaw) * Matrix3::from_angle_x(self.roll) * Self::DEFAULT_DIR,
|
|
);
|
|
|
|
view.update_buffer()
|
|
}
|
|
}
|