diff options
Diffstat (limited to 'scene/2d/tile_map_layer.cpp')
-rw-r--r-- | scene/2d/tile_map_layer.cpp | 97 |
1 files changed, 58 insertions, 39 deletions
diff --git a/scene/2d/tile_map_layer.cpp b/scene/2d/tile_map_layer.cpp index ba0958e74b..ebb03e4e73 100644 --- a/scene/2d/tile_map_layer.cpp +++ b/scene/2d/tile_map_layer.cpp @@ -443,13 +443,15 @@ void TileMapLayer::_rendering_notification(int p_what) { Transform2D tilemap_xform = get_global_transform(); for (KeyValue<Vector2i, CellData> &kv : tile_map_layer_data) { const CellData &cell_data = kv.value; - for (const RID &occluder : cell_data.occluders) { - if (occluder.is_null()) { - continue; + for (const LocalVector<RID> &polygons : cell_data.occluders) { + for (const RID &rid : polygons) { + if (rid.is_null()) { + continue; + } + Transform2D xform(0, tile_set->map_to_local(kv.key)); + rs->canvas_light_occluder_attach_to_canvas(rid, get_canvas()); + rs->canvas_light_occluder_set_transform(rid, tilemap_xform * xform); } - Transform2D xform(0, tile_set->map_to_local(kv.key)); - rs->canvas_light_occluder_attach_to_canvas(occluder, get_canvas()); - rs->canvas_light_occluder_set_transform(occluder, tilemap_xform * xform); } } } @@ -557,8 +559,10 @@ void TileMapLayer::_rendering_occluders_clear_cell(CellData &r_cell_data) { RenderingServer *rs = RenderingServer::get_singleton(); // Free the occluders. - for (const RID &rid : r_cell_data.occluders) { - rs->free(rid); + for (const LocalVector<RID> &polygons : r_cell_data.occluders) { + for (const RID &rid : polygons) { + rs->free(rid); + } } r_cell_data.occluders.clear(); } @@ -566,11 +570,12 @@ void TileMapLayer::_rendering_occluders_clear_cell(CellData &r_cell_data) { void TileMapLayer::_rendering_occluders_update_cell(CellData &r_cell_data) { RenderingServer *rs = RenderingServer::get_singleton(); - // Free unused occluders then resize the occluders array. + // Free unused occluders then resize the occluder array. for (uint32_t i = tile_set->get_occlusion_layers_count(); i < r_cell_data.occluders.size(); i++) { - RID occluder_id = r_cell_data.occluders[i]; - if (occluder_id.is_valid()) { - rs->free(occluder_id); + for (const RID &occluder_id : r_cell_data.occluders[i]) { + if (occluder_id.is_valid()) { + rs->free(occluder_id); + } } } r_cell_data.occluders.resize(tile_set->get_occlusion_layers_count()); @@ -598,30 +603,42 @@ void TileMapLayer::_rendering_occluders_update_cell(CellData &r_cell_data) { // Create, update or clear occluders. bool needs_set_not_interpolated = is_inside_tree() && get_tree()->is_physics_interpolation_enabled() && !is_physics_interpolated(); for (uint32_t occlusion_layer_index = 0; occlusion_layer_index < r_cell_data.occluders.size(); occlusion_layer_index++) { - Ref<OccluderPolygon2D> occluder_polygon = tile_data->get_occluder(occlusion_layer_index); - - RID &occluder = r_cell_data.occluders[occlusion_layer_index]; + LocalVector<RID> &occluders = r_cell_data.occluders[occlusion_layer_index]; - if (occluder_polygon.is_valid()) { - // Create or update occluder. - Transform2D xform; - xform.set_origin(tile_set->map_to_local(r_cell_data.coords)); - if (!occluder.is_valid()) { - occluder = rs->canvas_light_occluder_create(); - if (needs_set_not_interpolated) { - rs->canvas_light_occluder_set_interpolated(occluder, false); - } + // Free unused occluders then resize the occluders array. + for (uint32_t i = tile_data->get_occluder_polygons_count(occlusion_layer_index); i < r_cell_data.occluders[occlusion_layer_index].size(); i++) { + RID occluder_id = occluders[i]; + if (occluder_id.is_valid()) { + rs->free(occluder_id); } - rs->canvas_light_occluder_set_transform(occluder, get_global_transform() * xform); - rs->canvas_light_occluder_set_polygon(occluder, tile_data->get_occluder(occlusion_layer_index, flip_h, flip_v, transpose)->get_rid()); - rs->canvas_light_occluder_attach_to_canvas(occluder, get_canvas()); - rs->canvas_light_occluder_set_light_mask(occluder, tile_set->get_occlusion_layer_light_mask(occlusion_layer_index)); - rs->canvas_light_occluder_set_as_sdf_collision(occluder, tile_set->get_occlusion_layer_sdf_collision(occlusion_layer_index)); - } else { - // Clear occluder. - if (occluder.is_valid()) { - rs->free(occluder); - occluder = RID(); + } + occluders.resize(tile_data->get_occluder_polygons_count(occlusion_layer_index)); + + for (uint32_t occlusion_polygon_index = 0; occlusion_polygon_index < occluders.size(); occlusion_polygon_index++) { + RID &occluder = occluders[occlusion_polygon_index]; + Ref<OccluderPolygon2D> occluder_polygon = tile_data->get_occluder_polygon(occlusion_layer_index, occlusion_polygon_index); + if (occluder_polygon.is_valid()) { + // Create or update occluder. + + Transform2D xform; + xform.set_origin(tile_set->map_to_local(r_cell_data.coords)); + if (!occluder.is_valid()) { + occluder = rs->canvas_light_occluder_create(); + if (needs_set_not_interpolated) { + rs->canvas_light_occluder_set_interpolated(occluder, false); + } + } + rs->canvas_light_occluder_set_transform(occluder, get_global_transform() * xform); + rs->canvas_light_occluder_set_polygon(occluder, tile_data->get_occluder_polygon(occlusion_layer_index, occlusion_polygon_index, flip_h, flip_v, transpose)->get_rid()); + rs->canvas_light_occluder_attach_to_canvas(occluder, get_canvas()); + rs->canvas_light_occluder_set_light_mask(occluder, tile_set->get_occlusion_layer_light_mask(occlusion_layer_index)); + rs->canvas_light_occluder_set_as_sdf_collision(occluder, tile_set->get_occlusion_layer_sdf_collision(occlusion_layer_index)); + } else { + // Clear occluder. + if (occluder.is_valid()) { + rs->free(occluder); + occluder = RID(); + } } } } @@ -1709,11 +1726,13 @@ void TileMapLayer::_physics_interpolated_changed() { } for (const KeyValue<Vector2i, CellData> &E : tile_map_layer_data) { - for (const RID &occluder : E.value.occluders) { - if (occluder.is_valid()) { - rs->canvas_light_occluder_set_interpolated(occluder, interpolated); - if (needs_reset) { - rs->canvas_light_occluder_reset_physics_interpolation(occluder); + for (const LocalVector<RID> &polygons : E.value.occluders) { + for (const RID &occluder_id : polygons) { + if (occluder_id.is_valid()) { + rs->canvas_light_occluder_set_interpolated(occluder_id, interpolated); + if (needs_reset) { + rs->canvas_light_occluder_reset_physics_interpolation(occluder_id); + } } } } |