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.rs62
1 files changed, 62 insertions, 0 deletions
diff --git a/src/sim/sim_manager/utils.rs b/src/sim/sim_manager/utils.rs
new file mode 100644
index 0000000..b636186
--- /dev/null
+++ b/src/sim/sim_manager/utils.rs
@@ -0,0 +1,62 @@
+use crate::sim::{cell::materials::MaterialId, sim_manager::SimManager};
+
+pub fn write_rb_entity_to_world(
+ sim: &mut SimManager,
+ rb_entity_id: u32,
+ // make sure these cells will be simulated
+ seqno: u64,
+ // (entity_x, entity_y, cell_x, cell_y)
+) -> Vec<(u8, u8, i32, i32)> {
+ let mut cells_written: Vec<(u8, u8, i32, i32)> = Vec::new();
+ if let Some(rb_entity) = sim.rb_manager.rb_entities.get(&rb_entity_id)
+ && let Some((rb_x, rb_y, cos, sin)) = sim.rb_manager.get_rb_entity_transform(rb_entity_id)
+ {
+ let (half_size_x, half_size_y) =
+ (rb_entity.width as f32 / 2.0, rb_entity.height as f32 / 2.0);
+ // half-extent of the rotated grid's axis-aligned bounding box, plus a cell of margin
+ let (radius_x, radius_y) = (
+ half_size_x * (cos.abs() + sin.abs()) + 1.0,
+ half_size_y * (cos.abs() + sin.abs()) + 1.0,
+ );
+
+ let world_xl = (rb_x - radius_x).floor() as i32;
+ let world_xu = (rb_x + radius_x).ceil() as i32;
+ let world_yl = (rb_y - radius_y).floor() as i32;
+ let world_yu = (rb_y + radius_y).ceil() as i32;
+
+ for world_x in world_xl..=world_xu {
+ for world_y in world_yl..=world_yu {
+ if let Some(cur_world_cell) = sim
+ .cell_manager
+ .get_cell_from_game_position(world_x, world_y)
+ && cur_world_cell.material == MaterialId::Void
+ {
+ // same as shader
+ let d = (world_x as f32 + 0.5 - rb_x, world_y as f32 + 0.5 - rb_y);
+ let q = (d.0.floor() + 0.5, d.1.floor() + 0.5);
+ let (lx, ly) = (
+ (q.0 * cos + q.1 * sin + half_size_x).floor() as i32,
+ (-q.0 * sin + q.1 * cos + half_size_y).floor() as i32,
+ );
+
+ if lx < 0 || ly < 0 || lx >= rb_entity.width || ly >= rb_entity.height {
+ continue;
+ }
+
+ let mut cell = rb_entity.get_cell_at_local_position(lx as u8, ly as u8);
+ if cell.material == MaterialId::Void {
+ continue;
+ }
+
+ cell.match_parity(seqno);
+
+ // TODO: OPTIMIZE!!
+ sim.cell_manager
+ .set_cell_from_game_position(world_x, world_y, cell, false);
+ cells_written.push((lx as u8, ly as u8, world_x, world_y));
+ }
+ }
+ }
+ }
+ cells_written
+}