From fe9099aac98636030c956cdf4de11cb1b0acbff4 Mon Sep 17 00:00:00 2001 From: Michael Huebner Date: Mon, 10 Mar 2025 13:40:33 +0100 Subject: [PATCH] Find correct image rotations --- .../src/scene/general/free_camera_control.rs | 108 +++++++++++++++--- engine/src/scene/general/prelude.rs | 10 +- examples/simple_window/src/main.rs | 57 +++++---- skybox/src/lib.rs | 15 ++- 4 files changed, 131 insertions(+), 59 deletions(-) diff --git a/engine/src/scene/general/free_camera_control.rs b/engine/src/scene/general/free_camera_control.rs index ef2800e..ceb80ac 100644 --- a/engine/src/scene/general/free_camera_control.rs +++ b/engine/src/scene/general/free_camera_control.rs @@ -1,36 +1,110 @@ -use crate::prelude::*; +use crate::prelude::{cgmath::*, *}; use anyhow::Result; +use context::prelude::cgmath::num_traits::clamp; -pub struct FreeCameraControl {} +struct HoldInfo { + roll: Deg, + pitch: Deg, + yaw: Deg, -impl Default for FreeCameraControl { - fn default() -> Self { - Self {} + 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, + pitch: Deg, + yaw: Deg, + + mouse_position: (u32, u32), + + hold_info: Option, +} + impl FreeCameraControl { - pub fn roll(&mut self, view: &View) -> Result<()> { + const SCALE: f32 = 0.3; + const DEFAULT_DIR: Vector3 = vec3(0.0, 1.0, 0.0); + + pub fn new(view: &mut View) -> Result { + 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 pitch(&mut self, view: &View) -> Result<()> { - Ok(()) + pub fn forward_back(&mut self, _view: &mut View) -> Result<()> { + todo!() } - pub fn yaw(&mut self, view: &View) -> Result<()> { - Ok(()) + pub fn left_right(&mut self, _view: &mut View) -> Result<()> { + todo!() } - pub fn forward_back(&mut self, view: &View) -> Result<()> { - Ok(()) + pub fn up_down(&mut self, _view: &mut View) -> Result<()> { + todo!() } - pub fn left_right(&mut self, view: &View) -> Result<()> { - Ok(()) - } + 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, + ); - pub fn up_down(&mut self, view: &View) -> Result<()> { - Ok(()) + view.update_buffer() } } diff --git a/engine/src/scene/general/prelude.rs b/engine/src/scene/general/prelude.rs index 04e52e4..375cf62 100644 --- a/engine/src/scene/general/prelude.rs +++ b/engine/src/scene/general/prelude.rs @@ -1,11 +1,7 @@ pub use super::camera::*; - +pub use super::free_camera_control::*; pub use super::light::*; - -pub use super::validcommandbuffer::*; - -pub use super::view::*; - pub use super::top_down_camera_control::*; - +pub use super::validcommandbuffer::*; +pub use super::view::*; pub use super::view_frustum::*; diff --git a/examples/simple_window/src/main.rs b/examples/simple_window/src/main.rs index e66ee0e..f80d278 100644 --- a/examples/simple_window/src/main.rs +++ b/examples/simple_window/src/main.rs @@ -1,12 +1,9 @@ -use std::{path::Path, time::Duration}; +use std::path::Path; use anyhow::Result; use ecs::*; -use engine::prelude::{ - cgmath::{Deg, Matrix3, Vector3, vec3}, - *, -}; +use engine::prelude::*; use skybox::SkyBox; fn main() -> Result<()> { @@ -33,12 +30,8 @@ fn main() -> Result<()> { )?; let view = world_builder.resources.get_mut::().view_mut(); - let camera = view.camera_mut(); - - camera.look_at(false); - camera.set_center(vec3(0.0, 0.0, 0.0)); - camera.set_eye_dir(Vector3::unit_y()); - view.update_buffer()?; + let camera_control = FreeCameraControl::new(view)?; + world_builder.resources.insert(camera_control); world_builder.build().run() } @@ -56,7 +49,7 @@ impl GameState { let me = world.resources.get_mut_unchecked::(); match me { - GameState::Startup => *me = GameState::Game(Game { start: world.now() }), + GameState::Startup => *me = GameState::Game(Game), GameState::Game(game) => game.update(world)?, } @@ -75,28 +68,34 @@ impl EventConsumer for GameState { } } -struct Game { - start: Duration, -} +struct Game; impl Game { - fn update(&mut self, world: &mut World) -> Result<()> { - let now = world.now(); - let view = world.resources.get_mut::().view_mut(); - let camera = view.camera_mut(); - - let diff = now.as_secs_f32() - self.start.as_secs_f32(); - camera.set_eye_dir( - Matrix3::from_angle_z(Deg(diff * 36.0)) - * Matrix3::from_angle_x(Deg(diff.sin() * 30.0)) - * Vector3::unit_y(), - ); - view.update_buffer()?; - + fn update(&mut self, _world: &mut World) -> Result<()> { Ok(()) } - fn event(&mut self, _world: &mut World, _event: EngineEvent<'_>) -> Result<()> { + fn event(&mut self, world: &mut World, event: EngineEvent<'_>) -> Result<()> { + match event { + EngineEvent::MouseButtonDown(MouseButton::Left) => { + let camera_control = world.resources.get_mut::(); + camera_control.mouse_down(); + } + EngineEvent::MouseButtonUp(MouseButton::Left) => { + let camera_control = world.resources.get_mut::(); + camera_control.mouse_release(); + } + EngineEvent::MouseMotion(x, y) => { + let mut resources = world.resources.multi_mut(); + let scene = resources.get::(); + let camera_control = resources.get::(); + + camera_control.mouse_move(x, y, scene.view_mut())?; + } + + _ => (), + } + Ok(()) } } diff --git a/skybox/src/lib.rs b/skybox/src/lib.rs index 8971d49..1501c15 100644 --- a/skybox/src/lib.rs +++ b/skybox/src/lib.rs @@ -59,14 +59,17 @@ impl SkyBox { let images = images.into(); let cube_map = Image::cube_map([ ( - images.front.try_into()?, - vec![ImageModifier::Rotate90, ImageModifier::FlipH], + images.right.try_into()?, + vec![ImageModifier::FlipV, ImageModifier::Rotate90], ), - (images.left.try_into()?, vec![ImageModifier::Rotate90]), - (images.right.try_into()?, vec![ImageModifier::Rotate270]), + ( + images.left.try_into()?, + vec![ImageModifier::Rotate90, ImageModifier::FlipV], + ), + (images.front.try_into()?, vec![ImageModifier::FlipV]), (images.back.try_into()?, vec![ImageModifier::FlipH]), - (images.top.try_into()?, vec![ImageModifier::None]), - (images.bottom.try_into()?, vec![ImageModifier::None]), + (images.top.try_into()?, vec![ImageModifier::FlipV]), + (images.bottom.try_into()?, vec![ImageModifier::FlipH]), ])? .format(VK_FORMAT_R8G8B8A8_UNORM) .max_mip_map_levels()