engine/engine/src/scene/general/free_camera_control.rs
2025-03-10 13:40:33 +01:00

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()
}
}