Remove bone and weight painting support from PaintPolygon2D.

This commit is contained in:
Relintai 2023-08-25 20:52:11 +02:00
parent edf55fde28
commit c22d5d8946
4 changed files with 6 additions and 629 deletions

View File

@ -32,11 +32,6 @@
#include "modules/modules_enabled.gen.h"
#ifdef MODULE_SKELETON_2D_ENABLED
#include "modules/skeleton_2d/nodes/skeleton_2d.h"
#endif
#include "editor/plugins/canvas_item_editor_plugin.h"
#include "core/input/input.h"
#include "core/input/input_event.h"
#include "core/math/geometry.h"
@ -55,6 +50,7 @@
#include "core/variant/variant.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
#include "editor/plugins/canvas_item_editor_plugin.h"
#include "scene/2d/canvas_item.h"
#include "scene/2d/polygon_2d.h"
#include "scene/gui/box_container.h"
@ -109,7 +105,6 @@ void PaintPolygon2DEditor::_notification(int p_what) {
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
uv_edit_draw->add_theme_style_override("panel", get_theme_stylebox("bg", "Tree"));
bone_scroll->add_theme_style_override("bg", get_theme_stylebox("bg", "Tree"));
} break;
case NOTIFICATION_READY: {
button_uv->set_icon(get_theme_icon("Uv", "EditorIcons"));
@ -123,8 +118,6 @@ void PaintPolygon2DEditor::_notification(int p_what) {
uv_button[UV_MODE_SCALE]->set_icon(get_theme_icon("ToolScale", "EditorIcons"));
uv_button[UV_MODE_ADD_POLYGON]->set_icon(get_theme_icon("Edit", "EditorIcons"));
uv_button[UV_MODE_REMOVE_POLYGON]->set_icon(get_theme_icon("Close", "EditorIcons"));
uv_button[UV_MODE_PAINT_WEIGHT]->set_icon(get_theme_icon("Bucket", "EditorIcons"));
uv_button[UV_MODE_CLEAR_WEIGHT]->set_icon(get_theme_icon("Clear", "EditorIcons"));
b_snap_grid->set_icon(get_theme_icon("Grid", "EditorIcons"));
b_snap_enable->set_icon(get_theme_icon("SnapGrid", "EditorIcons"));
@ -141,104 +134,6 @@ void PaintPolygon2DEditor::_notification(int p_what) {
}
}
void PaintPolygon2DEditor::_sync_bones() {
#ifdef MODULE_SKELETON_2D_ENABLED
Skeleton2D *skeleton = nullptr;
if (!node->has_node(node->get_skeleton())) {
error->set_text(TTR("The skeleton property of the PaintPolygon2D does not point to a Skeleton2D node"));
error->popup_centered_minsize();
} else {
Node *sn = node->get_node(node->get_skeleton());
skeleton = Object::cast_to<Skeleton2D>(sn);
}
Array prev_bones = node->call("_get_bones");
node->clear_bones();
if (!skeleton) {
error->set_text(TTR("The skeleton property of the PaintPolygon2D does not point to a Skeleton2D node"));
error->popup_centered_minsize();
} else {
for (int i = 0; i < skeleton->get_bone_count(); i++) {
NodePath path = skeleton->get_path_to(skeleton->get_bone(i));
PoolVector<float> weights;
int wc = node->get_polygon().size();
for (int j = 0; j < prev_bones.size(); j += 2) {
NodePath pvp = prev_bones[j];
PoolVector<float> pv = prev_bones[j + 1];
if (pvp == path && pv.size() == wc) {
weights = pv;
}
}
if (weights.size() == 0) { //create them
weights.resize(node->get_polygon().size());
PoolVector<float>::Write w = weights.write();
for (int j = 0; j < wc; j++) {
w[j] = 0.0;
}
}
node->add_bone(path, weights);
}
}
Array new_bones = node->call("_get_bones");
undo_redo->create_action(TTR("Sync Bones"));
undo_redo->add_do_method(node, "_set_bones", new_bones);
undo_redo->add_undo_method(node, "_set_bones", prev_bones);
undo_redo->add_do_method(this, "_update_bone_list");
undo_redo->add_undo_method(this, "_update_bone_list");
undo_redo->add_do_method(uv_edit_draw, "update");
undo_redo->add_undo_method(uv_edit_draw, "update");
undo_redo->commit_action();
#endif
}
void PaintPolygon2DEditor::_update_bone_list() {
NodePath selected;
while (bone_scroll_vb->get_child_count()) {
CheckBox *cb = Object::cast_to<CheckBox>(bone_scroll_vb->get_child(0));
if (cb && cb->is_pressed()) {
selected = cb->get_meta("bone_path");
}
memdelete(bone_scroll_vb->get_child(0));
}
Ref<ButtonGroup> bg;
bg.instance();
for (int i = 0; i < node->get_bone_count(); i++) {
CheckBox *cb = memnew(CheckBox);
NodePath np = node->get_bone_path(i);
String name;
if (np.get_name_count()) {
name = np.get_name(np.get_name_count() - 1);
}
if (name == String()) {
name = "Bone " + itos(i);
}
cb->set_text(name);
cb->set_button_group(bg);
cb->set_meta("bone_path", np);
cb->set_focus_mode(FOCUS_NONE);
bone_scroll_vb->add_child(cb);
if (np == selected || bone_scroll_vb->get_child_count() < 2) {
cb->set_pressed(true);
}
cb->connect("pressed", this, "_bone_paint_selected", varray(i));
}
uv_edit_draw->update();
}
void PaintPolygon2DEditor::_bone_paint_selected(int p_index) {
uv_edit_draw->update();
}
void PaintPolygon2DEditor::_uv_edit_mode_select(int p_mode) {
if (p_mode == 0) { //uv
@ -250,14 +145,7 @@ void PaintPolygon2DEditor::_uv_edit_mode_select(int p_mode) {
}
uv_button[UV_MODE_ADD_POLYGON]->hide();
uv_button[UV_MODE_REMOVE_POLYGON]->hide();
uv_button[UV_MODE_PAINT_WEIGHT]->hide();
uv_button[UV_MODE_CLEAR_WEIGHT]->hide();
_uv_mode(UV_MODE_EDIT_POINT);
bone_scroll_main_vb->hide();
bone_paint_strength->hide();
bone_paint_radius->hide();
bone_paint_radius_label->hide();
} else if (p_mode == 1) { //poly
for (int i = 0; i <= UV_MODE_SCALE; i++) {
@ -265,14 +153,7 @@ void PaintPolygon2DEditor::_uv_edit_mode_select(int p_mode) {
}
uv_button[UV_MODE_ADD_POLYGON]->hide();
uv_button[UV_MODE_REMOVE_POLYGON]->hide();
uv_button[UV_MODE_PAINT_WEIGHT]->hide();
uv_button[UV_MODE_CLEAR_WEIGHT]->hide();
_uv_mode(UV_MODE_EDIT_POINT);
bone_scroll_main_vb->hide();
bone_paint_strength->hide();
bone_paint_radius->hide();
bone_paint_radius_label->hide();
} else if (p_mode == 2) { //splits
for (int i = 0; i <= UV_MODE_SCALE; i++) {
@ -280,29 +161,7 @@ void PaintPolygon2DEditor::_uv_edit_mode_select(int p_mode) {
}
uv_button[UV_MODE_ADD_POLYGON]->show();
uv_button[UV_MODE_REMOVE_POLYGON]->show();
uv_button[UV_MODE_PAINT_WEIGHT]->hide();
uv_button[UV_MODE_CLEAR_WEIGHT]->hide();
_uv_mode(UV_MODE_ADD_POLYGON);
bone_scroll_main_vb->hide();
bone_paint_strength->hide();
bone_paint_radius->hide();
bone_paint_radius_label->hide();
} else if (p_mode == 3) { //bones´
for (int i = 0; i <= UV_MODE_REMOVE_POLYGON; i++) {
uv_button[i]->hide();
}
uv_button[UV_MODE_PAINT_WEIGHT]->show();
uv_button[UV_MODE_CLEAR_WEIGHT]->show();
_uv_mode(UV_MODE_PAINT_WEIGHT);
bone_scroll_main_vb->show();
bone_paint_strength->show();
bone_paint_radius->show();
bone_paint_radius_label->show();
_update_bone_list();
bone_paint_pos = Vector2(-100000, -100000); //send brush away when switching
}
uv_edit->set_size(uv_edit->get_size()); // Necessary readjustment of the popup window.
@ -340,7 +199,6 @@ void PaintPolygon2DEditor::_menu_option(int p_option) {
} else {
uv_edit->popup_centered_ratio(0.85);
}
_update_bone_list();
} break;
case UVEDIT_POLYGON_TO_UV: {
PoolVector<Vector2> points = node->get_polygon();
@ -398,7 +256,6 @@ void PaintPolygon2DEditor::_cancel_editing() {
node->set_polygon(uv_create_poly_prev);
node->set_internal_vertex_count(uv_create_prev_internal_vertices);
node->set_vertex_colors(uv_create_colors_prev);
node->call("_set_bones", uv_create_bones_prev);
node->set_polygons(polygons_prev);
_update_polygon_editing_state();
@ -520,7 +377,6 @@ void PaintPolygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
uv_create_poly_prev = node->get_polygon();
uv_create_prev_internal_vertices = node->get_internal_vertex_count();
uv_create_colors_prev = node->get_vertex_colors();
uv_create_bones_prev = node->call("_get_bones");
polygons_prev = node->get_polygons();
disable_polygon_editing(false, String());
node->set_polygon(points_prev);
@ -542,8 +398,6 @@ void PaintPolygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
undo_redo->add_undo_method(node, "set_internal_vertex_count", uv_create_prev_internal_vertices);
undo_redo->add_do_method(node, "set_vertex_colors", Vector<Color>());
undo_redo->add_undo_method(node, "set_vertex_colors", uv_create_colors_prev);
undo_redo->add_do_method(node, "clear_bones");
undo_redo->add_undo_method(node, "_set_bones", uv_create_bones_prev);
undo_redo->add_do_method(this, "_update_polygon_editing_state");
undo_redo->add_undo_method(this, "_update_polygon_editing_state");
undo_redo->add_do_method(uv_edit_draw, "update");
@ -570,7 +424,6 @@ void PaintPolygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
uv_create_uv_prev = node->get_uv();
uv_create_poly_prev = node->get_polygon();
uv_create_colors_prev = node->get_vertex_colors();
uv_create_bones_prev = node->call("_get_bones");
int internal_vertices = node->get_internal_vertex_count();
Vector2 pos = mtx.affine_inverse().xform(snap_point(Vector2(mb->get_position().x, mb->get_position().y)));
@ -588,12 +441,6 @@ void PaintPolygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
undo_redo->add_undo_method(node, "set_polygon", node->get_polygon());
undo_redo->add_do_method(node, "set_vertex_colors", uv_create_colors_prev);
undo_redo->add_undo_method(node, "set_vertex_colors", node->get_vertex_colors());
for (int i = 0; i < node->get_bone_count(); i++) {
PoolVector<float> bonew = node->get_bone_weights(i);
bonew.push_back(0);
undo_redo->add_do_method(node, "set_bone_weights", i, bonew);
undo_redo->add_undo_method(node, "set_bone_weights", i, node->get_bone_weights(i));
}
undo_redo->add_do_method(node, "set_internal_vertex_count", internal_vertices + 1);
undo_redo->add_undo_method(node, "set_internal_vertex_count", internal_vertices);
undo_redo->add_do_method(this, "_update_polygon_editing_state");
@ -607,7 +454,6 @@ void PaintPolygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
uv_create_uv_prev = node->get_uv();
uv_create_poly_prev = node->get_polygon();
uv_create_colors_prev = node->get_vertex_colors();
uv_create_bones_prev = node->call("_get_bones");
int internal_vertices = node->get_internal_vertex_count();
if (internal_vertices <= 0) {
@ -643,12 +489,6 @@ void PaintPolygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
undo_redo->add_undo_method(node, "set_polygon", node->get_polygon());
undo_redo->add_do_method(node, "set_vertex_colors", uv_create_colors_prev);
undo_redo->add_undo_method(node, "set_vertex_colors", node->get_vertex_colors());
for (int i = 0; i < node->get_bone_count(); i++) {
PoolVector<float> bonew = node->get_bone_weights(i);
bonew.remove(closest);
undo_redo->add_do_method(node, "set_bone_weights", i, bonew);
undo_redo->add_undo_method(node, "set_bone_weights", i, node->get_bone_weights(i));
}
undo_redo->add_do_method(node, "set_internal_vertex_count", internal_vertices - 1);
undo_redo->add_undo_method(node, "set_internal_vertex_count", internal_vertices);
undo_redo->add_do_method(this, "_update_polygon_editing_state");
@ -757,23 +597,6 @@ void PaintPolygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
undo_redo->commit_action();
}
}
if (uv_move_current == UV_MODE_PAINT_WEIGHT || uv_move_current == UV_MODE_CLEAR_WEIGHT) {
int bone_selected = -1;
for (int i = 0; i < bone_scroll_vb->get_child_count(); i++) {
CheckBox *c = Object::cast_to<CheckBox>(bone_scroll_vb->get_child(i));
if (c && c->is_pressed()) {
bone_selected = i;
break;
}
}
if (bone_selected != -1 && node->get_bone_weights(bone_selected).size() == points_prev.size()) {
prev_weights = node->get_bone_weights(bone_selected);
bone_painting = true;
bone_painting_bone = bone_selected;
}
}
} else {
if (uv_drag && !uv_create) {
if (uv_edit_mode[0]->is_pressed()) { // Edit UV.
@ -794,24 +617,10 @@ void PaintPolygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
uv_drag = false;
}
if (bone_painting) {
undo_redo->create_action(TTR("Paint Bone Weights"));
undo_redo->add_do_method(node, "set_bone_weights", bone_painting_bone, node->get_bone_weights(bone_painting_bone));
undo_redo->add_undo_method(node, "set_bone_weights", bone_painting_bone, prev_weights);
undo_redo->add_do_method(uv_edit_draw, "update");
undo_redo->add_undo_method(uv_edit_draw, "update");
undo_redo->commit_action();
bone_painting = false;
}
}
} else if (mb->get_button_index() == BUTTON_RIGHT && mb->is_pressed()) {
_cancel_editing();
if (bone_painting) {
node->set_bone_weights(bone_painting_bone, prev_weights);
}
uv_edit_draw->update();
} else if (mb->get_button_index() == BUTTON_WHEEL_UP && mb->is_pressed()) {
@ -914,48 +723,15 @@ void PaintPolygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
node->set_polygon(uv_new);
}
} break;
case UV_MODE_PAINT_WEIGHT:
case UV_MODE_CLEAR_WEIGHT: {
bone_paint_pos = Vector2(mm->get_position().x, mm->get_position().y);
} break;
default: {
}
}
if (bone_painting) {
PoolVector<float> painted_weights = node->get_bone_weights(bone_painting_bone);
{
int pc = painted_weights.size();
float amount = bone_paint_strength->get_value();
float radius = bone_paint_radius->get_value() * EDSCALE;
if (uv_mode == UV_MODE_CLEAR_WEIGHT) {
amount = -amount;
}
PoolVector<float>::Write w = painted_weights.write();
PoolVector<float>::Read r = prev_weights.read();
PoolVector<Vector2>::Read rv = points_prev.read();
for (int i = 0; i < pc; i++) {
if (mtx.xform(rv[i]).distance_to(bone_paint_pos) < radius) {
w[i] = CLAMP(r[i] + amount, 0, 1);
}
}
}
node->set_bone_weights(bone_painting_bone, painted_weights);
}
uv_edit_draw->update();
CanvasItemEditor::get_singleton()->update_viewport();
} else if (polygon_create.size()) {
uv_create_to = mtx.affine_inverse().xform(Vector2(mm->get_position().x, mm->get_position().y));
uv_edit_draw->update();
} else if (uv_mode == UV_MODE_PAINT_WEIGHT || uv_mode == UV_MODE_CLEAR_WEIGHT) {
bone_paint_pos = Vector2(mm->get_position().x, mm->get_position().y);
uv_edit_draw->update();
}
}
@ -1043,23 +819,6 @@ void PaintPolygon2DEditor::_uv_draw() {
uvs = node->get_polygon();
}
PoolVector<float>::Read weight_r;
if (uv_edit_mode[3]->is_pressed()) {
int bone_selected = -1;
for (int i = 0; i < bone_scroll_vb->get_child_count(); i++) {
CheckBox *c = Object::cast_to<CheckBox>(bone_scroll_vb->get_child(i));
if (c && c->is_pressed()) {
bone_selected = i;
break;
}
}
if (bone_selected != -1 && node->get_bone_weights(bone_selected).size() == uvs.size()) {
weight_r = node->get_bone_weights(bone_selected).read();
}
}
// All UV points are sharp, so use the sharp handle icon
Ref<Texture> handle = get_theme_icon("EditorPathSharpHandle", "EditorIcons");
@ -1126,17 +885,11 @@ void PaintPolygon2DEditor::_uv_draw() {
}
for (int i = 0; i < uvs.size(); i++) {
if (weight_r.ptr()) {
Vector2 draw_pos = mtx.xform(uvs[i]);
float weight = weight_r[i];
uv_edit_draw->draw_rect(Rect2(draw_pos - Vector2(2, 2) * EDSCALE, Vector2(5, 5) * EDSCALE), Color(weight, weight, weight, 1.0), Math::round(EDSCALE));
if (i < uv_draw_max) {
uv_edit_draw->draw_texture(handle, mtx.xform(uvs[i]) - handle->get_size() * 0.5);
} else {
if (i < uv_draw_max) {
uv_edit_draw->draw_texture(handle, mtx.xform(uvs[i]) - handle->get_size() * 0.5);
} else {
// Internal vertex
uv_edit_draw->draw_texture(handle, mtx.xform(uvs[i]) - handle->get_size() * 0.5, Color(0.6, 0.8, 1));
}
// Internal vertex
uv_edit_draw->draw_texture(handle, mtx.xform(uvs[i]) - handle->get_size() * 0.5, Color(0.6, 0.8, 1));
}
}
@ -1148,66 +901,6 @@ void PaintPolygon2DEditor::_uv_draw() {
}
}
#ifdef MODULE_SKELETON_2D_ENABLED
if (uv_mode == UV_MODE_PAINT_WEIGHT || uv_mode == UV_MODE_CLEAR_WEIGHT) {
NodePath bone_path;
for (int i = 0; i < bone_scroll_vb->get_child_count(); i++) {
CheckBox *c = Object::cast_to<CheckBox>(bone_scroll_vb->get_child(i));
if (c && c->is_pressed()) {
bone_path = node->get_bone_path(i);
break;
}
}
//draw skeleton
NodePath skeleton_path = node->get_skeleton();
if (node->has_node(skeleton_path)) {
Skeleton2D *skeleton = Object::cast_to<Skeleton2D>(node->get_node(skeleton_path));
if (skeleton) {
for (int i = 0; i < skeleton->get_bone_count(); i++) {
Bone2D *bone = skeleton->get_bone(i);
if (bone->get_rest() == Transform2D(0, 0, 0, 0, 0, 0)) {
continue; //not set
}
bool current = bone_path == skeleton->get_path_to(bone);
bool found_child = false;
for (int j = 0; j < bone->get_child_count(); j++) {
Bone2D *n = Object::cast_to<Bone2D>(bone->get_child(j));
if (!n) {
continue;
}
found_child = true;
Transform2D bone_xform = node->get_global_transform().affine_inverse() * (skeleton->get_global_transform() * bone->get_skeleton_rest());
Transform2D endpoint_xform = bone_xform * n->get_transform();
Color color = current ? Color(1, 1, 1) : Color(0.5, 0.5, 0.5);
uv_edit_draw->draw_line(mtx.xform(bone_xform.get_origin()), mtx.xform(endpoint_xform.get_origin()), Color(0, 0, 0), Math::round((current ? 5 : 4) * EDSCALE));
uv_edit_draw->draw_line(mtx.xform(bone_xform.get_origin()), mtx.xform(endpoint_xform.get_origin()), color, Math::round((current ? 3 : 2) * EDSCALE));
}
if (!found_child) {
//draw normally
Transform2D bone_xform = node->get_global_transform().affine_inverse() * (skeleton->get_global_transform() * bone->get_skeleton_rest());
Transform2D endpoint_xform = bone_xform * Transform2D(0, Vector2(bone->get_length(), 0));
Color color = current ? Color(1, 1, 1) : Color(0.5, 0.5, 0.5);
uv_edit_draw->draw_line(mtx.xform(bone_xform.get_origin()), mtx.xform(endpoint_xform.get_origin()), Color(0, 0, 0), Math::round((current ? 5 : 4) * EDSCALE));
uv_edit_draw->draw_line(mtx.xform(bone_xform.get_origin()), mtx.xform(endpoint_xform.get_origin()), color, Math::round((current ? 3 : 2) * EDSCALE));
}
}
}
}
//draw paint circle
uv_edit_draw->draw_circle(bone_paint_pos, bone_paint_radius->get_value() * EDSCALE, Color(1, 1, 1, 0.1));
}
#endif
rect.position -= uv_edit_draw->get_size();
rect.size += uv_edit_draw->get_size() * 2.0;
@ -1256,10 +949,7 @@ void PaintPolygon2DEditor::_bind_methods() {
ClassDB::bind_method(D_METHOD("_set_snap_step_y"), &PaintPolygon2DEditor::_set_snap_step_y);
ClassDB::bind_method(D_METHOD("_uv_edit_mode_select"), &PaintPolygon2DEditor::_uv_edit_mode_select);
ClassDB::bind_method(D_METHOD("_uv_edit_popup_hide"), &PaintPolygon2DEditor::_uv_edit_popup_hide);
ClassDB::bind_method(D_METHOD("_sync_bones"), &PaintPolygon2DEditor::_sync_bones);
ClassDB::bind_method(D_METHOD("_update_bone_list"), &PaintPolygon2DEditor::_update_bone_list);
ClassDB::bind_method(D_METHOD("_update_polygon_editing_state"), &PaintPolygon2DEditor::_update_polygon_editing_state);
ClassDB::bind_method(D_METHOD("_bone_paint_selected"), &PaintPolygon2DEditor::_bone_paint_selected);
}
Vector2 PaintPolygon2DEditor::snap_point(Vector2 p_target) const {
@ -1306,25 +996,19 @@ PaintPolygon2DEditor::PaintPolygon2DEditor(EditorNode *p_editor) :
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[3] = memnew(ToolButton);
uv_mode_hb->add_child(uv_edit_mode[3]);
uv_edit_mode[3]->set_toggle_mode(true);
uv_edit_mode[0]->set_text(TTR("UV"));
uv_edit_mode[0]->set_pressed(true);
uv_edit_mode[1]->set_text(TTR("Points"));
uv_edit_mode[2]->set_text(TTR("Polygons"));
uv_edit_mode[3]->set_text(TTR("Bones"));
uv_edit_mode[0]->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[3]->set_button_group(uv_edit_group);
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[2]->connect("pressed", this, "_uv_edit_mode_select", varray(2));
uv_edit_mode[3]->connect("pressed", this, "_uv_edit_mode_select", varray(3));
uv_mode_hb->add_child(memnew(VSeparator));
@ -1350,40 +1034,14 @@ PaintPolygon2DEditor::PaintPolygon2DEditor(EditorNode *p_editor) :
uv_button[UV_MODE_SCALE]->set_tooltip(TTR("Scale Polygon"));
uv_button[UV_MODE_ADD_POLYGON]->set_tooltip(TTR("Create a custom polygon. Enables custom polygon rendering."));
uv_button[UV_MODE_REMOVE_POLYGON]->set_tooltip(TTR("Remove a custom polygon. If none remain, custom polygon rendering is disabled."));
uv_button[UV_MODE_PAINT_WEIGHT]->set_tooltip(TTR("Paint weights with specified intensity."));
uv_button[UV_MODE_CLEAR_WEIGHT]->set_tooltip(TTR("Unpaint weights with specified intensity."));
uv_button[UV_MODE_CREATE]->hide();
uv_button[UV_MODE_CREATE_INTERNAL]->hide();
uv_button[UV_MODE_REMOVE_INTERNAL]->hide();
uv_button[UV_MODE_ADD_POLYGON]->hide();
uv_button[UV_MODE_REMOVE_POLYGON]->hide();
uv_button[UV_MODE_PAINT_WEIGHT]->hide();
uv_button[UV_MODE_CLEAR_WEIGHT]->hide();
uv_button[UV_MODE_EDIT_POINT]->set_pressed(true);
bone_paint_strength = memnew(HSlider);
uv_mode_hb->add_child(bone_paint_strength);
bone_paint_strength->set_custom_minimum_size(Size2(75 * EDSCALE, 0));
bone_paint_strength->set_v_size_flags(SIZE_SHRINK_CENTER);
bone_paint_strength->set_min(0);
bone_paint_strength->set_max(1);
bone_paint_strength->set_step(0.01);
bone_paint_strength->set_value(0.5);
bone_paint_radius_label = memnew(Label(TTR("Radius:")));
uv_mode_hb->add_child(bone_paint_radius_label);
bone_paint_radius = memnew(SpinBox);
uv_mode_hb->add_child(bone_paint_radius);
bone_paint_strength->hide();
bone_paint_radius->hide();
bone_paint_radius_label->hide();
bone_paint_radius->set_min(1);
bone_paint_radius->set_max(100);
bone_paint_radius->set_step(1);
bone_paint_radius->set_value(32);
HSplitContainer *uv_main_hsc = memnew(HSplitContainer);
uv_main_vb->add_child(uv_main_hsc);
uv_main_hsc->set_v_size_flags(SIZE_EXPAND_FILL);
@ -1497,22 +1155,6 @@ PaintPolygon2DEditor::PaintPolygon2DEditor(EditorNode *p_editor) :
uv_edit_draw->add_child(uv_hscroll);
uv_hscroll->connect("value_changed", this, "_uv_scroll_changed");
bone_scroll_main_vb = memnew(VBoxContainer);
bone_scroll_main_vb->hide();
bone_scroll_main_vb->set_custom_minimum_size(Size2(150 * EDSCALE, 0));
sync_bones = memnew(Button(TTR("Sync Bones to Polygon")));
bone_scroll_main_vb->add_child(sync_bones);
sync_bones->set_h_size_flags(0);
sync_bones->connect("pressed", this, "_sync_bones");
uv_main_hsc->add_child(bone_scroll_main_vb);
bone_scroll = memnew(ScrollContainer);
bone_scroll->set_v_scroll(true);
bone_scroll->set_h_scroll(false);
bone_scroll_main_vb->add_child(bone_scroll);
bone_scroll->set_v_size_flags(SIZE_EXPAND_FILL);
bone_scroll_vb = memnew(VBoxContainer);
bone_scroll->add_child(bone_scroll_vb);
uv_edit_draw->connect("draw", this, "_uv_draw");
uv_edit_draw->connect("gui_input", this, "_uv_input");
uv_draw_zoom = 1.0;
@ -1520,7 +1162,6 @@ PaintPolygon2DEditor::PaintPolygon2DEditor(EditorNode *p_editor) :
uv_drag = false;
uv_create = false;
updating_uv_scroll = false;
bone_painting = false;
error = memnew(AcceptDialog);
add_child(error);

View File

@ -82,12 +82,10 @@ class PaintPolygon2DEditor : public AbstractPolygon2DEditor {
UV_MODE_SCALE,
UV_MODE_ADD_POLYGON,
UV_MODE_REMOVE_POLYGON,
UV_MODE_PAINT_WEIGHT,
UV_MODE_CLEAR_WEIGHT,
UV_MODE_MAX
};
ToolButton *uv_edit_mode[4];
ToolButton *uv_edit_mode[3];
Ref<ButtonGroup> uv_edit_group;
PaintPolygon2D *node;
@ -105,22 +103,8 @@ class PaintPolygon2DEditor : public AbstractPolygon2DEditor {
MenuButton *uv_menu;
TextureRect *uv_icon_zoom;
VBoxContainer *bone_scroll_main_vb;
ScrollContainer *bone_scroll;
VBoxContainer *bone_scroll_vb;
Button *sync_bones;
HSlider *bone_paint_strength;
SpinBox *bone_paint_radius;
Label *bone_paint_radius_label;
bool bone_painting;
int bone_painting_bone;
PoolVector<float> prev_weights;
Vector2 bone_paint_pos;
AcceptDialog *grid_settings;
void _sync_bones();
void _update_bone_list();
Vector2 uv_draw_ofs;
float uv_draw_zoom;
PoolVector<Vector2> points_prev;
@ -128,7 +112,6 @@ class PaintPolygon2DEditor : public AbstractPolygon2DEditor {
PoolVector<Vector2> uv_create_poly_prev;
PoolVector<Color> uv_create_colors_prev;
int uv_create_prev_internal_vertices;
Array uv_create_bones_prev;
Array polygons_prev;
Vector2 uv_create_to;
@ -168,7 +151,6 @@ class PaintPolygon2DEditor : public AbstractPolygon2DEditor {
void _uv_edit_mode_select(int p_mode);
void _uv_edit_popup_hide();
void _bone_paint_selected(int p_index);
int _get_polygon_count() const;

View File

@ -32,12 +32,6 @@
#include "core/math/geometry.h"
#include "modules/modules_enabled.gen.h"
#ifdef MODULE_SKELETON_2D_ENABLED
#include "modules/skeleton_2d/nodes/skeleton_2d.h"
#endif
#ifdef TOOLS_ENABLED
Dictionary PaintPolygon2D::_edit_get_state() const {
Dictionary state = Node2D::_edit_get_state();
@ -95,65 +89,13 @@ bool PaintPolygon2D::_edit_is_selected_on_click(const Point2 &p_point, double p_
}
#endif
void PaintPolygon2D::_skeleton_bone_setup_changed() {
update();
}
void PaintPolygon2D::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
// Must re-establish any existing links with skeletons on re-entering the tree.
update();
} break;
case NOTIFICATION_EXIT_TREE: {
// Always detach skeleton when exiting the tree, so skeletons don't inform
// PaintPolygon2Ds outside the tree that they have moved (this would be useless work).
RS::get_singleton()->canvas_item_attach_skeleton(get_canvas_item(), RID());
} break;
case NOTIFICATION_DRAW: {
if (polygon.size() < 3) {
return;
}
#ifdef MODULE_SKELETON_2D_ENABLED
Skeleton2D *skeleton_node = nullptr;
if (has_node(skeleton)) {
skeleton_node = Object::cast_to<Skeleton2D>(get_node(skeleton));
}
ObjectID new_skeleton_id = 0;
if (skeleton_node) {
RS::get_singleton()->canvas_item_attach_skeleton(get_canvas_item(), skeleton_node->get_skeleton());
new_skeleton_id = skeleton_node->get_instance_id();
// Sync the offset transform between the PaintPolygon2D and the skeleton.
// This is needed for accurate culling in VisualServer.
Transform2D global_xform_skel = skeleton_node->get_global_transform();
Transform2D global_xform_poly = get_global_transform();
// find the difference
Transform2D global_xform_offset = global_xform_skel.affine_inverse() * global_xform_poly;
RS::get_singleton()->canvas_item_set_skeleton_relative_xform(get_canvas_item(), global_xform_offset);
} else {
RS::get_singleton()->canvas_item_attach_skeleton(get_canvas_item(), RID());
}
if (new_skeleton_id != current_skeleton_id) {
Object *old_skeleton = ObjectDB::get_instance(current_skeleton_id);
if (old_skeleton) {
old_skeleton->disconnect("bone_setup_changed", this, "_skeleton_bone_setup_changed");
}
if (skeleton_node) {
skeleton_node->connect("bone_setup_changed", this, "_skeleton_bone_setup_changed");
}
current_skeleton_id = new_skeleton_id;
}
#endif
Vector<Vector2> points;
Vector<Vector2> uvs;
Vector<int> bones;
@ -249,73 +191,6 @@ void PaintPolygon2D::_notification(int p_what) {
}
}
#ifdef MODULE_SKELETON_2D_ENABLED
if (skeleton_node && !invert && bone_weights.size()) {
//a skeleton is set! fill indices and weights
int vc = len;
bones.resize(vc * 4);
weights.resize(vc * 4);
int *bonesw = bones.ptrw();
float *weightsw = weights.ptrw();
for (int i = 0; i < vc * 4; i++) {
bonesw[i] = 0;
weightsw[i] = 0;
}
for (int i = 0; i < bone_weights.size(); i++) {
if (bone_weights[i].weights.size() != points.size()) {
continue; //different number of vertices, sorry not using.
}
if (!skeleton_node->has_node(bone_weights[i].path)) {
continue; //node does not exist
}
Bone2D *bone = Object::cast_to<Bone2D>(skeleton_node->get_node(bone_weights[i].path));
if (!bone) {
continue;
}
int bone_index = bone->get_index_in_skeleton();
PoolVector<float>::Read r = bone_weights[i].weights.read();
for (int j = 0; j < vc; j++) {
if (r[j] == 0.0) {
continue; //weight is unpainted, skip
}
//find an index with a weight
for (int k = 0; k < 4; k++) {
if (weightsw[j * 4 + k] < r[j]) {
//this is less than this weight, insert weight!
for (int l = 3; l > k; l--) {
weightsw[j * 4 + l] = weightsw[j * 4 + l - 1];
bonesw[j * 4 + l] = bonesw[j * 4 + l - 1];
}
weightsw[j * 4 + k] = r[j];
bonesw[j * 4 + k] = bone_index;
break;
}
}
}
}
//normalize the weights
for (int i = 0; i < vc; i++) {
float tw = 0;
for (int j = 0; j < 4; j++) {
tw += weightsw[i * 4 + j];
}
if (tw == 0) {
continue; //unpainted, do nothing
}
//normalize
for (int j = 0; j < 4; j++) {
weightsw[i * 4 + j] /= tw;
}
}
}
#endif
Vector<Color> colors;
if (vertex_colors.size() == points.size()) {
colors.resize(len);
@ -511,74 +386,6 @@ Vector2 PaintPolygon2D::get_offset() const {
return offset;
}
void PaintPolygon2D::add_bone(const NodePath &p_path, const PoolVector<float> &p_weights) {
Bone bone;
bone.path = p_path;
bone.weights = p_weights;
bone_weights.push_back(bone);
}
int PaintPolygon2D::get_bone_count() const {
return bone_weights.size();
}
NodePath PaintPolygon2D::get_bone_path(int p_index) const {
ERR_FAIL_INDEX_V(p_index, bone_weights.size(), NodePath());
return bone_weights[p_index].path;
}
PoolVector<float> PaintPolygon2D::get_bone_weights(int p_index) const {
ERR_FAIL_INDEX_V(p_index, bone_weights.size(), PoolVector<float>());
return bone_weights[p_index].weights;
}
void PaintPolygon2D::erase_bone(int p_idx) {
ERR_FAIL_INDEX(p_idx, bone_weights.size());
bone_weights.remove(p_idx);
}
void PaintPolygon2D::clear_bones() {
bone_weights.clear();
}
void PaintPolygon2D::set_bone_weights(int p_index, const PoolVector<float> &p_weights) {
ERR_FAIL_INDEX(p_index, bone_weights.size());
bone_weights.write[p_index].weights = p_weights;
update();
}
void PaintPolygon2D::set_bone_path(int p_index, const NodePath &p_path) {
ERR_FAIL_INDEX(p_index, bone_weights.size());
bone_weights.write[p_index].path = p_path;
update();
}
Array PaintPolygon2D::_get_bones() const {
Array bones;
for (int i = 0; i < get_bone_count(); i++) {
// Convert path property to String to avoid errors due to invalid node path in editor,
// because it's relative to the Skeleton2D node and not PaintPolygon2D.
bones.push_back(String(get_bone_path(i)));
bones.push_back(get_bone_weights(i));
}
return bones;
}
void PaintPolygon2D::_set_bones(const Array &p_bones) {
ERR_FAIL_COND(p_bones.size() & 1);
clear_bones();
for (int i = 0; i < p_bones.size(); i += 2) {
// Convert back from String to NodePath.
add_bone(NodePath(p_bones[i].operator String()), p_bones[i + 1]);
}
}
void PaintPolygon2D::set_skeleton(const NodePath &p_skeleton) {
if (skeleton == p_skeleton) {
return;
}
skeleton = p_skeleton;
update();
}
NodePath PaintPolygon2D::get_skeleton() const {
return skeleton;
}
void PaintPolygon2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_polygon", "polygon"), &PaintPolygon2D::set_polygon);
ClassDB::bind_method(D_METHOD("get_polygon"), &PaintPolygon2D::get_polygon);
@ -622,26 +429,9 @@ void PaintPolygon2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_offset", "offset"), &PaintPolygon2D::set_offset);
ClassDB::bind_method(D_METHOD("get_offset"), &PaintPolygon2D::get_offset);
ClassDB::bind_method(D_METHOD("add_bone", "path", "weights"), &PaintPolygon2D::add_bone);
ClassDB::bind_method(D_METHOD("get_bone_count"), &PaintPolygon2D::get_bone_count);
ClassDB::bind_method(D_METHOD("get_bone_path", "index"), &PaintPolygon2D::get_bone_path);
ClassDB::bind_method(D_METHOD("get_bone_weights", "index"), &PaintPolygon2D::get_bone_weights);
ClassDB::bind_method(D_METHOD("erase_bone", "index"), &PaintPolygon2D::erase_bone);
ClassDB::bind_method(D_METHOD("clear_bones"), &PaintPolygon2D::clear_bones);
ClassDB::bind_method(D_METHOD("set_bone_path", "index", "path"), &PaintPolygon2D::set_bone_path);
ClassDB::bind_method(D_METHOD("set_bone_weights", "index", "weights"), &PaintPolygon2D::set_bone_weights);
ClassDB::bind_method(D_METHOD("set_skeleton", "skeleton"), &PaintPolygon2D::set_skeleton);
ClassDB::bind_method(D_METHOD("get_skeleton"), &PaintPolygon2D::get_skeleton);
ClassDB::bind_method(D_METHOD("set_internal_vertex_count", "internal_vertex_count"), &PaintPolygon2D::set_internal_vertex_count);
ClassDB::bind_method(D_METHOD("get_internal_vertex_count"), &PaintPolygon2D::get_internal_vertex_count);
ClassDB::bind_method(D_METHOD("_set_bones", "bones"), &PaintPolygon2D::_set_bones);
ClassDB::bind_method(D_METHOD("_get_bones"), &PaintPolygon2D::_get_bones);
ClassDB::bind_method(D_METHOD("_skeleton_bone_setup_changed"), &PaintPolygon2D::_skeleton_bone_setup_changed);
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_color", "get_color");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset"), "set_offset", "get_offset");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "antialiased"), "set_antialiased", "get_antialiased");
@ -652,8 +442,6 @@ void PaintPolygon2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "texture_scale", PROPERTY_HINT_LINK), "set_texture_scale", "get_texture_scale");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "texture_rotation_degrees", PROPERTY_HINT_RANGE, "-360,360,0.1,or_lesser,or_greater"), "set_texture_rotation_degrees", "get_texture_rotation_degrees");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "texture_rotation", PROPERTY_HINT_NONE, "", 0), "set_texture_rotation", "get_texture_rotation");
ADD_GROUP("Skeleton", "");
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "skeleton", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Skeleton2D"), "set_skeleton", "get_skeleton");
ADD_GROUP("Invert", "invert_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "invert_enable"), "set_invert", "get_invert");
@ -664,7 +452,6 @@ void PaintPolygon2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR2_ARRAY, "uv"), "set_uv", "get_uv");
ADD_PROPERTY(PropertyInfo(Variant::POOL_COLOR_ARRAY, "vertex_colors"), "set_vertex_colors", "get_vertex_colors");
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "polygons"), "set_polygons", "get_polygons");
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "bones", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "_set_bones", "_get_bones");
ADD_PROPERTY(PropertyInfo(Variant::INT, "internal_vertex_count", PROPERTY_HINT_RANGE, "0,1000"), "set_internal_vertex_count", "get_internal_vertex_count");
}
@ -678,13 +465,7 @@ PaintPolygon2D::PaintPolygon2D() {
color = Color(1, 1, 1);
rect_cache_dirty = true;
internal_vertices = 0;
current_skeleton_id = 0;
}
PaintPolygon2D::~PaintPolygon2D() {
// Most definitely don't want to leave references to this deleted canvas item
// in the skeleton.
if (get_canvas_item().is_valid()) {
RS::get_singleton()->canvas_item_attach_skeleton(get_canvas_item(), RID());
}
}

