TileSetEditor: Allow to toggle Convex/Concave collisions. Alternative fix to #24003
This commit is contained in:
parent
65084a70fd
commit
7b933d70a8
2 changed files with 170 additions and 34 deletions
|
@ -243,6 +243,7 @@ void TileSetEditor::_notification(int p_what) {
|
||||||
tools[ZOOM_1]->set_icon(get_icon("ZoomReset", "EditorIcons"));
|
tools[ZOOM_1]->set_icon(get_icon("ZoomReset", "EditorIcons"));
|
||||||
tools[ZOOM_IN]->set_icon(get_icon("ZoomMore", "EditorIcons"));
|
tools[ZOOM_IN]->set_icon(get_icon("ZoomMore", "EditorIcons"));
|
||||||
tools[VISIBLE_INFO]->set_icon(get_icon("InformationSign", "EditorIcons"));
|
tools[VISIBLE_INFO]->set_icon(get_icon("InformationSign", "EditorIcons"));
|
||||||
|
_update_toggle_shape_button();
|
||||||
|
|
||||||
tool_editmode[EDITMODE_REGION]->set_icon(get_icon("RegionEdit", "EditorIcons"));
|
tool_editmode[EDITMODE_REGION]->set_icon(get_icon("RegionEdit", "EditorIcons"));
|
||||||
tool_editmode[EDITMODE_COLLISION]->set_icon(get_icon("StaticBody2D", "EditorIcons"));
|
tool_editmode[EDITMODE_COLLISION]->set_icon(get_icon("StaticBody2D", "EditorIcons"));
|
||||||
|
@ -411,6 +412,12 @@ TileSetEditor::TileSetEditor(EditorNode *p_editor) {
|
||||||
tools[SHAPE_NEW_POLYGON]->set_button_group(tg);
|
tools[SHAPE_NEW_POLYGON]->set_button_group(tg);
|
||||||
tools[SHAPE_NEW_POLYGON]->set_tooltip(TTR("Create a new polygon."));
|
tools[SHAPE_NEW_POLYGON]->set_tooltip(TTR("Create a new polygon."));
|
||||||
|
|
||||||
|
separator_shape_toggle = memnew(VSeparator);
|
||||||
|
toolbar->add_child(separator_shape_toggle);
|
||||||
|
tools[SHAPE_TOGGLE_TYPE] = memnew(ToolButton);
|
||||||
|
tools[SHAPE_TOGGLE_TYPE]->connect("pressed", this, "_on_tool_clicked", varray(SHAPE_TOGGLE_TYPE));
|
||||||
|
toolbar->add_child(tools[SHAPE_TOGGLE_TYPE]);
|
||||||
|
|
||||||
separator_delete = memnew(VSeparator);
|
separator_delete = memnew(VSeparator);
|
||||||
toolbar->add_child(separator_delete);
|
toolbar->add_child(separator_delete);
|
||||||
tools[SHAPE_DELETE] = memnew(ToolButton);
|
tools[SHAPE_DELETE] = memnew(ToolButton);
|
||||||
|
@ -765,6 +772,7 @@ void TileSetEditor::_on_edit_mode_changed(int p_edit_mode) {
|
||||||
} break;
|
} break;
|
||||||
default: {}
|
default: {}
|
||||||
}
|
}
|
||||||
|
_update_toggle_shape_button();
|
||||||
workspace->update();
|
workspace->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1367,8 +1375,7 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) {
|
||||||
}
|
}
|
||||||
|
|
||||||
undo_redo->create_action(TTR("Edit Collision Polygon"));
|
undo_redo->create_action(TTR("Edit Collision Polygon"));
|
||||||
undo_redo->add_do_method(edited_collision_shape.ptr(), "set_points", points);
|
_set_edited_shape_points(points);
|
||||||
undo_redo->add_undo_method(edited_collision_shape.ptr(), "set_points", edited_collision_shape->get_points());
|
|
||||||
undo_redo->add_do_method(this, "_select_edited_shape_coord");
|
undo_redo->add_do_method(this, "_select_edited_shape_coord");
|
||||||
undo_redo->add_undo_method(this, "_select_edited_shape_coord");
|
undo_redo->add_undo_method(this, "_select_edited_shape_coord");
|
||||||
undo_redo->commit_action();
|
undo_redo->commit_action();
|
||||||
|
@ -1446,7 +1453,7 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) {
|
||||||
workspace->update();
|
workspace->update();
|
||||||
} else {
|
} else {
|
||||||
creating_shape = true;
|
creating_shape = true;
|
||||||
edited_collision_shape = Ref<ConvexPolygonShape2D>();
|
_set_edited_collision_shape(Ref<ConvexPolygonShape2D>());
|
||||||
current_shape.resize(0);
|
current_shape.resize(0);
|
||||||
current_shape.push_back(snap_point(pos));
|
current_shape.push_back(snap_point(pos));
|
||||||
workspace->update();
|
workspace->update();
|
||||||
|
@ -1466,7 +1473,7 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) {
|
||||||
} else if (tools[SHAPE_NEW_RECTANGLE]->is_pressed()) {
|
} else if (tools[SHAPE_NEW_RECTANGLE]->is_pressed()) {
|
||||||
if (mb.is_valid()) {
|
if (mb.is_valid()) {
|
||||||
if (mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
|
if (mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
|
||||||
edited_collision_shape = Ref<ConvexPolygonShape2D>();
|
_set_edited_collision_shape(Ref<ConvexPolygonShape2D>());
|
||||||
current_shape.resize(0);
|
current_shape.resize(0);
|
||||||
current_shape.push_back(snap_point(shape_anchor));
|
current_shape.push_back(snap_point(shape_anchor));
|
||||||
current_shape.push_back(snap_point(shape_anchor + Vector2(current_tile_region.size.x, 0)));
|
current_shape.push_back(snap_point(shape_anchor + Vector2(current_tile_region.size.x, 0)));
|
||||||
|
@ -1511,6 +1518,45 @@ void TileSetEditor::_on_tool_clicked(int p_tool) {
|
||||||
undo_redo->add_do_method(workspace, "update");
|
undo_redo->add_do_method(workspace, "update");
|
||||||
undo_redo->add_undo_method(workspace, "update");
|
undo_redo->add_undo_method(workspace, "update");
|
||||||
undo_redo->commit_action();
|
undo_redo->commit_action();
|
||||||
|
} else if (p_tool == SHAPE_TOGGLE_TYPE) {
|
||||||
|
if (edited_collision_shape.is_valid()) {
|
||||||
|
Ref<ConvexPolygonShape2D> convex = edited_collision_shape;
|
||||||
|
Ref<ConcavePolygonShape2D> concave = edited_collision_shape;
|
||||||
|
Ref<Shape2D> previous_shape = edited_collision_shape;
|
||||||
|
Array sd = tileset->call("tile_get_shapes", get_current_tile());
|
||||||
|
|
||||||
|
if (convex.is_valid()) {
|
||||||
|
// Make concave
|
||||||
|
undo_redo->create_action(TTR("Make Polygon Concave"));
|
||||||
|
Ref<ConcavePolygonShape2D> _concave = memnew(ConcavePolygonShape2D);
|
||||||
|
edited_collision_shape = _concave;
|
||||||
|
_set_edited_shape_points(_get_collision_shape_points(convex));
|
||||||
|
} else if (concave.is_valid()) {
|
||||||
|
// Make convex
|
||||||
|
undo_redo->create_action(TTR("Make Polygon Convex"));
|
||||||
|
Ref<ConvexPolygonShape2D> _convex = memnew(ConvexPolygonShape2D);
|
||||||
|
edited_collision_shape = _convex;
|
||||||
|
_set_edited_shape_points(_get_collision_shape_points(concave));
|
||||||
|
} else {
|
||||||
|
// Shoudn't haphen
|
||||||
|
}
|
||||||
|
for (int i = 0; i < sd.size(); i++) {
|
||||||
|
if (sd[i].get("shape") == previous_shape) {
|
||||||
|
undo_redo->add_undo_method(tileset.ptr(), "tile_set_shapes", get_current_tile(), sd.duplicate());
|
||||||
|
sd.remove(i);
|
||||||
|
sd.insert(i, edited_collision_shape);
|
||||||
|
undo_redo->add_do_method(tileset.ptr(), "tile_set_shapes", get_current_tile(), sd);
|
||||||
|
undo_redo->add_do_method(this, "_select_edited_shape_coord");
|
||||||
|
undo_redo->add_undo_method(this, "_select_edited_shape_coord");
|
||||||
|
undo_redo->commit_action();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_update_toggle_shape_button();
|
||||||
|
workspace->update();
|
||||||
|
workspace_container->update();
|
||||||
|
helper->_change_notify("");
|
||||||
|
}
|
||||||
} else if (p_tool == SELECT_NEXT) {
|
} else if (p_tool == SELECT_NEXT) {
|
||||||
_select_next_shape();
|
_select_next_shape();
|
||||||
} else if (p_tool == SELECT_PREVIOUS) {
|
} else if (p_tool == SELECT_PREVIOUS) {
|
||||||
|
@ -1629,6 +1675,48 @@ void TileSetEditor::_on_grid_snap_toggled(bool p_val) {
|
||||||
workspace->update();
|
workspace->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vector<Vector2> TileSetEditor::_get_collision_shape_points(const Ref<Shape2D> &p_shape) {
|
||||||
|
Ref<ConvexPolygonShape2D> convex = p_shape;
|
||||||
|
Ref<ConcavePolygonShape2D> concave = p_shape;
|
||||||
|
if (convex.is_valid()) {
|
||||||
|
return convex->get_points();
|
||||||
|
} else if (concave.is_valid()) {
|
||||||
|
Vector<Vector2> points;
|
||||||
|
for (int i = 0; i < concave->get_segments().size(); i += 2) {
|
||||||
|
points.push_back(concave->get_segments()[i]);
|
||||||
|
}
|
||||||
|
return points;
|
||||||
|
} else {
|
||||||
|
return Vector<Vector2>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector<Vector2> TileSetEditor::_get_edited_shape_points() {
|
||||||
|
return _get_collision_shape_points(edited_collision_shape);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TileSetEditor::_set_edited_shape_points(const Vector<Vector2> points) {
|
||||||
|
Ref<ConvexPolygonShape2D> convex = edited_collision_shape;
|
||||||
|
Ref<ConcavePolygonShape2D> concave = edited_collision_shape;
|
||||||
|
if (convex.is_valid()) {
|
||||||
|
undo_redo->add_do_method(convex.ptr(), "set_points", points);
|
||||||
|
undo_redo->add_undo_method(convex.ptr(), "set_points", _get_edited_shape_points());
|
||||||
|
} else if (concave.is_valid()) {
|
||||||
|
PoolVector2Array segments;
|
||||||
|
for (int i = 0; i < points.size() - 1; i++) {
|
||||||
|
segments.push_back(points[i]);
|
||||||
|
segments.push_back(points[i + 1]);
|
||||||
|
}
|
||||||
|
segments.push_back(points[points.size() - 1]);
|
||||||
|
segments.push_back(points[0]);
|
||||||
|
concave->set_segments(segments);
|
||||||
|
undo_redo->add_do_method(concave.ptr(), "set_segments", segments);
|
||||||
|
undo_redo->add_undo_method(concave.ptr(), "set_segments", concave->get_segments());
|
||||||
|
} else {
|
||||||
|
// Invalid shape
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TileSetEditor::_update_tile_data() {
|
void TileSetEditor::_update_tile_data() {
|
||||||
current_tile_data.clear();
|
current_tile_data.clear();
|
||||||
if (get_current_tile() < 0)
|
if (get_current_tile() < 0)
|
||||||
|
@ -1664,6 +1752,27 @@ void TileSetEditor::_update_tile_data() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TileSetEditor::_update_toggle_shape_button() {
|
||||||
|
Ref<ConvexPolygonShape2D> convex = edited_collision_shape;
|
||||||
|
Ref<ConcavePolygonShape2D> concave = edited_collision_shape;
|
||||||
|
separator_shape_toggle->show();
|
||||||
|
tools[SHAPE_TOGGLE_TYPE]->show();
|
||||||
|
if (edit_mode != EDITMODE_COLLISION || !edited_collision_shape.is_valid()) {
|
||||||
|
separator_shape_toggle->hide();
|
||||||
|
tools[SHAPE_TOGGLE_TYPE]->hide();
|
||||||
|
} else if (concave.is_valid()) {
|
||||||
|
tools[SHAPE_TOGGLE_TYPE]->set_icon(get_icon("ConvexPolygonShape2D", "EditorIcons"));
|
||||||
|
tools[SHAPE_TOGGLE_TYPE]->set_text("Make Convex");
|
||||||
|
} else if (convex.is_valid()) {
|
||||||
|
tools[SHAPE_TOGGLE_TYPE]->set_icon(get_icon("ConcavePolygonShape2D", "EditorIcons"));
|
||||||
|
tools[SHAPE_TOGGLE_TYPE]->set_text("Make Concave");
|
||||||
|
} else {
|
||||||
|
// Shoudn't happen
|
||||||
|
separator_shape_toggle->hide();
|
||||||
|
tools[SHAPE_TOGGLE_TYPE]->hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TileSetEditor::_select_next_tile() {
|
void TileSetEditor::_select_next_tile() {
|
||||||
Array tiles = _get_tiles_in_current_texture(true);
|
Array tiles = _get_tiles_in_current_texture(true);
|
||||||
if (tiles.size() == 0) {
|
if (tiles.size() == 0) {
|
||||||
|
@ -1842,11 +1951,11 @@ void TileSetEditor::_select_next_shape() {
|
||||||
} else {
|
} else {
|
||||||
int index = data.collisions.find(edited_collision_shape);
|
int index = data.collisions.find(edited_collision_shape);
|
||||||
if (index < 0) {
|
if (index < 0) {
|
||||||
edited_collision_shape = data.collisions[0];
|
_set_edited_collision_shape(data.collisions[0]);
|
||||||
} else if (index == data.collisions.size() - 1) {
|
} else if (index == data.collisions.size() - 1) {
|
||||||
_select_next_subtile();
|
_select_next_subtile();
|
||||||
} else {
|
} else {
|
||||||
edited_collision_shape = data.collisions[index + 1];
|
_set_edited_collision_shape(data.collisions[index + 1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
current_shape.resize(0);
|
current_shape.resize(0);
|
||||||
|
@ -1861,8 +1970,8 @@ void TileSetEditor::_select_next_shape() {
|
||||||
current_tile_region.position += shape_anchor;
|
current_tile_region.position += shape_anchor;
|
||||||
|
|
||||||
if (edited_collision_shape.is_valid()) {
|
if (edited_collision_shape.is_valid()) {
|
||||||
for (int i = 0; i < edited_collision_shape->get_points().size(); i++) {
|
for (int i = 0; i < _get_edited_shape_points().size(); i++) {
|
||||||
current_shape.push_back(edited_collision_shape->get_points()[i] + current_tile_region.position);
|
current_shape.push_back(_get_edited_shape_points()[i] + current_tile_region.position);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
workspace->update();
|
workspace->update();
|
||||||
|
@ -1877,7 +1986,7 @@ void TileSetEditor::_select_previous_shape() {
|
||||||
if (get_current_tile() != -1 && edit_mode == EDITMODE_COLLISION) {
|
if (get_current_tile() != -1 && edit_mode == EDITMODE_COLLISION) {
|
||||||
SubtileData data = current_tile_data[Vector2i(edited_shape_coord)];
|
SubtileData data = current_tile_data[Vector2i(edited_shape_coord)];
|
||||||
if (data.collisions.size() > 1) {
|
if (data.collisions.size() > 1) {
|
||||||
edited_collision_shape = data.collisions[data.collisions.size() - 1];
|
_set_edited_collision_shape(data.collisions[data.collisions.size() - 1]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
|
@ -1894,22 +2003,23 @@ void TileSetEditor::_select_previous_shape() {
|
||||||
_select_previous_subtile();
|
_select_previous_subtile();
|
||||||
data = current_tile_data[Vector2i(edited_shape_coord)];
|
data = current_tile_data[Vector2i(edited_shape_coord)];
|
||||||
if (data.collisions.size() > 1) {
|
if (data.collisions.size() > 1) {
|
||||||
edited_collision_shape = data.collisions[data.collisions.size() - 1];
|
_set_edited_collision_shape(data.collisions[data.collisions.size() - 1]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int index = data.collisions.find(edited_collision_shape);
|
int index = data.collisions.find(edited_collision_shape);
|
||||||
if (index < 0) {
|
if (index < 0) {
|
||||||
edited_collision_shape = data.collisions[data.collisions.size() - 1];
|
_set_edited_collision_shape(data.collisions[data.collisions.size() - 1]);
|
||||||
} else if (index == 0) {
|
} else if (index == 0) {
|
||||||
_select_previous_subtile();
|
_select_previous_subtile();
|
||||||
data = current_tile_data[Vector2i(edited_shape_coord)];
|
data = current_tile_data[Vector2i(edited_shape_coord)];
|
||||||
if (data.collisions.size() > 1) {
|
if (data.collisions.size() > 1) {
|
||||||
edited_collision_shape = data.collisions[data.collisions.size() - 1];
|
_set_edited_collision_shape(data.collisions[data.collisions.size() - 1]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
edited_collision_shape = data.collisions[index - 1];
|
_set_edited_collision_shape(data.collisions[index - 1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
current_shape.resize(0);
|
current_shape.resize(0);
|
||||||
Rect2 current_tile_region = tileset->tile_get_region(get_current_tile());
|
Rect2 current_tile_region = tileset->tile_get_region(get_current_tile());
|
||||||
current_tile_region.position += WORKSPACE_MARGIN;
|
current_tile_region.position += WORKSPACE_MARGIN;
|
||||||
|
@ -1922,8 +2032,8 @@ void TileSetEditor::_select_previous_shape() {
|
||||||
current_tile_region.position += shape_anchor;
|
current_tile_region.position += shape_anchor;
|
||||||
|
|
||||||
if (edited_collision_shape.is_valid()) {
|
if (edited_collision_shape.is_valid()) {
|
||||||
for (int i = 0; i < edited_collision_shape->get_points().size(); i++) {
|
for (int i = 0; i < _get_edited_shape_points().size(); i++) {
|
||||||
current_shape.push_back(edited_collision_shape->get_points()[i] + current_tile_region.position);
|
current_shape.push_back(_get_edited_shape_points()[i] + current_tile_region.position);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
workspace->update();
|
workspace->update();
|
||||||
|
@ -1932,6 +2042,11 @@ void TileSetEditor::_select_previous_shape() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TileSetEditor::_set_edited_collision_shape(const Ref<Shape2D> &p_shape) {
|
||||||
|
edited_collision_shape = p_shape;
|
||||||
|
_update_toggle_shape_button();
|
||||||
|
}
|
||||||
|
|
||||||
void TileSetEditor::_set_snap_step(Vector2 p_val) {
|
void TileSetEditor::_set_snap_step(Vector2 p_val) {
|
||||||
snap_step.x = CLAMP(p_val.x, 0, 256);
|
snap_step.x = CLAMP(p_val.x, 0, 256);
|
||||||
snap_step.y = CLAMP(p_val.y, 0, 256);
|
snap_step.y = CLAMP(p_val.y, 0, 256);
|
||||||
|
@ -2228,16 +2343,29 @@ void TileSetEditor::draw_polygon_shapes() {
|
||||||
}
|
}
|
||||||
anchor += WORKSPACE_MARGIN;
|
anchor += WORKSPACE_MARGIN;
|
||||||
anchor += tileset->tile_get_region(t_id).position;
|
anchor += tileset->tile_get_region(t_id).position;
|
||||||
Ref<ConvexPolygonShape2D> shape = sd[i].shape;
|
Ref<Shape2D> shape = sd[i].shape;
|
||||||
if (shape.is_valid()) {
|
if (shape.is_valid()) {
|
||||||
Color c_bg;
|
Color c_bg;
|
||||||
Color c_border;
|
Color c_border;
|
||||||
|
Ref<ConvexPolygonShape2D> convex = shape;
|
||||||
|
bool is_convex = convex.is_valid();
|
||||||
if ((tileset->tile_get_tile_mode(get_current_tile()) == TileSet::SINGLE_TILE || coord == edited_shape_coord) && sd[i].shape == edited_collision_shape) {
|
if ((tileset->tile_get_tile_mode(get_current_tile()) == TileSet::SINGLE_TILE || coord == edited_shape_coord) && sd[i].shape == edited_collision_shape) {
|
||||||
c_bg = Color(0, 1, 1, 0.5);
|
if (is_convex) {
|
||||||
c_border = Color(0, 1, 1);
|
c_bg = Color(0, 1, 1, 0.5);
|
||||||
|
c_border = Color(0, 1, 1);
|
||||||
|
} else {
|
||||||
|
c_bg = Color(0.8, 0, 1, 0.5);
|
||||||
|
c_border = Color(0.8, 0, 1);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
c_bg = Color(0.9, 0.7, 0.07, 0.5);
|
if (is_convex) {
|
||||||
c_border = Color(0.9, 0.7, 0.07, 1);
|
c_bg = Color(0.9, 0.7, 0.07, 0.5);
|
||||||
|
c_border = Color(0.9, 0.7, 0.07, 1);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
c_bg = Color(0.9, 0.45, 0.075, 0.5);
|
||||||
|
c_border = Color(0.9, 0.45, 0.075);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Vector<Vector2> polygon;
|
Vector<Vector2> polygon;
|
||||||
Vector<Color> colors;
|
Vector<Color> colors;
|
||||||
|
@ -2247,8 +2375,8 @@ void TileSetEditor::draw_polygon_shapes() {
|
||||||
colors.push_back(c_bg);
|
colors.push_back(c_bg);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (int j = 0; j < shape->get_points().size(); j++) {
|
for (int j = 0; j < _get_collision_shape_points(shape).size(); j++) {
|
||||||
polygon.push_back(shape->get_points()[j] + anchor);
|
polygon.push_back(_get_collision_shape_points(shape)[j] + anchor);
|
||||||
colors.push_back(c_bg);
|
colors.push_back(c_bg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2465,11 +2593,11 @@ void TileSetEditor::close_shape(const Vector2 &shape_anchor) {
|
||||||
if (current_shape.size() >= 3) {
|
if (current_shape.size() >= 3) {
|
||||||
Ref<ConvexPolygonShape2D> shape = memnew(ConvexPolygonShape2D);
|
Ref<ConvexPolygonShape2D> shape = memnew(ConvexPolygonShape2D);
|
||||||
|
|
||||||
Vector<Vector2> segments;
|
Vector<Vector2> points;
|
||||||
float p_total = 0;
|
float p_total = 0;
|
||||||
|
|
||||||
for (int i = 0; i < current_shape.size(); i++) {
|
for (int i = 0; i < current_shape.size(); i++) {
|
||||||
segments.push_back(current_shape[i] - shape_anchor);
|
points.push_back(current_shape[i] - shape_anchor);
|
||||||
|
|
||||||
if (i != current_shape.size() - 1)
|
if (i != current_shape.size() - 1)
|
||||||
p_total += ((current_shape[i + 1].x - current_shape[i].x) * (-current_shape[i + 1].y + (-current_shape[i].y)));
|
p_total += ((current_shape[i + 1].x - current_shape[i].x) * (-current_shape[i + 1].y + (-current_shape[i].y)));
|
||||||
|
@ -2478,9 +2606,9 @@ void TileSetEditor::close_shape(const Vector2 &shape_anchor) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p_total < 0)
|
if (p_total < 0)
|
||||||
segments.invert();
|
points.invert();
|
||||||
|
|
||||||
shape->set_points(segments);
|
shape->set_points(points);
|
||||||
|
|
||||||
undo_redo->create_action(TTR("Create Collision Polygon"));
|
undo_redo->create_action(TTR("Create Collision Polygon"));
|
||||||
// Necessary to get the version that returns a Array instead of a Vector.
|
// Necessary to get the version that returns a Array instead of a Vector.
|
||||||
|
@ -2573,7 +2701,7 @@ void TileSetEditor::select_coord(const Vector2 &coord) {
|
||||||
current_tile_region.position += WORKSPACE_MARGIN;
|
current_tile_region.position += WORKSPACE_MARGIN;
|
||||||
if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::SINGLE_TILE) {
|
if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::SINGLE_TILE) {
|
||||||
if (edited_collision_shape != tileset->tile_get_shape(get_current_tile(), 0))
|
if (edited_collision_shape != tileset->tile_get_shape(get_current_tile(), 0))
|
||||||
edited_collision_shape = tileset->tile_get_shape(get_current_tile(), 0);
|
_set_edited_collision_shape(tileset->tile_get_shape(get_current_tile(), 0));
|
||||||
if (edited_occlusion_shape != tileset->tile_get_light_occluder(get_current_tile()))
|
if (edited_occlusion_shape != tileset->tile_get_light_occluder(get_current_tile()))
|
||||||
edited_occlusion_shape = tileset->tile_get_light_occluder(get_current_tile());
|
edited_occlusion_shape = tileset->tile_get_light_occluder(get_current_tile());
|
||||||
if (edited_navigation_shape != tileset->tile_get_navigation_polygon(get_current_tile()))
|
if (edited_navigation_shape != tileset->tile_get_navigation_polygon(get_current_tile()))
|
||||||
|
@ -2582,8 +2710,8 @@ void TileSetEditor::select_coord(const Vector2 &coord) {
|
||||||
if (edit_mode == EDITMODE_COLLISION) {
|
if (edit_mode == EDITMODE_COLLISION) {
|
||||||
current_shape.resize(0);
|
current_shape.resize(0);
|
||||||
if (edited_collision_shape.is_valid()) {
|
if (edited_collision_shape.is_valid()) {
|
||||||
for (int i = 0; i < edited_collision_shape->get_points().size(); i++) {
|
for (int i = 0; i < _get_edited_shape_points().size(); i++) {
|
||||||
current_shape.push_back(edited_collision_shape->get_points()[i] + current_tile_region.position);
|
current_shape.push_back(_get_edited_shape_points()[i] + current_tile_region.position);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (edit_mode == EDITMODE_OCCLUSION) {
|
} else if (edit_mode == EDITMODE_OCCLUSION) {
|
||||||
|
@ -2610,13 +2738,13 @@ void TileSetEditor::select_coord(const Vector2 &coord) {
|
||||||
for (int i = 0; i < sd.size(); i++) {
|
for (int i = 0; i < sd.size(); i++) {
|
||||||
if (sd[i].autotile_coord == coord) {
|
if (sd[i].autotile_coord == coord) {
|
||||||
if (edited_collision_shape != sd[i].shape)
|
if (edited_collision_shape != sd[i].shape)
|
||||||
edited_collision_shape = sd[i].shape;
|
_set_edited_collision_shape(sd[i].shape);
|
||||||
found_collision_shape = true;
|
found_collision_shape = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!found_collision_shape)
|
if (!found_collision_shape)
|
||||||
edited_collision_shape = Ref<ConvexPolygonShape2D>(NULL);
|
_set_edited_collision_shape(Ref<ConvexPolygonShape2D>(NULL));
|
||||||
if (edited_occlusion_shape != tileset->autotile_get_light_occluder(get_current_tile(), coord))
|
if (edited_occlusion_shape != tileset->autotile_get_light_occluder(get_current_tile(), coord))
|
||||||
edited_occlusion_shape = tileset->autotile_get_light_occluder(get_current_tile(), coord);
|
edited_occlusion_shape = tileset->autotile_get_light_occluder(get_current_tile(), coord);
|
||||||
if (edited_navigation_shape != tileset->autotile_get_navigation_polygon(get_current_tile(), coord))
|
if (edited_navigation_shape != tileset->autotile_get_navigation_polygon(get_current_tile(), coord))
|
||||||
|
@ -2631,8 +2759,8 @@ void TileSetEditor::select_coord(const Vector2 &coord) {
|
||||||
if (edit_mode == EDITMODE_COLLISION) {
|
if (edit_mode == EDITMODE_COLLISION) {
|
||||||
current_shape.resize(0);
|
current_shape.resize(0);
|
||||||
if (edited_collision_shape.is_valid()) {
|
if (edited_collision_shape.is_valid()) {
|
||||||
for (int j = 0; j < edited_collision_shape->get_points().size(); j++) {
|
for (int j = 0; j < _get_edited_shape_points().size(); j++) {
|
||||||
current_shape.push_back(edited_collision_shape->get_points()[j] + shape_anchor);
|
current_shape.push_back(_get_edited_shape_points()[j] + shape_anchor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (edit_mode == EDITMODE_OCCLUSION) {
|
} else if (edit_mode == EDITMODE_OCCLUSION) {
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
#include "editor/editor_name_dialog.h"
|
#include "editor/editor_name_dialog.h"
|
||||||
#include "editor/editor_node.h"
|
#include "editor/editor_node.h"
|
||||||
#include "scene/2d/sprite.h"
|
#include "scene/2d/sprite.h"
|
||||||
|
#include "scene/resources/concave_polygon_shape_2d.h"
|
||||||
#include "scene/resources/convex_polygon_shape_2d.h"
|
#include "scene/resources/convex_polygon_shape_2d.h"
|
||||||
#include "scene/resources/tile_set.h"
|
#include "scene/resources/tile_set.h"
|
||||||
|
|
||||||
|
@ -84,6 +85,7 @@ class TileSetEditor : public HSplitContainer {
|
||||||
BITMASK_CLEAR,
|
BITMASK_CLEAR,
|
||||||
SHAPE_NEW_POLYGON,
|
SHAPE_NEW_POLYGON,
|
||||||
SHAPE_NEW_RECTANGLE,
|
SHAPE_NEW_RECTANGLE,
|
||||||
|
SHAPE_TOGGLE_TYPE,
|
||||||
SHAPE_DELETE,
|
SHAPE_DELETE,
|
||||||
SHAPE_KEEP_INSIDE_TILE,
|
SHAPE_KEEP_INSIDE_TILE,
|
||||||
TOOL_GRID_SNAP,
|
TOOL_GRID_SNAP,
|
||||||
|
@ -130,7 +132,7 @@ class TileSetEditor : public HSplitContainer {
|
||||||
Vector2 snap_offset;
|
Vector2 snap_offset;
|
||||||
Vector2 snap_separation;
|
Vector2 snap_separation;
|
||||||
|
|
||||||
Ref<ConvexPolygonShape2D> edited_collision_shape;
|
Ref<Shape2D> edited_collision_shape;
|
||||||
Ref<OccluderPolygon2D> edited_occlusion_shape;
|
Ref<OccluderPolygon2D> edited_occlusion_shape;
|
||||||
Ref<NavigationPolygon> edited_navigation_shape;
|
Ref<NavigationPolygon> edited_navigation_shape;
|
||||||
|
|
||||||
|
@ -146,6 +148,7 @@ class TileSetEditor : public HSplitContainer {
|
||||||
HSeparator *separator_editmode;
|
HSeparator *separator_editmode;
|
||||||
HBoxContainer *toolbar;
|
HBoxContainer *toolbar;
|
||||||
ToolButton *tools[TOOL_MAX];
|
ToolButton *tools[TOOL_MAX];
|
||||||
|
VSeparator *separator_shape_toggle;
|
||||||
VSeparator *separator_bitmask;
|
VSeparator *separator_bitmask;
|
||||||
VSeparator *separator_delete;
|
VSeparator *separator_delete;
|
||||||
VSeparator *separator_grid;
|
VSeparator *separator_grid;
|
||||||
|
@ -197,7 +200,11 @@ private:
|
||||||
void _on_priority_changed(float val);
|
void _on_priority_changed(float val);
|
||||||
void _on_z_index_changed(float val);
|
void _on_z_index_changed(float val);
|
||||||
void _on_grid_snap_toggled(bool p_val);
|
void _on_grid_snap_toggled(bool p_val);
|
||||||
|
Vector<Vector2> _get_collision_shape_points(const Ref<Shape2D> &p_shape);
|
||||||
|
Vector<Vector2> _get_edited_shape_points();
|
||||||
|
void _set_edited_shape_points(const Vector<Vector2> points);
|
||||||
void _update_tile_data();
|
void _update_tile_data();
|
||||||
|
void _update_toggle_shape_button();
|
||||||
void _select_next_tile();
|
void _select_next_tile();
|
||||||
void _select_previous_tile();
|
void _select_previous_tile();
|
||||||
Array _get_tiles_in_current_texture(bool sorted = false);
|
Array _get_tiles_in_current_texture(bool sorted = false);
|
||||||
|
@ -206,6 +213,7 @@ private:
|
||||||
void _select_previous_subtile();
|
void _select_previous_subtile();
|
||||||
void _select_next_shape();
|
void _select_next_shape();
|
||||||
void _select_previous_shape();
|
void _select_previous_shape();
|
||||||
|
void _set_edited_collision_shape(const Ref<Shape2D> &p_shape);
|
||||||
void _set_snap_step(Vector2 p_val);
|
void _set_snap_step(Vector2 p_val);
|
||||||
void _set_snap_off(Vector2 p_val);
|
void _set_snap_off(Vector2 p_val);
|
||||||
void _set_snap_sep(Vector2 p_val);
|
void _set_snap_sep(Vector2 p_val);
|
||||||
|
|
Loading…
Reference in a new issue