Merge pull request #110768 from Ir1ana/fix/110710

Fix nested TileMapLayers highlight rendering in editor
This commit is contained in:
Thaddeus Crews 2025-09-30 20:10:41 -05:00
commit a430bf6e8b
No known key found for this signature in database
GPG key ID: 8C6E5FEB5FC03CCC
2 changed files with 33 additions and 15 deletions

View file

@ -203,6 +203,18 @@ void TileMapLayer::_debug_update(bool p_force_cleanup) {
#endif // DEBUG_ENABLED #endif // DEBUG_ENABLED
Color TileMapLayer::_highlight_color(const Color &p_modulate) const {
if (highlight_mode == HIGHLIGHT_MODE_BELOW) {
return p_modulate.darkened(0.5);
}
if (highlight_mode == HIGHLIGHT_MODE_ABOVE) {
Color c = p_modulate.darkened(0.5);
c.a *= 0.3;
return c;
}
return p_modulate;
}
/////////////////////////////// Rendering ////////////////////////////////////// /////////////////////////////// Rendering //////////////////////////////////////
void TileMapLayer::_rendering_update(bool p_force_cleanup) { void TileMapLayer::_rendering_update(bool p_force_cleanup) {
RenderingServer *rs = RenderingServer::get_singleton(); RenderingServer *rs = RenderingServer::get_singleton();
@ -214,19 +226,14 @@ void TileMapLayer::_rendering_update(bool p_force_cleanup) {
} }
// ----------- Layer level processing ----------- // ----------- Layer level processing -----------
if (!forced_cleanup) {
// Modulate the layer. // Modulate the layer.
Color layer_modulate = get_modulate(); Color layer_modulate = get_self_modulate();
#ifdef TOOLS_ENABLED #ifdef TOOLS_ENABLED
if (highlight_mode == HIGHLIGHT_MODE_BELOW) { if (!forced_cleanup) {
layer_modulate = layer_modulate.darkened(0.5); layer_modulate = _highlight_color(layer_modulate);
} else if (highlight_mode == HIGHLIGHT_MODE_ABOVE) { rs->canvas_item_set_self_modulate(get_canvas_item(), layer_modulate);
layer_modulate = layer_modulate.darkened(0.5);
layer_modulate.a *= 0.3;
} }
#endif // TOOLS_ENABLED #endif // TOOLS_ENABLED
rs->canvas_item_set_modulate(get_canvas_item(), layer_modulate);
}
// ----------- Quadrants processing ----------- // ----------- Quadrants processing -----------
@ -347,7 +354,7 @@ void TileMapLayer::_rendering_update(bool p_force_cleanup) {
rs->canvas_item_set_light_mask(ci, get_light_mask()); rs->canvas_item_set_light_mask(ci, get_light_mask());
rs->canvas_item_set_z_as_relative_to_parent(ci, true); rs->canvas_item_set_z_as_relative_to_parent(ci, true);
rs->canvas_item_set_z_index(ci, tile_z_index); rs->canvas_item_set_z_index(ci, tile_z_index);
rs->canvas_item_set_self_modulate(ci, get_self_modulate()); rs->canvas_item_set_self_modulate(ci, layer_modulate);
rs->canvas_item_set_default_texture_filter(ci, RS::CanvasItemTextureFilter(get_texture_filter_in_tree())); rs->canvas_item_set_default_texture_filter(ci, RS::CanvasItemTextureFilter(get_texture_filter_in_tree()));
rs->canvas_item_set_default_texture_repeat(ci, RS::CanvasItemTextureRepeat(get_texture_repeat_in_tree())); rs->canvas_item_set_default_texture_repeat(ci, RS::CanvasItemTextureRepeat(get_texture_repeat_in_tree()));
@ -430,14 +437,15 @@ void TileMapLayer::_rendering_update(bool p_force_cleanup) {
if (dirty.flags[DIRTY_FLAGS_LAYER_LIGHT_MASK] || if (dirty.flags[DIRTY_FLAGS_LAYER_LIGHT_MASK] ||
dirty.flags[DIRTY_FLAGS_LAYER_TEXTURE_FILTER] || dirty.flags[DIRTY_FLAGS_LAYER_TEXTURE_FILTER] ||
dirty.flags[DIRTY_FLAGS_LAYER_TEXTURE_REPEAT] || dirty.flags[DIRTY_FLAGS_LAYER_TEXTURE_REPEAT] ||
dirty.flags[DIRTY_FLAGS_LAYER_SELF_MODULATE]) { dirty.flags[DIRTY_FLAGS_LAYER_SELF_MODULATE] ||
dirty.flags[DIRTY_FLAGS_LAYER_HIGHLIGHT_MODE]) {
for (KeyValue<Vector2i, Ref<RenderingQuadrant>> &kv : rendering_quadrant_map) { for (KeyValue<Vector2i, Ref<RenderingQuadrant>> &kv : rendering_quadrant_map) {
Ref<RenderingQuadrant> &rendering_quadrant = kv.value; Ref<RenderingQuadrant> &rendering_quadrant = kv.value;
for (const RID &ci : rendering_quadrant->canvas_items) { for (const RID &ci : rendering_quadrant->canvas_items) {
rs->canvas_item_set_light_mask(ci, get_light_mask()); rs->canvas_item_set_light_mask(ci, get_light_mask());
rs->canvas_item_set_default_texture_filter(ci, RS::CanvasItemTextureFilter(get_texture_filter_in_tree())); rs->canvas_item_set_default_texture_filter(ci, RS::CanvasItemTextureFilter(get_texture_filter_in_tree()));
rs->canvas_item_set_default_texture_repeat(ci, RS::CanvasItemTextureRepeat(get_texture_repeat_in_tree())); rs->canvas_item_set_default_texture_repeat(ci, RS::CanvasItemTextureRepeat(get_texture_repeat_in_tree()));
rs->canvas_item_set_self_modulate(ci, get_self_modulate()); rs->canvas_item_set_self_modulate(ci, layer_modulate);
} }
} }
} }
@ -1570,7 +1578,7 @@ void TileMapLayer::_scenes_update(bool p_force_cleanup) {
_scenes_clear_cell(kv.value); _scenes_clear_cell(kv.value);
} }
} else { } else {
if (_scenes_was_cleaned_up || dirty.flags[DIRTY_FLAGS_TILE_SET] || dirty.flags[DIRTY_FLAGS_LAYER_IN_TREE]) { if (_scenes_was_cleaned_up || dirty.flags[DIRTY_FLAGS_TILE_SET] || dirty.flags[DIRTY_FLAGS_LAYER_IN_TREE] || dirty.flags[DIRTY_FLAGS_LAYER_HIGHLIGHT_MODE]) {
// Update all cells. // Update all cells.
for (KeyValue<Vector2i, CellData> &kv : tile_map_layer_data) { for (KeyValue<Vector2i, CellData> &kv : tile_map_layer_data) {
_scenes_update_cell(kv.value); _scenes_update_cell(kv.value);
@ -1630,6 +1638,13 @@ void TileMapLayer::_scenes_update_cell(CellData &r_cell_data) {
xform.set_origin(tile_set->map_to_local(r_cell_data.coords)); xform.set_origin(tile_set->map_to_local(r_cell_data.coords));
scene_as_node2d->set_transform(xform * scene_as_node2d->get_transform()); scene_as_node2d->set_transform(xform * scene_as_node2d->get_transform());
} }
#ifdef TOOLS_ENABLED
RenderingServer *rs = RenderingServer::get_singleton();
CanvasItem *scene_as_ci = Object::cast_to<CanvasItem>(scene);
if (scene_as_ci) {
rs->canvas_item_set_modulate(scene_as_ci->get_canvas_item(), _highlight_color(scene_as_ci->get_modulate()));
}
#endif // TOOLS_ENABLED
if (tile_map_node) { if (tile_map_node) {
// Compatibility with TileMap. // Compatibility with TileMap.
tile_map_node->add_child(scene); tile_map_node->add_child(scene);
@ -3171,6 +3186,7 @@ void TileMapLayer::set_highlight_mode(HighlightMode p_highlight_mode) {
return; return;
} }
highlight_mode = p_highlight_mode; highlight_mode = p_highlight_mode;
dirty.flags[DIRTY_FLAGS_LAYER_HIGHLIGHT_MODE] = true;
_queue_internal_update(); _queue_internal_update();
} }

View file

@ -369,6 +369,7 @@ public:
DIRTY_FLAGS_LAYER_NAVIGATION_MAP, DIRTY_FLAGS_LAYER_NAVIGATION_MAP,
DIRTY_FLAGS_LAYER_NAVIGATION_VISIBILITY_MODE, DIRTY_FLAGS_LAYER_NAVIGATION_VISIBILITY_MODE,
DIRTY_FLAGS_LAYER_RUNTIME_UPDATE, DIRTY_FLAGS_LAYER_RUNTIME_UPDATE,
DIRTY_FLAGS_LAYER_HIGHLIGHT_MODE,
DIRTY_FLAGS_LAYER_INDEX_IN_TILE_MAP_NODE, // For compatibility. DIRTY_FLAGS_LAYER_INDEX_IN_TILE_MAP_NODE, // For compatibility.
@ -451,6 +452,7 @@ private:
bool _occlusion_was_cleaned_up = true; bool _occlusion_was_cleaned_up = true;
void _rendering_update(bool p_force_cleanup); void _rendering_update(bool p_force_cleanup);
void _rendering_notification(int p_what); void _rendering_notification(int p_what);
Color _highlight_color(const Color &p_modulate) const;
void _rendering_quadrants_update_cell(CellData &r_cell_data, SelfList<RenderingQuadrant>::List &r_dirty_rendering_quadrant_list); void _rendering_quadrants_update_cell(CellData &r_cell_data, SelfList<RenderingQuadrant>::List &r_dirty_rendering_quadrant_list);
void _rendering_occluders_clear_cell(CellData &r_cell_data); void _rendering_occluders_clear_cell(CellData &r_cell_data);
void _rendering_occluders_update_cell(CellData &r_cell_data); void _rendering_occluders_update_cell(CellData &r_cell_data);