summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRĂ©mi Verschelde <rverschelde@gmail.com>2017-01-02 14:47:08 +0100
committerGitHub <noreply@github.com>2017-01-02 14:47:08 +0100
commit3fc4ee624313bd319094c46c30f9446a50f20ad8 (patch)
tree977a13dab524732d3ae900bb35d7f941a38cb876
parentf50afe81d83dee7b2d64e14c68b300de4dd1062b (diff)
parent39771f22b6296f52842148332b601a9a49c16181 (diff)
Merge pull request #7401 from Zylann/bucket_fill_preview
Bucket fill preview
-rw-r--r--tools/editor/plugins/tile_map_editor_plugin.cpp87
-rw-r--r--tools/editor/plugins/tile_map_editor_plugin.h11
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 {