diff options
| author | Kai Stevenson <kai@kaistevenson.com> | 2026-08-23 02:48:43 -0700 |
|---|---|---|
| committer | Kai Stevenson <kai@kaistevenson.com> | 2026-08-23 02:48:43 -0700 |
| commit | 80824a8b69b70e6e40577e4f0236c28c4ad5c15b (patch) | |
| tree | bf3b72331c4ed9195bbe72d25d5e82c076d3220a /src/sim/sim_manager/mod.rs | |
| parent | d6664b9b5a9a3aab500b547e4d7448a8bc4ad416 (diff) | |
explosions affect rigidbodies, use "world" for rapier
Diffstat (limited to 'src/sim/sim_manager/mod.rs')
| -rw-r--r-- | src/sim/sim_manager/mod.rs | 153 |
1 files changed, 68 insertions, 85 deletions
diff --git a/src/sim/sim_manager/mod.rs b/src/sim/sim_manager/mod.rs index 1a16cfd..855b398 100644 --- a/src/sim/sim_manager/mod.rs +++ b/src/sim/sim_manager/mod.rs @@ -7,7 +7,7 @@ use crate::{ Config, config::{PHYSICS_DELTA_TIME, PHYSICS_FPS, SIM_FPS}, sim::{ - cell::cell::Cell, + cell::Cell, cell_manager::manager::CellManager, entity::{Entity, EntityDef}, particle_manager::ParticleManager, @@ -47,18 +47,14 @@ pub struct SimCtx<'a> { impl SimManager { pub fn create_entity(&mut self, def: EntityDef) -> u32 { let (rb_h, collider_h) = if let Some(rb) = def.rb { - let rb_h = self.rb_manager.physics_manager.rigid_body_set.insert(rb); + let rb_h = self.rb_manager.physics_manager.world.insert_body(rb); if let Some(collider) = def.collider { let collider_h = self .rb_manager .physics_manager - .collider_set - .insert_with_parent( - collider, - rb_h, - &mut self.rb_manager.physics_manager.rigid_body_set, - ); + .world + .insert_collider(collider, Some(rb_h)); (Some(rb_h), Some(collider_h)) } else { (Some(rb_h), None) @@ -67,8 +63,8 @@ impl SimManager { let collider_h = self .rb_manager .physics_manager - .collider_set - .insert(collider); + .world + .insert_collider(collider, None); (None, Some(collider_h)) } else { (None, None) @@ -91,28 +87,19 @@ impl SimManager { pub fn destroy_entity(&mut self, id: u32) { if let Some(entity) = self.entities.get(&id) { if let Some(rb_h) = entity.data.rb_h { - self.rb_manager.physics_manager.rigid_body_set.remove( - rb_h, - &mut self.rb_manager.physics_manager.island_manager, - &mut self.rb_manager.physics_manager.collider_set, - &mut self.rb_manager.physics_manager.impulse_joint_set, - &mut self.rb_manager.physics_manager.multibody_joint_set, - true, - ); + self.rb_manager.physics_manager.world.remove_body(rb_h); } else if let Some(collider_h) = entity.data.collider_h { - self.rb_manager.physics_manager.collider_set.remove( - collider_h, - &mut self.rb_manager.physics_manager.island_manager, - &mut self.rb_manager.physics_manager.rigid_body_set, - true, - ); + self.rb_manager + .physics_manager + .world + .remove_collider(collider_h); } self.entities.remove(&id); } } - fn cell_update(&mut self, config: &Config) { + fn cell_update(&mut self, config: &Config, delta_time: f32) { // before we tick, write all the entities into the sim world // TODO optimize let entity_ids: Vec<u32> = self.entities.keys().copied().collect(); @@ -125,53 +112,68 @@ impl SimManager { self.cell_manager.tick(config.use_threading); + let entity_ids: Vec<u32> = self.entities.keys().cloned().collect(); + for id in entity_ids { + let entity = self.entities.get_mut(&id); + let mut ctx = SimCtx { + cell_manager: &mut self.cell_manager, + rb_manager: &mut self.rb_manager, + particle_manager: &mut self.particle_manager, + }; + if let Some(entity) = entity + && let Some(result) = entity.update(&mut ctx, delta_time) + { + for d in result.deferred_destructions { + self.destroy_entity(d); + } + } + } + // after we tick, remove the written entity cells and update the entities // TODO optimize for (entity_id, cells_written) in cells_written_by_entity { - let entity = self.entities.get_mut(&entity_id).unwrap(); - let entity_cells = entity.data.cells.as_mut().unwrap(); - let mut should_update_entity = false; + if let Some(entity) = self.entities.get_mut(&entity_id) { + let entity_cells = entity.data.cells.as_mut().unwrap(); + let mut should_update_entity = false; - for (lx, ly, x, y) in cells_written { - // update the entity - // TODO optimize - let new_local_cell = self.cell_manager.get_cell_from_game_position(x, y).unwrap(); - if !new_local_cell.entity_integrated() { - // this means that the entity changed in some way, so we should recompute its shape - // TODO wait N frames to debounce this - should_update_entity = true; - } - // we do this unconditionally because it's cheaper than checking if it actually needs to be updated - // and because we don't have a good way to track changes to cell state - entity_cells - .set_cell_at_local_position(IVec2::new(lx as i32, ly as i32), new_local_cell); + for (lx, ly, x, y) in cells_written { + // update the entity + // TODO optimize + let new_local_cell = + self.cell_manager.get_cell_from_game_position(x, y).unwrap(); + if !new_local_cell.entity_integrated() { + // this means that the entity changed in some way, so we should recompute its shape + // TODO wait N frames to debounce this + should_update_entity = true; + } + // we do this unconditionally because it's cheaper than checking if it actually needs to be updated + // and because we don't have a good way to track changes to cell state + entity_cells.set_cell_at_local_position( + IVec2::new(lx as i32, ly as i32), + new_local_cell, + ); - // update the world - // TODO optimize - self.cell_manager - .set_cell_from_game_position(x, y, Cell::void(), false); - } + // update the world + // TODO optimize + self.cell_manager + .set_cell_from_game_position(x, y, Cell::void(), false); + } - if should_update_entity { - if let Some(new_collider) = entity.compute_collider() { - self.rb_manager.physics_manager.collider_set.remove( - entity.data.collider_h.unwrap(), - &mut self.rb_manager.physics_manager.island_manager, - &mut self.rb_manager.physics_manager.rigid_body_set, - true, - ); + if should_update_entity { + if let Some(new_collider) = entity.compute_collider() { + self.rb_manager + .physics_manager + .world + .remove_collider(entity.data.collider_h.unwrap()); - let new_handle = self - .rb_manager - .physics_manager - .collider_set - .insert_with_parent( - new_collider, - entity.data.rb_h.unwrap(), - &mut self.rb_manager.physics_manager.rigid_body_set, - ); + let new_handle = self + .rb_manager + .physics_manager + .world + .insert_collider(new_collider, Some(entity.data.rb_h.unwrap())); - entity.data.collider_h = Some(new_handle); + entity.data.collider_h = Some(new_handle); + } } } } @@ -194,7 +196,6 @@ impl SimManager { } } } - // before we move the rigidbodies, upsert the current terrain state // TODO make this range dynamic for cx in -5..5 { @@ -220,38 +221,20 @@ impl SimManager { } pub fn update(&mut self, config: &Config, delta_time: f32) { - let entity_ids: Vec<u32> = self.entities.keys().cloned().collect(); - for id in entity_ids { - if let Some(entity) = self.entities.get_mut(&id) { - let mut ctx = SimCtx { - cell_manager: &mut self.cell_manager, - rb_manager: &mut self.rb_manager, - particle_manager: &mut self.particle_manager, - }; - - entity.update(&mut ctx, delta_time); - if let Some(result) = entity.update(&mut ctx, delta_time) { - for d in result.deferred_destructions { - self.destroy_entity(d); - } - } - } - } - 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); + self.cell_update(config, 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); + self.cell_update(config, delta_time); self.cell_updates_due -= 1.0; cell_updates_done += 1; } |
