Add support for rotating scene tiles in TileMapLayer

This commit is contained in:
DexterFstone
2025-06-28 07:15:15 -07:00
parent 71a9948157
commit 6a399302c3
4 changed files with 50 additions and 15 deletions

View File

@ -127,18 +127,7 @@ void TileMapLayerEditorTilesPlugin::_update_transform_buttons() {
return;
}
bool has_scene_tile = false;
for (const KeyValue<Vector2i, TileMapCell> &E : selection_pattern->get_pattern()) {
if (Object::cast_to<TileSetScenesCollectionSource>(tile_set->get_source(E.value.source_id).ptr())) {
has_scene_tile = true;
break;
}
}
if (has_scene_tile) {
_set_transform_buttons_state({}, { transform_button_rotate_left, transform_button_rotate_right, transform_button_flip_h, transform_button_flip_v },
TTR("Can't transform scene tiles."));
} else if (tile_set->get_tile_shape() != TileSet::TILE_SHAPE_SQUARE && selection_pattern->get_size() != Vector2i(1, 1)) {
if (tile_set->get_tile_shape() != TileSet::TILE_SHAPE_SQUARE && selection_pattern->get_size() != Vector2i(1, 1)) {
_set_transform_buttons_state({ transform_button_flip_h, transform_button_flip_v }, { transform_button_rotate_left, transform_button_rotate_right },
TTR("Can't rotate patterns when using non-square tile grid."));
} else {

View File

@ -1571,6 +1571,7 @@ void TileMapLayer::_scenes_update_cell(CellData &r_cell_data) {
Transform2D xform;
xform.set_origin(tile_set->map_to_local(r_cell_data.coords));
scene_as_node2d->set_transform(xform * scene_as_node2d->get_transform());
_set_scene_transformed_alternative(c.alternative_tile, scene_as_node2d);
}
if (tile_map_node) {
// Compatibility with TileMap.
@ -1631,6 +1632,49 @@ void TileMapLayer::_scenes_draw_cell_debug(const RID &p_canvas_item, const Vecto
}
#endif // DEBUG_ENABLED
void TileMapLayer::_set_scene_transformed_alternative(const int p_alternative_id, Node2D *p_scene) {
// Determine the transformations based on the alternative ID.
bool transform_flip_h = p_alternative_id & TileSetAtlasSource::TRANSFORM_FLIP_H;
bool transform_flip_v = p_alternative_id & TileSetAtlasSource::TRANSFORM_FLIP_V;
bool transform_transpose = p_alternative_id & TileSetAtlasSource::TRANSFORM_TRANSPOSE;
double scene_rotation = 0.0;
Vector2 scene_scale = p_scene->get_scale();
// Determine the scene rotation and scale based on the transformation flags.
if (!transform_flip_h && !transform_flip_v && !transform_transpose) {
scene_rotation = 0.0;
scene_scale.x = 1;
} else if (transform_flip_h && !transform_flip_v && transform_transpose) {
scene_rotation = 90.0;
scene_scale.x = 1;
} else if (transform_flip_h && transform_flip_v && !transform_transpose) {
scene_rotation = 180.0;
scene_scale.x = 1;
} else if (!transform_flip_h && transform_flip_v && transform_transpose) {
scene_rotation = 270.0;
scene_scale.x = 1;
} else if (transform_flip_h && !transform_flip_v && !transform_transpose) {
scene_rotation = 0.0;
scene_scale.x = -1;
} else if (transform_flip_h && transform_flip_v && transform_transpose) {
scene_rotation = 90.0;
scene_scale.x = -1;
} else if (!transform_flip_h && transform_flip_v && !transform_transpose) {
scene_rotation = 180.0;
scene_scale.x = -1;
} else if (!transform_flip_h && !transform_flip_v && transform_transpose) {
scene_rotation = 270.0;
scene_scale.x = -1;
}
// Apply the transformations to the scene.
double current_rotation = p_scene->get_rotation_degrees() + scene_rotation;
Vector2 current_scale = p_scene->get_scale() + scene_scale;
p_scene->set_rotation_degrees(current_rotation);
p_scene->set_scale(current_scale);
}
/////////////////////////////////////////////////////////////////////
void TileMapLayer::_build_runtime_update_tile_data(bool p_force_cleanup) {

View File

@ -474,6 +474,7 @@ private:
#ifdef DEBUG_ENABLED
void _scenes_draw_cell_debug(const RID &p_canvas_item, const Vector2 &p_quadrant_pos, const CellData &r_cell_data);
#endif // DEBUG_ENABLED
void _set_scene_transformed_alternative(const int p_alternative_id, Node2D *p_scene);
// Terrains.
TileSet::TerrainsPattern _get_best_terrain_pattern_for_constraints(int p_terrain_set, const Vector2i &p_position, const RBSet<TerrainConstraint> &p_constraints, TileSet::TerrainsPattern p_current_pattern) const;

View File

@ -5775,7 +5775,7 @@ int TileSetScenesCollectionSource::get_alternative_tile_id(const Vector2i p_atla
bool TileSetScenesCollectionSource::has_alternative_tile(const Vector2i p_atlas_coords, int p_alternative_tile) const {
ERR_FAIL_COND_V(p_atlas_coords != Vector2i(), false);
return scenes.has(p_alternative_tile);
return scenes.has(TileSetAtlasSource::alternative_no_transform(p_alternative_tile));
}
int TileSetScenesCollectionSource::create_scene_tile(Ref<PackedScene> p_packed_scene, int p_id_override) {
@ -5837,8 +5837,9 @@ void TileSetScenesCollectionSource::set_scene_tile_scene(int p_id, Ref<PackedSce
}
Ref<PackedScene> TileSetScenesCollectionSource::get_scene_tile_scene(int p_id) const {
ERR_FAIL_COND_V(!scenes.has(p_id), Ref<PackedScene>());
return scenes[p_id].scene;
int scene_tile = TileSetAtlasSource::alternative_no_transform(p_id);
ERR_FAIL_COND_V(!scenes.has(scene_tile), Ref<PackedScene>());
return scenes[scene_tile].scene;
}
void TileSetScenesCollectionSource::set_scene_tile_display_placeholder(int p_id, bool p_display_placeholder) {