From 5f743f46fc2db31bb7d48b8e2f4dd09fbb9111d9 Mon Sep 17 00:00:00 2001 From: Zicklag Date: Thu, 9 Mar 2023 19:26:10 -0600 Subject: [PATCH] fix: fix incorrect ground state detection when intersecting jump-through tiles. (#708) Closes: #705 --- core/src/physics.rs | 34 ++++++++++++++++++++++++++++++---- core/src/physics/collisions.rs | 11 ++++++++++- 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/core/src/physics.rs b/core/src/physics.rs index dab90db441..0a653dd202 100644 --- a/core/src/physics.rs +++ b/core/src/physics.rs @@ -218,16 +218,42 @@ fn update_kinematic_bodies( // Check ground collision { let mut transform = transforms.get(entity).copied().unwrap(); + + // Don't get stuck floating in fall-through platforms + if body.velocity == Vec2::ZERO + && collision_world.tile_collision_filtered(transform, body.shape, |ent| { + collision_world + .tile_collision_kinds + .get(ent) + .map(|x| *x == TileCollisionKind::JumpThrough) + .unwrap_or(false) + }) == TileCollisionKind::JumpThrough + { + body.fall_through = true; + } + + // Move transform check down 1 slightly transform.translation.y -= 0.1; body.was_on_ground = body.is_on_ground; - let tile = collision_world.tile_collision(transform, body.shape); + let collider = collision_world.get_collider(entity); + + let tile = collision_world.tile_collision_filtered(transform, body.shape, |ent| { + if collider.seen_wood { + collision_world + .tile_collision_kinds + .get(ent) + .map(|x| *x != TileCollisionKind::JumpThrough) + .unwrap_or(false) + } else { + true + } + }); let on_jump_through_tile = tile == TileCollisionKind::JumpThrough; - body.is_on_ground = tile != TileCollisionKind::Empty - && !collision_world.get_collider(entity).seen_wood - && !(on_jump_through_tile && body.fall_through); + body.is_on_ground = + tile != TileCollisionKind::Empty && !(on_jump_through_tile && body.fall_through); body.is_on_platform = body.is_on_ground && on_jump_through_tile; } diff --git a/core/src/physics/collisions.rs b/core/src/physics/collisions.rs index f50bc04d23..18590920b3 100644 --- a/core/src/physics/collisions.rs +++ b/core/src/physics/collisions.rs @@ -870,6 +870,15 @@ impl<'a> CollisionWorld<'a> { /// Get the [`TileCollisionKind`] of the first tile detected colliding with the `shape` at the /// given `transform`. pub fn tile_collision(&self, transform: Transform, shape: ColliderShape) -> TileCollisionKind { + self.tile_collision_filtered(transform, shape, |_| true) + } + + pub fn tile_collision_filtered( + &self, + transform: Transform, + shape: ColliderShape, + filter: impl Fn(Entity) -> bool, + ) -> TileCollisionKind { self.ctx .query_pipeline .intersection_with_shape( @@ -883,7 +892,7 @@ impl<'a> CollisionWorld<'a> { &*shape.shared_shape(), rapier::QueryFilter::new().predicate(&|_handle, collider| { let ent = RapierUserData::entity(collider.user_data); - self.tile_collision_kinds.contains(ent) + self.tile_collision_kinds.contains(ent) && filter(ent) }), ) .map(|x| RapierUserData::entity(self.ctx.collider_set.get(x).unwrap().user_data))