Merge pull request #64661 from Mickeon/rename-tilemap-world

Rename TileMap/GridMap.`world_to_map` and opposite to `local_to_map`
This commit is contained in:
Rémi Verschelde 2022-09-06 17:01:16 +02:00
commit 5fb84e5702
10 changed files with 135 additions and 132 deletions

View file

@ -207,6 +207,13 @@
Returns if a layer Y-sorts its tiles. Returns if a layer Y-sorts its tiles.
</description> </description>
</method> </method>
<method name="local_to_map" qualifiers="const">
<return type="Vector2i" />
<param index="0" name="local_position" type="Vector2" />
<description>
Returns the map coordinates of the cell containing the given [param local_position]. If [param local_position] is in global coordinates, consider using [method Node2D.to_local] before passing it to this method. See also [method map_to_local].
</description>
</method>
<method name="map_pattern"> <method name="map_pattern">
<return type="Vector2i" /> <return type="Vector2i" />
<param index="0" name="position_in_tilemap" type="Vector2i" /> <param index="0" name="position_in_tilemap" type="Vector2i" />
@ -216,12 +223,12 @@
Returns for the given coordinate [param coords_in_pattern] in a [TileMapPattern] the corresponding cell coordinates if the pattern was pasted at the [param position_in_tilemap] coordinates (see [method set_pattern]). This mapping is required as in half-offset tile shapes, the mapping might not work by calculating [code]position_in_tile_map + coords_in_pattern[/code] Returns for the given coordinate [param coords_in_pattern] in a [TileMapPattern] the corresponding cell coordinates if the pattern was pasted at the [param position_in_tilemap] coordinates (see [method set_pattern]). This mapping is required as in half-offset tile shapes, the mapping might not work by calculating [code]position_in_tile_map + coords_in_pattern[/code]
</description> </description>
</method> </method>
<method name="map_to_world" qualifiers="const"> <method name="map_to_local" qualifiers="const">
<return type="Vector2" /> <return type="Vector2" />
<param index="0" name="map_position" type="Vector2i" /> <param index="0" name="map_position" type="Vector2i" />
<description> <description>
Returns a local position of the center of the cell at the given tilemap (grid-based) coordinates. Returns the centered position of a cell in the TileMap's local coordinate space. To convert the returned value into global coordinates, use [method Node2D.to_global]. See also [method local_to_map].
[b]Note:[/b] This doesn't correspond to the visual position of the tile, i.e. it ignores the [member TileData.texture_offset] property of individual tiles. [b]Note:[/b] This may not correspond to the visual position of the tile, i.e. it ignores the [member TileData.texture_offset] property of individual tiles.
</description> </description>
</method> </method>
<method name="move_layer"> <method name="move_layer">
@ -344,13 +351,6 @@
Paste the given [TileMapPattern] at the given [param position] and [param layer] in the tile map. Paste the given [TileMapPattern] at the given [param position] and [param layer] in the tile map.
</description> </description>
</method> </method>
<method name="world_to_map" qualifiers="const">
<return type="Vector2i" />
<param index="0" name="world_position" type="Vector2" />
<description>
Returns the tilemap (grid-based) coordinates corresponding to the given local position.
</description>
</method>
</methods> </methods>
<members> <members>
<member name="cell_quadrant_size" type="int" setter="set_quadrant_size" getter="get_quadrant_size" default="16"> <member name="cell_quadrant_size" type="int" setter="set_quadrant_size" getter="get_quadrant_size" default="16">

View file

