Merge pull request #470 from Jeff425/sliding_down_slope_output

#465 Add is_sliding_down_slope field to EffectiveCharacterMovement
This commit is contained in:
Sébastien Crozet
2023-03-26 14:56:04 +02:00
committed by GitHub
2 changed files with 23 additions and 9 deletions

View File

@@ -135,6 +135,8 @@ pub struct EffectiveCharacterMovement {
pub translation: Vector<Real>, pub translation: Vector<Real>,
/// Is the character touching the ground after applying `EffectiveKineamticMovement::translation`? /// Is the character touching the ground after applying `EffectiveKineamticMovement::translation`?
pub grounded: bool, pub grounded: bool,
/// Is the character sliding down a slope due to slope angle being larger than `min_slope_slide_angle`?
pub is_sliding_down_slope: bool,
} }
impl KinematicCharacterController { impl KinematicCharacterController {
@@ -184,6 +186,7 @@ impl KinematicCharacterController {
let mut result = EffectiveCharacterMovement { let mut result = EffectiveCharacterMovement {
translation: Vector::zeros(), translation: Vector::zeros(),
grounded: false, grounded: false,
is_sliding_down_slope: false,
}; };
let dims = self.compute_dims(character_shape); let dims = self.compute_dims(character_shape);
@@ -258,7 +261,8 @@ impl KinematicCharacterController {
&mut result, &mut result,
) { ) {
// No stairs, try to move along slopes. // No stairs, try to move along slopes.
translation_remaining = self.handle_slopes(&toi, &translation_remaining); translation_remaining =
self.handle_slopes(&toi, &translation_remaining, &mut result);
} }
} else { } else {
// No interference along the path. // No interference along the path.
@@ -472,13 +476,19 @@ impl KinematicCharacterController {
false false
} }
fn handle_slopes(&self, hit: &TOI, translation_remaining: &Vector<Real>) -> Vector<Real> { fn handle_slopes(
&self,
hit: &TOI,
translation_remaining: &Vector<Real>,
result: &mut EffectiveCharacterMovement,
) -> Vector<Real> {
let [vertical_translation, horizontal_translation] = let [vertical_translation, horizontal_translation] =
self.split_into_components(translation_remaining); self.split_into_components(translation_remaining);
let slope_translation = subtract_hit(*translation_remaining, hit); let slope_translation = subtract_hit(*translation_remaining, hit);
// Check if there is a slope to climb. // Check if there is a slope to climb.
let angle_with_floor = self.up.angle(&hit.normal1); let angle_with_floor = self.up.angle(&hit.normal1);
// We are climbing if the movement along the slope goes upward, and the angle with the // We are climbing if the movement along the slope goes upward, and the angle with the
// floor is smaller than pi/2 (in which case we hit some some sort of ceiling). // floor is smaller than pi/2 (in which case we hit some some sort of ceiling).
// //
@@ -495,6 +505,7 @@ impl KinematicCharacterController {
horizontal_translation horizontal_translation
} else { } else {
// Let it slide // Let it slide
result.is_sliding_down_slope = true;
slope_translation slope_translation
} }
} }

View File

@@ -6,7 +6,6 @@ use crate::math::{Isometry, Point, Real, Vector};
use crate::{dynamics::RigidBodySet, geometry::ColliderSet}; use crate::{dynamics::RigidBodySet, geometry::ColliderSet};
use parry::partitioning::{QbvhDataGenerator, QbvhUpdateWorkspace}; use parry::partitioning::{QbvhDataGenerator, QbvhUpdateWorkspace};
use parry::query::details::{ use parry::query::details::{
IntersectionCompositeShapeShapeBestFirstVisitor,
NonlinearTOICompositeShapeShapeBestFirstVisitor, PointCompositeShapeProjBestFirstVisitor, NonlinearTOICompositeShapeShapeBestFirstVisitor, PointCompositeShapeProjBestFirstVisitor,
PointCompositeShapeProjWithFeatureBestFirstVisitor, PointCompositeShapeProjWithFeatureBestFirstVisitor,
RayCompositeShapeToiAndNormalBestFirstVisitor, RayCompositeShapeToiBestFirstVisitor, RayCompositeShapeToiAndNormalBestFirstVisitor, RayCompositeShapeToiBestFirstVisitor,
@@ -539,12 +538,16 @@ impl QueryPipeline {
filter: QueryFilter, filter: QueryFilter,
) -> Option<ColliderHandle> { ) -> Option<ColliderHandle> {
let pipeline_shape = self.as_composite_shape(bodies, colliders, filter); let pipeline_shape = self.as_composite_shape(bodies, colliders, filter);
let mut visitor = IntersectionCompositeShapeShapeBestFirstVisitor::new( #[allow(deprecated)]
&*self.query_dispatcher, // TODO: replace this with IntersectionCompositeShapeShapeVisitor when it
shape_pos, // can return the shape part id.
&pipeline_shape, let mut visitor =
shape, parry::query::details::IntersectionCompositeShapeShapeBestFirstVisitor::new(
); &*self.query_dispatcher,
shape_pos,
&pipeline_shape,
shape,
);
self.qbvh self.qbvh
.traverse_best_first(&mut visitor) .traverse_best_first(&mut visitor)