From 5329ae00300f5564aea11960067a1a142f257937 Mon Sep 17 00:00:00 2001 From: Norton Corbett Date: Sat, 30 Nov 2019 13:44:59 +0000 Subject: Take into account the current zoom level when grabbing polygon points in the TileSet editor. The transform of the TileSet editor workspace is now used to calculate the distance from the mouse click to the nearest polygon point. Fixes https://github.com/godotengine/godot/issues/34001 --- editor/plugins/tile_set_editor_plugin.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/editor/plugins/tile_set_editor_plugin.cpp b/editor/plugins/tile_set_editor_plugin.cpp index a8cf5b46e1..dd61e13ae6 100644 --- a/editor/plugins/tile_set_editor_plugin.cpp +++ b/editor/plugins/tile_set_editor_plugin.cpp @@ -1529,13 +1529,15 @@ void TileSetEditor::_on_workspace_input(const Ref &p_ie) { shape_anchor.y *= (size.y + spacing); } const real_t grab_threshold = EDITOR_GET("editors/poly_editor/point_grab_radius"); + Transform2D xform = workspace->get_transform(); shape_anchor += current_tile_region.position; if (tools[TOOL_SELECT]->is_pressed()) { if (mb.is_valid()) { if (mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) { if (edit_mode != EDITMODE_PRIORITY && current_shape.size() > 0) { for (int i = 0; i < current_shape.size(); i++) { - if ((current_shape[i] - mb->get_position()).length_squared() <= grab_threshold) { + const real_t distance = xform.xform(current_shape[i]).distance_to(xform.xform(mb->get_position())); + if (distance < grab_threshold) { dragging_point = i; workspace->update(); return; @@ -1634,7 +1636,8 @@ void TileSetEditor::_on_workspace_input(const Ref &p_ie) { pos = snap_point(pos); if (creating_shape) { if (current_shape.size() > 0) { - if ((pos - current_shape[0]).length_squared() <= grab_threshold) { + const real_t distance = xform.xform(current_shape[0]).distance_to(xform.xform(pos)); + if (distance <= grab_threshold) { if (current_shape.size() > 2) { close_shape(shape_anchor); workspace->update(); @@ -1685,7 +1688,8 @@ void TileSetEditor::_on_workspace_input(const Ref &p_ie) { } } else if (!mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) { if (creating_shape) { - if ((current_shape[0] - current_shape[1]).length_squared() <= grab_threshold) { + const real_t distance = xform.xform(current_shape[0]).distance_to(xform.xform(current_shape[1])); + if (distance <= grab_threshold) { current_shape.set(0, snap_point(shape_anchor)); current_shape.set(1, snap_point(shape_anchor + Vector2(current_tile_region.size.x, 0))); current_shape.set(2, snap_point(shape_anchor + current_tile_region.size)); -- cgit v1.2.3 From 9584ff13b9aecdb11ced749c3941707e7616bb33 Mon Sep 17 00:00:00 2001 From: Norton Corbett Date: Sun, 1 Dec 2019 20:35:23 +0000 Subject: Fixed another point grabbing issue at lower zoom levels. This was caused by the fact that the points were being iterated sequentially and we were breaking out of the loop as soon as we found a point that was "close enough", rather than actually finding the closest point. The previous fix exposed this new issue. --- editor/plugins/tile_set_editor_plugin.cpp | 60 +++++++++++++++++++++---------- editor/plugins/tile_set_editor_plugin.h | 2 ++ 2 files changed, 44 insertions(+), 18 deletions(-) diff --git a/editor/plugins/tile_set_editor_plugin.cpp b/editor/plugins/tile_set_editor_plugin.cpp index dd61e13ae6..9eeb294fe1 100644 --- a/editor/plugins/tile_set_editor_plugin.cpp +++ b/editor/plugins/tile_set_editor_plugin.cpp @@ -1176,6 +1176,31 @@ void TileSetEditor::_on_workspace_overlay_draw() { } } +int TileSetEditor::get_grabbed_point(const Vector2 &p_mouse_pos, real_t p_grab_threshold) { + Transform2D xform = workspace->get_transform(); + + int grabbed_point = -1; + real_t min_distance = 1e10; + + for (int i = 0; i < current_shape.size(); i++) { + const real_t distance = xform.xform(current_shape[i]).distance_to(xform.xform(p_mouse_pos)); + if (distance < p_grab_threshold && distance < min_distance) { + min_distance = distance; + grabbed_point = i; + } + } + + return grabbed_point; +} + +bool TileSetEditor::is_within_grabbing_distance_of_first_point(const Vector2 &p_pos, real_t p_grab_threshold) { + Transform2D xform = workspace->get_transform(); + + const real_t distance = xform.xform(current_shape[0]).distance_to(xform.xform(p_pos)); + + return distance < p_grab_threshold; +} + void TileSetEditor::_on_workspace_input(const Ref &p_ie) { if (tileset.is_null() || !get_current_texture().is_valid()) @@ -1528,20 +1553,19 @@ void TileSetEditor::_on_workspace_input(const Ref &p_ie) { shape_anchor.x *= (size.x + spacing); shape_anchor.y *= (size.y + spacing); } + const real_t grab_threshold = EDITOR_GET("editors/poly_editor/point_grab_radius"); - Transform2D xform = workspace->get_transform(); shape_anchor += current_tile_region.position; if (tools[TOOL_SELECT]->is_pressed()) { if (mb.is_valid()) { if (mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) { if (edit_mode != EDITMODE_PRIORITY && current_shape.size() > 0) { - for (int i = 0; i < current_shape.size(); i++) { - const real_t distance = xform.xform(current_shape[i]).distance_to(xform.xform(mb->get_position())); - if (distance < grab_threshold) { - dragging_point = i; - workspace->update(); - return; - } + int grabbed_point = get_grabbed_point(mb->get_position(), grab_threshold); + + if (grabbed_point >= 0) { + dragging_point = grabbed_point; + workspace->update(); + return; } } if ((tileset->tile_get_tile_mode(get_current_tile()) == TileSet::AUTO_TILE || tileset->tile_get_tile_mode(get_current_tile()) == TileSet::ATLAS_TILE) && current_tile_region.has_point(mb->get_position())) { @@ -1635,14 +1659,12 @@ void TileSetEditor::_on_workspace_input(const Ref &p_ie) { Vector2 pos = mb->get_position(); pos = snap_point(pos); if (creating_shape) { - if (current_shape.size() > 0) { - const real_t distance = xform.xform(current_shape[0]).distance_to(xform.xform(pos)); - if (distance <= grab_threshold) { - if (current_shape.size() > 2) { - close_shape(shape_anchor); - workspace->update(); - return; - } + if (current_shape.size() > 2) { + + if (is_within_grabbing_distance_of_first_point(mb->get_position(), grab_threshold)) { + close_shape(shape_anchor); + workspace->update(); + return; } } current_shape.push_back(pos); @@ -1688,13 +1710,15 @@ void TileSetEditor::_on_workspace_input(const Ref &p_ie) { } } else if (!mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) { if (creating_shape) { - const real_t distance = xform.xform(current_shape[0]).distance_to(xform.xform(current_shape[1])); - if (distance <= grab_threshold) { + + // if the first two corners are within grabbing distance of one another, expand the rect to fill the tile + if (is_within_grabbing_distance_of_first_point(current_shape[1], grab_threshold)) { current_shape.set(0, snap_point(shape_anchor)); current_shape.set(1, snap_point(shape_anchor + Vector2(current_tile_region.size.x, 0))); current_shape.set(2, snap_point(shape_anchor + current_tile_region.size)); current_shape.set(3, snap_point(shape_anchor + Vector2(0, current_tile_region.size.y))); } + close_shape(shape_anchor); workspace->update(); return; diff --git a/editor/plugins/tile_set_editor_plugin.h b/editor/plugins/tile_set_editor_plugin.h index 944dc04e4e..5ff86000c5 100644 --- a/editor/plugins/tile_set_editor_plugin.h +++ b/editor/plugins/tile_set_editor_plugin.h @@ -244,6 +244,8 @@ private: void update_workspace_tile_mode(); void update_workspace_minsize(); void update_edited_region(const Vector2 &end_point); + int get_grabbed_point(const Vector2 &p_mouse_pos, real_t grab_threshold); + bool is_within_grabbing_distance_of_first_point(const Vector2 &p_pos, real_t p_grab_threshold); int get_current_tile() const; void set_current_tile(int p_id); -- cgit v1.2.3