diff options
author | RĂ©mi Verschelde <rverschelde@gmail.com> | 2017-01-02 14:47:08 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-01-02 14:47:08 +0100 |
commit | 3fc4ee624313bd319094c46c30f9446a50f20ad8 (patch) | |
tree | 977a13dab524732d3ae900bb35d7f941a38cb876 | |
parent | f50afe81d83dee7b2d64e14c68b300de4dd1062b (diff) | |
parent | 39771f22b6296f52842148332b601a9a49c16181 (diff) |
Merge pull request #7401 from Zylann/bucket_fill_preview
Bucket fill preview
-rw-r--r-- | tools/editor/plugins/tile_map_editor_plugin.cpp | 87 | ||||
-rw-r--r-- | tools/editor/plugins/tile_map_editor_plugin.h | 11 |
2 files changed, 89 insertions, 9 deletions
diff --git a/tools/editor/plugins/tile_map_editor_plugin.cpp b/tools/editor/plugins/tile_map_editor_plugin.cpp index 7c610770b0..5d4e3fd874 100644 --- a/tools/editor/plugins/tile_map_editor_plugin.cpp +++ b/tools/editor/plugins/tile_map_editor_plugin.cpp @@ -289,7 +289,7 @@ void TileMapEditor::_pick_tile(const Point2& p_pos) { canvas_item_editor->update(); } -DVector<Vector2> TileMapEditor::_bucket_fill(const Point2i& p_start, bool erase) { +DVector<Vector2> TileMapEditor::_bucket_fill(const Point2i& p_start, bool erase, bool preview) { int prev_id = node->get_cell(p_start.x, p_start.y); int id = TileMap::INVALID_CELL; @@ -300,10 +300,39 @@ DVector<Vector2> TileMapEditor::_bucket_fill(const Point2i& p_start, bool erase) return DVector<Vector2>(); } - Rect2 r = node->get_item_rect(); + Rect2i r = node->get_item_rect(); r.pos = r.pos/node->get_cell_size(); r.size = r.size/node->get_cell_size(); + int area = r.get_area(); + if(preview) { + // Test if we can re-use the result from preview bucket fill + bool invalidate_cache = false; + // Area changed + if(r != bucket_cache_rect) + _clear_bucket_cache(); + // Cache grid is not initialized + if(bucket_cache_visited == 0) { + bucket_cache_visited = new bool[area]; + invalidate_cache = true; + } + // Tile ID changed or position wasn't visited by the previous fill + int loc = (p_start.x - r.get_pos().x) + (p_start.y - r.get_pos().y) * r.get_size().x; + if(prev_id != bucket_cache_tile || !bucket_cache_visited[loc]) { + invalidate_cache = true; + } + if(invalidate_cache) { + for(int i = 0; i < area; ++i) + bucket_cache_visited[i] = false; + bucket_cache = DVector<Vector2>(); + bucket_cache_tile = prev_id; + bucket_cache_rect = r; + } + else { + return bucket_cache; + } + } + DVector<Vector2> points; List<Point2i> queue; @@ -319,9 +348,17 @@ DVector<Vector2> TileMapEditor::_bucket_fill(const Point2i& p_start, bool erase) if (node->get_cell(n.x, n.y) == prev_id) { - node->set_cellv(n, id, flip_h, flip_v, transpose); - - points.push_back(n); + if(preview) { + int loc = (n.x - r.get_pos().x) + (n.y - r.get_pos().y) * r.get_size().x; + if(bucket_cache_visited[loc]) + continue; + bucket_cache_visited[loc] = true; + bucket_cache.push_back(n); + } + else { + node->set_cellv(n, id, flip_h, flip_v, transpose); + points.push_back(n); + } queue.push_back(n + Point2i(0, 1)); queue.push_back(n + Point2i(0, -1)); @@ -330,7 +367,7 @@ DVector<Vector2> TileMapEditor::_bucket_fill(const Point2i& p_start, bool erase) } } - return points; + return preview ? bucket_cache : points; } void TileMapEditor::_fill_points(const DVector<Vector2> p_points, const Dictionary& p_op) { @@ -468,6 +505,25 @@ void TileMapEditor::_draw_cell(int p_cell, const Point2i& p_point, bool p_flip_h canvas_item_editor->draw_texture_rect_region(t, rect, r, Color(1,1,1,0.5), p_transpose); } +void TileMapEditor::_draw_fill_preview(int p_cell, const Point2i& p_point, bool p_flip_h, bool p_flip_v, bool p_transpose, const Matrix32& p_xform) { + + DVector<Vector2> points = _bucket_fill(p_point, false, true); + DVector<Vector2>::Read pr = points.read(); + int len = points.size(); + int time_after = OS::get_singleton()->get_ticks_msec(); + + for(int i = 0; i < len; ++i) { + _draw_cell(p_cell, pr[i], p_flip_h, p_flip_v, p_transpose, p_xform); + } +} + +void TileMapEditor::_clear_bucket_cache() { + if(bucket_cache_visited) { + delete[] bucket_cache_visited; + bucket_cache_visited = 0; + } +} + void TileMapEditor::_update_copydata() { copydata.clear(); @@ -1148,8 +1204,8 @@ void TileMapEditor::_canvas_draw() { canvas_item_editor->draw_line(endpoints[i],endpoints[(i+1)%4],col,2); - if (tool==TOOL_SELECTING || tool==TOOL_PICKING || tool==TOOL_BUCKET) { - + bool bucket_preview = EditorSettings::get_singleton()->get("tile_map/bucket_fill_preview"); + if (tool==TOOL_SELECTING || tool==TOOL_PICKING || !bucket_preview) { return; } @@ -1214,6 +1270,11 @@ void TileMapEditor::_canvas_draw() { canvas_item_editor->draw_colored_polygon(points, Color(0.2,1.0,0.8,0.2)); + } else if(tool == TOOL_BUCKET) { + + int tile = get_selected_tile(); + _draw_fill_preview(tile, over_tile, flip_h, flip_v, transpose, xform); + } else { int st = get_selected_tile(); @@ -1264,6 +1325,8 @@ void TileMapEditor::edit(Node *p_tile_map) { if (node) node->connect("settings_changed",this,"_tileset_settings_changed"); + _clear_bucket_cache(); + } void TileMapEditor::_tileset_settings_changed() { @@ -1365,6 +1428,9 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) { flip_v=false; transpose=false; + bucket_cache_tile = -1; + bucket_cache_visited = 0; + ED_SHORTCUT("tile_map_editor/erase_selection", TTR("Erase selection"), KEY_DELETE); ED_SHORTCUT("tile_map_editor/find_tile", TTR("Find tile"), KEY_MASK_CMD+KEY_F); ED_SHORTCUT("tile_map_editor/transpose", TTR("Transpose")); @@ -1479,6 +1545,10 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) { rotate_0->set_pressed(true); } +TileMapEditor::~TileMapEditor() { + _clear_bucket_cache(); +} + /////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////// @@ -1512,6 +1582,7 @@ TileMapEditorPlugin::TileMapEditorPlugin(EditorNode *p_node) { EDITOR_DEF("tile_map/preview_size",64); EDITOR_DEF("tile_map/palette_item_hseparation",8); EDITOR_DEF("tile_map/show_tile_names", true); + EDITOR_DEF("tile_map/bucket_fill_preview", true); tile_map_editor = memnew( TileMapEditor(p_node) ); add_control_to_container(CONTAINER_CANVAS_EDITOR_SIDE, tile_map_editor); diff --git a/tools/editor/plugins/tile_map_editor_plugin.h b/tools/editor/plugins/tile_map_editor_plugin.h index a5815e8f2e..44b83fe745 100644 --- a/tools/editor/plugins/tile_map_editor_plugin.h +++ b/tools/editor/plugins/tile_map_editor_plugin.h @@ -106,6 +106,11 @@ class TileMapEditor : public VBoxContainer { Point2i over_tile; + bool * bucket_cache_visited; + Rect2i bucket_cache_rect; + int bucket_cache_tile; + DVector<Vector2> bucket_cache; + struct CellOp { int idx; bool xf; @@ -129,7 +134,7 @@ class TileMapEditor : public VBoxContainer { void _pick_tile(const Point2& p_pos); - DVector<Vector2> _bucket_fill(const Point2i& p_start, bool erase=false); + DVector<Vector2> _bucket_fill(const Point2i& p_start, bool erase=false, bool preview=false); void _fill_points(const DVector<Vector2> p_points, const Dictionary& p_op); void _erase_points(const DVector<Vector2> p_points); @@ -137,6 +142,9 @@ class TileMapEditor : public VBoxContainer { void _select(const Point2i& p_from, const Point2i& p_to); void _draw_cell(int p_cell, const Point2i& p_point, bool p_flip_h, bool p_flip_v, bool p_transpose, const Matrix32& p_xform); + void _draw_fill_preview(int p_cell, const Point2i& p_point, bool p_flip_h, bool p_flip_v, bool p_transpose, const Matrix32& p_xform); + void _clear_bucket_cache(); + void _update_copydata(); int get_selected_tile() const; @@ -171,6 +179,7 @@ public: void edit(Node *p_tile_map); TileMapEditor(EditorNode *p_editor); + ~TileMapEditor(); }; class TileMapEditorPlugin : public EditorPlugin { |