summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main.rs19
-rw-r--r--src/sim/rb_sim/mod.rs57
2 files changed, 55 insertions, 21 deletions
diff --git a/src/main.rs b/src/main.rs
index 640e5b9..586b456 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -120,10 +120,6 @@ impl App {
&& let Some(rbsm) = &mut self.rb_sim_manager
{
self.input.trigger_test_2 = false;
- rbsm.test_add_collider_from_chunk(
- Vec2::new((cx * CHUNK_SIZE) as f32, (cy * CHUNK_SIZE) as f32),
- &world.chunks[*world.chunk_position_to_chunk_idx.get(&(cx, cy)).unwrap()],
- );
}
// --TEST DRAWING--
@@ -202,7 +198,22 @@ impl App {
// may be called multiple times if the physics time is behind
// physics_delta_time is statically 1/PHYSICS_FPS
fn physics_update(&mut self, physics_delta_time: f32) {
+ // before we move the rigidbodies, upsert the current terrain state
+ // TODO use the chunk sleeping, and make this range dynamic
if let Some(physics_manager) = &mut self.rb_sim_manager {
+ if let Some(world) = &self.world {
+ for cx in -5..5 {
+ for cy in -5..5 {
+ if let Some(chunk) = world
+ .chunk_position_to_chunk_idx
+ .get(&(cx, cy))
+ .map(|&idx| &world.chunks[idx])
+ {
+ physics_manager.upsert_chunk_collider(cx, cy, chunk);
+ }
+ }
+ }
+ }
physics_manager.rb_tick(physics_delta_time);
}
}
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(),
}