summaryrefslogtreecommitdiff
path: root/src/sim/sim_manager/utils.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/sim/sim_manager/utils.rs')
-rw-r--r--src/sim/sim_manager/utils.rs58
1 files changed, 53 insertions, 5 deletions
diff --git a/src/sim/sim_manager/utils.rs b/src/sim/sim_manager/utils.rs
index f30e9a0..264597d 100644
--- a/src/sim/sim_manager/utils.rs
+++ b/src/sim/sim_manager/utils.rs
@@ -1,10 +1,13 @@
use glam::IVec2;
+use rapier2d::{dynamics::RigidBodyBuilder, math::Pose};
use crate::{
+ config::CELLS_TO_METRES,
content::materials::MaterialId,
sim::{
cell::Cell,
- entity::{EntityId, EntityUpdateResult},
+ entity::{EntityCells, EntityDef, EntityId, EntityUpdateResult},
+ lib::components::compute_components,
sim_manager::SimManager,
},
};
@@ -117,10 +120,17 @@ pub fn read_back_entities_from_world(
if let Some(entity) = &mut entity
&& should_update_entity
{
- puffin::profile_scope!("Recompute collider");
- if let Some(new_collider) = entity.compute_collider() {
- {
- puffin::profile_scope!("Upsert collider");
+ // correctness: there's no way to get here if the entity is an uncelled entity
+ let ec = entity.data.cells.as_mut().unwrap();
+ // first check if the entity has been partitioned
+ let components = compute_components(&ec.cells, ec.size.x, ec.size.y);
+ if components.len() == 0 {
+ panic!("The entity was completely destroyed?")
+ } else if components.len() == 1 {
+ // the entity's cells were changed, but not partitioned
+ puffin::profile_scope!("Recompute collider");
+ if let Some(new_collider) = entity.compute_collider() {
+ // don't profile this separately as it's basically free
sim.rb_manager
.physics_manager
.world
@@ -134,6 +144,44 @@ pub fn read_back_entities_from_world(
entity.data.collider_h = Some(new_handle);
}
+ } else {
+ // the entity was partitioned
+ // destroy the original entity
+ // correctness -- not correct! because we don't have pos without rb
+ let old_rb = sim
+ .rb_manager
+ .physics_manager
+ .world
+ .bodies
+ .get(entity.data.rb_h.unwrap())
+ .unwrap();
+ let old_pose = old_rb.position().clone();
+ let old_linvel = old_rb.linvel().clone();
+ let old_angvel = old_rb.angvel().clone();
+
+ sim.destroy_entity(entity_id);
+ // and create a new entity for each component
+ for component in components {
+ let r = old_pose.transform_vector(component.position / CELLS_TO_METRES);
+ let mut pose = old_pose;
+ pose.translation += r;
+
+ let rb = RigidBodyBuilder::dynamic()
+ .pose(pose)
+ .linvel(old_linvel)
+ .angvel(old_angvel)
+ .build();
+
+ let def = EntityDef::from_cells_and_rb(
+ EntityCells {
+ cells: component.cells,
+ size: component.size,
+ },
+ rb,
+ None,
+ );
+ sim.create_entity(def);
+ }
}
}
}