Add some early returns

This commit is contained in:
Jan Nils Ferner
2023-01-26 21:07:44 +01:00
parent 8528c6e87b
commit ff85d79956

View File

@@ -247,36 +247,31 @@ impl KinematicCharacterController {
toi, toi,
}); });
if let Some(translation_on_slope) = // If the slope is too big, try to step on the stair.
self.handle_slopes(&toi, &mut translation_remaining, offset) if !self.handle_stairs(
{ bodies,
translation_remaining = translation_on_slope; colliders,
println!("[slope] translation_on_slope: {translation_on_slope:?}"); queries,
println!("[slope] translation_remaining: {translation_remaining:?}"); character_shape,
} else { &(Translation::from(result.translation) * character_pos),
// If the slope is too big, try to step on the stair. &dims,
let stair_handled = self.handle_stairs( filter,
bodies, handle,
colliders, &mut translation_remaining,
queries, &mut result,
character_shape, ) {
&(Translation::from(result.translation) * character_pos), if let Some(translation_on_slope) =
&dims, self.handle_slopes(&toi, &mut translation_remaining, offset)
filter, {
handle, translation_remaining = translation_on_slope;
&mut translation_remaining, } else {
&mut result,
);
println!("[stair] translation_remaining: {translation_remaining:?}");
println!("[stair]stair_handled: {stair_handled:?}");
if !stair_handled {
// No slopes or stairs ahead; try to move along obstacles. // No slopes or stairs ahead; try to move along obstacles.
let allowed_translation = subtract_hit(translation_remaining, &toi, offset); let allowed_translation = subtract_hit(translation_remaining, &toi, offset);
result.translation += allowed_translation; result.translation += allowed_translation;
translation_remaining -= allowed_translation; translation_remaining -= allowed_translation;
} }
} }
} else { } else {
// No interference along the path. // No interference along the path.
result.translation += translation_remaining; result.translation += translation_remaining;
@@ -490,6 +485,8 @@ impl KinematicCharacterController {
// 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);
let climbing = self.up.dot(&slope_translation) >= 0.0; let climbing = self.up.dot(&slope_translation) >= 0.0;
println!("angle_with_floor: {}, climbing: {}", angle_with_floor, climbing);
println!("max_slope_climb_angle: {}, min_slope_slide_angle: {}", self.max_slope_climb_angle, self.min_slope_slide_angle);
climbing climbing
.then(||(angle_with_floor <= self.max_slope_climb_angle) // Are we allowed to climb? .then(||(angle_with_floor <= self.max_slope_climb_angle) // Are we allowed to climb?
@@ -528,125 +525,127 @@ impl KinematicCharacterController {
translation_remaining: &mut Vector<Real>, translation_remaining: &mut Vector<Real>,
result: &mut EffectiveCharacterMovement, result: &mut EffectiveCharacterMovement,
) -> bool { ) -> bool {
if let Some(autostep) = self.autostep { let autostep = match self.autostep {
let min_width = autostep.min_width.eval(dims.x); Some(autostep) => autostep,
let max_height = autostep.max_height.eval(dims.y); None => return false,
};
let min_width = autostep.min_width.eval(dims.x);
let max_height = autostep.max_height.eval(dims.y);
if !autostep.include_dynamic_bodies { if !autostep.include_dynamic_bodies {
if colliders if colliders
.get(stair_handle) .get(stair_handle)
.and_then(|co| co.parent) .and_then(|co| co.parent)
.and_then(|p| bodies.get(p.handle)) .and_then(|p| bodies.get(p.handle))
.map(|b| b.is_dynamic()) .map(|b| b.is_dynamic())
== Some(true) == Some(true)
{ {
// The "stair" is a dynamic body, which the user wants to ignore. // The "stair" is a dynamic body, which the user wants to ignore.
return false; return false;
}
filter.flags |= QueryFilterFlags::EXCLUDE_DYNAMIC;
} }
let shifted_character_pos = Translation::from(*self.up * max_height) * character_pos; filter.flags |= QueryFilterFlags::EXCLUDE_DYNAMIC;
}
if let Some(horizontal_dir) = (*translation_remaining let shifted_character_pos = Translation::from(*self.up * max_height) * character_pos;
- *self.up * translation_remaining.dot(&self.up))
.try_normalize(1.0e-5)
{
if queries
.cast_shape(
bodies,
colliders,
character_pos,
&self.up,
character_shape,
max_height,
false,
filter,
)
.is_some()
{
// We cant go up.
return false;
}
if queries let horizontal_dir = match (*translation_remaining - *self.up * translation_remaining.dot(&self.up))
.cast_shape( .try_normalize(1.0e-5) {
bodies, Some(dir) => dir,
colliders, None => return false,
&shifted_character_pos, };
&horizontal_dir,
character_shape,
min_width,
false,
filter,
)
.is_some()
{
// We dont have enough room on the stair to stay on it.
return false;
}
// Check that we are not getting into a ramp that is too steep if queries
// after stepping. .cast_shape(
if let Some((_, hit)) = queries.cast_shape( bodies,
colliders,
character_pos,
&self.up,
character_shape,
max_height,
false,
filter,
)
.is_some()
{
// We cant go up.
return false;
}
if queries
.cast_shape(
bodies,
colliders,
&shifted_character_pos,
&horizontal_dir,
character_shape,
min_width,
false,
filter,
)
.is_some()
{
// We dont have enough room on the stair to stay on it.
return false;
}
// Check that we are not getting into a ramp that is too steep
// after stepping.
if let Some((_, hit)) = queries.cast_shape(
bodies,
colliders,
&(Translation::from(horizontal_dir * min_width) * shifted_character_pos),
&-self.up,
character_shape,
max_height,
false,
filter,
) {
let vertical_translation_remaining =
*self.up * (self.up.dot(translation_remaining));
let horizontal_translation_remaining =
*translation_remaining - vertical_translation_remaining;
let sliding_movement = horizontal_translation_remaining
- *hit.normal1 * horizontal_translation_remaining.dot(&hit.normal1);
let angle_with_floor = self.up.angle(&hit.normal1);
let climbing = self.up.dot(&sliding_movement) >= 0.0;
if climbing && angle_with_floor > self.max_slope_climb_angle {
return false; // The target ramp is too steep.
}
}
// We can step, we need to find the actual step height.
let step_height = self.offset.eval(dims.y) + max_height
- queries
.cast_shape(
bodies, bodies,
colliders, colliders,
&(Translation::from(horizontal_dir * min_width) * shifted_character_pos), &(Translation::from(horizontal_dir * min_width)
* shifted_character_pos),
&-self.up, &-self.up,
character_shape, character_shape,
max_height, max_height,
false, false,
filter, filter,
) { )
let vertical_translation_remaining = .map(|hit| hit.1.toi)
*self.up * (self.up.dot(translation_remaining)); .unwrap_or(max_height);
let horizontal_translation_remaining =
*translation_remaining - vertical_translation_remaining;
let sliding_movement = horizontal_translation_remaining
- *hit.normal1 * horizontal_translation_remaining.dot(&hit.normal1);
let angle_with_floor = self.up.angle(&hit.normal1); // Remove the step height from the vertical part of the self.
let climbing = self.up.dot(&sliding_movement) >= 0.0; *translation_remaining -=
*self.up * translation_remaining.dot(&self.up).clamp(0.0, step_height);
if climbing && angle_with_floor > self.max_slope_climb_angle { // Advance the collider on the step horizontally, to make sure further
return false; // The target ramp is too steep. // movement wont just get stuck on its edge.
} let horizontal_nudge =
} horizontal_dir * min_width.min(horizontal_dir.dot(translation_remaining));
*translation_remaining -= horizontal_nudge;
// We can step, we need to find the actual step height. result.translation += *self.up * step_height + horizontal_nudge;
let step_height = self.offset.eval(dims.y) + max_height return true;
- queries
.cast_shape(
bodies,
colliders,
&(Translation::from(horizontal_dir * min_width)
* shifted_character_pos),
&-self.up,
character_shape,
max_height,
false,
filter,
)
.map(|hit| hit.1.toi)
.unwrap_or(max_height);
// Remove the step height from the vertical part of the self.
*translation_remaining -=
*self.up * translation_remaining.dot(&self.up).clamp(0.0, step_height);
// Advance the collider on the step horizontally, to make sure further
// movement wont just get stuck on its edge.
let horizontal_nudge =
horizontal_dir * min_width.min(horizontal_dir.dot(translation_remaining));
*translation_remaining -= horizontal_nudge;
result.translation += *self.up * step_height + horizontal_nudge;
return true;
}
}
false
} }
/// For a given collision between a character and its environment, this method will apply /// For a given collision between a character and its environment, this method will apply