From fcb8d19de0c2155384b629a7cd5dcf84401e3409 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gilles=20Roudi=C3=A8re?= Date: Thu, 7 Dec 2023 18:18:18 +0100 Subject: [PATCH] Fixes TileMap occluders --- scene/2d/tile_map.cpp | 75 ++++++++++++++++++++++++++++--------------- scene/2d/tile_map.h | 2 +- 2 files changed, 50 insertions(+), 27 deletions(-) diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index a8f7d18503a..04e362c4268 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -447,9 +447,11 @@ void TileMapLayer::_rendering_update() { for (KeyValue &kv : tile_map) { CellData &cell_data = kv.value; for (const RID &occluder : cell_data.occluders) { - Transform2D xform(0, tile_map_node->map_to_local(kv.key)); - rs->canvas_light_occluder_attach_to_canvas(occluder, tile_map_node->get_canvas()); - rs->canvas_light_occluder_set_transform(occluder, tile_map_node->get_global_transform() * xform); + if (occluder.is_valid()) { + Transform2D xform(0, tile_map_node->map_to_local(kv.key)); + rs->canvas_light_occluder_attach_to_canvas(occluder, tile_map_node->get_canvas()); + rs->canvas_light_occluder_set_transform(occluder, tile_map_node->get_global_transform() * xform); + } } } } @@ -565,6 +567,15 @@ void TileMapLayer::_rendering_occluders_update_cell(CellData &r_cell_data) { const Ref &tile_set = tile_map_node->get_tileset(); RenderingServer *rs = RenderingServer::get_singleton(); + // Free unused occluders then resize the occluders 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); + } + } + r_cell_data.occluders.resize(tile_set->get_occlusion_layers_count()); + TileSetSource *source; if (tile_set->has_source(r_cell_data.cell.source_id)) { source = *tile_set->get_source(r_cell_data.cell.source_id); @@ -580,18 +591,30 @@ void TileMapLayer::_rendering_occluders_update_cell(CellData &r_cell_data) { tile_data = atlas_source->get_tile_data(r_cell_data.cell.get_atlas_coords(), r_cell_data.cell.alternative_tile); } - // Update/create occluders. - for (int i = 0; i < tile_set->get_occlusion_layers_count(); i++) { - Transform2D xform; - xform.set_origin(tile_map_node->map_to_local(r_cell_data.coords)); - if (tile_data->get_occluder(i).is_valid()) { - RID occluder_id = rs->canvas_light_occluder_create(); - rs->canvas_light_occluder_set_enabled(occluder_id, node_visible); - rs->canvas_light_occluder_set_transform(occluder_id, tile_map_node->get_global_transform() * xform); - rs->canvas_light_occluder_set_polygon(occluder_id, tile_map_node->get_transformed_polygon(Ref(tile_data->get_occluder(i)), r_cell_data.cell.alternative_tile)->get_rid()); - rs->canvas_light_occluder_attach_to_canvas(occluder_id, tile_map_node->get_canvas()); - rs->canvas_light_occluder_set_light_mask(occluder_id, tile_set->get_occlusion_layer_light_mask(i)); - r_cell_data.occluders.push_back(occluder_id); + // Create, update or clear occluders. + for (uint32_t occlusion_layer_index = 0; occlusion_layer_index < r_cell_data.occluders.size(); occlusion_layer_index++) { + Ref occluder_polygon = tile_data->get_occluder(occlusion_layer_index); + + RID &occluder = r_cell_data.occluders[occlusion_layer_index]; + + if (occluder_polygon.is_valid()) { + // Create or update occluder. + Transform2D xform; + xform.set_origin(tile_map_node->map_to_local(r_cell_data.coords)); + if (!occluder.is_valid()) { + occluder = rs->canvas_light_occluder_create(); + } + rs->canvas_light_occluder_set_enabled(occluder, node_visible); + rs->canvas_light_occluder_set_transform(occluder, tile_map_node->get_global_transform() * xform); + rs->canvas_light_occluder_set_polygon(occluder, tile_map_node->get_transformed_polygon(Ref(tile_data->get_occluder(occlusion_layer_index)), r_cell_data.cell.alternative_tile)->get_rid()); + rs->canvas_light_occluder_attach_to_canvas(occluder, tile_map_node->get_canvas()); + rs->canvas_light_occluder_set_light_mask(occluder, tile_set->get_occlusion_layer_light_mask(occlusion_layer_index)); + } else { + // Clear occluder. + if (occluder.is_valid()) { + rs->free(occluder); + occluder = RID(); + } } } @@ -778,7 +801,7 @@ void TileMapLayer::_physics_update_cell(CellData &r_cell_data) { } // Free unused bodies then resize the bodies array. - for (unsigned int i = tile_set->get_physics_layers_count(); i < r_cell_data.bodies.size(); i++) { + for (uint32_t i = tile_set->get_physics_layers_count(); i < r_cell_data.bodies.size(); i++) { RID body = r_cell_data.bodies[i]; if (body.is_valid()) { bodies_coords.erase(body); @@ -787,7 +810,7 @@ void TileMapLayer::_physics_update_cell(CellData &r_cell_data) { } r_cell_data.bodies.resize(tile_set->get_physics_layers_count()); - for (int tile_set_physics_layer = 0; tile_set_physics_layer < tile_set->get_physics_layers_count(); tile_set_physics_layer++) { + for (uint32_t tile_set_physics_layer = 0; tile_set_physics_layer < (uint32_t)tile_set->get_physics_layers_count(); tile_set_physics_layer++) { Ref physics_material = tile_set->get_physics_layer_physics_material(tile_set_physics_layer); uint32_t physics_layer = tile_set->get_physics_layer_collision_layer(tile_set_physics_layer); uint32_t physics_mask = tile_set->get_physics_layer_collision_mask(tile_set_physics_layer); @@ -998,7 +1021,7 @@ void TileMapLayer::_navigation_update() { void TileMapLayer::_navigation_clear_cell(CellData &r_cell_data) { NavigationServer2D *ns = NavigationServer2D::get_singleton(); // Clear navigation shapes. - for (unsigned int i = 0; i < r_cell_data.navigation_regions.size(); i++) { + for (uint32_t i = 0; i < r_cell_data.navigation_regions.size(); i++) { const RID ®ion = r_cell_data.navigation_regions[i]; if (region.is_valid()) { ns->region_set_map(region, RID()); @@ -1031,7 +1054,7 @@ void TileMapLayer::_navigation_update_cell(CellData &r_cell_data) { } // Free unused regions then resize the regions array. - for (unsigned int i = tile_set->get_navigation_layers_count(); i < r_cell_data.navigation_regions.size(); i++) { + for (uint32_t i = tile_set->get_navigation_layers_count(); i < r_cell_data.navigation_regions.size(); i++) { RID ®ion = r_cell_data.navigation_regions[i]; if (region.is_valid()) { ns->region_set_map(region, RID()); @@ -1042,7 +1065,7 @@ void TileMapLayer::_navigation_update_cell(CellData &r_cell_data) { r_cell_data.navigation_regions.resize(tile_set->get_navigation_layers_count()); // Create, update or clear regions. - for (unsigned int navigation_layer_index = 0; navigation_layer_index < r_cell_data.navigation_regions.size(); navigation_layer_index++) { + for (uint32_t navigation_layer_index = 0; navigation_layer_index < r_cell_data.navigation_regions.size(); navigation_layer_index++) { Ref navigation_polygon; navigation_polygon = tile_data->get_navigation_polygon(navigation_layer_index); navigation_polygon = tile_map_node->get_transformed_polygon(Ref(navigation_polygon), c.alternative_tile); @@ -3250,7 +3273,7 @@ void TileMap::add_layer(int p_to_pos) { new_layer.instantiate(); new_layer->set_tile_map(this); layers.insert(p_to_pos, new_layer); - for (unsigned int i = 0; i < layers.size(); i++) { + for (uint32_t i = 0; i < layers.size(); i++) { layers[i]->set_layer_index_in_tile_map_node(i); } queue_internal_update(); @@ -3269,7 +3292,7 @@ void TileMap::move_layer(int p_layer, int p_to_pos) { Ref layer = layers[p_layer]; layers.insert(p_to_pos, layer); layers.remove_at(p_to_pos < p_layer ? p_layer + 1 : p_layer); - for (unsigned int i = 0; i < layers.size(); i++) { + for (uint32_t i = 0; i < layers.size(); i++) { layers[i]->set_layer_index_in_tile_map_node(i); } queue_internal_update(); @@ -3289,7 +3312,7 @@ void TileMap::remove_layer(int p_layer) { // Clear before removing the layer. layers.remove_at(p_layer); - for (unsigned int i = 0; i < layers.size(); i++) { + for (uint32_t i = 0; i < layers.size(); i++) { layers[i]->set_layer_index_in_tile_map_node(i); } queue_internal_update(); @@ -3526,7 +3549,7 @@ Vector2i TileMap::get_coords_for_body_rid(RID p_physics_body) { } int TileMap::get_layer_for_body_rid(RID p_physics_body) { - for (unsigned int i = 0; i < layers.size(); i++) { + for (uint32_t i = 0; i < layers.size(); i++) { if (layers[i]->has_body_rid(p_physics_body)) { return i; } @@ -3576,7 +3599,7 @@ Rect2 TileMap::_edit_get_rect() const { bool changed = false; Rect2 rect = layers[0]->get_rect(changed); any_changed |= changed; - for (unsigned int i = 1; i < layers.size(); i++) { + for (uint32_t i = 1; i < layers.size(); i++) { rect = rect.merge(layers[i]->get_rect(changed)); any_changed |= changed; } @@ -3755,7 +3778,7 @@ void TileMap::_get_property_list(List *p_list) const { p_list->push_back(PropertyInfo(m_type, property_name, PROPERTY_HINT_NONE, m_hint, (get(property_name) == property_get_revert(property_name)) ? PROPERTY_USAGE_EDITOR : PROPERTY_USAGE_DEFAULT)); \ } - for (unsigned int i = 0; i < layers.size(); i++) { + for (uint32_t i = 0; i < layers.size(); i++) { MAKE_LAYER_PROPERTY(Variant::STRING, "name", ""); MAKE_LAYER_PROPERTY(Variant::BOOL, "enabled", ""); MAKE_LAYER_PROPERTY(Variant::COLOR, "modulate", ""); diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h index 1136e4190d5..9a847a7ebb8 100644 --- a/scene/2d/tile_map.h +++ b/scene/2d/tile_map.h @@ -104,7 +104,7 @@ struct CellData { // Rendering. Ref rendering_quadrant; SelfList rendering_quadrant_list_element; - List occluders; + LocalVector occluders; // Physics. LocalVector bodies;