summaryrefslogtreecommitdiff
path: root/src/sim/rb_sim/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/sim/rb_sim/mod.rs')
-rw-r--r--src/sim/rb_sim/mod.rs131
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(),
+ }
+ }
+}