summaryrefslogtreecommitdiff
path: root/src/sim/rb_sim
diff options
context:
space:
mode:
Diffstat (limited to 'src/sim/rb_sim')
-rw-r--r--src/sim/rb_sim/debug_ops.rs48
-rw-r--r--src/sim/rb_sim/debug_render.rs71
-rw-r--r--src/sim/rb_sim/mod.rs289
-rw-r--r--src/sim/rb_sim/rb_entity.rs39
4 files changed, 0 insertions, 447 deletions
diff --git a/src/sim/rb_sim/debug_ops.rs b/src/sim/rb_sim/debug_ops.rs
deleted file mode 100644
index d6852da..0000000
--- a/src/sim/rb_sim/debug_ops.rs
+++ /dev/null
@@ -1,48 +0,0 @@
-use glam::{ivec2, vec2};
-
-use crate::sim::{
- cell::{cell::Cell, materials::MaterialId},
- rb_sim::RbSimManager,
-};
-
-pub trait DebugOperator {
- fn test_spawn_box(&mut self, x: f32, y: f32, material: MaterialId) -> ();
- fn test_spawn_ball(&mut self, x: f32, y: f32, material: MaterialId) -> ();
-}
-
-impl DebugOperator for RbSimManager {
- fn test_spawn_box(&mut self, x: f32, y: f32, material: MaterialId) {
- let w = 10;
- let h = 10;
- let mut test_cells = vec![Cell::void(); (w * h) as usize];
-
- for x in 0..w {
- for y in 0..h {
- let cell_idx = x + y * w;
- test_cells[cell_idx as usize] = Cell::from_material(material);
- test_cells[cell_idx as usize].set_rb(true);
- }
- }
-
- self.create_rb_entity(vec2(x, y), test_cells, w, h);
- }
-
- fn test_spawn_ball(&mut self, x: f32, y: f32, material: MaterialId) {
- let r = 5;
- let w = r * 2;
- let h = r * 2;
- let mut test_cells = vec![Cell::void(); (w * h) as usize];
-
- for x in 0..w {
- for y in 0..h {
- let cell_idx = x + y * w;
- if ivec2(x, y).distance_squared(ivec2(w / 2, h / 2)) < r.pow(2) {
- test_cells[cell_idx as usize] = Cell::from_material(material);
- test_cells[cell_idx as usize].set_rb(true);
- }
- }
- }
-
- self.create_rb_entity(vec2(x, y), test_cells, w, h);
- }
-}
diff --git a/src/sim/rb_sim/debug_render.rs b/src/sim/rb_sim/debug_render.rs
deleted file mode 100644
index 342fc5b..0000000
--- a/src/sim/rb_sim/debug_render.rs
+++ /dev/null
@@ -1,71 +0,0 @@
-use rapier2d::pipeline::{DebugColor, DebugRenderBackend, DebugRenderObject};
-
-use crate::config::PIXELS_TO_METRES;
-
-#[repr(C)]
-#[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
-pub struct DebugVertex {
- pub position: [f32; 2],
- pub color: [f32; 4],
-}
-
-#[derive(Default)]
-pub struct DebugLineBuffer {
- pub vertices: Vec<DebugVertex>,
-}
-
-impl DebugRenderBackend for DebugLineBuffer {
- fn draw_line(
- &mut self,
- _object: DebugRenderObject,
- a: rapier2d::math::Vector,
- b: rapier2d::math::Vector,
- color: DebugColor,
- ) {
- let color = hsla_to_linear_rgba(color);
- self.vertices.push(DebugVertex {
- position: [a.x * PIXELS_TO_METRES, a.y * PIXELS_TO_METRES],
- color,
- });
- self.vertices.push(DebugVertex {
- position: [b.x * PIXELS_TO_METRES, b.y * PIXELS_TO_METRES],
- color,
- });
- }
-}
-
-fn hsla_to_linear_rgba(hsla: DebugColor) -> [f32; 4] {
- let [hue, saturation, lightness, alpha] = hsla;
-
- let hue = hue.rem_euclid(360.0) / 60.0;
- let saturation = saturation.clamp(0.0, 1.0);
- let lightness = lightness.clamp(0.0, 1.0);
-
- let chroma = (1.0 - (2.0 * lightness - 1.0).abs()) * saturation;
- let second = chroma * (1.0 - (hue % 2.0 - 1.0).abs());
- let (r, g, b) = match hue as u32 {
- 0 => (chroma, second, 0.0),
- 1 => (second, chroma, 0.0),
- 2 => (0.0, chroma, second),
- 3 => (0.0, second, chroma),
- 4 => (second, 0.0, chroma),
- _ => (chroma, 0.0, second),
- };
- let m = lightness - chroma / 2.0;
-
- [
- srgb_to_linear(r + m),
- srgb_to_linear(g + m),
- srgb_to_linear(b + m),
- alpha.clamp(0.0, 1.0),
- ]
-}
-
-fn srgb_to_linear(channel: f32) -> f32 {
- let channel = channel.clamp(0.0, 1.0);
- if channel <= 0.04045 {
- channel / 12.92
- } else {
- ((channel + 0.055) / 1.055).powf(2.4)
- }
-}
diff --git a/src/sim/rb_sim/mod.rs b/src/sim/rb_sim/mod.rs
deleted file mode 100644
index f81d5f1..0000000
--- a/src/sim/rb_sim/mod.rs
+++ /dev/null
@@ -1,289 +0,0 @@
-pub mod debug_ops;
-pub mod debug_render;
-pub mod rb_entity;
-
-use fxhash::FxHashMap;
-use glam::Vec2;
-use rapier2d::{dynamics, geometry, glamx::vec2, prelude};
-
-use crate::{
- config::{CHUNK_SIZE, PHYSICS_DELTA_TIME, PIXELS_TO_METRES},
- sim::{
- cell::cell::Cell,
- cell_sim::chunk::Chunk,
- lib::marching_squares::{Marchable, marching_squares_vertex_trace},
- rb_sim::{
- debug_render::{DebugLineBuffer, DebugVertex},
- rb_entity::RbEntity,
- },
- },
-};
-
-pub use rapier2d::pipeline::DebugRenderMode;
-
-pub struct PhysicsManager {
- rigid_body_set: prelude::RigidBodySet,
- collider_set: prelude::ColliderSet,
- physics_pipeline: prelude::PhysicsPipeline,
- integration_parameters: prelude::IntegrationParameters,
- island_manager: prelude::IslandManager,
- broad_phase: prelude::DefaultBroadPhase,
- narrow_phase: prelude::NarrowPhase,
- impulse_joint_set: prelude::ImpulseJointSet,
- multibody_joint_set: prelude::MultibodyJointSet,
- ccd_solver: prelude::CCDSolver,
- debug_render_pipeline: prelude::DebugRenderPipeline,
-}
-
-impl PhysicsManager {
- pub fn new() -> Self {
- PhysicsManager {
- rigid_body_set: prelude::RigidBodySet::new(),
- collider_set: prelude::ColliderSet::new(),
- physics_pipeline: prelude::PhysicsPipeline::new(),
- integration_parameters: prelude::IntegrationParameters {
- // 20 pixels <-> 1 meter
- length_unit: PIXELS_TO_METRES,
- dt: PHYSICS_DELTA_TIME,
- ..prelude::IntegrationParameters::default()
- },
- island_manager: prelude::IslandManager::new(),
- broad_phase: prelude::DefaultBroadPhase::new(),
- narrow_phase: prelude::NarrowPhase::new(),
- impulse_joint_set: prelude::ImpulseJointSet::new(),
- multibody_joint_set: prelude::MultibodyJointSet::new(),
- ccd_solver: prelude::CCDSolver::new(),
- debug_render_pipeline: prelude::DebugRenderPipeline::new(
- prelude::DebugRenderStyle {
- sleep_color_multiplier: [1.0; 4],
- sleep_eligible_color_multiplier: [1.0; 4],
- ..prelude::DebugRenderStyle::default()
- },
- prelude::DebugRenderMode::default(),
- ),
- }
- }
-}
-
-pub struct RbSimManager {
- chunk_colliders: FxHashMap<(i32, i32), geometry::ColliderHandle>,
- pub rb_entities: FxHashMap<u32, RbEntity>,
-
- physics_manager: PhysicsManager,
- next_id: u32,
- debug_line_buffer: DebugLineBuffer,
-}
-
-impl RbSimManager {
- pub fn rb_tick(&mut self, delta_time: f32) {
- let gravity = vec2(0.0, 9.81);
-
- self.physics_manager.physics_pipeline.step(
- gravity,
- &self.physics_manager.integration_parameters,
- &mut self.physics_manager.island_manager,
- &mut self.physics_manager.broad_phase,
- &mut self.physics_manager.narrow_phase,
- &mut self.physics_manager.rigid_body_set,
- &mut self.physics_manager.collider_set,
- &mut self.physics_manager.impulse_joint_set,
- &mut self.physics_manager.multibody_joint_set,
- &mut self.physics_manager.ccd_solver,
- &(),
- &(),
- );
- }
-
- pub fn debug_render(&mut self, mode: DebugRenderMode) -> &[DebugVertex] {
- puffin::profile_function!();
-
- let physics = &mut self.physics_manager;
- self.debug_line_buffer.vertices.clear();
- physics.debug_render_pipeline.mode = mode;
- physics.debug_render_pipeline.render(
- &mut self.debug_line_buffer,
- &physics.rigid_body_set,
- &physics.collider_set,
- &physics.impulse_joint_set,
- &physics.multibody_joint_set,
- &physics.narrow_phase,
- );
-
- &self.debug_line_buffer.vertices
- }
-
- pub fn create_rb_entity(&mut self, position: Vec2, cells: Vec<Cell>, w: i32, h: i32) -> u32 {
- let id = self.next_id;
- self.next_id += 1;
-
- let rb = dynamics::RigidBodyBuilder::dynamic()
- .translation(position / PIXELS_TO_METRES)
- .build();
- let rb_handle = self.physics_manager.rigid_body_set.insert(rb);
-
- let mut entity: RbEntity = RbEntity {
- id,
- cells,
- width: w,
- height: h,
- rb: rb_handle,
- collider: None,
- };
-
- let collider = self
- .convex_hull_collider_from_marchable(&entity, None)
- .build();
- let collider_handle = self.physics_manager.collider_set.insert_with_parent(
- collider,
- rb_handle,
- &mut self.physics_manager.rigid_body_set,
- );
-
- entity.collider = Some(collider_handle);
-
- self.rb_entities.insert(id, entity);
-
- id
- }
-
- pub fn update_rb_entity(&mut self, entity_id: u32) {
- let entity = self.rb_entities.get(&entity_id).unwrap();
- let new_collider = self
- .convex_hull_collider_from_marchable(entity, None)
- .build();
-
- self.physics_manager.collider_set.remove(
- entity.collider.unwrap(),
- &mut self.physics_manager.island_manager,
- &mut self.physics_manager.rigid_body_set,
- false,
- );
-
- let new_collider_handle = self.physics_manager.collider_set.insert_with_parent(
- new_collider,
- entity.rb,
- &mut self.physics_manager.rigid_body_set,
- );
-
- let entity = self.rb_entities.get_mut(&entity_id).unwrap();
- entity.collider = Some(new_collider_handle);
- }
-
- pub fn destroy_rb_entity(&mut self, entity_id: u32) {
- if let Some(entity) = self.rb_entities.get(&entity_id) {
- self.physics_manager.rigid_body_set.remove(
- entity.rb,
- &mut self.physics_manager.island_manager,
- &mut self.physics_manager.collider_set,
- &mut self.physics_manager.impulse_joint_set,
- &mut self.physics_manager.multibody_joint_set,
- true,
- );
- self.rb_entities.remove(&entity_id);
- }
- }
-
- pub fn get_rb_entity_transform(&self, entity_id: u32) -> Option<(f32, f32, f32, f32)> {
- let entity = self.rb_entities.get(&entity_id);
- match entity {
- Some(entity) => {
- let rb = self.physics_manager.rigid_body_set.get(entity.rb);
- rb.map(|rb| {
- let position = rb.position();
- let angle = position.rotation.angle();
- (
- position.translation.x * PIXELS_TO_METRES,
- position.translation.y * PIXELS_TO_METRES,
- angle.cos(),
- angle.sin(),
- )
- })
- }
- None => return None,
- }
- }
-
- fn polyline_from_marchable(
- &self,
- marchable: &impl Marchable,
- minimum_verts: Option<u32>,
- ) -> (Vec<Vec2>, Vec<[u32; 2]>) {
- let (w, h) = marchable.size();
- let polys = marching_squares_vertex_trace(marchable, w, h);
- let mut vertices = Vec::new();
- let mut indices = Vec::new();
-
- let minimum_verts = minimum_verts.unwrap_or(3);
-
- for poly in polys {
- let v = vertices.len() as u32;
- let p = poly.len() as u32;
- if p < minimum_verts {
- continue;
- }
- for i in 0..p {
- vertices.push(
- (poly[i as usize] - vec2((w as f32 - 1.0) / 2.0, (h as f32 - 1.0) / 2.0))
- / PIXELS_TO_METRES,
- );
- indices.push([v + i, v + (i + 1) % p]);
- }
- }
-
- (vertices, indices)
- }
-
- fn polyline_collider_from_marchable(
- &self,
- marchable: &impl Marchable,
- minimum_verts: Option<u32>,
- ) -> geometry::ColliderBuilder {
- let (vertices, indices) = self.polyline_from_marchable(marchable, minimum_verts);
-
- geometry::ColliderBuilder::polyline(vertices, Some(indices))
- }
-
- fn convex_hull_collider_from_marchable(
- &self,
- marchable: &impl Marchable,
- minimum_verts: Option<u32>,
- ) -> geometry::ColliderBuilder {
- let (vertices, indices) = self.polyline_from_marchable(marchable, minimum_verts);
- geometry::ColliderBuilder::convex_decomposition(&vertices, &indices)
- }
-
- pub fn upsert_chunk_collider(&mut self, cx: i32, cy: i32, chunk: &Chunk) {
- puffin::profile_function!();
- let collider = self
- .polyline_collider_from_marchable(chunk, Some(20))
- .translation(
- vec2(
- (cx as f32 + 0.5) * CHUNK_SIZE as f32,
- (cy as f32 + 0.5) * CHUNK_SIZE as f32,
- ) / PIXELS_TO_METRES,
- );
-
- 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 new() -> Self {
- RbSimManager {
- rb_entities: FxHashMap::default(),
- chunk_colliders: FxHashMap::default(),
-
- physics_manager: PhysicsManager::new(),
- next_id: 0,
- debug_line_buffer: DebugLineBuffer::default(),
- }
- }
-}
diff --git a/src/sim/rb_sim/rb_entity.rs b/src/sim/rb_sim/rb_entity.rs
deleted file mode 100644
index 18a6693..0000000
--- a/src/sim/rb_sim/rb_entity.rs
+++ /dev/null
@@ -1,39 +0,0 @@
-use rapier2d::prelude;
-
-use crate::sim::{
- cell::{cell::Cell, materials::MaterialId},
- lib::marching_squares::Marchable,
-};
-
-pub struct RbEntity {
- pub id: u32,
- pub width: i32,
- pub height: i32,
- pub cells: Vec<Cell>,
- pub rb: prelude::RigidBodyHandle,
- pub collider: Option<prelude::ColliderHandle>,
-}
-
-impl RbEntity {
- #[inline]
- pub fn get_cell_at_local_position(&self, x: u8, y: u8) -> Cell {
- self.cells[x as usize + y as usize * self.width as usize]
- }
- #[inline]
- pub fn set_cell_at_local_position(&mut self, x: u8, y: u8, cell: Cell) {
- self.cells[x as usize + y as usize * self.width as usize] = cell;
- }
-}
-
-impl Marchable for RbEntity {
- fn occupied(&self, x: i32, y: i32) -> bool {
- if x < 0 || x >= self.width || y < 0 || y >= self.height {
- false
- } else {
- self.get_cell_at_local_position(x as u8, y as u8).material != MaterialId::Void
- }
- }
- fn size(&self) -> (i32, i32) {
- (self.width, self.height)
- }
-}