diff options
| author | Kai Stevenson <kai@kaistevenson.com> | 2026-08-16 17:29:42 -0700 |
|---|---|---|
| committer | Kai Stevenson <kai@kaistevenson.com> | 2026-08-16 17:29:42 -0700 |
| commit | f177cc716c5f2aa5b50b14ccbb421de89e3a7854 (patch) | |
| tree | db06f9f44251d6d90e5e9709d47e6cc4397b9443 /src/sim/rb_sim/mod.rs | |
| parent | 40e9d818195824749293dff3afcfdd5c1432adbe (diff) | |
wip
Diffstat (limited to 'src/sim/rb_sim/mod.rs')
| -rw-r--r-- | src/sim/rb_sim/mod.rs | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/src/sim/rb_sim/mod.rs b/src/sim/rb_sim/mod.rs new file mode 100644 index 0000000..1818052 --- /dev/null +++ b/src/sim/rb_sim/mod.rs @@ -0,0 +1,131 @@ +pub mod rb_entity; + +use fxhash::FxHashMap; +use rapier2d::{ + dynamics::{self}, + geometry, + glamx::vec2, + math, prelude, +}; + +use crate::{ + config::{CELLS_IN_CHUNK, PHYSICS_DELTA_TIME}, + sim::{ + cell::{cell::Cell, materials::MaterialId}, + rb_sim::rb_entity::RbEntity, + }, +}; + +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, +} + +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: 20.0, + 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(), + } + } +} + +pub struct RbSimManager { + physics_manager: PhysicsManager, + pub rb_entities: FxHashMap<u32, RbEntity>, +} + +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 get_rb_entity_position(&self, entity_id: u32) -> Option<(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_parent); + rb.map(|rb| (rb.position().translation.x, rb.position().translation.y)) + } + None => return None, + } + } + + pub fn test(&mut self) { + /* Create the ground. */ + let collider = geometry::ColliderBuilder::cuboid(100.0, 0.1).build(); + self.physics_manager.collider_set.insert(collider); + + /* Create the bouncing ball. */ + let rigid_body = dynamics::RigidBodyBuilder::dynamic() + .translation(math::Vector::new(0.0, 10.0)) + .build(); + let collider = geometry::ColliderBuilder::ball(0.5) + .restitution(0.7) + .build(); + let ball_body_handle = self.physics_manager.rigid_body_set.insert(rigid_body); + self.physics_manager.collider_set.insert_with_parent( + collider, + ball_body_handle, + &mut self.physics_manager.rigid_body_set, + ); + + let test_cells = Box::new([Cell::void(); CELLS_IN_CHUNK]); + let mut rb_entity = RbEntity { + id: 0, + cells: test_cells, + rb_parent: ball_body_handle, + }; + + for x in 0..10 { + for y in 0..10 { + rb_entity.set_cell_at_local_position(x, y, Cell::from_material(MaterialId::Wood)); + } + } + + self.rb_entities.insert(0, rb_entity); + } + + pub fn new() -> Self { + RbSimManager { + physics_manager: PhysicsManager::new(), + rb_entities: FxHashMap::default(), + } + } +} |
