summaryrefslogtreecommitdiff
path: root/src/sim/sim_manager/mod.rs
diff options
context:
space:
mode:
authorKai Stevenson <kai@kaistevenson.com>2026-08-23 02:48:43 -0700
committerKai Stevenson <kai@kaistevenson.com>2026-08-23 02:48:43 -0700
commit80824a8b69b70e6e40577e4f0236c28c4ad5c15b (patch)
treebf3b72331c4ed9195bbe72d25d5e82c076d3220a /src/sim/sim_manager/mod.rs
parentd6664b9b5a9a3aab500b547e4d7448a8bc4ad416 (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.rs153
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;
}