Skip to content

Commit c285a69

Browse files
horvbalintcart
andcommitted
Add the Inside version to the Collision enum (#2489)
# Objective I think the 'collide' function inside the 'bevy/crates/bevy_sprite/src/collide_aabb.rs' file should return 'Some' if the two rectangles are fully overlapping or one is inside the other. This can happen on low-end machines when a lot of time passes between two frames because of a stutter, so a bullet for example gets inside its target. I can also think of situations where this is a valid use case even without stutters. ## Solution I added an 'Inside' version to the Collision enum declared in the file. And I use it, when the two rectangles are overlapping, but we can't say from which direction it happened. I gave a 'penetration depth' of minus Infinity to these cases, so that this variant only appears, when the two rectangles overlap from each side fully. I am not sure if this is the right thing to do. Fixes #1980 Co-authored-by: Carter Anderson <[email protected]>
1 parent 4134577 commit c285a69

File tree

2 files changed

+12
-17
lines changed

2 files changed

+12
-17
lines changed

crates/bevy_sprite/src/collide_aabb.rs

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ pub enum Collision {
88
Right,
99
Top,
1010
Bottom,
11+
Inside,
1112
}
1213

1314
// TODO: ideally we can remove this once bevy gets a physics system
@@ -27,35 +28,28 @@ pub fn collide(a_pos: Vec3, a_size: Vec2, b_pos: Vec3, b_size: Vec2) -> Option<C
2728
// check to see if we hit on the left or right side
2829
let (x_collision, x_depth) = if a_min.x < b_min.x && a_max.x > b_min.x && a_max.x < b_max.x
2930
{
30-
(Some(Collision::Left), b_min.x - a_max.x)
31+
(Collision::Left, b_min.x - a_max.x)
3132
} else if a_min.x > b_min.x && a_min.x < b_max.x && a_max.x > b_max.x {
32-
(Some(Collision::Right), a_min.x - b_max.x)
33+
(Collision::Right, a_min.x - b_max.x)
3334
} else {
34-
(None, 0.0)
35+
(Collision::Inside, -f32::INFINITY)
3536
};
3637

3738
// check to see if we hit on the top or bottom side
3839
let (y_collision, y_depth) = if a_min.y < b_min.y && a_max.y > b_min.y && a_max.y < b_max.y
3940
{
40-
(Some(Collision::Bottom), b_min.y - a_max.y)
41+
(Collision::Bottom, b_min.y - a_max.y)
4142
} else if a_min.y > b_min.y && a_min.y < b_max.y && a_max.y > b_max.y {
42-
(Some(Collision::Top), a_min.y - b_max.y)
43+
(Collision::Top, a_min.y - b_max.y)
4344
} else {
44-
(None, 0.0)
45+
(Collision::Inside, -f32::INFINITY)
4546
};
4647

4748
// if we had an "x" and a "y" collision, pick the "primary" side using penetration depth
48-
match (x_collision, y_collision) {
49-
(Some(x_collision), Some(y_collision)) => {
50-
if y_depth.abs() < x_depth.abs() {
51-
Some(y_collision)
52-
} else {
53-
Some(x_collision)
54-
}
55-
}
56-
(Some(x_collision), None) => Some(x_collision),
57-
(None, Some(y_collision)) => Some(y_collision),
58-
(None, None) => None,
49+
if y_depth.abs() < x_depth.abs() {
50+
Some(y_collision)
51+
} else {
52+
Some(x_collision)
5953
}
6054
} else {
6155
None

examples/game/breakout.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,7 @@ fn ball_collision_system(
288288
Collision::Right => reflect_x = velocity.x < 0.0,
289289
Collision::Top => reflect_y = velocity.y < 0.0,
290290
Collision::Bottom => reflect_y = velocity.y > 0.0,
291+
Collision::Inside => { /* do nothing */ }
291292
}
292293

293294
// reflect velocity on the x-axis if we hit something on the x-axis

0 commit comments

Comments
 (0)