use crossbeam::channel::Receiver; use rapier2d::{ dynamics::{ CCDSolver, GenericJoint, ImpulseJointSet, IntegrationParameters, IslandManager, MultibodyJointSet, RigidBody, RigidBodyHandle, RigidBodySet, }, geometry::{BroadPhase, Collider, ColliderHandle, ColliderSet, CollisionEvent, NarrowPhase}, na::vector, pipeline::{ChannelEventCollector, PhysicsPipeline}, }; /// Wraps Rapier2d physics parameters pub struct PhysWrapper { ip: IntegrationParameters, pp: PhysicsPipeline, im: IslandManager, bp: BroadPhase, np: NarrowPhase, mj: MultibodyJointSet, ccd: CCDSolver, rigid_body_set: RigidBodySet, collider_set: ColliderSet, joint_set: ImpulseJointSet, collision_handler: ChannelEventCollector, /// Collision event queue /// this should be emptied after every frame. pub collision_queue: Receiver, } impl PhysWrapper { /// Make a new physics wrapper pub fn new() -> Self { let (collision_send, collision_queue) = crossbeam::channel::unbounded(); let (contact_force_send, _) = crossbeam::channel::unbounded(); Self { ip: IntegrationParameters::default(), pp: PhysicsPipeline::new(), im: IslandManager::new(), bp: BroadPhase::new(), np: NarrowPhase::new(), mj: MultibodyJointSet::new(), ccd: CCDSolver::new(), collision_queue, collision_handler: ChannelEventCollector::new(collision_send, contact_force_send), rigid_body_set: RigidBodySet::new(), collider_set: ColliderSet::new(), joint_set: ImpulseJointSet::new(), } } /// Step physics sim by `t` seconds pub fn step(&mut self, t: f32) { self.ip.dt = t; self.pp.step( &vector![0.0, 0.0], &self.ip, &mut self.im, &mut self.bp, &mut self.np, &mut self.rigid_body_set, &mut self.collider_set, &mut self.joint_set, &mut self.mj, &mut self.ccd, None, &(), &mut self.collision_handler, ); } /// Remove a rigid body and all its colliders from this physics wrapper pub fn remove_rigid_body(&mut self, body: RigidBodyHandle) -> Option { return self.rigid_body_set.remove( body, &mut self.im, &mut self.collider_set, &mut self.joint_set, &mut self.mj, true, ); } } impl PhysWrapper { /// Get a rigidbody from this physics wrapper pub fn get_rigid_body(&self, h: RigidBodyHandle) -> Option<&RigidBody> { self.rigid_body_set.get(h) } /// Get a rigidbody from this physics wrapper, mutably pub fn get_rigid_body_mut(&mut self, h: RigidBodyHandle) -> Option<&mut RigidBody> { self.rigid_body_set.get_mut(h) } /// Get a collider from this physics wrapper pub fn get_collider(&self, h: ColliderHandle) -> Option<&Collider> { self.collider_set.get(h) } /// Get a collider from this physics wrapper, mutably pub fn get_collider_mut(&mut self, h: ColliderHandle) -> Option<&mut Collider> { self.collider_set.get_mut(h) } /// Add a rigid body pub fn insert_rigid_body(&mut self, rb: RigidBody) -> RigidBodyHandle { self.rigid_body_set.insert(rb) } /// Attach a collider to a rigid body pub fn insert_collider( &mut self, collider: Collider, parent_handle: RigidBodyHandle, ) -> ColliderHandle { self.collider_set .insert_with_parent(collider, parent_handle, &mut self.rigid_body_set) } /// Add an impulse joint between two bodies pub fn add_joint( &mut self, body1: RigidBodyHandle, body2: RigidBodyHandle, joint: impl Into, ) { self.joint_set.insert(body1, body2, joint, false); } }