From b9e68c815526ef94217148e35e700f3d1dd00be8 Mon Sep 17 00:00:00 2001 From: PouleyKetchoupp Date: Wed, 4 Aug 2021 16:13:33 -0700 Subject: Fix one-way collision in Tilemap In a given quadrant there can be one or more bodies used, and the process iterated over cells to add the shapes, so the shape index doesn't necessarily correspond to the polygon shape index. Instead body shape indices need to be tracked separately. --- scene/2d/tile_map.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index 6afa0c0779..a91bb8e968 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -1053,9 +1053,13 @@ void TileMap::_physics_update_dirty_quadrants(SelfList::List &r Vector2 quadrant_pos = map_to_world(q.coords * get_effective_quadrant_size(q.layer)); + LocalVector body_shape_count; + body_shape_count.resize(q.bodies.size()); + // Clear shapes. for (int body_index = 0; body_index < q.bodies.size(); body_index++) { ps->body_clear_shapes(q.bodies[body_index]); + body_shape_count[body_index] = 0; // Position the bodies. Transform2D xform; @@ -1080,6 +1084,8 @@ void TileMap::_physics_update_dirty_quadrants(SelfList::List &r TileData *tile_data = Object::cast_to(atlas_source->get_tile_data(c.get_atlas_coords(), c.alternative_tile)); for (int body_index = 0; body_index < q.bodies.size(); body_index++) { + int &body_shape_index = body_shape_count[body_index]; + // Add the shapes again. for (int polygon_index = 0; polygon_index < tile_data->get_collision_polygons_count(body_index); polygon_index++) { bool one_way_collision = tile_data->is_collision_polygon_one_way(body_index, polygon_index); @@ -1093,8 +1099,10 @@ void TileMap::_physics_update_dirty_quadrants(SelfList::List &r // Add decomposed convex shapes. Ref shape = tile_data->get_collision_polygon_shape(body_index, polygon_index, shape_index); ps->body_add_shape(q.bodies[body_index], shape->get_rid(), xform); - ps->body_set_shape_metadata(q.bodies[body_index], shape_index, E_cell->get()); - ps->body_set_shape_as_one_way_collision(q.bodies[body_index], shape_index, one_way_collision, one_way_collision_margin); + ps->body_set_shape_metadata(q.bodies[body_index], body_shape_index, E_cell->get()); + ps->body_set_shape_as_one_way_collision(q.bodies[body_index], body_shape_index, one_way_collision, one_way_collision_margin); + + ++body_shape_index; } } } -- cgit v1.2.3