diff options
| -rw-r--r-- | src/camera.rs | 15 | ||||
| -rw-r--r-- | src/input.rs | 159 | ||||
| -rw-r--r-- | src/main.rs | 187 | ||||
| -rw-r--r-- | src/renderer/mod.rs | 12 | ||||
| -rw-r--r-- | src/renderer/ui.rs | 81 | ||||
| -rw-r--r-- | src/sim/entity/mod.rs | 22 | ||||
| -rw-r--r-- | src/sim/sim_manager/mod.rs | 19 | ||||
| -rw-r--r-- | src/sim/sim_manager/utils.rs | 6 |
8 files changed, 275 insertions, 226 deletions
diff --git a/src/camera.rs b/src/camera.rs index 13c5ec9..0fe9f22 100644 --- a/src/camera.rs +++ b/src/camera.rs @@ -1,4 +1,7 @@ -use crate::{Input, config::CAMERA_MOVEMENT_SPEED}; +use crate::{ + config::CAMERA_MOVEMENT_SPEED, + input::{Input, InputManager}, +}; #[repr(C)] #[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)] @@ -28,18 +31,18 @@ impl Camera { (xl, xu, yl, yu) } - pub fn handle_camera_input(&mut self, input: &Input, delta_time: f32) { + pub fn handle_camera_input(&mut self, input_manager: &InputManager, delta_time: f32) { // wasd movement - let x: f32 = if input.is_left_pressed { + let x: f32 = if input_manager.held(Input::Left) { -1.0 - } else if input.is_right_pressed { + } else if input_manager.held(Input::Right) { 1.0 } else { 0.0 }; - let y: f32 = if input.is_down_pressed { + let y: f32 = if input_manager.held(Input::Down) { 1.0 - } else if input.is_up_pressed { + } else if input_manager.held(Input::Up) { -1.0 } else { 0.0 diff --git a/src/input.rs b/src/input.rs new file mode 100644 index 0000000..dd49cd0 --- /dev/null +++ b/src/input.rs @@ -0,0 +1,159 @@ +use glam::{IVec2, Vec2}; +use winit::{ + event::{KeyEvent, MouseButton, WindowEvent}, + keyboard::{KeyCode, PhysicalKey}, +}; + +use crate::{camera::Camera, sim::cell_manager::manager::CellManager}; + +#[derive(Clone, Copy, PartialEq, Eq, Debug)] +pub enum Input { + // movement + Up, + Left, + Down, + Right, + + // sim management + Pause, + Step, + ClearGrid, + ClearEntities, + ClearParticles, + + // placeholder actions + Action1, + Action2, + Action3, + Action4, + Action5, + Action6, +} + +const INPUT_VAR_LEN: usize = 17; + +const KEYMAP: [(KeyCode, Input); 15] = [ + (KeyCode::KeyW, Input::Up), + (KeyCode::KeyA, Input::Left), + (KeyCode::KeyS, Input::Down), + (KeyCode::KeyD, Input::Right), + (KeyCode::Space, Input::Pause), + (KeyCode::KeyX, Input::Step), + (KeyCode::KeyC, Input::ClearGrid), + (KeyCode::KeyV, Input::ClearEntities), + (KeyCode::KeyP, Input::ClearParticles), + (KeyCode::Digit1, Input::Action1), + (KeyCode::Digit2, Input::Action2), + (KeyCode::Digit3, Input::Action3), + (KeyCode::Digit4, Input::Action4), + (KeyCode::Digit5, Input::Action5), + (KeyCode::Digit6, Input::Action6), +]; + +pub struct InputManager { + pub screen_mouse_pos: Vec2, + pub world_mouse_pos: Vec2, + pub chunk_mouse_pos: IVec2, + pub local_mouse_pos: IVec2, + + pub lmb_pressed: bool, + pub lmb_held: bool, + pub rmb_pressed: bool, + pub rmb_held: bool, + pressed: [bool; INPUT_VAR_LEN], + held: [bool; INPUT_VAR_LEN], +} + +impl InputManager { + pub fn reset_for_frame(&mut self) { + self.pressed = [false; INPUT_VAR_LEN]; + self.lmb_pressed = false; + self.rmb_pressed = false; + } + + pub fn apply_event(&mut self, event: &WindowEvent, camera: &Camera) { + match event { + WindowEvent::KeyboardInput { + event: + KeyEvent { + physical_key: PhysicalKey::Code(code), + repeat: false, + state, + .. + }, + .. + } => { + if let Some(&(_, input)) = KEYMAP.iter().find(|m| m.0 == *code) { + if state.is_pressed() { + self.held[input as usize] = true; + self.pressed[input as usize] = true; + } else { + self.held[input as usize] = false; + } + } + } + WindowEvent::CursorMoved { position, .. } => { + let (wp_x, wp_y) = + camera.screen_position_to_world(position.x as f32, position.y as f32); + + let ((cx, cy), (lx, ly)) = + CellManager::split_game_position(wp_x.round() as i32, wp_y.round() as i32); + + self.screen_mouse_pos = Vec2::new(position.x as f32, position.y as f32); + self.world_mouse_pos = Vec2::new(wp_x, wp_y); + self.chunk_mouse_pos = IVec2::new(cx, cy); + self.local_mouse_pos = IVec2::new(lx as i32, ly as i32); + } + WindowEvent::MouseInput { state, button, .. } => { + if *button == MouseButton::Left { + if state.is_pressed() { + self.lmb_pressed = true; + self.lmb_held = true; + } else { + self.lmb_held = false; + } + } else if *button == MouseButton::Right { + if state.is_pressed() { + self.rmb_pressed = true; + self.rmb_held = true; + } else { + self.rmb_held = false; + } + } + } + _ => {} + } + } + + pub fn pressed(&self, input: Input) -> bool { + if input as usize >= INPUT_VAR_LEN { + false + } else { + self.pressed[input as usize] + } + } + + pub fn held(&self, input: Input) -> bool { + if input as usize >= INPUT_VAR_LEN { + false + } else { + self.held[input as usize] + } + } + + pub fn new() -> Self { + InputManager { + screen_mouse_pos: Vec2::ZERO, + world_mouse_pos: Vec2::ZERO, + chunk_mouse_pos: IVec2::ZERO, + local_mouse_pos: IVec2::ZERO, + + lmb_pressed: false, + lmb_held: false, + rmb_pressed: false, + rmb_held: false, + pressed: [false; INPUT_VAR_LEN], + held: [false; INPUT_VAR_LEN], + } + } +} diff --git a/src/main.rs b/src/main.rs index 0daef91..704a276 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,7 @@ mod camera; mod config; mod content; +mod input; mod renderer; mod sim; @@ -10,12 +11,8 @@ use rand::random_range; use std::{collections::VecDeque, sync::Arc, time::Instant}; use winit::{ application::ApplicationHandler, - event::{ - ElementState, KeyEvent, MouseButton, - WindowEvent::{self}, - }, + event::WindowEvent::{self}, event_loop::{ActiveEventLoop, ControlFlow, EventLoop}, - keyboard::{KeyCode, PhysicalKey}, window::Window, }; @@ -26,12 +23,14 @@ use crate::{ entities::{entity_cube::entity_cube_def, entity_grenade::entity_grenade_def}, materials::MaterialId, }, + input::{ + Input::{self}, + InputManager, + }, renderer::RendererState, sim::{ cell::Cell, - cell_manager::manager::CellManager, - entity::EntityId, - lib::force::{apply_bullet, apply_explosion}, + lib::force::apply_bullet, rb_manager::DebugRenderMode, sim_manager::{SimCtx, SimManager}, }, @@ -50,26 +49,6 @@ struct Config { debug_render_mode: DebugRenderMode, } -struct Input { - last_mouse_pos_on_screen: Option<(f32, f32)>, - last_mouse_world_pos: Option<(f32, f32)>, - last_mouse_chunk_pos: Option<(i32, i32)>, - last_mouse_local_pos: Option<(u8, u8)>, - is_lmb_pressed: bool, - is_rmb_pressed: bool, - trigger_test_1: bool, - trigger_test_2: bool, - trigger_test_3: bool, - trigger_test_4: bool, - trigger_test_5: bool, - - // keybindings - is_up_pressed: bool, - is_left_pressed: bool, - is_down_pressed: bool, - is_right_pressed: bool, -} - struct Diagnostics { frame_times: VecDeque<f32>, fps: f32, @@ -84,7 +63,7 @@ struct App { bullet_origin: Option<Vec2>, // game - input: Input, + input_manager: InputManager, camera: Option<Camera>, sim_manager: Option<SimManager>, @@ -102,87 +81,64 @@ impl App { fn update(&mut self, delta_time: f32) { // apply inputs if let Some(camera) = &mut self.camera { - camera.handle_camera_input(&self.input, delta_time) + camera.handle_camera_input(&self.input_manager, delta_time) } if let Some(sim) = &mut self.sim_manager { // --TEST SPAWNING-- - if self.input.trigger_test_1 - && let Some(lm) = self.input.last_mouse_world_pos - { - self.input.trigger_test_1 = false; + if self.input_manager.pressed(Input::Action1) { sim.create_entity(entity_cube_def( - Vec2::new(lm.0, lm.1), + self.input_manager.world_mouse_pos, self.config.dropper_material, )); } - if self.input.trigger_test_2 - && let Some(lm) = self.input.last_mouse_world_pos - { - self.input.trigger_test_2 = false; - sim.create_entity(entity_grenade_def(Vec2::new(lm.0, lm.1), 3.0)); + if self.input_manager.pressed(Input::Action2) { + sim.create_entity(entity_grenade_def(self.input_manager.world_mouse_pos, 3.0)); } - if self.input.trigger_test_3 - && let Some(lm) = self.input.last_mouse_world_pos - { - self.input.trigger_test_3 = false; + if self.input_manager.pressed(Input::Action3) { if let Some(origin) = self.bullet_origin { apply_bullet( &mut SimCtx { + input_manager: &self.input_manager, cell_manager: &mut sim.cell_manager, particle_manager: &mut sim.particle_manager, rb_manager: &mut sim.rb_manager, }, origin, - Vec2::new(lm.0, lm.1), + self.input_manager.world_mouse_pos, 800, ); self.bullet_origin = None; } else { - self.bullet_origin = Some(Vec2::new(lm.0, lm.1)); + self.bullet_origin = Some(self.input_manager.world_mouse_pos); } } - if self.input.trigger_test_4 - && let Some(lm) = self.input.last_mouse_world_pos - { - let mouse = Vec2::new(lm.0, lm.1); - self.input.trigger_test_4 = false; - apply_explosion( - &mut SimCtx { - cell_manager: &mut sim.cell_manager, - particle_manager: &mut sim.particle_manager, - rb_manager: &mut sim.rb_manager, - }, - mouse, - 30, - Vec2::new(0.0, -0.6), - 300.0, - ); - } - // --TEST DRAWING-- - if (self.input.is_lmb_pressed || self.input.is_rmb_pressed) - && let Some(lm) = self.input.last_mouse_world_pos - { + if self.input_manager.lmb_held || self.input_manager.rmb_held { // start with the bounding box of the drawing brush circle + some margin // clamp the bounding box to the board sie - let bb_xl = (lm.0 - self.config.brush_radius).round() as i32; - let bb_xu = (lm.0 + self.config.brush_radius).round() as i32; - let bb_yl = (lm.1 - self.config.brush_radius).round() as i32; - let bb_yu = (lm.1 + self.config.brush_radius).round() as i32; + let bb_xl = (self.input_manager.world_mouse_pos.x - self.config.brush_radius) + .round() as i32; + let bb_xu = (self.input_manager.world_mouse_pos.x + self.config.brush_radius) + .round() as i32; + let bb_yl = (self.input_manager.world_mouse_pos.y - self.config.brush_radius) + .round() as i32; + let bb_yu = (self.input_manager.world_mouse_pos.y + self.config.brush_radius) + .round() as i32; // for each point, check if the distance is less than the brush size and write the pixel for x in bb_xl..bb_xu { for y in bb_yl..bb_yu { let r = random_range(0.0..1.0); - if ((x - lm.0.round() as i32).pow(2) + (y - lm.1.round() as i32).pow(2)) + if ((x - self.input_manager.world_mouse_pos.x.round() as i32).pow(2) + + (y - self.input_manager.world_mouse_pos.y.round() as i32).pow(2)) < (self.config.brush_radius as i32).pow(2) && r > 0.9 { - let cell = if self.input.is_lmb_pressed { + let cell = if self.input_manager.lmb_held { let mut cell = Cell::from_material(self.config.brush_material); // ensure we simulate on the first tick cell.match_parity(sim.cell_manager.seqno); @@ -198,7 +154,8 @@ impl App { } } - sim.update(&self.config, delta_time); + sim.update(&self.config, &self.input_manager, delta_time); + self.input_manager.reset_for_frame(); } } } @@ -211,24 +168,7 @@ impl Default for App { bullet_origin: None, - input: Input { - last_mouse_pos_on_screen: None, - last_mouse_world_pos: None, - last_mouse_chunk_pos: None, - last_mouse_local_pos: None, - - trigger_test_1: false, - trigger_test_2: false, - trigger_test_3: false, - trigger_test_4: false, - trigger_test_5: false, - is_lmb_pressed: false, - is_rmb_pressed: false, - is_up_pressed: false, - is_left_pressed: false, - is_down_pressed: false, - is_right_pressed: false, - }, + input_manager: InputManager::new(), camera: None, @@ -290,64 +230,11 @@ impl ApplicationHandler for App { } } - match event { - WindowEvent::KeyboardInput { - event: - KeyEvent { - physical_key: PhysicalKey::Code(code), - state, - repeat, - .. - }, - .. - } => { - if let Some(sim) = &mut self.sim_manager { - let pressed = state.is_pressed(); - match code { - KeyCode::KeyW => self.input.is_up_pressed = pressed, - KeyCode::KeyA => self.input.is_left_pressed = pressed, - KeyCode::KeyS => self.input.is_down_pressed = pressed, - KeyCode::KeyD => self.input.is_right_pressed = pressed, - KeyCode::KeyC => sim.cell_manager = CellManager::from_default_size(), - KeyCode::KeyP => sim.particle_manager.particles = Vec::new(), - KeyCode::KeyV => { - let ids: Vec<EntityId> = sim.entities.keys().cloned().collect(); - for id in ids { - sim.destroy_entity(id); - } - } - KeyCode::Space if pressed => sim.paused = !sim.paused, - KeyCode::KeyX if pressed => sim.ignore_pause_next_tick = true, - KeyCode::Digit1 if pressed && !repeat => self.input.trigger_test_1 = true, - KeyCode::Digit2 if pressed && !repeat => self.input.trigger_test_2 = true, - KeyCode::Digit3 if pressed && !repeat => self.input.trigger_test_3 = true, - KeyCode::Digit4 if pressed && !repeat => self.input.trigger_test_4 = true, - KeyCode::Digit5 if pressed && !repeat => self.input.trigger_test_5 = true, - _ => {} - } - } - } - WindowEvent::CursorMoved { position, .. } => { - self.input.last_mouse_pos_on_screen = Some((position.x as f32, position.y as f32)); - - if let Some(camera) = &mut self.camera { - let world_pos = - camera.screen_position_to_world(position.x as f32, position.y as f32); + if let Some(camera) = &self.camera { + self.input_manager.apply_event(&event, &camera); + } - self.input.last_mouse_world_pos = Some(world_pos); - let ((cx, cy), (lx, ly)) = - CellManager::split_game_position(world_pos.0 as i32, world_pos.1 as i32); - self.input.last_mouse_chunk_pos = Some((cx, cy)); - self.input.last_mouse_local_pos = Some((lx, ly)); - } - } - WindowEvent::MouseInput { state, button, .. } => { - if button == MouseButton::Left { - self.input.is_lmb_pressed = state == ElementState::Pressed - } else if button == MouseButton::Right { - self.input.is_rmb_pressed = state == ElementState::Pressed - } - } + match event { WindowEvent::Resized(size) => { if let Some(renderer_state) = &mut self.renderer_state && let Some(camera) = &mut self.camera @@ -391,7 +278,7 @@ impl ApplicationHandler for App { camera, &mut self.config, &self.diagnostics, - &self.input, + &self.input_manager, ); } } diff --git a/src/renderer/mod.rs b/src/renderer/mod.rs index 54a6667..b37dc09 100644 --- a/src/renderer/mod.rs +++ b/src/renderer/mod.rs @@ -6,7 +6,7 @@ use fxhash::FxHashMap; use winit::window::Window; use crate::{ - Config, Diagnostics, Input, + Config, Diagnostics, InputManager, camera::Camera, config::{CELLS_IN_CHUNK, CHUNK_SIZE}, content::materials::MaterialId, @@ -578,7 +578,7 @@ impl RendererState { camera: &mut Camera, config: &mut Config, diagnostics: &Diagnostics, - input: &Input, + input_manager: &InputManager, ) { puffin::profile_function!(); @@ -626,7 +626,7 @@ impl RendererState { .resizable(false) // TODO collapse button .show_collapsible(ui, &mut true, |panel_ui| { - draw_egui(panel_ui, config, camera, diagnostics, input, sim) + draw_egui(panel_ui, config, camera, diagnostics, input_manager, sim) }); }); @@ -747,11 +747,7 @@ impl RendererState { for (id, slot) in &self.renderer_rb_entities { if let Some(entity) = sim.entities.get(id) && let Some(cells) = &entity.data.cells - && let Some((pos, (cos, sin))) = entity.data.transform(&SimCtx { - cell_manager: &mut sim.cell_manager, - particle_manager: &mut sim.particle_manager, - rb_manager: &mut sim.rb_manager, - }) + && let Some((pos, (cos, sin))) = entity.data._transform(&sim.rb_manager) { instances.push(RendererInstance { centre: pos.to_array(), diff --git a/src/renderer/ui.rs b/src/renderer/ui.rs index a7395a0..46fb853 100644 --- a/src/renderer/ui.rs +++ b/src/renderer/ui.rs @@ -1,8 +1,9 @@ use egui::{Color32, Stroke, Ui, epaint::CircleShape}; use crate::{ - Camera, Config, Diagnostics, Input, + Camera, Config, Diagnostics, content::materials::MaterialId, + input::InputManager, sim::{rb_manager::DebugRenderMode, sim_manager::SimManager}, }; @@ -20,7 +21,7 @@ pub fn draw_egui<'a>( config: &mut Config, camera: &mut Camera, diagnostics: &Diagnostics, - input: &Input, + input_manager: &InputManager, sim: &SimManager, ) { puffin::profile_function!(); @@ -104,44 +105,50 @@ pub fn draw_egui<'a>( ui.add(egui::Slider::new(&mut camera.zoom, 0.0..=10.0).text("Zoom")); ui.heading("Input"); - input - .last_mouse_world_pos - .map(|p| ui.label(format!("Mouse (world): x,y=({x}, {y})", x = p.0, y = p.1,))); + ui.label(format!( + "Mouse (world): x,y=({x}, {y})", + x = input_manager.world_mouse_pos.x, + y = input_manager.world_mouse_pos.y + )); - if let Some(p) = input.last_mouse_chunk_pos { - ui.label(format!("Mouse (chunk): x,y=({x}, {y})", x = p.0, y = p.1,)); - if let Some(&chunk) = sim.cell_manager.chunk_position_to_chunk_idx.get(&p) { - ui.label(format!( - "Sleeping={}", - sim.cell_manager.chunks[chunk].sleeping - )); - } + ui.label(format!( + "Mouse (chunk): x,y=({x}, {y})", + x = input_manager.chunk_mouse_pos.x, + y = input_manager.chunk_mouse_pos.y + )); + + if let Some(&chunk) = sim.cell_manager.chunk_position_to_chunk_idx.get(&( + input_manager.chunk_mouse_pos.x, + input_manager.chunk_mouse_pos.y, + )) { + ui.label(format!( + "Sleeping={}", + sim.cell_manager.chunks[chunk].sleeping + )); } - input - .last_mouse_local_pos - .map(|p| ui.label(format!("Mouse (local): x,y=({x}, {y})", x = p.0, y = p.1,))); + ui.label(format!( + "Mouse (local): x,y=({x}, {y})", + x = input_manager.local_mouse_pos.x, + y = input_manager.local_mouse_pos.y + )); - if let Some((x, y)) = input.last_mouse_world_pos { - ui.heading("Entity"); - if let Some(cell) = sim - .cell_manager - .get_cell_from_game_position(x.round() as i32, y.round() as i32) - { - let material = cell.material.def(); - let cell_label = ui.label( - egui::RichText::new(format!("Cell: {}", material.name)).color(Color32::LIGHT_BLUE), - ); - ui.painter().add(egui::Shape::Circle(CircleShape { - center: cell_label.rect.right_center() + egui::vec2(10.0, 0.0), - radius: cell_label.rect.height() / 2.5, - stroke: Stroke::NONE, - fill: Color32::from_rgb(material.color.0, material.color.1, material.color.2), - })); - ui.label( - egui::RichText::new(format!("Flags: {:b}", cell.flags)).color(Color32::YELLOW), - ); - ui.label(egui::RichText::new(format!("Data: {:b}", cell.data)).color(Color32::RED)); - } + ui.heading("Entity"); + if let Some(cell) = sim.cell_manager.get_cell_from_game_position( + input_manager.world_mouse_pos.x.round() as i32, + input_manager.world_mouse_pos.y.round() as i32, + ) { + let material = cell.material.def(); + let cell_label = ui.label( + egui::RichText::new(format!("Cell: {}", material.name)).color(Color32::LIGHT_BLUE), + ); + ui.painter().add(egui::Shape::Circle(CircleShape { + center: cell_label.rect.right_center() + egui::vec2(10.0, 0.0), + radius: cell_label.rect.height() / 2.5, + stroke: Stroke::NONE, + fill: Color32::from_rgb(material.color.0, material.color.1, material.color.2), + })); + ui.label(egui::RichText::new(format!("Flags: {:b}", cell.flags)).color(Color32::YELLOW)); + ui.label(egui::RichText::new(format!("Data: {:b}", cell.data)).color(Color32::RED)); } } diff --git a/src/sim/entity/mod.rs b/src/sim/entity/mod.rs index 044d07c..2a046c5 100644 --- a/src/sim/entity/mod.rs +++ b/src/sim/entity/mod.rs @@ -126,21 +126,19 @@ impl<'a> EntityUpdateCtx<'a> { } impl EntityData { - pub fn transform(&self, ctx: &SimCtx) -> Option<(Vec2, (f32, f32))> { + pub fn _transform(&self, rb_manager: &RbManager) -> Option<(Vec2, (f32, f32))> { self.rb_h.and_then(|rb_h| { - ctx.rb_manager - .physics_manager - .world - .bodies - .get(rb_h) - .map(|rb| { - ( - rb.translation() * CELLS_TO_METRES, - (rb.rotation().cos(), rb.rotation().sin()), - ) - }) + rb_manager.physics_manager.world.bodies.get(rb_h).map(|rb| { + ( + rb.translation() * CELLS_TO_METRES, + (rb.rotation().cos(), rb.rotation().sin()), + ) + }) }) } + pub fn transform(&self, ctx: &SimCtx) -> Option<(Vec2, (f32, f32))> { + self._transform(ctx.rb_manager) + } } pub struct Entity { diff --git a/src/sim/sim_manager/mod.rs b/src/sim/sim_manager/mod.rs index 74c21fa..be75eeb 100644 --- a/src/sim/sim_manager/mod.rs +++ b/src/sim/sim_manager/mod.rs @@ -3,7 +3,7 @@ use std::time::Instant; use fxhash::FxHashMap; use crate::{ - Config, + Config, InputManager, config::{PHYSICS_DELTA_TIME, PHYSICS_FPS, SIM_FPS}, sim::{ cell_manager::manager::CellManager, @@ -37,6 +37,7 @@ pub struct SimManager { } pub struct SimCtx<'a> { + pub input_manager: &'a InputManager, pub cell_manager: &'a mut CellManager, pub rb_manager: &'a mut RbManager, pub particle_manager: &'a mut ParticleManager, @@ -91,7 +92,7 @@ impl SimManager { } } - fn cell_update(&mut self, config: &Config, delta_time: f32) { + fn cell_update(&mut self, config: &Config, input_manager: &InputManager, delta_time: f32) { // before we tick, write all the entities into the sim world let cells_written_by_entity = write_entities_to_world(self); @@ -103,6 +104,7 @@ impl SimManager { for id in entity_ids { let entity = self.entities.get_mut(&id); let mut ctx = SimCtx { + input_manager, cell_manager: &mut self.cell_manager, rb_manager: &mut self.rb_manager, particle_manager: &mut self.particle_manager, @@ -121,11 +123,12 @@ impl SimManager { read_back_entities_from_world(self, cells_written_by_entity); } - fn physics_update(&mut self, delta_time: f32) { + fn physics_update(&mut self, input_manager: &InputManager, delta_time: f32) { let entity_ids: Vec<EntityId> = self.entities.keys().cloned().collect(); for id in entity_ids { let entity = self.entities.get_mut(&id); let mut ctx = SimCtx { + input_manager, cell_manager: &mut self.cell_manager, rb_manager: &mut self.rb_manager, particle_manager: &mut self.particle_manager, @@ -162,21 +165,21 @@ impl SimManager { .tick(&mut self.cell_manager, delta_time); } - pub fn update(&mut self, config: &Config, delta_time: f32) { + pub fn update(&mut self, config: &Config, input_manager: &InputManager, delta_time: f32) { let now = Instant::now(); let secs_since_last_cell_update = (now - self.last_cell_update).as_secs_f32(); let expected_secs_since_last_cell_update = 1.0 / SIM_FPS as f32; self.last_cell_update = now; if self.paused && self.ignore_pause_next_tick { - self.cell_update(config, delta_time); + self.cell_update(config, input_manager, delta_time); } else if !self.paused { self.cell_updates_due += secs_since_last_cell_update / expected_secs_since_last_cell_update; let mut cell_updates_done = 0; // don't ever update more than 3 times per frame, or else we can get a pseudo deadlock while self.cell_updates_due >= 1.0 && cell_updates_done < 3 { - self.cell_update(config, delta_time); + self.cell_update(config, input_manager, delta_time); self.cell_updates_due -= 1.0; cell_updates_done += 1; } @@ -189,14 +192,14 @@ impl SimManager { self.last_physics_update = now; if self.paused && self.ignore_pause_next_tick { - self.physics_update(PHYSICS_DELTA_TIME); + self.physics_update(input_manager, PHYSICS_DELTA_TIME); } else if !self.paused { self.physics_updates_due += secs_since_last_physics_update / expected_secs_since_last_physics_update; let mut updates_done = 0; // don't ever update more than 3 times per frame, or else we can get a pseudo deadlock while self.physics_updates_due >= 1.0 && updates_done < 3 { - self.physics_update(PHYSICS_DELTA_TIME); + self.physics_update(input_manager, PHYSICS_DELTA_TIME); self.physics_updates_due -= 1.0; updates_done += 1; } diff --git a/src/sim/sim_manager/utils.rs b/src/sim/sim_manager/utils.rs index 413e709..506844c 100644 --- a/src/sim/sim_manager/utils.rs +++ b/src/sim/sim_manager/utils.rs @@ -9,11 +9,7 @@ fn write_entity_to_world(sim: &mut SimManager, entity_id: EntityId) -> Vec<(u8, let mut cells_written: Vec<(u8, u8, i32, i32)> = Vec::new(); if let Some(entity) = sim.entities.get(&entity_id) && let Some(cells) = &entity.data.cells - && let Some((pos, (cos, sin))) = entity.data.transform(&super::SimCtx { - cell_manager: &mut sim.cell_manager, - rb_manager: &mut sim.rb_manager, - particle_manager: &mut sim.particle_manager, - }) + && let Some((pos, (cos, sin))) = entity.data._transform(&sim.rb_manager) { let (half_size_x, half_size_y) = (cells.size.x as f32 / 2.0, cells.size.y as f32 / 2.0); // half-extent of the rotated grid's axis-aligned bounding box, plus a cell of margin |
