Merge pull request #109820 from groud/fix_one_way_collision_tilemaplayer

Fix one-way-collision polygons being merged despite being on different Y-origins in TileMapLayer
This commit is contained in:
Thaddeus Crews
2025-08-22 16:11:53 -05:00
2 changed files with 12 additions and 1 deletions

View File

@@ -841,6 +841,7 @@ void TileMapLayer::_physics_update(bool p_force_cleanup) {
physics_body_key.angular_velocity = angular_velocity;
physics_body_key.one_way_collision = tile_data->is_collision_polygon_one_way(tile_set_physics_layer, polygon_index);
physics_body_key.one_way_collision_margin = tile_data->get_collision_polygon_one_way_margin(tile_set_physics_layer, polygon_index);
physics_body_key.y_origin = map_to_local(cell_data.coords).y;
if (!physics_quadrant->bodies.has(physics_body_key)) {
RID body = ps->body_create();

View File

@@ -243,14 +243,20 @@ public:
int physics_layer = 0;
Vector2 linear_velocity;
real_t angular_velocity = 0.0;
bool one_way_collision = false;
real_t one_way_collision_margin = 0.0;
int64_t y_origin = 0; // This is only used if one_way_collision is on, to avoid merging polygons vertically in that case.
bool operator<(const PhysicsBodyKey &p_other) const {
if (physics_layer == p_other.physics_layer) {
if (linear_velocity == p_other.linear_velocity) {
if (angular_velocity == p_other.angular_velocity) {
if (one_way_collision == p_other.one_way_collision) {
if (one_way_collision && y_origin != p_other.y_origin) {
return y_origin < p_other.y_origin;
}
return one_way_collision_margin < p_other.one_way_collision_margin;
}
return one_way_collision < p_other.one_way_collision;
@@ -270,7 +276,8 @@ public:
linear_velocity == p_other.linear_velocity &&
angular_velocity == p_other.angular_velocity &&
one_way_collision == p_other.one_way_collision &&
one_way_collision_margin == p_other.one_way_collision_margin;
one_way_collision_margin == p_other.one_way_collision_margin &&
(!one_way_collision || y_origin == p_other.y_origin);
}
};
@@ -280,6 +287,9 @@ public:
h = hash_murmur3_one_real(p_hash.linear_velocity.x);
h = hash_murmur3_one_real(p_hash.linear_velocity.y, h);
h = hash_murmur3_one_real(p_hash.angular_velocity, h);
if (p_hash.one_way_collision) {
h = hash_murmur3_one_32(p_hash.y_origin, h);
}
return h;
}
};