diff options
| author | Sébastien Crozet <developer@crozet.re> | 2020-08-25 22:10:25 +0200 |
|---|---|---|
| committer | Sébastien Crozet <developer@crozet.re> | 2020-08-25 22:10:25 +0200 |
| commit | 754a48b7ff6d8c58b1ee08651e60112900b60455 (patch) | |
| tree | 7d777a6c003f1f5d8f8d24f533f35a95a88957fe /src/pipeline/collision_pipeline.rs | |
| download | rapier-0.1.0.tar.gz rapier-0.1.0.tar.bz2 rapier-0.1.0.zip | |
First public release of Rapier.v0.1.0
Diffstat (limited to 'src/pipeline/collision_pipeline.rs')
| -rw-r--r-- | src/pipeline/collision_pipeline.rs | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/src/pipeline/collision_pipeline.rs b/src/pipeline/collision_pipeline.rs new file mode 100644 index 0000000..0184295 --- /dev/null +++ b/src/pipeline/collision_pipeline.rs @@ -0,0 +1,111 @@ +//! Physics pipeline structures. + +use crate::dynamics::{JointSet, RigidBody, RigidBodyHandle, RigidBodySet}; +use crate::geometry::{BroadPhase, BroadPhasePairEvent, ColliderPair, ColliderSet, NarrowPhase}; +use crate::pipeline::EventHandler; + +/// The collision pipeline, responsible for performing collision detection between colliders. +/// +/// This structure only contains temporary data buffers. It can be dropped and replaced by a fresh +/// copy at any time. For performance reasons it is recommended to reuse the same physics pipeline +/// instance to benefit from the cached data. +// NOTE: this contains only workspace data, so there is no point in making this serializable. +pub struct CollisionPipeline { + broadphase_collider_pairs: Vec<ColliderPair>, + broad_phase_events: Vec<BroadPhasePairEvent>, + empty_joints: JointSet, +} + +#[allow(dead_code)] +fn check_pipeline_send_sync() { + fn do_test<T: Sync>() {} + do_test::<CollisionPipeline>(); +} + +impl CollisionPipeline { + /// Initializes a new physics pipeline. + pub fn new() -> CollisionPipeline { + CollisionPipeline { + broadphase_collider_pairs: Vec::new(), + broad_phase_events: Vec::new(), + empty_joints: JointSet::new(), + } + } + + /// Executes one step of the collision detection. + pub fn step( + &mut self, + prediction_distance: f32, + broad_phase: &mut BroadPhase, + narrow_phase: &mut NarrowPhase, + bodies: &mut RigidBodySet, + colliders: &mut ColliderSet, + events: &dyn EventHandler, + ) { + bodies.maintain_active_set(); + self.broadphase_collider_pairs.clear(); + + broad_phase.update_aabbs(prediction_distance, bodies, colliders); + + self.broad_phase_events.clear(); + broad_phase.find_pairs(&mut self.broad_phase_events); + + narrow_phase.register_pairs(colliders, &self.broad_phase_events, events); + + narrow_phase.compute_contacts(prediction_distance, bodies, colliders, events); + narrow_phase.compute_proximities(prediction_distance, bodies, colliders, events); + + bodies.update_active_set_with_contacts( + colliders, + narrow_phase.contact_graph(), + self.empty_joints.joint_graph(), + 0, + ); + + // // Update kinematic bodies velocities. + // bodies.foreach_active_kinematic_body_mut_internal(|_, body| { + // body.compute_velocity_from_predicted_position(integration_parameters.inv_dt()); + // }); + + // Update colliders positions and kinematic bodies positions. + bodies.foreach_active_body_mut_internal(|_, rb| { + if rb.is_kinematic() { + rb.position = rb.predicted_position; + } else { + rb.update_predicted_position(0.0); + } + + for handle in &rb.colliders { + let collider = &mut colliders[*handle]; + collider.position = rb.position * collider.delta; + collider.predicted_position = rb.predicted_position * collider.delta; + } + }); + + bodies.modified_inactive_set.clear(); + } + + /// Remove a rigid-body and all its associated data. + pub fn remove_rigid_body( + &mut self, + handle: RigidBodyHandle, + broad_phase: &mut BroadPhase, + narrow_phase: &mut NarrowPhase, + bodies: &mut RigidBodySet, + colliders: &mut ColliderSet, + ) -> Option<RigidBody> { + // Remove the body. + let body = bodies.remove_internal(handle)?; + + // Remove this rigid-body from the broad-phase and narrow-phase. + broad_phase.remove_colliders(&body.colliders, colliders); + narrow_phase.remove_colliders(&body.colliders, colliders, bodies); + + // Remove all colliders attached to this body. + for collider in &body.colliders { + colliders.remove_internal(*collider); + } + + Some(body) + } +} |
