Add a split editor to polygon 2D UV editor, moving an inch closer to adding support for in the future
This commit is contained in:
parent
eec9261a75
commit
125fc8cc44
72
editor/icons/icon_add_split.svg
Normal file
72
editor/icons/icon_add_split.svg
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="16"
|
||||||
|
height="16"
|
||||||
|
version="1.1"
|
||||||
|
viewBox="0 0 16 16"
|
||||||
|
id="svg4"
|
||||||
|
sodipodi:docname="icon_add_split.svg"
|
||||||
|
inkscape:version="0.92.2 (5c3e80d, 2017-08-06)">
|
||||||
|
<metadata
|
||||||
|
id="metadata10">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<defs
|
||||||
|
id="defs8" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1"
|
||||||
|
objecttolerance="10"
|
||||||
|
gridtolerance="10"
|
||||||
|
guidetolerance="10"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:window-width="3066"
|
||||||
|
inkscape:window-height="1689"
|
||||||
|
id="namedview6"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="41.7193"
|
||||||
|
inkscape:cx="7.7924561"
|
||||||
|
inkscape:cy="6.0148972"
|
||||||
|
inkscape:window-x="134"
|
||||||
|
inkscape:window-y="55"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg4" />
|
||||||
|
<rect
|
||||||
|
style="fill:#800000"
|
||||||
|
id="rect12"
|
||||||
|
width="1.8456686"
|
||||||
|
height="2.0853658"
|
||||||
|
x="0.62321275"
|
||||||
|
y="6.9394455" />
|
||||||
|
<rect
|
||||||
|
style="fill:#800000"
|
||||||
|
id="rect14"
|
||||||
|
width="1.6299411"
|
||||||
|
height="1.9894869"
|
||||||
|
x="12.488225"
|
||||||
|
y="7.1791425" />
|
||||||
|
<rect
|
||||||
|
style="fill:#e9afaf"
|
||||||
|
id="rect16"
|
||||||
|
width="10.067283"
|
||||||
|
height="0.69512194"
|
||||||
|
x="2.492851"
|
||||||
|
y="7.7304463" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.9 KiB |
95
editor/icons/icon_delete_split.svg
Normal file
95
editor/icons/icon_delete_split.svg
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="16"
|
||||||
|
height="16"
|
||||||
|
version="1.1"
|
||||||
|
viewBox="0 0 16 16"
|
||||||
|
id="svg4"
|
||||||
|
sodipodi:docname="icon_delete_split.svg"
|
||||||
|
inkscape:version="0.92.2 (5c3e80d, 2017-08-06)">
|
||||||
|
<metadata
|
||||||
|
id="metadata10">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<defs
|
||||||
|
id="defs8" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1"
|
||||||
|
objecttolerance="10"
|
||||||
|
gridtolerance="10"
|
||||||
|
guidetolerance="10"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:window-width="3066"
|
||||||
|
inkscape:window-height="1689"
|
||||||
|
id="namedview6"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="41.7193"
|
||||||
|
inkscape:cx="7.7924561"
|
||||||
|
inkscape:cy="6.0148972"
|
||||||
|
inkscape:window-x="134"
|
||||||
|
inkscape:window-y="55"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg4" />
|
||||||
|
<rect
|
||||||
|
style="fill:#800000"
|
||||||
|
id="rect12"
|
||||||
|
width="1.8456686"
|
||||||
|
height="2.0853658"
|
||||||
|
x="0.62321275"
|
||||||
|
y="6.9394455" />
|
||||||
|
<rect
|
||||||
|
style="fill:#800000"
|
||||||
|
id="rect14"
|
||||||
|
width="1.6299411"
|
||||||
|
height="1.9894869"
|
||||||
|
x="12.488225"
|
||||||
|
y="7.1791425" />
|
||||||
|
<rect
|
||||||
|
style="fill:#e9afaf"
|
||||||
|
id="rect37"
|
||||||
|
width="3.1640031"
|
||||||
|
height="0.40748528"
|
||||||
|
x="2.5407906"
|
||||||
|
y="7.9701433" />
|
||||||
|
<rect
|
||||||
|
style="fill:#e9afaf"
|
||||||
|
id="rect39"
|
||||||
|
width="3.5235491"
|
||||||
|
height="0.52733386"
|
||||||
|
x="9.0126152"
|
||||||
|
y="8.0420523" />
|
||||||
|
<rect
|
||||||
|
style="fill:#e9afaf"
|
||||||
|
id="rect41"
|
||||||
|
width="3.6433976"
|
||||||
|
height="0.4554247"
|
||||||
|
x="1.5110972"
|
||||||
|
y="-9.732645"
|
||||||
|
transform="rotate(123.99908)" />
|
||||||
|
<rect
|
||||||
|
style="fill:#e9afaf"
|
||||||
|
id="rect41-3"
|
||||||
|
width="3.6433976"
|
||||||
|
height="0.4554247"
|
||||||
|
x="0.072069742"
|
||||||
|
y="-12.144793"
|
||||||
|
transform="rotate(123.99908)" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.3 KiB |
@ -64,6 +64,8 @@ void Polygon2DEditor::_notification(int p_what) {
|
|||||||
uv_button[UV_MODE_MOVE]->set_icon(get_icon("ToolMove", "EditorIcons"));
|
uv_button[UV_MODE_MOVE]->set_icon(get_icon("ToolMove", "EditorIcons"));
|
||||||
uv_button[UV_MODE_ROTATE]->set_icon(get_icon("ToolRotate", "EditorIcons"));
|
uv_button[UV_MODE_ROTATE]->set_icon(get_icon("ToolRotate", "EditorIcons"));
|
||||||
uv_button[UV_MODE_SCALE]->set_icon(get_icon("ToolScale", "EditorIcons"));
|
uv_button[UV_MODE_SCALE]->set_icon(get_icon("ToolScale", "EditorIcons"));
|
||||||
|
uv_button[UV_MODE_ADD_SPLIT]->set_icon(get_icon("AddSplit", "EditorIcons"));
|
||||||
|
uv_button[UV_MODE_REMOVE_SPLIT]->set_icon(get_icon("DeleteSplit", "EditorIcons"));
|
||||||
|
|
||||||
b_snap_grid->set_icon(get_icon("Grid", "EditorIcons"));
|
b_snap_grid->set_icon(get_icon("Grid", "EditorIcons"));
|
||||||
b_snap_enable->set_icon(get_icon("SnapGrid", "EditorIcons"));
|
b_snap_enable->set_icon(get_icon("SnapGrid", "EditorIcons"));
|
||||||
@ -79,12 +81,28 @@ void Polygon2DEditor::_notification(int p_what) {
|
|||||||
void Polygon2DEditor::_uv_edit_mode_select(int p_mode) {
|
void Polygon2DEditor::_uv_edit_mode_select(int p_mode) {
|
||||||
|
|
||||||
if (p_mode == 0) {
|
if (p_mode == 0) {
|
||||||
if (uv_button[UV_MODE_CREATE]->is_pressed()) {
|
|
||||||
_uv_mode(1);
|
|
||||||
}
|
|
||||||
uv_button[UV_MODE_CREATE]->hide();
|
uv_button[UV_MODE_CREATE]->hide();
|
||||||
|
for (int i = UV_MODE_MOVE; i <= UV_MODE_SCALE; i++) {
|
||||||
|
uv_button[i]->show();
|
||||||
|
}
|
||||||
|
uv_button[UV_MODE_ADD_SPLIT]->hide();
|
||||||
|
uv_button[UV_MODE_REMOVE_SPLIT]->hide();
|
||||||
|
_uv_mode(UV_MODE_EDIT_POINT);
|
||||||
|
|
||||||
|
} else if (p_mode == 1) {
|
||||||
|
for (int i = 0; i <= UV_MODE_SCALE; i++) {
|
||||||
|
uv_button[i]->show();
|
||||||
|
}
|
||||||
|
uv_button[UV_MODE_ADD_SPLIT]->hide();
|
||||||
|
uv_button[UV_MODE_REMOVE_SPLIT]->hide();
|
||||||
|
_uv_mode(UV_MODE_EDIT_POINT);
|
||||||
} else {
|
} else {
|
||||||
uv_button[UV_MODE_CREATE]->show();
|
for (int i = 0; i <= UV_MODE_SCALE; i++) {
|
||||||
|
uv_button[i]->hide();
|
||||||
|
}
|
||||||
|
uv_button[UV_MODE_ADD_SPLIT]->show();
|
||||||
|
uv_button[UV_MODE_REMOVE_SPLIT]->show();
|
||||||
|
_uv_mode(UV_MODE_ADD_SPLIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
uv_edit_draw->update();
|
uv_edit_draw->update();
|
||||||
@ -195,6 +213,10 @@ void Polygon2DEditor::_set_snap_step_y(float p_val) {
|
|||||||
|
|
||||||
void Polygon2DEditor::_uv_mode(int p_mode) {
|
void Polygon2DEditor::_uv_mode(int p_mode) {
|
||||||
|
|
||||||
|
split_create = false;
|
||||||
|
uv_drag = false;
|
||||||
|
uv_create = false;
|
||||||
|
|
||||||
uv_mode = UVMode(p_mode);
|
uv_mode = UVMode(p_mode);
|
||||||
for (int i = 0; i < UV_MODE_MAX; i++) {
|
for (int i = 0; i < UV_MODE_MAX; i++) {
|
||||||
uv_button[i]->set_pressed(p_mode == i);
|
uv_button[i]->set_pressed(p_mode == i);
|
||||||
@ -219,10 +241,11 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
|
|||||||
uv_drag = true;
|
uv_drag = true;
|
||||||
uv_prev = node->get_uv();
|
uv_prev = node->get_uv();
|
||||||
|
|
||||||
if (uv_edit_mode[0]->is_pressed()) //edit uv
|
if (uv_edit_mode[0]->is_pressed()) { //edit uv
|
||||||
uv_prev = node->get_uv();
|
uv_prev = node->get_uv();
|
||||||
else
|
} else { //edit polygon
|
||||||
uv_prev = node->get_polygon();
|
uv_prev = node->get_polygon();
|
||||||
|
}
|
||||||
|
|
||||||
uv_move_current = uv_mode;
|
uv_move_current = uv_mode;
|
||||||
if (uv_move_current == UV_MODE_CREATE) {
|
if (uv_move_current == UV_MODE_CREATE) {
|
||||||
@ -238,6 +261,7 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
|
|||||||
uv_create = true;
|
uv_create = true;
|
||||||
uv_create_uv_prev = node->get_uv();
|
uv_create_uv_prev = node->get_uv();
|
||||||
uv_create_poly_prev = node->get_polygon();
|
uv_create_poly_prev = node->get_polygon();
|
||||||
|
splits_prev = node->get_splits();
|
||||||
node->set_polygon(uv_prev);
|
node->set_polygon(uv_prev);
|
||||||
node->set_uv(uv_prev);
|
node->set_uv(uv_prev);
|
||||||
|
|
||||||
@ -292,6 +316,109 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
|
|||||||
uv_drag = false;
|
uv_drag = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (uv_move_current == UV_MODE_ADD_SPLIT) {
|
||||||
|
|
||||||
|
int drag_index = -1;
|
||||||
|
drag_index = -1;
|
||||||
|
for (int i = 0; i < uv_prev.size(); i++) {
|
||||||
|
|
||||||
|
Vector2 tuv = mtx.xform(uv_prev[i]);
|
||||||
|
if (tuv.distance_to(Vector2(mb->get_position().x, mb->get_position().y)) < 8) {
|
||||||
|
drag_index = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (drag_index == -1) {
|
||||||
|
split_create = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (split_create) {
|
||||||
|
|
||||||
|
split_create = false;
|
||||||
|
if (drag_index < uv_drag_index) {
|
||||||
|
SWAP(drag_index, uv_drag_index);
|
||||||
|
}
|
||||||
|
bool valid = true;
|
||||||
|
if (drag_index == uv_drag_index) {
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
if (drag_index + 1 == uv_drag_index) {
|
||||||
|
//not a split,goes along the edge
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
if (drag_index == uv_prev.size() - 1 && uv_drag_index == 0) {
|
||||||
|
//not a split,goes along the edge
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < splits_prev.size(); i += 2) {
|
||||||
|
if (splits_prev[i] == uv_drag_index && splits_prev[i + 1] == drag_index) {
|
||||||
|
//already exists
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
if (splits_prev[i] > uv_drag_index && splits_prev[i + 1] > drag_index) {
|
||||||
|
//crossing
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (splits_prev[i] < uv_drag_index && splits_prev[i + 1] < drag_index) {
|
||||||
|
//crossing opposite direction
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (valid) {
|
||||||
|
|
||||||
|
splits_prev.push_back(uv_drag_index);
|
||||||
|
splits_prev.push_back(drag_index);
|
||||||
|
|
||||||
|
undo_redo->create_action(TTR("Add Split"));
|
||||||
|
|
||||||
|
undo_redo->add_do_method(node, "set_splits", splits_prev);
|
||||||
|
undo_redo->add_undo_method(node, "set_splits", node->get_splits());
|
||||||
|
undo_redo->add_do_method(uv_edit_draw, "update");
|
||||||
|
undo_redo->add_undo_method(uv_edit_draw, "update");
|
||||||
|
undo_redo->commit_action();
|
||||||
|
} else {
|
||||||
|
error->set_text(TTR("Invalid Split"));
|
||||||
|
error->popup_centered_minsize();
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
uv_drag_index = drag_index;
|
||||||
|
split_create = true;
|
||||||
|
uv_create_to = mtx.affine_inverse().xform(Vector2(mb->get_position().x, mb->get_position().y));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uv_move_current == UV_MODE_REMOVE_SPLIT) {
|
||||||
|
|
||||||
|
for (int i = 0; i < splits_prev.size(); i += 2) {
|
||||||
|
if (splits_prev[i] < 0 || splits_prev[i] >= uv_prev.size())
|
||||||
|
continue;
|
||||||
|
if (splits_prev[i + 1] < 0 || splits_prev[i] >= uv_prev.size())
|
||||||
|
continue;
|
||||||
|
Vector2 e[2] = { mtx.xform(uv_prev[splits_prev[i]]), mtx.xform(uv_prev[splits_prev[i + 1]]) };
|
||||||
|
Vector2 mp = Vector2(mb->get_position().x, mb->get_position().y);
|
||||||
|
Vector2 cp = Geometry::get_closest_point_to_segment_2d(mp, e);
|
||||||
|
if (cp.distance_to(mp) < 8) {
|
||||||
|
splits_prev.remove(i);
|
||||||
|
splits_prev.remove(i);
|
||||||
|
|
||||||
|
undo_redo->create_action(TTR("Remove Split"));
|
||||||
|
|
||||||
|
undo_redo->add_do_method(node, "set_splits", splits_prev);
|
||||||
|
undo_redo->add_undo_method(node, "set_splits", node->get_splits());
|
||||||
|
undo_redo->add_do_method(uv_edit_draw, "update");
|
||||||
|
undo_redo->add_undo_method(uv_edit_draw, "update");
|
||||||
|
undo_redo->commit_action();
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} else if (uv_drag && !uv_create) {
|
} else if (uv_drag && !uv_create) {
|
||||||
|
|
||||||
undo_redo->create_action(TTR("Transform UV Map"));
|
undo_redo->create_action(TTR("Transform UV Map"));
|
||||||
@ -299,7 +426,7 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
|
|||||||
if (uv_edit_mode[0]->is_pressed()) { //edit uv
|
if (uv_edit_mode[0]->is_pressed()) { //edit uv
|
||||||
undo_redo->add_do_method(node, "set_uv", node->get_uv());
|
undo_redo->add_do_method(node, "set_uv", node->get_uv());
|
||||||
undo_redo->add_undo_method(node, "set_uv", uv_prev);
|
undo_redo->add_undo_method(node, "set_uv", uv_prev);
|
||||||
} else {
|
} else if (uv_edit_mode[1]->is_pressed()) { //edit polygon
|
||||||
undo_redo->add_do_method(node, "set_polygon", node->get_polygon());
|
undo_redo->add_do_method(node, "set_polygon", node->get_polygon());
|
||||||
undo_redo->add_undo_method(node, "set_polygon", uv_prev);
|
undo_redo->add_undo_method(node, "set_polygon", uv_prev);
|
||||||
}
|
}
|
||||||
@ -318,16 +445,20 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
|
|||||||
uv_create = false;
|
uv_create = false;
|
||||||
node->set_uv(uv_create_uv_prev);
|
node->set_uv(uv_create_uv_prev);
|
||||||
node->set_polygon(uv_create_poly_prev);
|
node->set_polygon(uv_create_poly_prev);
|
||||||
|
node->set_splits(splits_prev);
|
||||||
uv_edit_draw->update();
|
uv_edit_draw->update();
|
||||||
} else if (uv_drag) {
|
} else if (uv_drag) {
|
||||||
|
|
||||||
uv_drag = false;
|
uv_drag = false;
|
||||||
if (uv_edit_mode[0]->is_pressed()) { //edit uv
|
if (uv_edit_mode[0]->is_pressed()) { //edit uv
|
||||||
node->set_uv(uv_prev);
|
node->set_uv(uv_prev);
|
||||||
} else {
|
} else if (uv_edit_mode[1]->is_pressed()) { //edit polygon
|
||||||
node->set_polygon(uv_prev);
|
node->set_polygon(uv_prev);
|
||||||
}
|
}
|
||||||
uv_edit_draw->update();
|
uv_edit_draw->update();
|
||||||
|
} else if (split_create) {
|
||||||
|
split_create = false;
|
||||||
|
uv_edit_draw->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (mb->get_button_index() == BUTTON_WHEEL_UP && mb->is_pressed()) {
|
} else if (mb->get_button_index() == BUTTON_WHEEL_UP && mb->is_pressed()) {
|
||||||
@ -368,7 +499,7 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
|
|||||||
|
|
||||||
if (uv_edit_mode[0]->is_pressed()) { //edit uv
|
if (uv_edit_mode[0]->is_pressed()) { //edit uv
|
||||||
node->set_uv(uv_new);
|
node->set_uv(uv_new);
|
||||||
} else {
|
} else if (uv_edit_mode[1]->is_pressed()) { //edit polygon
|
||||||
node->set_polygon(uv_new);
|
node->set_polygon(uv_new);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
@ -380,7 +511,7 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
|
|||||||
|
|
||||||
if (uv_edit_mode[0]->is_pressed()) { //edit uv
|
if (uv_edit_mode[0]->is_pressed()) { //edit uv
|
||||||
node->set_uv(uv_new);
|
node->set_uv(uv_new);
|
||||||
} else {
|
} else if (uv_edit_mode[1]->is_pressed()) { //edit polygon
|
||||||
node->set_polygon(uv_new);
|
node->set_polygon(uv_new);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -404,7 +535,7 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
|
|||||||
|
|
||||||
if (uv_edit_mode[0]->is_pressed()) { //edit uv
|
if (uv_edit_mode[0]->is_pressed()) { //edit uv
|
||||||
node->set_uv(uv_new);
|
node->set_uv(uv_new);
|
||||||
} else {
|
} else if (uv_edit_mode[1]->is_pressed()) { //edit polygon
|
||||||
node->set_polygon(uv_new);
|
node->set_polygon(uv_new);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -433,12 +564,15 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
|
|||||||
|
|
||||||
if (uv_edit_mode[0]->is_pressed()) { //edit uv
|
if (uv_edit_mode[0]->is_pressed()) { //edit uv
|
||||||
node->set_uv(uv_new);
|
node->set_uv(uv_new);
|
||||||
} else {
|
} else if (uv_edit_mode[1]->is_pressed()) { //edit polygon
|
||||||
node->set_polygon(uv_new);
|
node->set_polygon(uv_new);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
uv_edit_draw->update();
|
uv_edit_draw->update();
|
||||||
|
} else if (split_create) {
|
||||||
|
uv_create_to = mtx.affine_inverse().xform(Vector2(mm->get_position().x, mm->get_position().y));
|
||||||
|
uv_edit_draw->update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -509,10 +643,11 @@ void Polygon2DEditor::_uv_draw() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
PoolVector<Vector2> uvs;
|
PoolVector<Vector2> uvs;
|
||||||
if (uv_edit_mode[0]->is_pressed()) //edit uv
|
if (uv_edit_mode[0]->is_pressed()) { //edit uv
|
||||||
uvs = node->get_uv();
|
uvs = node->get_uv();
|
||||||
else
|
} else { //edit polygon
|
||||||
uvs = node->get_polygon();
|
uvs = node->get_polygon();
|
||||||
|
}
|
||||||
|
|
||||||
Ref<Texture> handle = get_icon("EditorHandle", "EditorIcons");
|
Ref<Texture> handle = get_icon("EditorHandle", "EditorIcons");
|
||||||
|
|
||||||
@ -531,6 +666,22 @@ void Polygon2DEditor::_uv_draw() {
|
|||||||
rect.expand_to(mtx.basis_xform(uvs[i]));
|
rect.expand_to(mtx.basis_xform(uvs[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (split_create) {
|
||||||
|
Vector2 from = uvs[uv_drag_index];
|
||||||
|
Vector2 to = uv_create_to;
|
||||||
|
uv_edit_draw->draw_line(mtx.xform(from), mtx.xform(to), Color(0.9, 0.5, 0.5), 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
PoolVector<int> splits = node->get_splits();
|
||||||
|
|
||||||
|
for (int i = 0; i < splits.size(); i += 2) {
|
||||||
|
int idx_from = splits[i];
|
||||||
|
int idx_to = splits[i + 1];
|
||||||
|
if (idx_from < 0 || idx_to >= uvs.size())
|
||||||
|
continue;
|
||||||
|
uv_edit_draw->draw_line(mtx.xform(uvs[idx_from]), mtx.xform(uvs[idx_to]), Color(0.9, 0.5, 0.5), 2);
|
||||||
|
}
|
||||||
|
|
||||||
rect = rect.grow(200);
|
rect = rect.grow(200);
|
||||||
updating_uv_scroll = true;
|
updating_uv_scroll = true;
|
||||||
uv_hscroll->set_min(rect.position.x);
|
uv_hscroll->set_min(rect.position.x);
|
||||||
@ -601,16 +752,22 @@ Polygon2DEditor::Polygon2DEditor(EditorNode *p_editor) :
|
|||||||
uv_edit_mode[1] = memnew(ToolButton);
|
uv_edit_mode[1] = memnew(ToolButton);
|
||||||
uv_mode_hb->add_child(uv_edit_mode[1]);
|
uv_mode_hb->add_child(uv_edit_mode[1]);
|
||||||
uv_edit_mode[1]->set_toggle_mode(true);
|
uv_edit_mode[1]->set_toggle_mode(true);
|
||||||
|
uv_edit_mode[2] = memnew(ToolButton);
|
||||||
|
uv_mode_hb->add_child(uv_edit_mode[2]);
|
||||||
|
uv_edit_mode[2]->set_toggle_mode(true);
|
||||||
|
|
||||||
uv_edit_mode[0]->set_text(TTR("UV"));
|
uv_edit_mode[0]->set_text(TTR("UV"));
|
||||||
uv_edit_mode[0]->set_pressed(true);
|
uv_edit_mode[0]->set_pressed(true);
|
||||||
uv_edit_mode[1]->set_text(TTR("Poly"));
|
uv_edit_mode[1]->set_text(TTR("Poly"));
|
||||||
|
uv_edit_mode[2]->set_text(TTR("Splits"));
|
||||||
|
|
||||||
uv_edit_mode[0]->set_button_group(uv_edit_group);
|
uv_edit_mode[0]->set_button_group(uv_edit_group);
|
||||||
uv_edit_mode[1]->set_button_group(uv_edit_group);
|
uv_edit_mode[1]->set_button_group(uv_edit_group);
|
||||||
|
uv_edit_mode[2]->set_button_group(uv_edit_group);
|
||||||
|
|
||||||
uv_edit_mode[0]->connect("pressed", this, "_uv_edit_mode_select", varray(0));
|
uv_edit_mode[0]->connect("pressed", this, "_uv_edit_mode_select", varray(0));
|
||||||
uv_edit_mode[1]->connect("pressed", this, "_uv_edit_mode_select", varray(1));
|
uv_edit_mode[1]->connect("pressed", this, "_uv_edit_mode_select", varray(1));
|
||||||
|
uv_edit_mode[2]->connect("pressed", this, "_uv_edit_mode_select", varray(2));
|
||||||
|
|
||||||
uv_mode_hb->add_child(memnew(VSeparator));
|
uv_mode_hb->add_child(memnew(VSeparator));
|
||||||
|
|
||||||
@ -629,8 +786,12 @@ Polygon2DEditor::Polygon2DEditor(EditorNode *p_editor) :
|
|||||||
uv_button[2]->set_tooltip(TTR("Move Polygon"));
|
uv_button[2]->set_tooltip(TTR("Move Polygon"));
|
||||||
uv_button[3]->set_tooltip(TTR("Rotate Polygon"));
|
uv_button[3]->set_tooltip(TTR("Rotate Polygon"));
|
||||||
uv_button[4]->set_tooltip(TTR("Scale Polygon"));
|
uv_button[4]->set_tooltip(TTR("Scale Polygon"));
|
||||||
|
uv_button[5]->set_tooltip(TTR("Connect two points to make a split"));
|
||||||
|
uv_button[6]->set_tooltip(TTR("Select a split to erase it"));
|
||||||
|
|
||||||
uv_button[0]->hide();
|
uv_button[0]->hide();
|
||||||
|
uv_button[5]->hide();
|
||||||
|
uv_button[6]->hide();
|
||||||
uv_button[1]->set_pressed(true);
|
uv_button[1]->set_pressed(true);
|
||||||
HBoxContainer *uv_main_hb = memnew(HBoxContainer);
|
HBoxContainer *uv_main_hb = memnew(HBoxContainer);
|
||||||
uv_main_vb->add_child(uv_main_hb);
|
uv_main_vb->add_child(uv_main_hb);
|
||||||
@ -737,8 +898,9 @@ Polygon2DEditor::Polygon2DEditor(EditorNode *p_editor) :
|
|||||||
uv_draw_zoom = 1.0;
|
uv_draw_zoom = 1.0;
|
||||||
uv_drag_index = -1;
|
uv_drag_index = -1;
|
||||||
uv_drag = false;
|
uv_drag = false;
|
||||||
uv_create = true;
|
uv_create = false;
|
||||||
updating_uv_scroll = false;
|
updating_uv_scroll = false;
|
||||||
|
split_create = false;
|
||||||
|
|
||||||
error = memnew(AcceptDialog);
|
error = memnew(AcceptDialog);
|
||||||
add_child(error);
|
add_child(error);
|
||||||
|
@ -55,17 +55,19 @@ class Polygon2DEditor : public AbstractPolygon2DEditor {
|
|||||||
UV_MODE_MOVE,
|
UV_MODE_MOVE,
|
||||||
UV_MODE_ROTATE,
|
UV_MODE_ROTATE,
|
||||||
UV_MODE_SCALE,
|
UV_MODE_SCALE,
|
||||||
|
UV_MODE_ADD_SPLIT,
|
||||||
|
UV_MODE_REMOVE_SPLIT,
|
||||||
UV_MODE_MAX
|
UV_MODE_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
ToolButton *uv_edit_mode[2];
|
ToolButton *uv_edit_mode[3];
|
||||||
Ref<ButtonGroup> uv_edit_group;
|
Ref<ButtonGroup> uv_edit_group;
|
||||||
|
|
||||||
Polygon2D *node;
|
Polygon2D *node;
|
||||||
|
|
||||||
UVMode uv_mode;
|
UVMode uv_mode;
|
||||||
AcceptDialog *uv_edit;
|
AcceptDialog *uv_edit;
|
||||||
ToolButton *uv_button[5];
|
ToolButton *uv_button[UV_MODE_MAX];
|
||||||
ToolButton *b_snap_enable;
|
ToolButton *b_snap_enable;
|
||||||
ToolButton *b_snap_grid;
|
ToolButton *b_snap_grid;
|
||||||
Control *uv_edit_draw;
|
Control *uv_edit_draw;
|
||||||
@ -81,10 +83,13 @@ class Polygon2DEditor : public AbstractPolygon2DEditor {
|
|||||||
PoolVector<Vector2> uv_prev;
|
PoolVector<Vector2> uv_prev;
|
||||||
PoolVector<Vector2> uv_create_uv_prev;
|
PoolVector<Vector2> uv_create_uv_prev;
|
||||||
PoolVector<Vector2> uv_create_poly_prev;
|
PoolVector<Vector2> uv_create_poly_prev;
|
||||||
|
PoolVector<int> splits_prev;
|
||||||
|
|
||||||
Vector2 uv_create_to;
|
Vector2 uv_create_to;
|
||||||
int uv_drag_index;
|
int uv_drag_index;
|
||||||
bool uv_drag;
|
bool uv_drag;
|
||||||
bool uv_create;
|
bool uv_create;
|
||||||
|
bool split_create;
|
||||||
UVMode uv_move_current;
|
UVMode uv_move_current;
|
||||||
Vector2 uv_drag_from;
|
Vector2 uv_drag_from;
|
||||||
bool updating_uv_scroll;
|
bool updating_uv_scroll;
|
||||||
|
@ -192,7 +192,80 @@ void Polygon2D::_notification(int p_what) {
|
|||||||
// Vector<int> indices = Geometry::triangulate_polygon(points);
|
// Vector<int> indices = Geometry::triangulate_polygon(points);
|
||||||
// VS::get_singleton()->canvas_item_add_triangle_array(get_canvas_item(), indices, points, colors, uvs, texture.is_valid() ? texture->get_rid() : RID());
|
// VS::get_singleton()->canvas_item_add_triangle_array(get_canvas_item(), indices, points, colors, uvs, texture.is_valid() ? texture->get_rid() : RID());
|
||||||
|
|
||||||
VS::get_singleton()->canvas_item_add_polygon(get_canvas_item(), points, colors, uvs, texture.is_valid() ? texture->get_rid() : RID(), RID(), antialiased);
|
if (invert || splits.size() == 0) {
|
||||||
|
VS::get_singleton()->canvas_item_add_polygon(get_canvas_item(), points, colors, uvs, texture.is_valid() ? texture->get_rid() : RID(), RID(), antialiased);
|
||||||
|
} else {
|
||||||
|
//use splits
|
||||||
|
Vector<int> loop;
|
||||||
|
int sc = splits.size();
|
||||||
|
PoolVector<int>::Read r = splits.read();
|
||||||
|
int last = points.size();
|
||||||
|
|
||||||
|
Vector<Vector<int> > loops;
|
||||||
|
|
||||||
|
for (int i = 0; i < last; i++) {
|
||||||
|
|
||||||
|
int split;
|
||||||
|
int min_end = -1;
|
||||||
|
|
||||||
|
do {
|
||||||
|
|
||||||
|
loop.push_back(i);
|
||||||
|
|
||||||
|
split = -1;
|
||||||
|
int end = -1;
|
||||||
|
|
||||||
|
for (int j = 0; j < sc; j += 2) {
|
||||||
|
if (r[j + 1] >= last)
|
||||||
|
continue; //no longer valid
|
||||||
|
if (min_end != -1 && r[j + 1] >= min_end)
|
||||||
|
continue;
|
||||||
|
if (r[j] == i) {
|
||||||
|
if (split == -1 || r[j + 1] > end) {
|
||||||
|
split = r[j];
|
||||||
|
end = r[j + 1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (split != -1) {
|
||||||
|
for (int j = end; j < last; j++) {
|
||||||
|
loop.push_back(j);
|
||||||
|
}
|
||||||
|
loops.push_back(loop);
|
||||||
|
last = end + 1;
|
||||||
|
loop.clear();
|
||||||
|
min_end = end; //avoid this split from repeating
|
||||||
|
}
|
||||||
|
|
||||||
|
} while (split != -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (loop.size()) {
|
||||||
|
loops.push_back(loop);
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector<int> indices;
|
||||||
|
|
||||||
|
for (int i = 0; i < loops.size(); i++) {
|
||||||
|
Vector<int> loop = loops[i];
|
||||||
|
Vector<Vector2> vertices;
|
||||||
|
vertices.resize(loop.size());
|
||||||
|
for (int j = 0; j < vertices.size(); j++) {
|
||||||
|
vertices[j] = points[loop[j]];
|
||||||
|
}
|
||||||
|
Vector<int> sub_indices = Geometry::triangulate_polygon(vertices);
|
||||||
|
int from = indices.size();
|
||||||
|
indices.resize(from + sub_indices.size());
|
||||||
|
for (int j = 0; j < sub_indices.size(); j++) {
|
||||||
|
indices[from + j] = loop[sub_indices[j]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//print_line("loops: " + itos(loops.size()) + " indices: " + itos(indices.size()));
|
||||||
|
|
||||||
|
VS::get_singleton()->canvas_item_add_triangle_array(get_canvas_item(), indices, points, colors, uvs, texture.is_valid() ? texture->get_rid() : RID());
|
||||||
|
}
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
@ -220,6 +293,18 @@ PoolVector<Vector2> Polygon2D::get_uv() const {
|
|||||||
return uv;
|
return uv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Polygon2D::set_splits(const PoolVector<int> &p_splits) {
|
||||||
|
|
||||||
|
ERR_FAIL_COND(p_splits.size() & 1); //splits should be multiple of 2
|
||||||
|
splits = p_splits;
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
PoolVector<int> Polygon2D::get_splits() const {
|
||||||
|
|
||||||
|
return splits;
|
||||||
|
}
|
||||||
|
|
||||||
void Polygon2D::set_color(const Color &p_color) {
|
void Polygon2D::set_color(const Color &p_color) {
|
||||||
|
|
||||||
color = p_color;
|
color = p_color;
|
||||||
@ -352,6 +437,9 @@ void Polygon2D::_bind_methods() {
|
|||||||
ClassDB::bind_method(D_METHOD("set_color", "color"), &Polygon2D::set_color);
|
ClassDB::bind_method(D_METHOD("set_color", "color"), &Polygon2D::set_color);
|
||||||
ClassDB::bind_method(D_METHOD("get_color"), &Polygon2D::get_color);
|
ClassDB::bind_method(D_METHOD("get_color"), &Polygon2D::get_color);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_splits", "splits"), &Polygon2D::set_splits);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_splits"), &Polygon2D::get_splits);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("set_vertex_colors", "vertex_colors"), &Polygon2D::set_vertex_colors);
|
ClassDB::bind_method(D_METHOD("set_vertex_colors", "vertex_colors"), &Polygon2D::set_vertex_colors);
|
||||||
ClassDB::bind_method(D_METHOD("get_vertex_colors"), &Polygon2D::get_vertex_colors);
|
ClassDB::bind_method(D_METHOD("get_vertex_colors"), &Polygon2D::get_vertex_colors);
|
||||||
|
|
||||||
@ -384,6 +472,7 @@ void Polygon2D::_bind_methods() {
|
|||||||
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR2_ARRAY, "polygon"), "set_polygon", "get_polygon");
|
ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR2_ARRAY, "polygon"), "set_polygon", "get_polygon");
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR2_ARRAY, "uv"), "set_uv", "get_uv");
|
ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR2_ARRAY, "uv"), "set_uv", "get_uv");
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::POOL_INT_ARRAY, "splits"), "set_splits", "get_splits");
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_color", "get_color");
|
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_color", "get_color");
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::POOL_COLOR_ARRAY, "vertex_colors"), "set_vertex_colors", "get_vertex_colors");
|
ADD_PROPERTY(PropertyInfo(Variant::POOL_COLOR_ARRAY, "vertex_colors"), "set_vertex_colors", "get_vertex_colors");
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset"), "set_offset", "get_offset");
|
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset"), "set_offset", "get_offset");
|
||||||
|
@ -40,6 +40,8 @@ class Polygon2D : public Node2D {
|
|||||||
PoolVector<Vector2> polygon;
|
PoolVector<Vector2> polygon;
|
||||||
PoolVector<Vector2> uv;
|
PoolVector<Vector2> uv;
|
||||||
PoolVector<Color> vertex_colors;
|
PoolVector<Color> vertex_colors;
|
||||||
|
PoolVector<int> splits;
|
||||||
|
|
||||||
Color color;
|
Color color;
|
||||||
Ref<Texture> texture;
|
Ref<Texture> texture;
|
||||||
Size2 tex_scale;
|
Size2 tex_scale;
|
||||||
@ -75,6 +77,9 @@ public:
|
|||||||
void set_uv(const PoolVector<Vector2> &p_uv);
|
void set_uv(const PoolVector<Vector2> &p_uv);
|
||||||
PoolVector<Vector2> get_uv() const;
|
PoolVector<Vector2> get_uv() const;
|
||||||
|
|
||||||
|
void set_splits(const PoolVector<int> &p_uv);
|
||||||
|
PoolVector<int> get_splits() const;
|
||||||
|
|
||||||
void set_color(const Color &p_color);
|
void set_color(const Color &p_color);
|
||||||
Color get_color() const;
|
Color get_color() const;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user