@ -577,7 +577,7 @@ bool TileMapEditorTilesPlugin::forward_canvas_gui_input(const Ref<InputEvent> &p
_fix_invalid_tiles_in_tile_map_selection(); _fix_invalid_tiles_in_tile_map_selection();
} break; } break;
case DRAG_TYPE_BUCKET: { case DRAG_TYPE_BUCKET: {
Vector<Vector2i> line = TileMapEditor::get_line(tile_map, tile_map->world_to_map(drag_last_mouse_pos), tile_map->world_to_map(mpos)); Vector<Vector2i> line = TileMapEditor::get_line(tile_map, tile_map->local_to_map(drag_last_mouse_pos), tile_map->local_to_map(mpos));
for (int i = 0; i < line.size(); i++) { for (int i = 0; i < line.size(); i++) {
if (!drag_modified.has(line[i])) { if (!drag_modified.has(line[i])) {
HashMap<Vector2i, TileMapCell> to_draw = _draw_bucket_fill(line[i], bucket_contiguous_checkbox->is_pressed(), drag_erasing); HashMap<Vector2i, TileMapCell> to_draw = _draw_bucket_fill(line[i], bucket_contiguous_checkbox->is_pressed(), drag_erasing);
@ -624,7 +624,7 @@ bool TileMapEditorTilesPlugin::forward_canvas_gui_input(const Ref<InputEvent> &p
} }
} else if (tool_buttons_group->get_pressed_button() == select_tool_button) { } else if (tool_buttons_group->get_pressed_button() == select_tool_button) {
drag_start_mouse_pos = mpos; drag_start_mouse_pos = mpos;
if (tile_map_selection.has(tile_map->world_to_map(drag_start_mouse_pos)) && !mb->is_shift_pressed()) { if (tile_map_selection.has(tile_map->local_to_map(drag_start_mouse_pos)) && !mb->is_shift_pressed()) {
// Move the selection // Move the selection
_update_selection_pattern_from_tilemap_selection(); // Make sure the pattern is up to date before moving. _update_selection_pattern_from_tilemap_selection(); // Make sure the pattern is up to date before moving.
drag_type = DRAG_TYPE_MOVE; drag_type = DRAG_TYPE_MOVE;
@ -673,7 +673,7 @@ bool TileMapEditorTilesPlugin::forward_canvas_gui_input(const Ref<InputEvent> &p
drag_type = DRAG_TYPE_BUCKET; drag_type = DRAG_TYPE_BUCKET;
drag_start_mouse_pos = mpos; drag_start_mouse_pos = mpos;
drag_modified.clear(); drag_modified.clear();
Vector<Vector2i> line = TileMapEditor::get_line(tile_map, tile_map->world_to_map(drag_last_mouse_pos), tile_map->world_to_map(mpos)); Vector<Vector2i> line = TileMapEditor::get_line(tile_map, tile_map->local_to_map(drag_last_mouse_pos), tile_map->local_to_map(mpos));
for (int i = 0; i < line.size(); i++) { for (int i = 0; i < line.size(); i++) {
if (!drag_modified.has(line[i])) { if (!drag_modified.has(line[i])) {
HashMap<Vector2i, TileMapCell> to_draw = _draw_bucket_fill(line[i], bucket_contiguous_checkbox->is_pressed(), drag_erasing); HashMap<Vector2i, TileMapCell> to_draw = _draw_bucket_fill(line[i], bucket_contiguous_checkbox->is_pressed(), drag_erasing);
@ -752,14 +752,14 @@ void TileMapEditorTilesPlugin::forward_canvas_draw_over_viewport(Control *p_over
if (drag_type == DRAG_TYPE_PICK) { if (drag_type == DRAG_TYPE_PICK) {
// Draw the area being picked. // Draw the area being picked.
Rect2i rect = Rect2i(tile_map->world_to_map(drag_start_mouse_pos), tile_map->world_to_map(drag_last_mouse_pos) - tile_map->world_to_map(drag_start_mouse_pos)).abs(); Rect2i rect = Rect2i(tile_map->local_to_map(drag_start_mouse_pos), tile_map->local_to_map(drag_last_mouse_pos) - tile_map->local_to_map(drag_start_mouse_pos)).abs();
rect.size += Vector2i(1, 1); rect.size += Vector2i(1, 1);
for (int x = rect.position.x; x < rect.get_end().x; x++) { for (int x = rect.position.x; x < rect.get_end().x; x++) {
for (int y = rect.position.y; y < rect.get_end().y; y++) { for (int y = rect.position.y; y < rect.get_end().y; y++) {
Vector2i coords = Vector2i(x, y); Vector2i coords = Vector2i(x, y);
if (tile_map->get_cell_source_id(tile_map_layer, coords) != TileSet::INVALID_SOURCE) { if (tile_map->get_cell_source_id(tile_map_layer, coords) != TileSet::INVALID_SOURCE) {
Transform2D tile_xform; Transform2D tile_xform;
tile_xform.set_origin(tile_map->map_to_world(coords)); tile_xform.set_origin(tile_map->map_to_local(coords));
tile_xform.set_scale(tile_shape_size); tile_xform.set_scale(tile_shape_size);
tile_set->draw_tile_shape(p_overlay, xform * tile_xform, Color(1.0, 1.0, 1.0), false); tile_set->draw_tile_shape(p_overlay, xform * tile_xform, Color(1.0, 1.0, 1.0), false);
} }
@ -767,7 +767,7 @@ void TileMapEditorTilesPlugin::forward_canvas_draw_over_viewport(Control *p_over
} }
} else if (drag_type == DRAG_TYPE_SELECT) { } else if (drag_type == DRAG_TYPE_SELECT) {
// Draw the area being selected. // Draw the area being selected.
Rect2i rect = Rect2i(tile_map->world_to_map(drag_start_mouse_pos), tile_map->world_to_map(drag_last_mouse_pos) - tile_map->world_to_map(drag_start_mouse_pos)).abs(); Rect2i rect = Rect2i(tile_map->local_to_map(drag_start_mouse_pos), tile_map->local_to_map(drag_last_mouse_pos) - tile_map->local_to_map(drag_start_mouse_pos)).abs();
rect.size += Vector2i(1, 1); rect.size += Vector2i(1, 1);
RBSet<Vector2i> to_draw; RBSet<Vector2i> to_draw;
for (int x = rect.position.x; x < rect.get_end().x; x++) { for (int x = rect.position.x; x < rect.get_end().x; x++) {
@ -789,8 +789,8 @@ void TileMapEditorTilesPlugin::forward_canvas_draw_over_viewport(Control *p_over
for (const Vector2i &E : tile_map_selection) { for (const Vector2i &E : tile_map_selection) {
top_left = top_left.min(E); top_left = top_left.min(E);
} }
Vector2i offset = drag_start_mouse_pos - tile_map->map_to_world(top_left); Vector2i offset = drag_start_mouse_pos - tile_map->map_to_local(top_left);
offset = tile_map->world_to_map(drag_last_mouse_pos - offset) - tile_map->world_to_map(drag_start_mouse_pos - offset); offset = tile_map->local_to_map(drag_last_mouse_pos - offset) - tile_map->local_to_map(drag_start_mouse_pos - offset);
TypedArray<Vector2i> selection_used_cells = selection_pattern->get_used_cells(); TypedArray<Vector2i> selection_used_cells = selection_pattern->get_used_cells();
for (int i = 0; i < selection_used_cells.size(); i++) { for (int i = 0; i < selection_used_cells.size(); i++) {
@ -803,7 +803,7 @@ void TileMapEditorTilesPlugin::forward_canvas_draw_over_viewport(Control *p_over
Vector2 mouse_offset = (Vector2(tile_map_clipboard->get_size()) / 2.0 - Vector2(0.5, 0.5)) * tile_set->get_tile_size(); Vector2 mouse_offset = (Vector2(tile_map_clipboard->get_size()) / 2.0 - Vector2(0.5, 0.5)) * tile_set->get_tile_size();
TypedArray<Vector2i> clipboard_used_cells = tile_map_clipboard->get_used_cells(); TypedArray<Vector2i> clipboard_used_cells = tile_map_clipboard->get_used_cells();
for (int i = 0; i < clipboard_used_cells.size(); i++) { for (int i = 0; i < clipboard_used_cells.size(); i++) {
Vector2i coords = tile_map->map_pattern(tile_map->world_to_map(drag_last_mouse_pos - mouse_offset), clipboard_used_cells[i], tile_map_clipboard); Vector2i coords = tile_map->map_pattern(tile_map->local_to_map(drag_last_mouse_pos - mouse_offset), clipboard_used_cells[i], tile_map_clipboard);
preview[coords] = TileMapCell(tile_map_clipboard->get_cell_source_id(clipboard_used_cells[i]), tile_map_clipboard->get_cell_atlas_coords(clipboard_used_cells[i]), tile_map_clipboard->get_cell_alternative_tile(clipboard_used_cells[i])); preview[coords] = TileMapCell(tile_map_clipboard->get_cell_source_id(clipboard_used_cells[i]), tile_map_clipboard->get_cell_atlas_coords(clipboard_used_cells[i]), tile_map_clipboard->get_cell_alternative_tile(clipboard_used_cells[i]));
} }
} else if (!picker_button->is_pressed() && !(drag_type == DRAG_TYPE_NONE && Input::get_singleton()->is_key_pressed(Key::CTRL) && !Input::get_singleton()->is_key_pressed(Key::SHIFT))) { } else if (!picker_button->is_pressed() && !(drag_type == DRAG_TYPE_NONE && Input::get_singleton()->is_key_pressed(Key::CTRL) && !Input::get_singleton()->is_key_pressed(Key::SHIFT))) {
@ -824,11 +824,11 @@ void TileMapEditorTilesPlugin::forward_canvas_draw_over_viewport(Control *p_over
} }
} else if (drag_type == DRAG_TYPE_RECT) { } else if (drag_type == DRAG_TYPE_RECT) {
// Preview for a rect pattern. // Preview for a rect pattern.
preview = _draw_rect(tile_map->world_to_map(drag_start_mouse_pos), tile_map->world_to_map(drag_last_mouse_pos), drag_erasing); preview = _draw_rect(tile_map->local_to_map(drag_start_mouse_pos), tile_map->local_to_map(drag_last_mouse_pos), drag_erasing);
expand_grid = true; expand_grid = true;
} else if (tool_buttons_group->get_pressed_button() == bucket_tool_button && drag_type == DRAG_TYPE_NONE) { } else if (tool_buttons_group->get_pressed_button() == bucket_tool_button && drag_type == DRAG_TYPE_NONE) {
// Preview for a fill pattern. // Preview for a fill pattern.
preview = _draw_bucket_fill(tile_map->world_to_map(drag_last_mouse_pos), bucket_contiguous_checkbox->is_pressed(), erase_button->is_pressed()); preview = _draw_bucket_fill(tile_map->local_to_map(drag_last_mouse_pos), bucket_contiguous_checkbox->is_pressed(), erase_button->is_pressed());
} }
// Expand the grid if needed // Expand the grid if needed
@ -861,7 +861,7 @@ void TileMapEditorTilesPlugin::forward_canvas_draw_over_viewport(Control *p_over
float opacity = CLAMP(MIN(left_opacity, MIN(right_opacity, MIN(top_opacity, bottom_opacity))) + 0.1, 0.0f, 1.0f); float opacity = CLAMP(MIN(left_opacity, MIN(right_opacity, MIN(top_opacity, bottom_opacity))) + 0.1, 0.0f, 1.0f);
Transform2D tile_xform; Transform2D tile_xform;
tile_xform.set_origin(tile_map->map_to_world(Vector2(x, y))); tile_xform.set_origin(tile_map->map_to_local(Vector2(x, y)));
tile_xform.set_scale(tile_shape_size); tile_xform.set_scale(tile_shape_size);
Color color = grid_color; Color color = grid_color;
color.a = color.a * opacity; color.a = color.a * opacity;
@ -874,7 +874,7 @@ void TileMapEditorTilesPlugin::forward_canvas_draw_over_viewport(Control *p_over
// Draw the preview. // Draw the preview.
for (const KeyValue<Vector2i, TileMapCell> &E : preview) { for (const KeyValue<Vector2i, TileMapCell> &E : preview) {
Transform2D tile_xform; Transform2D tile_xform;
tile_xform.set_origin(tile_map->map_to_world(E.key)); tile_xform.set_origin(tile_map->map_to_local(E.key));
tile_xform.set_scale(tile_set->get_tile_size()); tile_xform.set_scale(tile_set->get_tile_size());
if (!(drag_erasing || erase_button->is_pressed()) && random_tile_toggle->is_pressed()) { if (!(drag_erasing || erase_button->is_pressed()) && random_tile_toggle->is_pressed()) {
tile_set->draw_tile_shape(p_overlay, xform * tile_xform, Color(1.0, 1.0, 1.0, 0.5), true); tile_set->draw_tile_shape(p_overlay, xform * tile_xform, Color(1.0, 1.0, 1.0, 0.5), true);
@ -899,9 +899,9 @@ void TileMapEditorTilesPlugin::forward_canvas_draw_over_viewport(Control *p_over
bool transpose = tile_data->get_transpose(); bool transpose = tile_data->get_transpose();
if (transpose) { if (transpose) {
dest_rect.position = (tile_map->map_to_world(E.key) - Vector2(dest_rect.size.y, dest_rect.size.x) / 2 - tile_offset); dest_rect.position = (tile_map->map_to_local(E.key) - Vector2(dest_rect.size.y, dest_rect.size.x) / 2 - tile_offset);
} else { } else {
dest_rect.position = (tile_map->map_to_world(E.key) - dest_rect.size / 2 - tile_offset); dest_rect.position = (tile_map->map_to_local(E.key) - dest_rect.size / 2 - tile_offset);
} }
dest_rect = xform.xform(dest_rect); dest_rect = xform.xform(dest_rect);
@ -1012,7 +1012,7 @@ HashMap<Vector2i, TileMapCell> TileMapEditorTilesPlugin::_draw_line(Vector2 p_st
// Paint the tiles on the tile map. // Paint the tiles on the tile map.
if (!p_erase && random_tile_toggle->is_pressed()) { if (!p_erase && random_tile_toggle->is_pressed()) {
// Paint a random tile. // Paint a random tile.
Vector<Vector2i> line = TileMapEditor::get_line(tile_map, tile_map->world_to_map(p_from_mouse_pos), tile_map->world_to_map(p_to_mouse_pos)); Vector<Vector2i> line = TileMapEditor::get_line(tile_map, tile_map->local_to_map(p_from_mouse_pos), tile_map->local_to_map(p_to_mouse_pos));
for (int i = 0; i < line.size(); i++) { for (int i = 0; i < line.size(); i++) {
output.insert(line[i], _pick_random_tile(pattern)); output.insert(line[i], _pick_random_tile(pattern));
} }
@ -1020,9 +1020,9 @@ HashMap<Vector2i, TileMapCell> TileMapEditorTilesPlugin::_draw_line(Vector2 p_st
// Paint the pattern. // Paint the pattern.
// If we paint several tiles, we virtually move the mouse as if it was in the center of the "brush" // If we paint several tiles, we virtually move the mouse as if it was in the center of the "brush"
Vector2 mouse_offset = (Vector2(pattern->get_size()) / 2.0 - Vector2(0.5, 0.5)) * tile_set->get_tile_size(); Vector2 mouse_offset = (Vector2(pattern->get_size()) / 2.0 - Vector2(0.5, 0.5)) * tile_set->get_tile_size();
Vector2i last_hovered_cell = tile_map->world_to_map(p_from_mouse_pos - mouse_offset); Vector2i last_hovered_cell = tile_map->local_to_map(p_from_mouse_pos - mouse_offset);
Vector2i new_hovered_cell = tile_map->world_to_map(p_to_mouse_pos - mouse_offset); Vector2i new_hovered_cell = tile_map->local_to_map(p_to_mouse_pos - mouse_offset);
Vector2i drag_start_cell = tile_map->world_to_map(p_start_drag_mouse_pos - mouse_offset); Vector2i drag_start_cell = tile_map->local_to_map(p_start_drag_mouse_pos - mouse_offset);
TypedArray<Vector2i> used_cells = pattern->get_used_cells(); TypedArray<Vector2i> used_cells = pattern->get_used_cells();
Vector2i offset = Vector2i(Math::posmod(drag_start_cell.x, pattern->get_size().x), Math::posmod(drag_start_cell.y, pattern->get_size().y)); // Note: no posmodv for Vector2i for now. Meh.s Vector2i offset = Vector2i(Math::posmod(drag_start_cell.x, pattern->get_size().x), Math::posmod(drag_start_cell.y, pattern->get_size().y)); // Note: no posmodv for Vector2i for now. Meh.s
@ -1241,7 +1241,7 @@ void TileMapEditorTilesPlugin::_stop_dragging() {
if (!Input::get_singleton()->is_key_pressed(Key::SHIFT) && !Input::get_singleton()->is_key_pressed(Key::CTRL)) { if (!Input::get_singleton()->is_key_pressed(Key::SHIFT) && !Input::get_singleton()->is_key_pressed(Key::CTRL)) {
tile_map_selection.clear(); tile_map_selection.clear();
} }
Rect2i rect = Rect2i(tile_map->world_to_map(drag_start_mouse_pos), tile_map->world_to_map(mpos) - tile_map->world_to_map(drag_start_mouse_pos)).abs(); Rect2i rect = Rect2i(tile_map->local_to_map(drag_start_mouse_pos), tile_map->local_to_map(mpos) - tile_map->local_to_map(drag_start_mouse_pos)).abs();
for (int x = rect.position.x; x <= rect.get_end().x; x++) { for (int x = rect.position.x; x <= rect.get_end().x; x++) {
for (int y = rect.position.y; y <= rect.get_end().y; y++) { for (int y = rect.position.y; y <= rect.get_end().y; y++) {
Vector2i coords = Vector2i(x, y); Vector2i coords = Vector2i(x, y);
@ -1287,8 +1287,8 @@ void TileMapEditorTilesPlugin::_stop_dragging() {
} }
// Get the offset from the mouse. // Get the offset from the mouse.
Vector2i offset = drag_start_mouse_pos - tile_map->map_to_world(top_left); Vector2i offset = drag_start_mouse_pos - tile_map->map_to_local(top_left);
offset = tile_map->world_to_map(mpos - offset) - tile_map->world_to_map(drag_start_mouse_pos - offset); offset = tile_map->local_to_map(mpos - offset) - tile_map->local_to_map(drag_start_mouse_pos - offset);
TypedArray<Vector2i> selection_used_cells = selection_pattern->get_used_cells(); TypedArray<Vector2i> selection_used_cells = selection_pattern->get_used_cells();
@ -1334,7 +1334,7 @@ void TileMapEditorTilesPlugin::_stop_dragging() {
} }
} break; } break;
case DRAG_TYPE_PICK: { case DRAG_TYPE_PICK: {
Rect2i rect = Rect2i(tile_map->world_to_map(drag_start_mouse_pos), tile_map->world_to_map(mpos) - tile_map->world_to_map(drag_start_mouse_pos)).abs(); Rect2i rect = Rect2i(tile_map->local_to_map(drag_start_mouse_pos), tile_map->local_to_map(mpos) - tile_map->local_to_map(drag_start_mouse_pos)).abs();
rect.size += Vector2i(1, 1); rect.size += Vector2i(1, 1);
int picked_source = -1; int picked_source = -1;
@ -1394,7 +1394,7 @@ void TileMapEditorTilesPlugin::_stop_dragging() {
undo_redo->commit_action(); undo_redo->commit_action();
} break; } break;
case DRAG_TYPE_RECT: { case DRAG_TYPE_RECT: {
HashMap<Vector2i, TileMapCell> to_draw = _draw_rect(tile_map->world_to_map(drag_start_mouse_pos), tile_map->world_to_map(mpos), drag_erasing); HashMap<Vector2i, TileMapCell> to_draw = _draw_rect(tile_map->local_to_map(drag_start_mouse_pos), tile_map->local_to_map(mpos), drag_erasing);
undo_redo->create_action(TTR("Paint tiles")); undo_redo->create_action(TTR("Paint tiles"));
for (const KeyValue<Vector2i, TileMapCell> &E : to_draw) { for (const KeyValue<Vector2i, TileMapCell> &E : to_draw) {
if (!drag_erasing && E.value.source_id == TileSet::INVALID_SOURCE) { if (!drag_erasing && E.value.source_id == TileSet::INVALID_SOURCE) {
@ -1418,7 +1418,7 @@ void TileMapEditorTilesPlugin::_stop_dragging() {
undo_redo->create_action(TTR("Paste tiles")); undo_redo->create_action(TTR("Paste tiles"));
TypedArray<Vector2i> used_cells = tile_map_clipboard->get_used_cells(); TypedArray<Vector2i> used_cells = tile_map_clipboard->get_used_cells();
for (int i = 0; i < used_cells.size(); i++) { for (int i = 0; i < used_cells.size(); i++) {
Vector2i coords = tile_map->map_pattern(tile_map->world_to_map(mpos - mouse_offset), used_cells[i], tile_map_clipboard); Vector2i coords = tile_map->map_pattern(tile_map->local_to_map(mpos - mouse_offset), used_cells[i], tile_map_clipboard);
undo_redo->add_do_method(tile_map, "set_cell", tile_map_layer, coords, tile_map_clipboard->get_cell_source_id(used_cells[i]), tile_map_clipboard->get_cell_atlas_coords(used_cells[i]), tile_map_clipboard->get_cell_alternative_tile(used_cells[i])); undo_redo->add_do_method(tile_map, "set_cell", tile_map_layer, coords, tile_map_clipboard->get_cell_source_id(used_cells[i]), tile_map_clipboard->get_cell_atlas_coords(used_cells[i]), tile_map_clipboard->get_cell_alternative_tile(used_cells[i]));
undo_redo->add_undo_method(tile_map, "set_cell", tile_map_layer, coords, tile_map->get_cell_source_id(tile_map_layer, coords), tile_map->get_cell_atlas_coords(tile_map_layer, coords), tile_map->get_cell_alternative_tile(tile_map_layer, coords)); undo_redo->add_undo_method(tile_map, "set_cell", tile_map_layer, coords, tile_map->get_cell_source_id(tile_map_layer, coords), tile_map->get_cell_atlas_coords(tile_map_layer, coords), tile_map->get_cell_alternative_tile(tile_map_layer, coords));
} }
@ -2640,7 +2640,7 @@ void TileMapEditorTerrainsPlugin::_stop_dragging() {
switch (drag_type) { switch (drag_type) {
case DRAG_TYPE_PICK: { case DRAG_TYPE_PICK: {
Vector2i coords = tile_map->world_to_map(mpos); Vector2i coords = tile_map->local_to_map(mpos);
TileMapCell cell = tile_map->get_cell(tile_map_layer, coords); TileMapCell cell = tile_map->get_cell(tile_map_layer, coords);
TileData *tile_data = nullptr; TileData *tile_data = nullptr;
@ -2714,7 +2714,7 @@ void TileMapEditorTerrainsPlugin::_stop_dragging() {
undo_redo->commit_action(false); undo_redo->commit_action(false);
} break; } break;
case DRAG_TYPE_LINE: { case DRAG_TYPE_LINE: {
HashMap<Vector2i, TileMapCell> to_draw = _draw_line(tile_map->world_to_map(drag_start_mouse_pos), tile_map->world_to_map(mpos), drag_erasing); HashMap<Vector2i, TileMapCell> to_draw = _draw_line(tile_map->local_to_map(drag_start_mouse_pos), tile_map->local_to_map(mpos), drag_erasing);
undo_redo->create_action(TTR("Paint terrain")); undo_redo->create_action(TTR("Paint terrain"));
for (const KeyValue<Vector2i, TileMapCell> &E : to_draw) { for (const KeyValue<Vector2i, TileMapCell> &E : to_draw) {
if (!drag_erasing && E.value.source_id == TileSet::INVALID_SOURCE) { if (!drag_erasing && E.value.source_id == TileSet::INVALID_SOURCE) {
@ -2726,7 +2726,7 @@ void TileMapEditorTerrainsPlugin::_stop_dragging() {
undo_redo->commit_action(); undo_redo->commit_action();
} break; } break;
case DRAG_TYPE_RECT: { case DRAG_TYPE_RECT: {
HashMap<Vector2i, TileMapCell> to_draw = _draw_rect(tile_map->world_to_map(drag_start_mouse_pos), tile_map->world_to_map(mpos), drag_erasing); HashMap<Vector2i, TileMapCell> to_draw = _draw_rect(tile_map->local_to_map(drag_start_mouse_pos), tile_map->local_to_map(mpos), drag_erasing);
undo_redo->create_action(TTR("Paint terrain")); undo_redo->create_action(TTR("Paint terrain"));
for (const KeyValue<Vector2i, TileMapCell> &E : to_draw) { for (const KeyValue<Vector2i, TileMapCell> &E : to_draw) {
if (!drag_erasing && E.value.source_id == TileSet::INVALID_SOURCE) { if (!drag_erasing && E.value.source_id == TileSet::INVALID_SOURCE) {
@ -2836,7 +2836,7 @@ bool TileMapEditorTerrainsPlugin::forward_canvas_gui_input(const Ref<InputEvent>
switch (drag_type) { switch (drag_type) {
case DRAG_TYPE_PAINT: { case DRAG_TYPE_PAINT: {
if (selected_terrain_set >= 0) { if (selected_terrain_set >= 0) {
HashMap<Vector2i, TileMapCell> to_draw = _draw_line(tile_map->world_to_map(drag_last_mouse_pos), tile_map->world_to_map(mpos), drag_erasing); HashMap<Vector2i, TileMapCell> to_draw = _draw_line(tile_map->local_to_map(drag_last_mouse_pos), tile_map->local_to_map(mpos), drag_erasing);
for (const KeyValue<Vector2i, TileMapCell> &E : to_draw) { for (const KeyValue<Vector2i, TileMapCell> &E : to_draw) {
if (!drag_modified.has(E.key)) { if (!drag_modified.has(E.key)) {
drag_modified[E.key] = tile_map->get_cell(tile_map_layer, E.key); drag_modified[E.key] = tile_map->get_cell(tile_map_layer, E.key);
@ -2880,7 +2880,7 @@ bool TileMapEditorTerrainsPlugin::forward_canvas_gui_input(const Ref<InputEvent>
drag_start_mouse_pos = mpos; drag_start_mouse_pos = mpos;
drag_modified.clear(); drag_modified.clear();
Vector2i cell = tile_map->world_to_map(mpos); Vector2i cell = tile_map->local_to_map(mpos);
HashMap<Vector2i, TileMapCell> to_draw = _draw_line(cell, cell, drag_erasing); HashMap<Vector2i, TileMapCell> to_draw = _draw_line(cell, cell, drag_erasing);
for (const KeyValue<Vector2i, TileMapCell> &E : to_draw) { for (const KeyValue<Vector2i, TileMapCell> &E : to_draw) {
drag_modified[E.key] = tile_map->get_cell(tile_map_layer, E.key); drag_modified[E.key] = tile_map->get_cell(tile_map_layer, E.key);
@ -2907,7 +2907,7 @@ bool TileMapEditorTerrainsPlugin::forward_canvas_gui_input(const Ref<InputEvent>
drag_type = DRAG_TYPE_BUCKET; drag_type = DRAG_TYPE_BUCKET;
drag_start_mouse_pos = mpos; drag_start_mouse_pos = mpos;
drag_modified.clear(); drag_modified.clear();
Vector<Vector2i> line = TileMapEditor::get_line(tile_map, tile_map->world_to_map(drag_last_mouse_pos), tile_map->world_to_map(mpos)); Vector<Vector2i> line = TileMapEditor::get_line(tile_map, tile_map->local_to_map(drag_last_mouse_pos), tile_map->local_to_map(mpos));
for (int i = 0; i < line.size(); i++) { for (int i = 0; i < line.size(); i++) {
if (!drag_modified.has(line[i])) { if (!drag_modified.has(line[i])) {
HashMap<Vector2i, TileMapCell> to_draw = _draw_bucket_fill(line[i], bucket_contiguous_checkbox->is_pressed(), drag_erasing); HashMap<Vector2i, TileMapCell> to_draw = _draw_bucket_fill(line[i], bucket_contiguous_checkbox->is_pressed(), drag_erasing);
@ -2971,10 +2971,10 @@ void TileMapEditorTerrainsPlugin::forward_canvas_draw_over_viewport(Control *p_o
if (drag_type == DRAG_TYPE_PICK) { if (drag_type == DRAG_TYPE_PICK) {
// Draw the area being picked. // Draw the area being picked.
Vector2i coords = tile_map->world_to_map(drag_last_mouse_pos); Vector2i coords = tile_map->local_to_map(drag_last_mouse_pos);
if (tile_map->get_cell_source_id(tile_map_layer, coords) != TileSet::INVALID_SOURCE) { if (tile_map->get_cell_source_id(tile_map_layer, coords) != TileSet::INVALID_SOURCE) {
Transform2D tile_xform; Transform2D tile_xform;
tile_xform.set_origin(tile_map->map_to_world(coords)); tile_xform.set_origin(tile_map->map_to_local(coords));
tile_xform.set_scale(tile_shape_size); tile_xform.set_scale(tile_shape_size);
tile_set->draw_tile_shape(p_overlay, xform * tile_xform, Color(1.0, 1.0, 1.0), false); tile_set->draw_tile_shape(p_overlay, xform * tile_xform, Color(1.0, 1.0, 1.0), false);
} }
@ -2982,15 +2982,15 @@ void TileMapEditorTerrainsPlugin::forward_canvas_draw_over_viewport(Control *p_o
bool expand_grid = false; bool expand_grid = false;
if (tool_buttons_group->get_pressed_button() == paint_tool_button && drag_type == DRAG_TYPE_NONE) { if (tool_buttons_group->get_pressed_button() == paint_tool_button && drag_type == DRAG_TYPE_NONE) {
// Preview for a single tile. // Preview for a single tile.
preview.insert(tile_map->world_to_map(drag_last_mouse_pos)); preview.insert(tile_map->local_to_map(drag_last_mouse_pos));
expand_grid = true; expand_grid = true;
} else if (tool_buttons_group->get_pressed_button() == line_tool_button || drag_type == DRAG_TYPE_LINE) { } else if (tool_buttons_group->get_pressed_button() == line_tool_button || drag_type == DRAG_TYPE_LINE) {
if (drag_type == DRAG_TYPE_NONE) { if (drag_type == DRAG_TYPE_NONE) {
// Preview for a single tile. // Preview for a single tile.
preview.insert(tile_map->world_to_map(drag_last_mouse_pos)); preview.insert(tile_map->local_to_map(drag_last_mouse_pos));
} else if (drag_type == DRAG_TYPE_LINE) { } else if (drag_type == DRAG_TYPE_LINE) {
// Preview for a line. // Preview for a line.
Vector<Vector2i> line = TileMapEditor::get_line(tile_map, tile_map->world_to_map(drag_start_mouse_pos), tile_map->world_to_map(drag_last_mouse_pos)); Vector<Vector2i> line = TileMapEditor::get_line(tile_map, tile_map->local_to_map(drag_start_mouse_pos), tile_map->local_to_map(drag_last_mouse_pos));
for (int i = 0; i < line.size(); i++) { for (int i = 0; i < line.size(); i++) {
preview.insert(line[i]); preview.insert(line[i]);
} }
@ -2999,8 +2999,8 @@ void TileMapEditorTerrainsPlugin::forward_canvas_draw_over_viewport(Control *p_o
} else if (drag_type == DRAG_TYPE_RECT) { } else if (drag_type == DRAG_TYPE_RECT) {
// Preview for a rect. // Preview for a rect.
Rect2i rect; Rect2i rect;
rect.set_position(tile_map->world_to_map(drag_start_mouse_pos)); rect.set_position(tile_map->local_to_map(drag_start_mouse_pos));
rect.set_end(tile_map->world_to_map(drag_last_mouse_pos)); rect.set_end(tile_map->local_to_map(drag_last_mouse_pos));
rect = rect.abs(); rect = rect.abs();
HashMap<Vector2i, TileSet::TerrainsPattern> to_draw; HashMap<Vector2i, TileSet::TerrainsPattern> to_draw;
@ -3012,7 +3012,7 @@ void TileMapEditorTerrainsPlugin::forward_canvas_draw_over_viewport(Control *p_o
expand_grid = true; expand_grid = true;
} else if (tool_buttons_group->get_pressed_button() == bucket_tool_button && drag_type == DRAG_TYPE_NONE) { } else if (tool_buttons_group->get_pressed_button() == bucket_tool_button && drag_type == DRAG_TYPE_NONE) {
// Preview for a fill. // Preview for a fill.
preview = _get_cells_for_bucket_fill(tile_map->world_to_map(drag_last_mouse_pos), bucket_contiguous_checkbox->is_pressed()); preview = _get_cells_for_bucket_fill(tile_map->local_to_map(drag_last_mouse_pos), bucket_contiguous_checkbox->is_pressed());
} }
// Expand the grid if needed // Expand the grid if needed
@ -3045,7 +3045,7 @@ void TileMapEditorTerrainsPlugin::forward_canvas_draw_over_viewport(Control *p_o
float opacity = CLAMP(MIN(left_opacity, MIN(right_opacity, MIN(top_opacity, bottom_opacity))) + 0.1, 0.0f, 1.0f); float opacity = CLAMP(MIN(left_opacity, MIN(right_opacity, MIN(top_opacity, bottom_opacity))) + 0.1, 0.0f, 1.0f);
Transform2D tile_xform; Transform2D tile_xform;
tile_xform.set_origin(tile_map->map_to_world(Vector2(x, y))); tile_xform.set_origin(tile_map->map_to_local(Vector2(x, y)));
tile_xform.set_scale(tile_shape_size); tile_xform.set_scale(tile_shape_size);
Color color = grid_color; Color color = grid_color;
color.a = color.a * opacity; color.a = color.a * opacity;
@ -3058,7 +3058,7 @@ void TileMapEditorTerrainsPlugin::forward_canvas_draw_over_viewport(Control *p_o
// Draw the preview. // Draw the preview.
for (const Vector2i &E : preview) { for (const Vector2i &E : preview) {
Transform2D tile_xform; Transform2D tile_xform;
tile_xform.set_origin(tile_map->map_to_world(E)); tile_xform.set_origin(tile_map->map_to_local(E));
tile_xform.set_scale(tile_set->get_tile_size()); tile_xform.set_scale(tile_set->get_tile_size());
if (drag_erasing || erase_button->is_pressed()) { if (drag_erasing || erase_button->is_pressed()) {
tile_set->draw_tile_shape(p_overlay, xform * tile_xform, Color(0.0, 0.0, 0.0, 0.5), true); tile_set->draw_tile_shape(p_overlay, xform * tile_xform, Color(0.0, 0.0, 0.0, 0.5), true);
@ -3838,7 +3838,7 @@ void TileMapEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
// Draw the scaled tile. // Draw the scaled tile.
Transform2D tile_xform; Transform2D tile_xform;
tile_xform.set_origin(tile_map->map_to_world(coords)); tile_xform.set_origin(tile_map->map_to_local(coords));
tile_xform.set_scale(tile_shape_size); tile_xform.set_scale(tile_shape_size);
tile_set->draw_tile_shape(p_overlay, xform * tile_xform, color, true, warning_pattern_texture); tile_set->draw_tile_shape(p_overlay, xform * tile_xform, color, true, warning_pattern_texture);
} }
@ -3848,7 +3848,7 @@ void TileMapEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
Vector2 icon_size; Vector2 icon_size;
icon_size[min_axis] = tile_set->get_tile_size()[min_axis] / 3; icon_size[min_axis] = tile_set->get_tile_size()[min_axis] / 3;
icon_size[(min_axis + 1) % 2] = (icon_size[min_axis] * missing_tile_texture->get_size()[(min_axis + 1) % 2] / missing_tile_texture->get_size()[min_axis]); icon_size[(min_axis + 1) % 2] = (icon_size[min_axis] * missing_tile_texture->get_size()[(min_axis + 1) % 2] / missing_tile_texture->get_size()[min_axis]);
Rect2 rect = Rect2(xform.xform(tile_map->map_to_world(coords)) - (icon_size * xform.get_scale() / 2), icon_size * xform.get_scale()); Rect2 rect = Rect2(xform.xform(tile_map->map_to_local(coords)) - (icon_size * xform.get_scale() / 2), icon_size * xform.get_scale());
p_overlay->draw_texture_rect(missing_tile_texture, rect); p_overlay->draw_texture_rect(missing_tile_texture, rect);
} }
} }
@ -3861,10 +3861,10 @@ void TileMapEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
// Determine the drawn area. // Determine the drawn area.
Size2 screen_size = p_overlay->get_size(); Size2 screen_size = p_overlay->get_size();
Rect2i screen_rect; Rect2i screen_rect;
screen_rect.position = tile_map->world_to_map(xform_inv.xform(Vector2())); screen_rect.position = tile_map->local_to_map(xform_inv.xform(Vector2()));
screen_rect.expand_to(tile_map->world_to_map(xform_inv.xform(Vector2(0, screen_size.height)))); screen_rect.expand_to(tile_map->local_to_map(xform_inv.xform(Vector2(0, screen_size.height))));
screen_rect.expand_to(tile_map->world_to_map(xform_inv.xform(Vector2(screen_size.width, 0)))); screen_rect.expand_to(tile_map->local_to_map(xform_inv.xform(Vector2(screen_size.width, 0))));
screen_rect.expand_to(tile_map->world_to_map(xform_inv.xform(screen_size))); screen_rect.expand_to(tile_map->local_to_map(xform_inv.xform(screen_size)));
screen_rect = screen_rect.grow(1); screen_rect = screen_rect.grow(1);
Rect2i tilemap_used_rect = tile_map->get_used_rect(); Rect2i tilemap_used_rect = tile_map->get_used_rect();
@ -3897,7 +3897,7 @@ void TileMapEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
float opacity = CLAMP(MIN(left_opacity, MIN(right_opacity, MIN(top_opacity, bottom_opacity))) + 0.1, 0.0f, 1.0f); float opacity = CLAMP(MIN(left_opacity, MIN(right_opacity, MIN(top_opacity, bottom_opacity))) + 0.1, 0.0f, 1.0f);
Transform2D tile_xform; Transform2D tile_xform;
tile_xform.set_origin(tile_map->map_to_world(Vector2(x, y))); tile_xform.set_origin(tile_map->map_to_local(Vector2(x, y)));
tile_xform.set_scale(tile_shape_size); tile_xform.set_scale(tile_shape_size);
Color color = grid_color; Color color = grid_color;
color.a = color.a * opacity; color.a = color.a * opacity;
@ -3910,7 +3910,7 @@ void TileMapEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
/*Ref<Font> font = get_theme_font(SNAME("font"), SNAME("Label")); /*Ref<Font> font = get_theme_font(SNAME("font"), SNAME("Label"));
for (int x = displayed_rect.position.x; x < (displayed_rect.position.x + displayed_rect.size.x); x++) { for (int x = displayed_rect.position.x; x < (displayed_rect.position.x + displayed_rect.size.x); x++) {
for (int y = displayed_rect.position.y; y < (displayed_rect.position.y + displayed_rect.size.y); y++) { for (int y = displayed_rect.position.y; y < (displayed_rect.position.y + displayed_rect.size.y); y++) {
p_overlay->draw_string(font, xform.xform(tile_map->map_to_world(Vector2(x, y))) + Vector2i(-tile_shape_size.x / 2, 0), vformat("%s", Vector2(x, y))); p_overlay->draw_string(font, xform.xform(tile_map->map_to_local(Vector2(x, y))) + Vector2i(-tile_shape_size.x / 2, 0), vformat("%s", Vector2(x, y)));
} }
}*/ }*/

View file

@ -91,10 +91,10 @@ void TilesEditorPlugin::_thread() {
TypedArray<Vector2i> used_cells = tile_map->get_used_cells(0); TypedArray<Vector2i> used_cells = tile_map->get_used_cells(0);
Rect2 encompassing_rect = Rect2(); Rect2 encompassing_rect = Rect2();
encompassing_rect.set_position(tile_map->map_to_world(used_cells[0])); encompassing_rect.set_position(tile_map->map_to_local(used_cells[0]));
for (int i = 0; i < used_cells.size(); i++) { for (int i = 0; i < used_cells.size(); i++) {
Vector2i cell = used_cells[i]; Vector2i cell = used_cells[i];
Vector2 world_pos = tile_map->map_to_world(cell); Vector2 world_pos = tile_map->map_to_local(cell);
encompassing_rect.expand_to(world_pos); encompassing_rect.expand_to(world_pos);
// Texture. // Texture.

View file

@ -547,6 +547,7 @@ static const char *gdscript_function_renames[][2] = {
{ "update_gizmo", "update_gizmos" }, // Node3D { "update_gizmo", "update_gizmos" }, // Node3D
{ "viewport_set_use_arvr", "viewport_set_use_xr" }, // RenderingServer { "viewport_set_use_arvr", "viewport_set_use_xr" }, // RenderingServer
{ "warp_mouse_position", "warp_mouse" }, // Input { "warp_mouse_position", "warp_mouse" }, // Input
{ "world_to_map", "local_to_map" }, // TileMap, GridMap
{ "set_shader_param", "set_shader_parameter" }, // ShaderMaterial { "set_shader_param", "set_shader_parameter" }, // ShaderMaterial
{ "get_shader_param", "get_shader_parameter" }, // ShaderMaterial { "get_shader_param", "get_shader_parameter" }, // ShaderMaterial
{ "set_uniform_name", "set_parameter_name" }, // ParameterRef { "set_uniform_name", "set_parameter_name" }, // ParameterRef
@ -959,6 +960,7 @@ static const char *csharp_function_renames[][2] = {
{ "UpdateGizmo", "UpdateGizmos" }, // Node3D { "UpdateGizmo", "UpdateGizmos" }, // Node3D
{ "ViewportSetUseArvr", "ViewportSetUseXr" }, // RenderingServer { "ViewportSetUseArvr", "ViewportSetUseXr" }, // RenderingServer
{ "WarpMousePosition", "WarpMouse" }, // Input { "WarpMousePosition", "WarpMouse" }, // Input
{ "WorldToMap", "LocalToMap" }, // TileMap, GridMap
{ "SetShaderParam", "SetShaderParameter" }, // ShaderMaterial { "SetShaderParam", "SetShaderParameter" }, // ShaderMaterial
{ "GetShaderParam", "GetShaderParameter" }, // ShaderMaterial { "GetShaderParam", "GetShaderParameter" }, // ShaderMaterial
{ "SetUniformName", "SetParameterName" }, // ParameterRef { "SetUniformName", "SetParameterName" }, // ParameterRef
@ -2434,7 +2436,7 @@ bool ProjectConverter3To4::test_conversion(RegExContainer &reg_container) {
valid = valid & test_conversion_gdscript_builtin("set_cell_item(a, b)", "set_cell_item(a, b)", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); valid = valid & test_conversion_gdscript_builtin("set_cell_item(a, b)", "set_cell_item(a, b)", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
valid = valid & test_conversion_gdscript_builtin("get_cell_item_orientation(a, b,c)", "get_cell_item_orientation(Vector3i(a,b,c))", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); valid = valid & test_conversion_gdscript_builtin("get_cell_item_orientation(a, b,c)", "get_cell_item_orientation(Vector3i(a,b,c))", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
valid = valid & test_conversion_gdscript_builtin("get_cell_item(a, b,c)", "get_cell_item(Vector3i(a,b,c))", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); valid = valid & test_conversion_gdscript_builtin("get_cell_item(a, b,c)", "get_cell_item(Vector3i(a,b,c))", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
valid = valid & test_conversion_gdscript_builtin("map_to_world(a, b,c)", "map_to_world(Vector3i(a,b,c))", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); valid = valid & test_conversion_gdscript_builtin("map_to_world(a, b,c)", "map_to_local(Vector3i(a,b,c))", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
valid = valid & test_conversion_gdscript_builtin("PackedStringArray(req_godot).join('.')", "'.'.join(PackedStringArray(req_godot))", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); valid = valid & test_conversion_gdscript_builtin("PackedStringArray(req_godot).join('.')", "'.'.join(PackedStringArray(req_godot))", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
valid = valid & test_conversion_gdscript_builtin("=PackedStringArray(req_godot).join('.')", "='.'.join(PackedStringArray(req_godot))", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); valid = valid & test_conversion_gdscript_builtin("=PackedStringArray(req_godot).join('.')", "='.'.join(PackedStringArray(req_godot))", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
@ -3462,14 +3464,16 @@ void ProjectConverter3To4::process_gdscript_line(String &line, const RegExContai
} }
} }
} }
// map_to_world(a, b, c) -> map_to_world(Vector3i(a, b, c)) // map_to_world(a, b, c) -> map_to_local(Vector3i(a, b, c))
if (line.contains("map_to_world(")) { if (line.contains("map_to_world(")) {
int start = line.find("map_to_world("); int start = line.find("map_to_world(");
int end = get_end_parenthess(line.substr(start)) + 1; int end = get_end_parenthess(line.substr(start)) + 1;
if (end > -1) { if (end > -1) {
Vector<String> parts = parse_arguments(line.substr(start, end)); Vector<String> parts = parse_arguments(line.substr(start, end));
if (parts.size() == 3) { if (parts.size() == 3) {
line = line.substr(0, start) + "map_to_world(Vector3i(" + parts[0] + "," + parts[1] + "," + parts[2] + "))" + line.substr(end + start); line = line.substr(0, start) + "map_to_local(Vector3i(" + parts[0] + "," + parts[1] + "," + parts[2] + "))" + line.substr(end + start);
} else if (parts.size() == 1) {
line = line.substr(0, start) + "map_to_local(" + parts[0] + ")" + line.substr(end + start);
} }
} }
} }

View file

@ -5271,7 +5271,7 @@ void GLTFDocument::_convert_grid_map_to_gltf(GridMap *p_grid_map, GLTFNodeIndex
cell_xform.basis.scale(Vector3(p_grid_map->get_cell_scale(), cell_xform.basis.scale(Vector3(p_grid_map->get_cell_scale(),
p_grid_map->get_cell_scale(), p_grid_map->get_cell_scale(),
p_grid_map->get_cell_scale())); p_grid_map->get_cell_scale()));
cell_xform.set_origin(p_grid_map->map_to_world( cell_xform.set_origin(p_grid_map->map_to_local(
Vector3(cell_location.x, cell_location.y, cell_location.z))); Vector3(cell_location.x, cell_location.y, cell_location.z)));
Ref<GLTFMesh> gltf_mesh; Ref<GLTFMesh> gltf_mesh;
gltf_mesh.instantiate(); gltf_mesh.instantiate();

View file

@ -84,7 +84,7 @@
<method name="get_meshes" qualifiers="const"> <method name="get_meshes" qualifiers="const">
<return type="Array" /> <return type="Array" />
<description> <description>
Returns an array of [Transform3D] and [Mesh] references corresponding to the non-empty cells in the grid. The transforms are specified in world space. Returns an array of [Transform3D] and [Mesh] references corresponding to the non-empty cells in the grid. The transforms are specified in local space.
</description> </description>
</method> </method>
<method name="get_navigation_layer_value" qualifiers="const"> <method name="get_navigation_layer_value" qualifiers="const">
@ -114,6 +114,13 @@
Returns an array of all cells with the given item index specified in [code]item[/code]. Returns an array of all cells with the given item index specified in [code]item[/code].
</description> </description>
</method> </method>
<method name="local_to_map" qualifiers="const">
<return type="Vector3i" />
<param index="0" name="local_position" type="Vector3" />
<description>
Returns the map coordinates of the cell containing the given [param local_position]. If [param local_position] is in global coordinates, consider using [method Node3D.to_local] before passing it to this method. See also [method map_to_local].
</description>
</method>
<method name="make_baked_meshes"> <method name="make_baked_meshes">
<return type="void" /> <return type="void" />
<param index="0" name="gen_lightmap_uv" type="bool" default="false" /> <param index="0" name="gen_lightmap_uv" type="bool" default="false" />
@ -121,11 +128,11 @@
<description> <description>
</description> </description>
</method> </method>
<method name="map_to_world" qualifiers="const"> <method name="map_to_local" qualifiers="const">
<return type="Vector3" /> <return type="Vector3" />
<param index="0" name="map_position" type="Vector3i" /> <param index="0" name="map_position" type="Vector3i" />
<description> <description>
Returns the position of a grid cell in the GridMap's local coordinate space. Returns the position of a grid cell in the GridMap's local coordinate space. To convert the returned value into global coordinates, use [method Node3D.to_global]. See also [method map_to_local].
</description> </description>
</method> </method>
<method name="resource_changed"> <method name="resource_changed">
@ -169,14 +176,6 @@
Based on [code]value[/code], enables or disables the specified layer in the [member navigation_layers] bitmask, given a [code]layer_number[/code] between 1 and 32. Based on [code]value[/code], enables or disables the specified layer in the [member navigation_layers] bitmask, given a [code]layer_number[/code] between 1 and 32.
</description> </description>
</method> </method>
<method name="world_to_map" qualifiers="const">
<return type="Vector3i" />
<param index="0" name="world_position" type="Vector3" />
<description>
Returns the coordinates of the grid cell containing the given point.
[code]pos[/code] should be in the GridMap's local coordinate space.
</description>
</method>
</methods> </methods>
<members> <members>
<member name="bake_navigation" type="bool" setter="set_bake_navigation" getter="is_baking_navigation" default="false"> <member name="bake_navigation" type="bool" setter="set_bake_navigation" getter="is_baking_navigation" default="false">

View file

@ -497,18 +497,18 @@ int GridMap::get_orthogonal_index_from_basis(const Basis &p_basis) const {
return 0; return 0;
} }
Vector3i GridMap::world_to_map(const Vector3 &p_world_position) const { Vector3i GridMap::local_to_map(const Vector3 &p_world_position) const {
Vector3 map_position = (p_world_position / cell_size).floor(); Vector3 map_position = (p_world_position / cell_size).floor();
return Vector3i(map_position); return Vector3i(map_position);
} }
Vector3 GridMap::map_to_world(const Vector3i &p_map_position) const { Vector3 GridMap::map_to_local(const Vector3i &p_map_position) const {
Vector3 offset = _get_offset(); Vector3 offset = _get_offset();
Vector3 world_pos( Vector3 local_position(
p_map_position.x * cell_size.x + offset.x, p_map_position.x * cell_size.x + offset.x,
p_map_position.y * cell_size.y + offset.y, p_map_position.y * cell_size.y + offset.y,
p_map_position.z * cell_size.z + offset.z); p_map_position.z * cell_size.z + offset.z);
return world_pos; return local_position;
} }
void GridMap::_octant_transform(const OctantKey &p_key) { void GridMap::_octant_transform(const OctantKey &p_key) {
@ -1047,8 +1047,8 @@ void GridMap::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_basis_with_orthogonal_index", "index"), &GridMap::get_basis_with_orthogonal_index); ClassDB::bind_method(D_METHOD("get_basis_with_orthogonal_index", "index"), &GridMap::get_basis_with_orthogonal_index);
ClassDB::bind_method(D_METHOD("get_orthogonal_index_from_basis", "basis"), &GridMap::get_orthogonal_index_from_basis); ClassDB::bind_method(D_METHOD("get_orthogonal_index_from_basis", "basis"), &GridMap::get_orthogonal_index_from_basis);
ClassDB::bind_method(D_METHOD("world_to_map", "world_position"), &GridMap::world_to_map); ClassDB::bind_method(D_METHOD("local_to_map", "local_position"), &GridMap::local_to_map);
ClassDB::bind_method(D_METHOD("map_to_world", "map_position"), &GridMap::map_to_world); ClassDB::bind_method(D_METHOD("map_to_local", "map_position"), &GridMap::map_to_local);
ClassDB::bind_method(D_METHOD("_update_octants_callback"), &GridMap::_update_octants_callback); ClassDB::bind_method(D_METHOD("_update_octants_callback"), &GridMap::_update_octants_callback);
ClassDB::bind_method(D_METHOD("resource_changed", "resource"), &GridMap::resource_changed); ClassDB::bind_method(D_METHOD("resource_changed", "resource"), &GridMap::resource_changed);

View file

@ -276,8 +276,8 @@ public:
Basis get_basis_with_orthogonal_index(int p_index) const; Basis get_basis_with_orthogonal_index(int p_index) const;
int get_orthogonal_index_from_basis(const Basis &p_basis) const; int get_orthogonal_index_from_basis(const Basis &p_basis) const;
Vector3i world_to_map(const Vector3 &p_world_position) const; Vector3i local_to_map(const Vector3 &p_local_position) const;
Vector3 map_to_world(const Vector3i &p_map_position) const; Vector3 map_to_local(const Vector3i &p_map_position) const;
void set_cell_scale(float p_scale); void set_cell_scale(float p_scale);
float get_cell_scale() const; float get_cell_scale() const;

View file

@ -828,13 +828,13 @@ void TileMap::_update_dirty_quadrants() {
// Update the coords cache. // Update the coords cache.
for (SelfList<TileMapQuadrant> *q = dirty_quadrant_list.first(); q; q = q->next()) { for (SelfList<TileMapQuadrant> *q = dirty_quadrant_list.first(); q; q = q->next()) {
q->self()->map_to_world.clear(); q->self()->map_to_local.clear();
q->self()->world_to_map.clear(); q->self()->local_to_map.clear();
for (const Vector2i &E : q->self()->cells) { for (const Vector2i &E : q->self()->cells) {
Vector2i pk = E; Vector2i pk = E;
Vector2i pk_world_coords = map_to_world(pk); Vector2i pk_local_coords = map_to_local(pk);
q->self()->map_to_world[pk] = pk_world_coords; q->self()->map_to_local[pk] = pk_local_coords;
q->self()->world_to_map[pk_world_coords] = pk; q->self()->local_to_map[pk_local_coords] = pk;
} }
} }
@ -852,7 +852,7 @@ void TileMap::_update_dirty_quadrants() {
for (SelfList<TileMapQuadrant> *q = dirty_quadrant_list.first(); q; q = q->next()) { for (SelfList<TileMapQuadrant> *q = dirty_quadrant_list.first(); q; q = q->next()) {
rs->canvas_item_clear(q->self()->debug_canvas_item); rs->canvas_item_clear(q->self()->debug_canvas_item);
Transform2D xform; Transform2D xform;
xform.set_origin(map_to_world(q->self()->coords * get_effective_quadrant_size(layer))); xform.set_origin(map_to_local(q->self()->coords * get_effective_quadrant_size(layer)));
rs->canvas_item_set_transform(q->self()->debug_canvas_item, xform); rs->canvas_item_set_transform(q->self()->debug_canvas_item, xform);
_rendering_draw_quadrant_debug(q->self()); _rendering_draw_quadrant_debug(q->self());
@ -978,10 +978,10 @@ void TileMap::_recompute_rect_cache() {
for (unsigned int layer = 0; layer < layers.size(); layer++) { for (unsigned int layer = 0; layer < layers.size(); layer++) {
for (const KeyValue<Vector2i, TileMapQuadrant> &E : layers[layer].quadrant_map) { for (const KeyValue<Vector2i, TileMapQuadrant> &E : layers[layer].quadrant_map) {
Rect2 r; Rect2 r;
r.position = map_to_world(E.key * get_effective_quadrant_size(layer)); r.position = map_to_local(E.key * get_effective_quadrant_size(layer));
r.expand_to(map_to_world((E.key + Vector2i(1, 0)) * get_effective_quadrant_size(layer))); r.expand_to(map_to_local((E.key + Vector2i(1, 0)) * get_effective_quadrant_size(layer)));
r.expand_to(map_to_world((E.key + Vector2i(1, 1)) * get_effective_quadrant_size(layer))); r.expand_to(map_to_local((E.key + Vector2i(1, 1)) * get_effective_quadrant_size(layer)));
r.expand_to(map_to_world((E.key + Vector2i(0, 1)) * get_effective_quadrant_size(layer))); r.expand_to(map_to_local((E.key + Vector2i(0, 1)) * get_effective_quadrant_size(layer)));
if (first) { if (first) {
r_total = r; r_total = r;
first = false; first = false;
@ -1010,7 +1010,7 @@ void TileMap::_rendering_notification(int p_what) {
TileMapQuadrant &q = E_quadrant.value; TileMapQuadrant &q = E_quadrant.value;
// Update occluders transform. // Update occluders transform.
for (const KeyValue<Vector2i, Vector2i> &E_cell : q.world_to_map) { for (const KeyValue<Vector2i, Vector2i> &E_cell : q.local_to_map) {
Transform2D xform; Transform2D xform;
xform.set_origin(E_cell.key); xform.set_origin(E_cell.key);
for (const RID &occluder : q.occluders) { for (const RID &occluder : q.occluders) {
@ -1030,7 +1030,7 @@ void TileMap::_rendering_notification(int p_what) {
TileMapQuadrant &q = E_quadrant.value; TileMapQuadrant &q = E_quadrant.value;
// Update occluders transform. // Update occluders transform.
for (const KeyValue<Vector2i, Vector2i> &E_cell : q.world_to_map) { for (const KeyValue<Vector2i, Vector2i> &E_cell : q.local_to_map) {
Transform2D xform; Transform2D xform;
xform.set_origin(E_cell.key); xform.set_origin(E_cell.key);
for (const RID &occluder : q.occluders) { for (const RID &occluder : q.occluders) {
@ -1126,7 +1126,7 @@ void TileMap::_rendering_update_dirty_quadrants(SelfList<TileMapQuadrant>::List
} }
// Iterate over the cells of the quadrant. // Iterate over the cells of the quadrant.
for (const KeyValue<Vector2i, Vector2i> &E_cell : q.world_to_map) { for (const KeyValue<Vector2i, Vector2i> &E_cell : q.local_to_map) {
TileMapCell c = get_cell(q.layer, E_cell.value, true); TileMapCell c = get_cell(q.layer, E_cell.value, true);
TileSetSource *source; TileSetSource *source;
@ -1151,7 +1151,7 @@ void TileMap::_rendering_update_dirty_quadrants(SelfList<TileMapQuadrant>::List
int z_index = tile_data->get_z_index(); int z_index = tile_data->get_z_index();
// Quandrant pos. // Quandrant pos.
Vector2 position = map_to_world(q.coords * get_effective_quadrant_size(q.layer)); Vector2 position = map_to_local(q.coords * get_effective_quadrant_size(q.layer));
if (is_y_sort_enabled() && layers[q.layer].y_sort_enabled) { if (is_y_sort_enabled() && layers[q.layer].y_sort_enabled) {
// When Y-sorting, the quandrant size is sure to be 1, we can thus offset the CanvasItem. // When Y-sorting, the quandrant size is sure to be 1, we can thus offset the CanvasItem.
position.y += layers[q.layer].y_sort_origin + tile_data->get_y_sort_origin(); position.y += layers[q.layer].y_sort_origin + tile_data->get_y_sort_origin();
@ -1223,14 +1223,14 @@ void TileMap::_rendering_update_dirty_quadrants(SelfList<TileMapQuadrant>::List
int index = -(int64_t)0x80000000; //always must be drawn below children. int index = -(int64_t)0x80000000; //always must be drawn below children.
for (int layer = 0; layer < (int)layers.size(); layer++) { for (int layer = 0; layer < (int)layers.size(); layer++) {
// Sort the quadrants coords per world coordinates // Sort the quadrants coords per local coordinates.
RBMap<Vector2i, Vector2i, TileMapQuadrant::CoordsWorldComparator> world_to_map; RBMap<Vector2i, Vector2i, TileMapQuadrant::CoordsWorldComparator> local_to_map;
for (const KeyValue<Vector2i, TileMapQuadrant> &E : layers[layer].quadrant_map) { for (const KeyValue<Vector2i, TileMapQuadrant> &E : layers[layer].quadrant_map) {
world_to_map[map_to_world(E.key)] = E.key; local_to_map[map_to_local(E.key)] = E.key;
} }
// Sort the quadrants // Sort the quadrants.
for (const KeyValue<Vector2i, Vector2i> &E : world_to_map) { for (const KeyValue<Vector2i, Vector2i> &E : local_to_map) {
TileMapQuadrant &q = layers[layer].quadrant_map[E.value]; TileMapQuadrant &q = layers[layer].quadrant_map[E.value];
for (const RID &ci : q.canvas_items) { for (const RID &ci : q.canvas_items) {
RS::get_singleton()->canvas_item_set_draw_index(ci, index++); RS::get_singleton()->canvas_item_set_draw_index(ci, index++);
@ -1270,7 +1270,7 @@ void TileMap::_rendering_draw_quadrant_debug(TileMapQuadrant *p_quadrant) {
// Draw a placeholder for scenes needing one. // Draw a placeholder for scenes needing one.
RenderingServer *rs = RenderingServer::get_singleton(); RenderingServer *rs = RenderingServer::get_singleton();
Vector2 quadrant_pos = map_to_world(p_quadrant->coords * get_effective_quadrant_size(p_quadrant->layer)); Vector2 quadrant_pos = map_to_local(p_quadrant->coords * get_effective_quadrant_size(p_quadrant->layer));
for (const Vector2i &E_cell : p_quadrant->cells) { for (const Vector2i &E_cell : p_quadrant->cells) {
const TileMapCell &c = get_cell(p_quadrant->layer, E_cell, true); const TileMapCell &c = get_cell(p_quadrant->layer, E_cell, true);
@ -1302,7 +1302,7 @@ void TileMap::_rendering_draw_quadrant_debug(TileMapQuadrant *p_quadrant) {
// Draw a placeholder tile. // Draw a placeholder tile.
Transform2D xform; Transform2D xform;
xform.set_origin(map_to_world(E_cell) - quadrant_pos); xform.set_origin(map_to_local(E_cell) - quadrant_pos);
rs->canvas_item_add_set_transform(p_quadrant->debug_canvas_item, xform); rs->canvas_item_add_set_transform(p_quadrant->debug_canvas_item, xform);
rs->canvas_item_add_circle(p_quadrant->debug_canvas_item, Vector2(), MIN(tile_set->get_tile_size().x, tile_set->get_tile_size().y) / 4.0, color); rs->canvas_item_add_circle(p_quadrant->debug_canvas_item, Vector2(), MIN(tile_set->get_tile_size().x, tile_set->get_tile_size().y) / 4.0, color);
} }
@ -1423,7 +1423,7 @@ void TileMap::_physics_notification(int p_what) {
for (RID body : q.bodies) { for (RID body : q.bodies) {
Transform2D xform; Transform2D xform;
xform.set_origin(map_to_world(bodies_coords[body])); xform.set_origin(map_to_local(bodies_coords[body]));
xform = global_transform * xform; xform = global_transform * xform;
PhysicsServer2D::get_singleton()->body_set_state(body, PhysicsServer2D::BODY_STATE_TRANSFORM, xform); PhysicsServer2D::get_singleton()->body_set_state(body, PhysicsServer2D::BODY_STATE_TRANSFORM, xform);
} }
@ -1446,7 +1446,7 @@ void TileMap::_physics_notification(int p_what) {
for (RID body : q.bodies) { for (RID body : q.bodies) {
Transform2D xform; Transform2D xform;
xform.set_origin(map_to_world(bodies_coords[body])); xform.set_origin(map_to_local(bodies_coords[body]));
xform = new_transform * xform; xform = new_transform * xform;
PhysicsServer2D::get_singleton()->body_set_state(body, PhysicsServer2D::BODY_STATE_TRANSFORM, xform); PhysicsServer2D::get_singleton()->body_set_state(body, PhysicsServer2D::BODY_STATE_TRANSFORM, xform);
@ -1516,7 +1516,7 @@ void TileMap::_physics_update_dirty_quadrants(SelfList<TileMapQuadrant>::List &r
ps->body_set_space(body, space); ps->body_set_space(body, space);
Transform2D xform; Transform2D xform;
xform.set_origin(map_to_world(E_cell)); xform.set_origin(map_to_local(E_cell));
xform = global_transform * xform; xform = global_transform * xform;
ps->body_set_state(body, PhysicsServer2D::BODY_STATE_TRANSFORM, xform); ps->body_set_state(body, PhysicsServer2D::BODY_STATE_TRANSFORM, xform);
@ -1602,7 +1602,7 @@ void TileMap::_physics_draw_quadrant_debug(TileMapQuadrant *p_quadrant) {
Vector<Color> color; Vector<Color> color;
color.push_back(debug_collision_color); color.push_back(debug_collision_color);
Vector2 quadrant_pos = map_to_world(p_quadrant->coords * get_effective_quadrant_size(p_quadrant->layer)); Vector2 quadrant_pos = map_to_local(p_quadrant->coords * get_effective_quadrant_size(p_quadrant->layer));
Transform2D qudrant_xform; Transform2D qudrant_xform;
qudrant_xform.set_origin(quadrant_pos); qudrant_xform.set_origin(quadrant_pos);
Transform2D global_transform_inv = (get_global_transform() * qudrant_xform).affine_inverse(); Transform2D global_transform_inv = (get_global_transform() * qudrant_xform).affine_inverse();
@ -1641,7 +1641,7 @@ void TileMap::_navigation_notification(int p_what) {
continue; continue;
} }
Transform2D tile_transform; Transform2D tile_transform;
tile_transform.set_origin(map_to_world(E_region.key)); tile_transform.set_origin(map_to_local(E_region.key));
NavigationServer2D::get_singleton()->region_set_transform(region, tilemap_xform * tile_transform); NavigationServer2D::get_singleton()->region_set_transform(region, tilemap_xform * tile_transform);
} }
} }
@ -1709,7 +1709,7 @@ void TileMap::_navigation_update_dirty_quadrants(SelfList<TileMapQuadrant>::List
if (navpoly.is_valid()) { if (navpoly.is_valid()) {
Transform2D tile_transform; Transform2D tile_transform;
tile_transform.set_origin(map_to_world(E_cell)); tile_transform.set_origin(map_to_local(E_cell));
RID region = NavigationServer2D::get_singleton()->region_create(); RID region = NavigationServer2D::get_singleton()->region_create();
NavigationServer2D::get_singleton()->region_set_map(region, get_world_2d()->get_navigation_map()); NavigationServer2D::get_singleton()->region_set_map(region, get_world_2d()->get_navigation_map());
@ -1769,7 +1769,7 @@ void TileMap::_navigation_draw_quadrant_debug(TileMapQuadrant *p_quadrant) {
Color color = get_tree()->get_debug_navigation_color(); Color color = get_tree()->get_debug_navigation_color();
RandomPCG rand; RandomPCG rand;
Vector2 quadrant_pos = map_to_world(p_quadrant->coords * get_effective_quadrant_size(p_quadrant->layer)); Vector2 quadrant_pos = map_to_local(p_quadrant->coords * get_effective_quadrant_size(p_quadrant->layer));
for (const Vector2i &E_cell : p_quadrant->cells) { for (const Vector2i &E_cell : p_quadrant->cells) {
TileMapCell c = get_cell(p_quadrant->layer, E_cell, true); TileMapCell c = get_cell(p_quadrant->layer, E_cell, true);
@ -1792,7 +1792,7 @@ void TileMap::_navigation_draw_quadrant_debug(TileMapQuadrant *p_quadrant) {
} }
Transform2D xform; Transform2D xform;
xform.set_origin(map_to_world(E_cell) - quadrant_pos); xform.set_origin(map_to_local(E_cell) - quadrant_pos);
rs->canvas_item_add_set_transform(p_quadrant->debug_canvas_item, xform); rs->canvas_item_add_set_transform(p_quadrant->debug_canvas_item, xform);
for (int layer_index = 0; layer_index < tile_set->get_navigation_layers_count(); layer_index++) { for (int layer_index = 0; layer_index < tile_set->get_navigation_layers_count(); layer_index++) {
@ -1866,10 +1866,10 @@ void TileMap::_scenes_update_dirty_quadrants(SelfList<TileMapQuadrant>::List &r_
Control *scene_as_control = Object::cast_to<Control>(scene); Control *scene_as_control = Object::cast_to<Control>(scene);
Node2D *scene_as_node2d = Object::cast_to<Node2D>(scene); Node2D *scene_as_node2d = Object::cast_to<Node2D>(scene);
if (scene_as_control) { if (scene_as_control) {
scene_as_control->set_position(map_to_world(E_cell) + scene_as_control->get_position()); scene_as_control->set_position(map_to_local(E_cell) + scene_as_control->get_position());
} else if (scene_as_node2d) { } else if (scene_as_node2d) {
Transform2D xform; Transform2D xform;
xform.set_origin(map_to_world(E_cell)); xform.set_origin(map_to_local(E_cell));
scene_as_node2d->set_transform(xform * scene_as_node2d->get_transform()); scene_as_node2d->set_transform(xform * scene_as_node2d->get_transform());
} }
q.scenes[E_cell] = scene->get_name(); q.scenes[E_cell] = scene->get_name();
@ -1903,7 +1903,7 @@ void TileMap::_scenes_draw_quadrant_debug(TileMapQuadrant *p_quadrant) {
// Draw a placeholder for scenes needing one. // Draw a placeholder for scenes needing one.
RenderingServer *rs = RenderingServer::get_singleton(); RenderingServer *rs = RenderingServer::get_singleton();
Vector2 quadrant_pos = map_to_world(p_quadrant->coords * get_effective_quadrant_size(p_quadrant->layer)); Vector2 quadrant_pos = map_to_local(p_quadrant->coords * get_effective_quadrant_size(p_quadrant->layer));
for (const Vector2i &E_cell : p_quadrant->cells) { for (const Vector2i &E_cell : p_quadrant->cells) {
const TileMapCell &c = get_cell(p_quadrant->layer, E_cell, true); const TileMapCell &c = get_cell(p_quadrant->layer, E_cell, true);
@ -1933,7 +1933,7 @@ void TileMap::_scenes_draw_quadrant_debug(TileMapQuadrant *p_quadrant) {
// Draw a placeholder tile. // Draw a placeholder tile.
Transform2D xform; Transform2D xform;
xform.set_origin(map_to_world(E_cell) - quadrant_pos); xform.set_origin(map_to_local(E_cell) - quadrant_pos);
rs->canvas_item_add_set_transform(p_quadrant->debug_canvas_item, xform); rs->canvas_item_add_set_transform(p_quadrant->debug_canvas_item, xform);
rs->canvas_item_add_circle(p_quadrant->debug_canvas_item, Vector2(), MIN(tile_set->get_tile_size().x, tile_set->get_tile_size().y) / 4.0, color); rs->canvas_item_add_circle(p_quadrant->debug_canvas_item, Vector2(), MIN(tile_set->get_tile_size().x, tile_set->get_tile_size().y) / 4.0, color);
} }
@ -2822,7 +2822,7 @@ void TileMap::_build_runtime_update_tile_data(SelfList<TileMapQuadrant>::List &r
while (q_list_element) { while (q_list_element) {
TileMapQuadrant &q = *q_list_element->self(); TileMapQuadrant &q = *q_list_element->self();
// Iterate over the cells of the quadrant. // Iterate over the cells of the quadrant.
for (const KeyValue<Vector2i, Vector2i> &E_cell : q.world_to_map) { for (const KeyValue<Vector2i, Vector2i> &E_cell : q.local_to_map) {
TileMapCell c = get_cell(q.layer, E_cell.value, true); TileMapCell c = get_cell(q.layer, E_cell.value, true);
TileSetSource *source; TileSetSource *source;
@ -2981,7 +2981,7 @@ void TileMap::_get_property_list(List<PropertyInfo> *p_list) const {
} }
} }
Vector2 TileMap::map_to_world(const Vector2i &p_pos) const { Vector2 TileMap::map_to_local(const Vector2i &p_pos) const {
// SHOULD RETURN THE CENTER OF THE CELL // SHOULD RETURN THE CENTER OF THE CELL
ERR_FAIL_COND_V(!tile_set.is_valid(), Vector2()); ERR_FAIL_COND_V(!tile_set.is_valid(), Vector2());
@ -3058,10 +3058,10 @@ Vector2 TileMap::map_to_world(const Vector2i &p_pos) const {
return (ret + Vector2(0.5, 0.5)) * tile_set->get_tile_size(); return (ret + Vector2(0.5, 0.5)) * tile_set->get_tile_size();
} }
Vector2i TileMap::world_to_map(const Vector2 &p_pos) const { Vector2i TileMap::local_to_map(const Vector2 &p_local_position) const {
ERR_FAIL_COND_V(!tile_set.is_valid(), Vector2i()); ERR_FAIL_COND_V(!tile_set.is_valid(), Vector2i());
Vector2 ret = p_pos; Vector2 ret = p_local_position;
ret /= tile_set->get_tile_size(); ret /= tile_set->get_tile_size();
TileSet::TileShape tile_shape = tile_set->get_tile_shape(); TileSet::TileShape tile_shape = tile_set->get_tile_shape();
@ -3086,7 +3086,7 @@ Vector2i TileMap::world_to_map(const Vector2 &p_pos) const {
ret.x /= overlapping_ratio; ret.x /= overlapping_ratio;
} }
// For each half-offset shape, we check if we are in the corner of the tile, and thus should correct the world position accordingly. // For each half-offset shape, we check if we are in the corner of the tile, and thus should correct the local position accordingly.
if (tile_shape == TileSet::TILE_SHAPE_HALF_OFFSET_SQUARE || tile_shape == TileSet::TILE_SHAPE_HEXAGON || tile_shape == TileSet::TILE_SHAPE_ISOMETRIC) { if (tile_shape == TileSet::TILE_SHAPE_HALF_OFFSET_SQUARE || tile_shape == TileSet::TILE_SHAPE_HEXAGON || tile_shape == TileSet::TILE_SHAPE_ISOMETRIC) {
// Technically, those 3 shapes are equivalent, as they are basically half-offset, but with different levels or overlap. // Technically, those 3 shapes are equivalent, as they are basically half-offset, but with different levels or overlap.
// square = no overlap, hexagon = 0.25 overlap, isometric = 0.5 overlap // square = no overlap, hexagon = 0.25 overlap, isometric = 0.5 overlap
@ -3771,7 +3771,7 @@ void TileMap::draw_cells_outline(Control *p_control, RBSet<Vector2i> p_cells, Co
TileSet::TileShape shape = tile_set->get_tile_shape(); TileSet::TileShape shape = tile_set->get_tile_shape();
for (const Vector2i &E : p_cells) { for (const Vector2i &E : p_cells) {
Vector2 center = map_to_world(E); Vector2 center = map_to_local(E);
#define DRAW_SIDE_IF_NEEDED(side, polygon_index_from, polygon_index_to) \ #define DRAW_SIDE_IF_NEEDED(side, polygon_index_from, polygon_index_to) \
if (!p_cells.has(get_neighbor_cell(E, side))) { \ if (!p_cells.has(get_neighbor_cell(E, side))) { \
@ -3901,8 +3901,8 @@ void TileMap::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_used_cells", "layer"), &TileMap::get_used_cells); ClassDB::bind_method(D_METHOD("get_used_cells", "layer"), &TileMap::get_used_cells);
ClassDB::bind_method(D_METHOD("get_used_rect"), &TileMap::get_used_rect); ClassDB::bind_method(D_METHOD("get_used_rect"), &TileMap::get_used_rect);
ClassDB::bind_method(D_METHOD("map_to_world", "map_position"), &TileMap::map_to_world); ClassDB::bind_method(D_METHOD("map_to_local", "map_position"), &TileMap::map_to_local);
ClassDB::bind_method(D_METHOD("world_to_map", "world_position"), &TileMap::world_to_map); ClassDB::bind_method(D_METHOD("local_to_map", "local_position"), &TileMap::local_to_map);
ClassDB::bind_method(D_METHOD("get_neighbor_cell", "coords", "neighbor"), &TileMap::get_neighbor_cell); ClassDB::bind_method(D_METHOD("get_neighbor_cell", "coords", "neighbor"), &TileMap::get_neighbor_cell);

View file

@ -40,7 +40,7 @@ class TileSetAtlasSource;
struct TileMapQuadrant { struct TileMapQuadrant {
struct CoordsWorldComparator { struct CoordsWorldComparator {
_ALWAYS_INLINE_ bool operator()(const Vector2i &p_a, const Vector2i &p_b) const { _ALWAYS_INLINE_ bool operator()(const Vector2i &p_a, const Vector2i &p_b) const {
// We sort the cells by their world coords, as it is needed by rendering. // We sort the cells by their local coords, as it is needed by rendering.
if (p_a.y == p_b.y) { if (p_a.y == p_b.y) {
return p_a.x > p_b.x; return p_a.x > p_b.x;
} else { } else {
@ -49,7 +49,7 @@ struct TileMapQuadrant {
} }
}; };
// Dirty list element // Dirty list element.
SelfList<TileMapQuadrant> dirty_list_element; SelfList<TileMapQuadrant> dirty_list_element;
// Quadrant layer and coords. // Quadrant layer and coords.
@ -58,10 +58,10 @@ struct TileMapQuadrant {
// TileMapCells // TileMapCells
RBSet<Vector2i> cells; RBSet<Vector2i> cells;
// We need those two maps to sort by world position for rendering // We need those two maps to sort by local position for rendering
// This is kind of workaround, it would be better to sort the cells directly in the "cells" set instead. // This is kind of workaround, it would be better to sort the cells directly in the "cells" set instead.
RBMap<Vector2i, Vector2i> map_to_world; RBMap<Vector2i, Vector2i> map_to_local;
RBMap<Vector2i, Vector2i, CoordsWorldComparator> world_to_map; RBMap<Vector2i, Vector2i, CoordsWorldComparator> local_to_map;
// Debug. // Debug.
RID debug_canvas_item; RID debug_canvas_item;
@ -368,8 +368,8 @@ public:
virtual void set_y_sort_enabled(bool p_enable) override; virtual void set_y_sort_enabled(bool p_enable) override;
Vector2 map_to_world(const Vector2i &p_pos) const; Vector2 map_to_local(const Vector2i &p_pos) const;
Vector2i world_to_map(const Vector2 &p_pos) const; Vector2i local_to_map(const Vector2 &p_pos) const;
bool is_existing_neighbor(TileSet::CellNeighbor p_cell_neighbor) const; bool is_existing_neighbor(TileSet::CellNeighbor p_cell_neighbor) const;
Vector2i get_neighbor_cell(const Vector2i &p_coords, TileSet::CellNeighbor p_cell_neighbor) const; Vector2i get_neighbor_cell(const Vector2i &p_coords, TileSet::CellNeighbor p_cell_neighbor) const;