From 07056fc0ce7265729179dd98fed45f8a5595dadd Mon Sep 17 00:00:00 2001 From: Florian RICHER Date: Thu, 12 Jun 2025 19:36:49 +0200 Subject: [PATCH] Move input_manager and camera as resource --- src/core/app/context.rs | 12 --- src/core/input/mod.rs | 9 ++- src/core/render/primitives/camera.rs | 6 +- src/core/scene/manager.rs | 2 + src/game/scenes/main_scene.rs | 111 ++++++++++++++------------- 5 files changed, 72 insertions(+), 68 deletions(-) diff --git a/src/core/app/context.rs b/src/core/app/context.rs index c247443..ca37b65 100644 --- a/src/core/app/context.rs +++ b/src/core/app/context.rs @@ -141,18 +141,6 @@ impl WindowContext { f(&mut gui) } - /// Méthode utilitaire pour accéder à l'input manager de manière thread-safe - pub fn with_input_manager(&self, f: F) -> T - where - F: FnOnce(&InputManager) -> T, - { - let input_manager = self - .input_manager - .read() - .expect("Failed to lock input_manager"); - f(&input_manager) - } - /// Méthode utilitaire pour accéder au timer de manière thread-safe pub fn with_timer(&self, f: F) -> T where diff --git a/src/core/input/mod.rs b/src/core/input/mod.rs index f4a1642..aa3c85f 100644 --- a/src/core/input/mod.rs +++ b/src/core/input/mod.rs @@ -1,5 +1,9 @@ -use std::collections::HashMap; +use std::{ + collections::HashMap, + sync::{Arc, RwLock}, +}; +use bevy_ecs::resource::Resource; use cache::{CachedElementState, CachedMovement}; use virtual_input::VirtualInput; use winit::{ @@ -22,6 +26,9 @@ pub struct InputManager { virtual_input: VirtualInput, } +#[derive(Resource)] +pub struct InputManagerResource(pub Arc>); + impl std::fmt::Debug for InputManager { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("InputManager") diff --git a/src/core/render/primitives/camera.rs b/src/core/render/primitives/camera.rs index 1841079..f25c41c 100644 --- a/src/core/render/primitives/camera.rs +++ b/src/core/render/primitives/camera.rs @@ -1,5 +1,6 @@ use std::{f32::consts::FRAC_PI_2, sync::Arc}; +use bevy_ecs::resource::Resource; use glam::{Mat4, Vec3, Vec4}; use vulkano::{ Validated, @@ -19,7 +20,7 @@ const OPENGL_TO_VULKAN_Y_AXIS_FLIP: Mat4 = Mat4 { w_axis: Vec4::new(0.0, 0.0, 0.0, 1.0), }; -#[derive(Default)] +#[derive(Resource)] pub struct Camera3D { projection: Mat4, @@ -50,7 +51,6 @@ impl Camera3D { timer: &Timer, movement_speed: f32, camera_sensitivity: f32, - window_aspect_ratio: f32, ) { // Process camera rotation let camera_delta = camera_sensitivity * timer.delta_time(); @@ -79,7 +79,9 @@ impl Camera3D { let tz = input_manager.get_virtual_input_state("move_forward") * movement_delta; self.position += tz * forward; + } + pub fn update_projection(&mut self, window_aspect_ratio: f32) { if self.aspect_ratio != window_aspect_ratio { self.aspect_ratio = window_aspect_ratio; self.projection = diff --git a/src/core/scene/manager.rs b/src/core/scene/manager.rs index 5f63f4e..6d59be3 100644 --- a/src/core/scene/manager.rs +++ b/src/core/scene/manager.rs @@ -2,6 +2,7 @@ use std::error::Error; use crate::core::app::DEPTH_IMAGE_ID; use crate::core::app::context::WindowContext; +use crate::core::input::InputManagerResource; use crate::core::render::primitives::vulkan_resource::{ VulkanCommandBufferAllocator, VulkanComputeQueue, VulkanDescriptorSetAllocator, VulkanDevice, VulkanGraphicsQueue, VulkanInstance, VulkanMemoryAllocator, VulkanTransferQueue, @@ -76,6 +77,7 @@ impl SceneManager { )); world.insert_resource(texture_loader); world.insert_resource(pipeline_loader); + world.insert_resource(InputManagerResource(window_context.input_manager.clone())); world } diff --git a/src/game/scenes/main_scene.rs b/src/game/scenes/main_scene.rs index 6e561bb..45e7dfa 100644 --- a/src/game/scenes/main_scene.rs +++ b/src/game/scenes/main_scene.rs @@ -5,6 +5,7 @@ use super::settings_scene::SettingsScene; use crate::core::app::DEPTH_IMAGE_ID; use crate::core::app::context::WindowContext; use crate::core::app::user_event::UserEvent; +use crate::core::input::InputManagerResource; use crate::core::render::primitives::camera::Camera3D; use crate::core::render::primitives::transform::Transform; use crate::core::render::primitives::velocity::Velocity; @@ -44,11 +45,12 @@ pub struct Cube; pub struct MainSceneState { square: SquareMesh, obj: ObjMesh, - camera: Camera3D, - speed: f32, scheduler: Schedule, } +#[derive(Resource)] +pub struct CameraSpeed(f32); + #[derive(Default)] pub struct MainScene { state: Option, @@ -115,19 +117,19 @@ impl AsScene for MainScene { 1000.0, ) }); + world.insert_resource(CameraSpeed(50.0)); + world.insert_resource(camera); let mut scheduler = Schedule::default(); scheduler.add_systems(update_velocity_system); scheduler.add_systems(update_timer_system); - + scheduler.add_systems(update_camera_system); world.insert_resource(Timer::new()); Self::create_entities(world, 100, 10.0, 10.0); self.state = Some(MainSceneState { square, obj, - camera, - speed: 50.0, scheduler, }); @@ -141,50 +143,41 @@ impl AsScene for MainScene { ) -> Result<(), Box> { let state = self.state.as_mut().unwrap(); - window_context.with_input_manager(|input_manager| { - window_context.with_timer(|timer| { - state.camera.update( - input_manager, - timer, - state.speed, - 10.0, - window_context.get_aspect_ratio(), - ); - }); - }); + { + let mut camera = world.resource_mut::(); + camera.update_projection(window_context.get_aspect_ratio()); + } + + { + let input_manager = world.resource::().0.read().unwrap(); + + if input_manager.get_virtual_input_state("mouse_left") > 0.0 { + let _ = window_context + .event_loop_proxy + .send_event(UserEvent::CursorVisible(window_context.window_id, false)); + let _ = window_context + .event_loop_proxy + .send_event(UserEvent::CursorGrabMode( + window_context.window_id, + CursorGrabMode::Locked, + )); + } + + if input_manager.get_virtual_input_state("mouse_right") > 0.0 { + let _ = window_context + .event_loop_proxy + .send_event(UserEvent::CursorVisible(window_context.window_id, true)); + let _ = window_context + .event_loop_proxy + .send_event(UserEvent::CursorGrabMode( + window_context.window_id, + CursorGrabMode::None, + )); + } + } state.scheduler.run(world); - if window_context - .with_input_manager(|input_manager| input_manager.get_virtual_input_state("mouse_left")) - > 0.0 - { - let _ = window_context - .event_loop_proxy - .send_event(UserEvent::CursorVisible(window_context.window_id, false)); - let _ = window_context - .event_loop_proxy - .send_event(UserEvent::CursorGrabMode( - window_context.window_id, - CursorGrabMode::Locked, - )); - } - - if window_context.with_input_manager(|input_manager| { - input_manager.get_virtual_input_state("mouse_right") - }) > 0.0 - { - let _ = window_context - .event_loop_proxy - .send_event(UserEvent::CursorVisible(window_context.window_id, true)); - let _ = window_context - .event_loop_proxy - .send_event(UserEvent::CursorGrabMode( - window_context.window_id, - CursorGrabMode::None, - )); - } - Ok(()) } @@ -220,8 +213,8 @@ impl AsScene for MainScene { // Create camera uniform using the actual camera let camera_uniform = Arc::new( - state - .camera + world + .resource::() .create_buffer(VulkanMemoryAllocator::get_from_world(world))?, ); let square_transforms = world @@ -285,13 +278,15 @@ impl AsScene for MainScene { let swapchain_image_view = window_context.with_renderer(|renderer| renderer.swapchain_image_view().clone()); - let input_manager_status = - window_context.with_input_manager(|input_manager| format!("{:#?}", input_manager)); + let input_manager_status = { + let input_manager = world.resource::().0.read().unwrap(); + format!("{:#?}", input_manager) + }; let event_loop_proxy = window_context.event_loop_proxy.clone(); let delta_time = window_context.get_delta_time(); let window_id = window_context.window_id; let window_size = window_context.get_window_size(); - + let camera = world.resource::(); let render_future = window_context.with_gui_mut(|gui| { gui.immediate_ui(|gui| { let ctx = gui.context(); @@ -323,7 +318,7 @@ impl AsScene for MainScene { ui.separator(); ui.label("Position caméra:"); - let position = state.camera.get_position(); + let position = camera.get_position(); ui.label(format!(" X: {:.2}", position[0])); ui.label(format!(" Y: {:.2}", position[1])); ui.label(format!(" Z: {:.2}", position[2])); @@ -331,7 +326,7 @@ impl AsScene for MainScene { ui.separator(); ui.label("Rotation caméra:"); - let rotation = state.camera.get_rotation(); + let rotation = camera.get_rotation(); ui.label(format!(" Yaw: {:.2}°", rotation.y.to_degrees())); ui.label(format!(" Pitch: {:.2}°", rotation.x.to_degrees())); @@ -437,3 +432,13 @@ fn update_velocity_system(mut query: Query<(&mut Transform, &Velocity)>, time: R fn update_timer_system(mut timer: ResMut) { timer.update(); } + +fn update_camera_system( + mut camera: ResMut, + input_manager: Res, + timer: Res, + camera_speed: Res, +) { + let input_manager = input_manager.0.read().unwrap(); + camera.update(&input_manager, &timer, camera_speed.0, 10.0); +}