Small refactoring of the PhysicsPipeline.

This commit is contained in:
Crozet Sébastien
2021-03-28 11:54:33 +02:00
parent 7306821c46
commit dec3e4197f
2 changed files with 92 additions and 33 deletions

View File

@@ -647,7 +647,7 @@ impl NarrowPhase {
/// Retrieve all the interactions with at least one contact point, happening between two active bodies. /// Retrieve all the interactions with at least one contact point, happening between two active bodies.
// NOTE: this is very similar to the code from JointSet::select_active_interactions. // NOTE: this is very similar to the code from JointSet::select_active_interactions.
pub(crate) fn sort_and_select_active_contacts<'a>( pub(crate) fn select_active_contacts<'a>(
&'a mut self, &'a mut self,
bodies: &RigidBodySet, bodies: &RigidBodySet,
out_manifolds: &mut Vec<&'a mut ContactManifold>, out_manifolds: &mut Vec<&'a mut ContactManifold>,

View File

@@ -58,33 +58,16 @@ impl PhysicsPipeline {
} }
} }
/// Executes one timestep of the physics simulation. fn detect_collisions(
pub fn step(
&mut self, &mut self,
gravity: &Vector<Real>,
integration_parameters: &IntegrationParameters, integration_parameters: &IntegrationParameters,
broad_phase: &mut BroadPhase, broad_phase: &mut BroadPhase,
narrow_phase: &mut NarrowPhase, narrow_phase: &mut NarrowPhase,
bodies: &mut RigidBodySet, bodies: &mut RigidBodySet,
colliders: &mut ColliderSet, colliders: &mut ColliderSet,
joints: &mut JointSet,
ccd_solver: Option<&mut CCDSolver>,
hooks: &dyn PhysicsHooks, hooks: &dyn PhysicsHooks,
events: &dyn EventHandler, events: &dyn EventHandler,
) { ) {
self.counters.step_started();
bodies.maintain(colliders);
narrow_phase.maintain(colliders, bodies);
// Update kinematic bodies velocities.
// TODO: what is the best place for this? It should at least be
// located before the island computation because we test the velocity
// there to determine if this kinematic body should wake-up dynamic
// bodies it is touching.
bodies.foreach_active_kinematic_body_mut_internal(|_, body| {
body.compute_velocity_from_next_position(integration_parameters.inv_dt());
});
self.counters.stages.collision_detection_time.start(); self.counters.stages.collision_detection_time.start();
self.counters.cd.broad_phase_time.start(); self.counters.cd.broad_phase_time.start();
self.broad_phase_events.clear(); self.broad_phase_events.clear();
@@ -96,15 +79,14 @@ impl PhysicsPipeline {
colliders, colliders,
&mut self.broad_phase_events, &mut self.broad_phase_events,
); );
narrow_phase.register_pairs(colliders, bodies, &self.broad_phase_events, events);
self.counters.cd.broad_phase_time.pause(); self.counters.cd.broad_phase_time.pause();
// println!("Num contact pairs: {}", pairs.len()); // println!("Num contact pairs: {}", pairs.len());
self.counters.cd.narrow_phase_time.start(); self.counters.cd.narrow_phase_time.start();
narrow_phase.maintain(colliders, bodies);
narrow_phase.register_pairs(colliders, bodies, &self.broad_phase_events, events);
// let t = instant::now();
narrow_phase.compute_contacts( narrow_phase.compute_contacts(
integration_parameters.prediction_distance, integration_parameters.prediction_distance,
bodies, bodies,
@@ -113,8 +95,19 @@ impl PhysicsPipeline {
events, events,
); );
narrow_phase.compute_intersections(bodies, colliders, hooks, events); narrow_phase.compute_intersections(bodies, colliders, hooks, events);
// println!("Compute contact time: {}", instant::now() - t); self.counters.cd.narrow_phase_time.pause();
self.counters.stages.collision_detection_time.pause();
}
fn build_islands_and_solve_constraints(
&mut self,
gravity: &Vector<Real>,
integration_parameters: &IntegrationParameters,
narrow_phase: &mut NarrowPhase,
bodies: &mut RigidBodySet,
colliders: &mut ColliderSet,
joints: &mut JointSet,
) {
self.counters.stages.island_construction_time.start(); self.counters.stages.island_construction_time.start();
bodies.update_active_set_with_contacts( bodies.update_active_set_with_contacts(
colliders, colliders,
@@ -135,16 +128,9 @@ impl PhysicsPipeline {
} }
let mut manifolds = Vec::new(); let mut manifolds = Vec::new();
narrow_phase.sort_and_select_active_contacts( narrow_phase.select_active_contacts(bodies, &mut manifolds, &mut self.manifold_indices);
bodies,
&mut manifolds,
&mut self.manifold_indices,
);
joints.select_active_interactions(bodies, &mut self.joint_constraint_indices); joints.select_active_interactions(bodies, &mut self.joint_constraint_indices);
self.counters.cd.narrow_phase_time.pause();
self.counters.stages.collision_detection_time.pause();
self.counters.stages.update_time.start(); self.counters.stages.update_time.start();
bodies.foreach_active_dynamic_body_mut_internal(|_, b| { bodies.foreach_active_dynamic_body_mut_internal(|_, b| {
b.update_world_mass_properties(); b.update_world_mass_properties();
@@ -218,7 +204,17 @@ impl PhysicsPipeline {
}); });
}); });
} }
self.counters.stages.solver_time.pause();
}
fn run_ccd_motion_clamping(
&mut self,
integration_parameters: &IntegrationParameters,
bodies: &mut RigidBodySet,
colliders: &mut ColliderSet,
ccd_solver: Option<&mut CCDSolver>,
events: &dyn EventHandler,
) {
// Handle CCD // Handle CCD
if let Some(ccd_solver) = ccd_solver { if let Some(ccd_solver) = ccd_solver {
let impacts = ccd_solver.predict_next_impacts( let impacts = ccd_solver.predict_next_impacts(
@@ -230,7 +226,13 @@ impl PhysicsPipeline {
); );
ccd_solver.clamp_motions(integration_parameters.dt, bodies, &impacts); ccd_solver.clamp_motions(integration_parameters.dt, bodies, &impacts);
} }
}
fn advance_to_final_positions(
&mut self,
bodies: &mut RigidBodySet,
colliders: &mut ColliderSet,
) {
// Set the rigid-bodies and kinematic bodies to their final position. // Set the rigid-bodies and kinematic bodies to their final position.
bodies.foreach_active_body_mut_internal(|_, rb| { bodies.foreach_active_body_mut_internal(|_, rb| {
if rb.is_kinematic() { if rb.is_kinematic() {
@@ -241,11 +243,68 @@ impl PhysicsPipeline {
rb.position = rb.next_position; rb.position = rb.next_position;
rb.update_colliders_positions(colliders); rb.update_colliders_positions(colliders);
}); });
}
self.counters.stages.solver_time.pause(); fn interpolate_kinematic_velocities(
&mut self,
integration_parameters: &IntegrationParameters,
bodies: &mut RigidBodySet,
) {
// Update kinematic bodies velocities.
// TODO: what is the best place for this? It should at least be
// located before the island computation because we test the velocity
// there to determine if this kinematic body should wake-up dynamic
// bodies it is touching.
bodies.foreach_active_kinematic_body_mut_internal(|_, body| {
body.compute_velocity_from_next_position(integration_parameters.inv_dt());
});
}
/// Executes one timestep of the physics simulation.
pub fn step(
&mut self,
gravity: &Vector<Real>,
integration_parameters: &IntegrationParameters,
broad_phase: &mut BroadPhase,
narrow_phase: &mut NarrowPhase,
bodies: &mut RigidBodySet,
colliders: &mut ColliderSet,
joints: &mut JointSet,
ccd_solver: Option<&mut CCDSolver>,
hooks: &dyn PhysicsHooks,
events: &dyn EventHandler,
) {
self.counters.step_started();
bodies.maintain(colliders);
self.interpolate_kinematic_velocities(integration_parameters, bodies);
self.detect_collisions(
integration_parameters,
broad_phase,
narrow_phase,
bodies,
colliders,
hooks,
events,
);
self.build_islands_and_solve_constraints(
gravity,
integration_parameters,
narrow_phase,
bodies,
colliders,
joints,
);
self.run_ccd_motion_clamping(
integration_parameters,
bodies,
colliders,
ccd_solver,
events,
);
self.advance_to_final_positions(bodies, colliders);
bodies.modified_inactive_set.clear(); bodies.modified_inactive_set.clear();
self.counters.step_completed(); self.counters.step_completed();
} }
} }