diff options
| author | Kai Stevenson <kai@kaistevenson.com> | 2026-08-18 08:55:24 -0700 |
|---|---|---|
| committer | Kai Stevenson <kai@kaistevenson.com> | 2026-08-18 08:55:24 -0700 |
| commit | 5877fbf3991b1f35696bf86d9e1b3da3ece01f42 (patch) | |
| tree | 941eedd26173d200243b669dcf89150cfbd52246 /src/sim/rb_sim | |
| parent | 4d4f28f4d0e93541e92277f44451aacdc23b8227 (diff) | |
automatic chunk marching
Diffstat (limited to 'src/sim/rb_sim')
| -rw-r--r-- | src/sim/rb_sim/mod.rs | 57 |
1 files changed, 40 insertions, 17 deletions
diff --git a/src/sim/rb_sim/mod.rs b/src/sim/rb_sim/mod.rs index 0192555..b79de86 100644 --- a/src/sim/rb_sim/mod.rs +++ b/src/sim/rb_sim/mod.rs @@ -5,7 +5,7 @@ use fxhash::FxHashMap; use glam::Vec2; use rapier2d::{ dynamics::{self}, - geometry, + geometry::{self, ColliderHandle}, glamx::vec2, math, prelude, }; @@ -70,8 +70,10 @@ impl PhysicsManager { } pub struct RbSimManager { - physics_manager: PhysicsManager, + chunk_colliders: FxHashMap<(i32, i32), ColliderHandle>, pub rb_entities: FxHashMap<u32, RbEntity>, + + physics_manager: PhysicsManager, next_id: u32, debug_line_buffer: DebugLineBuffer, } @@ -165,25 +167,44 @@ impl RbSimManager { } fn collider_from_chunk(&self, position: Vec2, chunk: &Chunk) -> geometry::Collider { - let mut paths = marching_squares_vertex_trace(chunk, CHUNK_SIZE, CHUNK_SIZE); - let mut path: Vec<Vec2> = paths - // NAIVE, using the second and assuming it's the outer path - .swap_remove(0) - .iter() - .map(|v| v / PIXELS_TO_METRES) - .collect(); - // close the loop - let first = (*path.first().unwrap()).clone(); - path.push(first); + let polys = marching_squares_vertex_trace(chunk, CHUNK_SIZE, CHUNK_SIZE); + let mut vertices = Vec::new(); + let mut indices = Vec::new(); - geometry::ColliderBuilder::polyline(path, None) + for poly in polys { + let v = vertices.len() as u32; + let p = poly.len() as u32; + if p < 3 { + continue; + } + for i in 0..p { + vertices.push(poly[i as usize] / PIXELS_TO_METRES); + indices.push([v + i, v + (i + 1) % p]); + } + } + + geometry::ColliderBuilder::polyline(vertices, Some(indices)) .translation(position / PIXELS_TO_METRES) .build() } - pub fn test_add_collider_from_chunk(&mut self, position: Vec2, chunk: &Chunk) { - let collider = self.collider_from_chunk(position, chunk); - self.physics_manager.collider_set.insert(collider); + pub fn upsert_chunk_collider(&mut self, cx: i32, cy: i32, chunk: &Chunk) { + let collider = self.collider_from_chunk( + Vec2::new((cx * CHUNK_SIZE) as f32, (cy * CHUNK_SIZE) as f32), + chunk, + ); + + if let Some(handle) = self.chunk_colliders.remove(&(cx, cy)) { + self.physics_manager.collider_set.remove( + handle, + &mut self.physics_manager.island_manager, + &mut self.physics_manager.rigid_body_set, + false, + ); + } + + let handle = self.physics_manager.collider_set.insert(collider); + self.chunk_colliders.insert((cx, cy), handle); } pub fn test(&mut self) { @@ -231,8 +252,10 @@ impl RbSimManager { pub fn new() -> Self { RbSimManager { - physics_manager: PhysicsManager::new(), rb_entities: FxHashMap::default(), + chunk_colliders: FxHashMap::default(), + + physics_manager: PhysicsManager::new(), next_id: 0, debug_line_buffer: DebugLineBuffer::default(), } |
