feat: change the character controller’s solve_character_collision_impulses to take multiple CharacterCollision (#646)

* character controller: solve multiple collisions

* add solve multiple collisions to changelog

* chore: apply review comments

---------

Co-authored-by: Sébastien Crozet <sebcrozet@dimforge.com>
This commit is contained in:
Thierry Berger
2024-06-09 13:20:58 +02:00
committed by GitHub
parent a8a0f297f5
commit 8160b4ebdb
3 changed files with 43 additions and 15 deletions

View File

@@ -51,6 +51,8 @@ This release introduces two new crates:
- Rename `JointAxesMask::X/Y/Z` to `::LIN_X/LIN_Y/LIN_Z` to avoid confusing it with `::ANG_X/ANG_Y/ANG_Z`. - Rename `JointAxesMask::X/Y/Z` to `::LIN_X/LIN_Y/LIN_Z` to avoid confusing it with `::ANG_X/ANG_Y/ANG_Z`.
- The function `RigidBody::add_collider` is now private. It was only public because it was needed for some internal - The function `RigidBody::add_collider` is now private. It was only public because it was needed for some internal
`bevy_rapier` plumbings, but it is no longer useful. Adding a collider must always go througthe `ColliderSet`. `bevy_rapier` plumbings, but it is no longer useful. Adding a collider must always go througthe `ColliderSet`.
- `CharacterController::solve_character_collision_impulses` now takes multiple `CharacterCollision` as parameter:
this change will allow further internal optimizations.
## v0.19.0 (05 May 2024) ## v0.19.0 (05 May 2024)

View File

@@ -782,11 +782,40 @@ impl KinematicCharacterController {
true true
} }
/// For a given collision between a character and its environment, this method will apply /// For the given collisions between a character and its environment, this method will apply
/// impulses to the rigid-bodies surrounding the character shape at the time of the collision. /// impulses to the rigid-bodies surrounding the character shape at the time of the collisions.
/// Note that the impulse calculation is only approximate as it is not based on a global /// Note that the impulse calculation is only approximate as it is not based on a global
/// constraints resolution scheme. /// constraints resolution scheme.
pub fn solve_character_collision_impulses( pub fn solve_character_collision_impulses(
&self,
dt: Real,
bodies: &mut RigidBodySet,
colliders: &ColliderSet,
queries: &QueryPipeline,
character_shape: &dyn Shape,
character_mass: Real,
collisions: impl IntoIterator<Item = CharacterCollision>,
filter: QueryFilter,
) {
for collision in collisions {
self.solve_single_character_collision_impulse(
dt,
bodies,
colliders,
queries,
character_shape,
character_mass,
&collision,
filter,
);
}
}
/// For the given collision between a character and its environment, this method will apply
/// impulses to the rigid-bodies surrounding the character shape at the time of the collision.
/// Note that the impulse calculation is only approximate as it is not based on a global
/// constraints resolution scheme.
fn solve_single_character_collision_impulse(
&self, &self,
dt: Real, dt: Real,
bodies: &mut RigidBodySet, bodies: &mut RigidBodySet,

View File

@@ -811,8 +811,6 @@ impl<'a, 'b, 'c, 'd, 'e, 'f> Testbed<'a, 'b, 'c, 'd, 'e, 'f> {
QueryFilter::new().exclude_rigid_body(character_handle), QueryFilter::new().exclude_rigid_body(character_handle),
|c| collisions.push(c), |c| collisions.push(c),
); );
for collision in &collisions {
controller.solve_character_collision_impulses( controller.solve_character_collision_impulses(
phx.integration_parameters.dt, phx.integration_parameters.dt,
&mut phx.bodies, &mut phx.bodies,
@@ -820,10 +818,9 @@ impl<'a, 'b, 'c, 'd, 'e, 'f> Testbed<'a, 'b, 'c, 'd, 'e, 'f> {
&phx.query_pipeline, &phx.query_pipeline,
character_collider.shape(), character_collider.shape(),
character_mass, character_mass,
collision, collisions,
QueryFilter::new().exclude_rigid_body(character_handle), QueryFilter::new().exclude_rigid_body(character_handle),
) );
}
let character_body = &mut phx.bodies[character_handle]; let character_body = &mut phx.bodies[character_handle];
let pos = character_body.position(); let pos = character_body.position();