View File

@ -42,13 +42,6 @@ class PaintPolygon2D : public PaintNode {
Array polygons;
int internal_vertices;
struct Bone {
NodePath path;
PoolVector<float> weights;
};
Vector<Bone> bone_weights;
Color color;
Ref<Texture> texture;
Size2 tex_scale;
@ -63,14 +56,6 @@ class PaintPolygon2D : public PaintNode {
mutable bool rect_cache_dirty;
mutable Rect2 item_rect;
NodePath skeleton;
ObjectID current_skeleton_id;
Array _get_bones() const;
void _set_bones(const Array &p_bones);
void _skeleton_bone_setup_changed();
protected:
void _notification(int p_what);
static void _bind_methods();
@ -134,18 +119,6 @@ public:
void set_offset(const Vector2 &p_offset);
Vector2 get_offset() const;
void add_bone(const NodePath &p_path = NodePath(), const PoolVector<float> &p_weights = PoolVector<float>());
int get_bone_count() const;
NodePath get_bone_path(int p_index) const;
PoolVector<float> get_bone_weights(int p_index) const;
void erase_bone(int p_idx);
void clear_bones();
void set_bone_weights(int p_index, const PoolVector<float> &p_weights);
void set_bone_path(int p_index, const NodePath &p_path);
void set_skeleton(const NodePath &p_skeleton);
NodePath get_skeleton() const;
PaintPolygon2D();
virtual ~PaintPolygon2D();
};