Add some early returns
This commit is contained in:
@@ -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 can’t 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 don’t 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 can’t go up.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if queries
|
||||||
|
.cast_shape(
|
||||||
|
bodies,
|
||||||
|
colliders,
|
||||||
|
&shifted_character_pos,
|
||||||
|
&horizontal_dir,
|
||||||
|
character_shape,
|
||||||
|
min_width,
|
||||||
|
false,
|
||||||
|
filter,
|
||||||
|
)
|
||||||
|
.is_some()
|
||||||
|
{
|
||||||
|
// We don’t 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 won’t 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 won’t 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
|
||||||
|
|||||||
Reference in New Issue
Block a user