Renamed the new paint classes and added them to the build.

This commit is contained in:
Relintai 2023-08-25 19:16:52 +02:00
parent 3424e44400
commit edf55fde28
12 changed files with 405 additions and 677 deletions

View File

@ -36,7 +36,12 @@ module_env.add_source_files(env.modules_sources,"bush_prefabs.cpp")
module_env.add_source_files(env.modules_sources,"nodes/paint_node.cpp")
module_env.add_source_files(env.modules_sources,"nodes/paint_canvas.cpp")
module_env.add_source_files(env.modules_sources,"nodes/paint_project.cpp")
module_env.add_source_files(env.modules_sources,"nodes/curve_2d/paint_curve_2d.cpp")
module_env.add_source_files(env.modules_sources,"nodes/polygon_2d/paint_polygon_2d.cpp")
if 'TOOLS_ENABLED' in env["CPPDEFINES"]:
module_env.add_source_files(env.modules_sources,"editor/paint_editor_plugin.cpp")
module_env.add_source_files(env.modules_sources,"editor/paint_inspector_plugin.cpp")
module_env.add_source_files(env.modules_sources,"nodes/curve_2d/editor/paint_curve_2d_editor_plugin.cpp")
module_env.add_source_files(env.modules_sources,"nodes/polygon_2d/editor/paint_polygon_2d_editor_plugin.cpp")

View File

@ -34,6 +34,9 @@ def get_doc_classes():
"PaintProjectPropertyInspector",
"PaintProjectToolsPropertyInspector",
"PaintToolsPropertyInspector",
"PaintPolygon2D",
"PaintCurve2D",
]
def get_doc_path():

View File

@ -28,9 +28,9 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "path_2d_editor_plugin.h"
#include "paint_curve_2d_editor_plugin.h"
#include "canvas_item_editor_plugin.h"
#include "editor/plugins/canvas_item_editor_plugin.h"
#include "core/os/keyboard.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
@ -55,7 +55,9 @@
#include "scene/resources/curve.h"
#include "scene/resources/texture.h"
void Path2DEditor::_notification(int p_what) {
#include "../paint_curve_2d.h"
void PaintCurve2DEditor::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_READY: {
//button_create->set_icon( get_theme_icon("Edit","EditorIcons"));
@ -68,14 +70,14 @@ void Path2DEditor::_notification(int p_what) {
} break;
}
}
void Path2DEditor::_node_removed(Node *p_node) {
void PaintCurve2DEditor::_node_removed(Node *p_node) {
if (p_node == node) {
node = nullptr;
hide();
}
}
bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
bool PaintCurve2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
if (!node) {
return false;
}
@ -375,7 +377,7 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
return false;
}
void Path2DEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
void PaintCurve2DEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
if (!node || !node->is_visible_in_tree() || !node->get_curve().is_valid()) {
return;
}
@ -434,7 +436,7 @@ void Path2DEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
}
}
void Path2DEditor::_node_visibility_changed() {
void PaintCurve2DEditor::_node_visibility_changed() {
if (!node) {
return;
}
@ -442,13 +444,13 @@ void Path2DEditor::_node_visibility_changed() {
canvas_item_editor->update_viewport();
}
void Path2DEditor::edit(Node *p_path2d) {
void PaintCurve2DEditor::edit(Node *p_path2d) {
if (!canvas_item_editor) {
canvas_item_editor = CanvasItemEditor::get_singleton();
}
if (p_path2d) {
node = Object::cast_to<Path2D>(p_path2d);
node = Object::cast_to<PaintCurve2D>(p_path2d);
if (!node->is_connected("visibility_changed", this, "_node_visibility_changed")) {
node->connect("visibility_changed", this, "_node_visibility_changed");
}
@ -462,14 +464,14 @@ void Path2DEditor::edit(Node *p_path2d) {
}
}
void Path2DEditor::_bind_methods() {
//ClassDB::bind_method(D_METHOD("_menu_option"),&Path2DEditor::_menu_option);
ClassDB::bind_method(D_METHOD("_node_visibility_changed"), &Path2DEditor::_node_visibility_changed);
ClassDB::bind_method(D_METHOD("_mode_selected"), &Path2DEditor::_mode_selected);
ClassDB::bind_method(D_METHOD("_handle_option_pressed"), &Path2DEditor::_handle_option_pressed);
void PaintCurve2DEditor::_bind_methods() {
//ClassDB::bind_method(D_METHOD("_menu_option"),&PaintCurve2DEditor::_menu_option);
ClassDB::bind_method(D_METHOD("_node_visibility_changed"), &PaintCurve2DEditor::_node_visibility_changed);
ClassDB::bind_method(D_METHOD("_mode_selected"), &PaintCurve2DEditor::_mode_selected);
ClassDB::bind_method(D_METHOD("_handle_option_pressed"), &PaintCurve2DEditor::_handle_option_pressed);
}
void Path2DEditor::_mode_selected(int p_mode) {
void PaintCurve2DEditor::_mode_selected(int p_mode) {
if (p_mode == MODE_CREATE) {
curve_create->set_pressed(true);
curve_edit->set_pressed(false);
@ -518,7 +520,7 @@ void Path2DEditor::_mode_selected(int p_mode) {
mode = Mode(p_mode);
}
void Path2DEditor::_handle_option_pressed(int p_option) {
void PaintCurve2DEditor::_handle_option_pressed(int p_option) {
PopupMenu *pm;
pm = handle_menu->get_popup();
@ -537,7 +539,7 @@ void Path2DEditor::_handle_option_pressed(int p_option) {
}
}
Path2DEditor::Path2DEditor(EditorNode *p_editor) {
PaintCurve2DEditor::PaintCurve2DEditor(EditorNode *p_editor) {
canvas_item_editor = nullptr;
editor = p_editor;
undo_redo = editor->get_undo_redo();
@ -606,15 +608,15 @@ Path2DEditor::Path2DEditor(EditorNode *p_editor) {
curve_edit->set_pressed(true);
}
void Path2DEditorPlugin::edit(Object *p_object) {
void PaintCurve2DEditorPlugin::edit(Object *p_object) {
path2d_editor->edit(Object::cast_to<Node>(p_object));
}
bool Path2DEditorPlugin::handles(Object *p_object) const {
return p_object->is_class("Path2D");
bool PaintCurve2DEditorPlugin::handles(Object *p_object) const {
return p_object->is_class("PaintCurve2D");
}
void Path2DEditorPlugin::make_visible(bool p_visible) {
void PaintCurve2DEditorPlugin::make_visible(bool p_visible) {
if (p_visible) {
path2d_editor->show();
path2d_editor->base_hb->show();
@ -626,12 +628,12 @@ void Path2DEditorPlugin::make_visible(bool p_visible) {
}
}
Path2DEditorPlugin::Path2DEditorPlugin(EditorNode *p_node) {
PaintCurve2DEditorPlugin::PaintCurve2DEditorPlugin(EditorNode *p_node) {
editor = p_node;
path2d_editor = memnew(Path2DEditor(p_node));
path2d_editor = memnew(PaintCurve2DEditor(p_node));
CanvasItemEditor::get_singleton()->add_control_to_menu_panel(path2d_editor);
path2d_editor->hide();
}
Path2DEditorPlugin::~Path2DEditorPlugin() {
PaintCurve2DEditorPlugin::~PaintCurve2DEditorPlugin() {
}

View File

@ -1,5 +1,6 @@
#ifndef PATH_2D_EDITOR_PLUGIN_H
#define PATH_2D_EDITOR_PLUGIN_H
#ifndef PAINT_CURVE_2D_EDITOR_PLUGIN_H
#define PAINT_CURVE_2D_EDITOR_PLUGIN_H
/*************************************************************************/
/* path_2d_editor_plugin.h */
/*************************************************************************/
@ -46,20 +47,21 @@ class InputEvent;
class MenuButton;
class Node;
class Panel;
class Path2D;
class PaintCurve2D;
class Separator;
class ToolButton;
class UndoRedo;
class PaintCurve2D;
class Path2DEditor : public HBoxContainer {
GDCLASS(Path2DEditor, HBoxContainer);
class PaintCurve2DEditor : public HBoxContainer {
GDCLASS(PaintCurve2DEditor, HBoxContainer);
UndoRedo *undo_redo;
CanvasItemEditor *canvas_item_editor;
EditorNode *editor;
Panel *panel;
Path2D *node;
PaintCurve2D *node;
HBoxContainer *base_hb;
Separator *sep;
@ -109,7 +111,7 @@ class Path2DEditor : public HBoxContainer {
void _handle_option_pressed(int p_option);
void _node_visibility_changed();
friend class Path2DEditorPlugin;
friend class PaintCurve2DEditorPlugin;
protected:
void _notification(int p_what);
@ -120,27 +122,27 @@ public:
bool forward_gui_input(const Ref<InputEvent> &p_event);
void forward_canvas_draw_over_viewport(Control *p_overlay);
void edit(Node *p_path2d);
Path2DEditor(EditorNode *p_editor);
PaintCurve2DEditor(EditorNode *p_editor);
};
class Path2DEditorPlugin : public EditorPlugin {
GDCLASS(Path2DEditorPlugin, EditorPlugin);
class PaintCurve2DEditorPlugin : public EditorPlugin {
GDCLASS(PaintCurve2DEditorPlugin, EditorPlugin);
Path2DEditor *path2d_editor;
PaintCurve2DEditor *path2d_editor;
EditorNode *editor;
public:
virtual bool forward_canvas_gui_input(const Ref<InputEvent> &p_event) { return path2d_editor->forward_gui_input(p_event); }
virtual void forward_canvas_draw_over_viewport(Control *p_overlay) { path2d_editor->forward_canvas_draw_over_viewport(p_overlay); }
virtual String get_name() const { return "Path2D"; }
virtual String get_name() const { return "PaintCurve2D"; }
bool has_main_screen() const { return false; }
virtual void edit(Object *p_object);
virtual bool handles(Object *p_object) const;
virtual void make_visible(bool p_visible);
Path2DEditorPlugin(EditorNode *p_node);
~Path2DEditorPlugin();
PaintCurve2DEditorPlugin(EditorNode *p_node);
~PaintCurve2DEditorPlugin();
};
#endif // PATH_2D_EDITOR_PLUGIN_H

View File

@ -0,0 +1,165 @@
/*************************************************************************/
/* path_2d.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "paint_curve_2d.h"
#include "core/config/engine.h"
#include "scene/resources/curve.h"
#include "scene/scene_string_names.h"
#ifdef TOOLS_ENABLED
#include "editor/editor_scale.h"
#endif
#ifdef TOOLS_ENABLED
Rect2 PaintCurve2D::_edit_get_rect() const {
if (!curve.is_valid() || curve->get_point_count() == 0) {
return Rect2(0, 0, 0, 0);
}
Rect2 aabb = Rect2(curve->get_point_position(0), Vector2(0, 0));
for (int i = 0; i < curve->get_point_count(); i++) {
for (int j = 0; j <= 8; j++) {
real_t frac = j / 8.0;
Vector2 p = curve->interpolate(i, frac);
aabb.expand_to(p);
}
}
return aabb;
}
bool PaintCurve2D::_edit_use_rect() const {
return curve.is_valid() && curve->get_point_count() != 0;
}
bool PaintCurve2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {
if (curve.is_null()) {
return false;
}
for (int i = 0; i < curve->get_point_count(); i++) {
Vector2 s[2];
s[0] = curve->get_point_position(i);
for (int j = 1; j <= 8; j++) {
real_t frac = j / 8.0;
s[1] = curve->interpolate(i, frac);
Vector2 p = Geometry::get_closest_point_to_segment_2d(p_point, s);
if (p.distance_to(p_point) <= p_tolerance) {
return true;
}
s[0] = s[1];
}
}
return false;
}
#endif
void PaintCurve2D::_notification(int p_what) {
if (p_what == NOTIFICATION_DRAW && curve.is_valid()) {
//draw the curve!!
if (!Engine::get_singleton()->is_editor_hint() && !get_tree()->is_debugging_navigation_hint()) {
return;
}
if (curve->get_point_count() < 2) {
return;
}
#ifdef TOOLS_ENABLED
const float line_width = 2 * EDSCALE;
#else
const float line_width = 2;
#endif
const Color color = Color(1.0, 1.0, 1.0, 1.0);
_cached_draw_pts.resize(curve->get_point_count() * 8);
int count = 0;
for (int i = 0; i < curve->get_point_count(); i++) {
for (int j = 0; j < 8; j++) {
real_t frac = j * (1.0 / 8.0);
Vector2 p = curve->interpolate(i, frac);
_cached_draw_pts.set(count++, p);
}
}
draw_polyline(_cached_draw_pts, color, line_width, true);
}
}
void PaintCurve2D::_curve_changed() {
if (!is_inside_tree()) {
return;
}
if (!Engine::get_singleton()->is_editor_hint() && !get_tree()->is_debugging_navigation_hint()) {
return;
}
update();
}
void PaintCurve2D::set_curve(const Ref<Curve2D> &p_curve) {
if (curve.is_valid()) {
curve->disconnect("changed", this, "_curve_changed");
}
curve = p_curve;
if (curve.is_valid()) {
curve->connect("changed", this, "_curve_changed");
}
_curve_changed();
}
Ref<Curve2D> PaintCurve2D::get_curve() const {
return curve;
}
void PaintCurve2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_curve", "curve"), &PaintCurve2D::set_curve);
ClassDB::bind_method(D_METHOD("get_curve"), &PaintCurve2D::get_curve);
ClassDB::bind_method(D_METHOD("_curve_changed"), &PaintCurve2D::_curve_changed);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve2D"), "set_curve", "get_curve");
}
PaintCurve2D::PaintCurve2D() {
set_curve(Ref<Curve2D>(memnew(Curve2D))); //create one by default
set_self_modulate(Color(0.5, 0.6, 1.0, 0.7));
}

View File

@ -1,5 +1,6 @@
#ifndef PATH_2D_H
#define PATH_2D_H
#ifndef PAINT_CURVE_2D_H
#define PAINT_CURVE_2D_H
/*************************************************************************/
/* path_2d.h */
/*************************************************************************/
@ -30,12 +31,12 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "scene/2d/node_2d.h"
#include "../paint_node.h"
class Curve2D;
class Path2D : public Node2D {
GDCLASS(Path2D, Node2D);
class PaintCurve2D : public PaintNode {
GDCLASS(PaintCurve2D, PaintNode);
Ref<Curve2D> curve;
Vector<Vector2> _cached_draw_pts;
@ -56,59 +57,7 @@ public:
void set_curve(const Ref<Curve2D> &p_curve);
Ref<Curve2D> get_curve() const;
Path2D();
};
class PathFollow2D : public Node2D {
GDCLASS(PathFollow2D, Node2D);
public:
private:
Path2D *path;
real_t offset;
real_t h_offset;
real_t v_offset;
real_t lookahead;
bool cubic;
bool loop;
bool rotate;
void _update_transform();
protected:
virtual void _validate_property(PropertyInfo &property) const;
void _notification(int p_what);
static void _bind_methods();
public:
void set_offset(float p_offset);
float get_offset() const;
void set_h_offset(float p_h_offset);
float get_h_offset() const;
void set_v_offset(float p_v_offset);
float get_v_offset() const;
void set_unit_offset(float p_unit_offset);
float get_unit_offset() const;
void set_lookahead(float p_lookahead);
float get_lookahead() const;
void set_loop(bool p_loop);
bool has_loop() const;
void set_rotate(bool p_rotate);
bool is_rotating() const;
void set_cubic_interpolation(bool p_enable);
bool get_cubic_interpolation() const;
String get_configuration_warning() const;
PathFollow2D();
PaintCurve2D();
};
#endif // PATH_2D_H

View File

@ -1,412 +0,0 @@
/*************************************************************************/
/* path_2d.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "path_2d.h"
#include "core/config/engine.h"
#include "scene/resources/curve.h"
#include "scene/scene_string_names.h"
#ifdef TOOLS_ENABLED
#include "editor/editor_scale.h"
#endif
#ifdef TOOLS_ENABLED
Rect2 Path2D::_edit_get_rect() const {
if (!curve.is_valid() || curve->get_point_count() == 0) {
return Rect2(0, 0, 0, 0);
}
Rect2 aabb = Rect2(curve->get_point_position(0), Vector2(0, 0));
for (int i = 0; i < curve->get_point_count(); i++) {
for (int j = 0; j <= 8; j++) {
real_t frac = j / 8.0;
Vector2 p = curve->interpolate(i, frac);
aabb.expand_to(p);
}
}
return aabb;
}
bool Path2D::_edit_use_rect() const {
return curve.is_valid() && curve->get_point_count() != 0;
}
bool Path2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {
if (curve.is_null()) {
return false;
}
for (int i = 0; i < curve->get_point_count(); i++) {
Vector2 s[2];
s[0] = curve->get_point_position(i);
for (int j = 1; j <= 8; j++) {
real_t frac = j / 8.0;
s[1] = curve->interpolate(i, frac);
Vector2 p = Geometry::get_closest_point_to_segment_2d(p_point, s);
if (p.distance_to(p_point) <= p_tolerance) {
return true;
}
s[0] = s[1];
}
}
return false;
}
#endif
void Path2D::_notification(int p_what) {
if (p_what == NOTIFICATION_DRAW && curve.is_valid()) {
//draw the curve!!
if (!Engine::get_singleton()->is_editor_hint() && !get_tree()->is_debugging_navigation_hint()) {
return;
}
if (curve->get_point_count() < 2) {
return;
}
#ifdef TOOLS_ENABLED
const float line_width = 2 * EDSCALE;
#else
const float line_width = 2;
#endif
const Color color = Color(1.0, 1.0, 1.0, 1.0);
_cached_draw_pts.resize(curve->get_point_count() * 8);
int count = 0;
for (int i = 0; i < curve->get_point_count(); i++) {
for (int j = 0; j < 8; j++) {
real_t frac = j * (1.0 / 8.0);
Vector2 p = curve->interpolate(i, frac);
_cached_draw_pts.set(count++, p);
}
}
draw_polyline(_cached_draw_pts, color, line_width, true);
}
}
void Path2D::_curve_changed() {
if (!is_inside_tree()) {
return;
}
if (!Engine::get_singleton()->is_editor_hint() && !get_tree()->is_debugging_navigation_hint()) {
return;
}
update();
}
void Path2D::set_curve(const Ref<Curve2D> &p_curve) {
if (curve.is_valid()) {
curve->disconnect("changed", this, "_curve_changed");
}
curve = p_curve;
if (curve.is_valid()) {
curve->connect("changed", this, "_curve_changed");
}
_curve_changed();
}
Ref<Curve2D> Path2D::get_curve() const {
return curve;
}
void Path2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_curve", "curve"), &Path2D::set_curve);
ClassDB::bind_method(D_METHOD("get_curve"), &Path2D::get_curve);
ClassDB::bind_method(D_METHOD("_curve_changed"), &Path2D::_curve_changed);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve2D"), "set_curve", "get_curve");
}
Path2D::Path2D() {
set_curve(Ref<Curve2D>(memnew(Curve2D))); //create one by default
set_self_modulate(Color(0.5, 0.6, 1.0, 0.7));
}
/////////////////////////////////////////////////////////////////////////////////
void PathFollow2D::_update_transform() {
if (!path) {
return;
}
Ref<Curve2D> c = path->get_curve();
if (!c.is_valid()) {
return;
}
float path_length = c->get_baked_length();
if (path_length == 0) {
return;
}
Vector2 pos = c->interpolate_baked(offset, cubic);
if (rotate) {
float ahead = offset + lookahead;
if (loop && ahead >= path_length) {
// If our lookahead will loop, we need to check if the path is closed.
int point_count = c->get_point_count();
if (point_count > 0) {
Vector2 start_point = c->get_point_position(0);
Vector2 end_point = c->get_point_position(point_count - 1);
if (start_point == end_point) {
// Since the path is closed we want to 'smooth off'
// the corner at the start/end.
// So we wrap the lookahead back round.
ahead = Math::fmod(ahead, path_length);
}
}
}
Vector2 ahead_pos = c->interpolate_baked(ahead, cubic);
Vector2 tangent_to_curve;
if (ahead_pos == pos) {
// This will happen at the end of non-looping or non-closed paths.
// We'll try a look behind instead, in order to get a meaningful angle.
tangent_to_curve =
(pos - c->interpolate_baked(offset - lookahead, cubic)).normalized();
} else {
tangent_to_curve = (ahead_pos - pos).normalized();
}
Vector2 normal_of_curve = -tangent_to_curve.tangent();
pos += tangent_to_curve * h_offset;
pos += normal_of_curve * v_offset;
set_rotation(tangent_to_curve.angle());
} else {
pos.x += h_offset;
pos.y += v_offset;
}
set_position(pos);
}
void PathFollow2D::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
path = Object::cast_to<Path2D>(get_parent());
if (path) {
_update_transform();
}
} break;
case NOTIFICATION_EXIT_TREE: {
path = nullptr;
} break;
}
}
void PathFollow2D::set_cubic_interpolation(bool p_enable) {
cubic = p_enable;
}
bool PathFollow2D::get_cubic_interpolation() const {
return cubic;
}
void PathFollow2D::_validate_property(PropertyInfo &property) const {
if (property.name == "offset") {
float max = 10000;
if (path && path->get_curve().is_valid()) {
max = path->get_curve()->get_baked_length();
}
property.hint_string = "0," + rtos(max) + ",0.01,or_lesser,or_greater";
}
}
String PathFollow2D::get_configuration_warning() const {
if (!is_visible_in_tree() || !is_inside_tree()) {
return String();
}
String warning = Node2D::get_configuration_warning();
if (!Object::cast_to<Path2D>(get_parent())) {
if (warning != String()) {
warning += "\n\n";
}
warning += TTR("PathFollow2D only works when set as a child of a Path2D node.");
}
return warning;
}
void PathFollow2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_offset", "offset"), &PathFollow2D::set_offset);
ClassDB::bind_method(D_METHOD("get_offset"), &PathFollow2D::get_offset);
ClassDB::bind_method(D_METHOD("set_h_offset", "h_offset"), &PathFollow2D::set_h_offset);
ClassDB::bind_method(D_METHOD("get_h_offset"), &PathFollow2D::get_h_offset);
ClassDB::bind_method(D_METHOD("set_v_offset", "v_offset"), &PathFollow2D::set_v_offset);
ClassDB::bind_method(D_METHOD("get_v_offset"), &PathFollow2D::get_v_offset);
ClassDB::bind_method(D_METHOD("set_unit_offset", "unit_offset"), &PathFollow2D::set_unit_offset);
ClassDB::bind_method(D_METHOD("get_unit_offset"), &PathFollow2D::get_unit_offset);
ClassDB::bind_method(D_METHOD("set_rotate", "enable"), &PathFollow2D::set_rotate);
ClassDB::bind_method(D_METHOD("is_rotating"), &PathFollow2D::is_rotating);
ClassDB::bind_method(D_METHOD("set_cubic_interpolation", "enable"), &PathFollow2D::set_cubic_interpolation);
ClassDB::bind_method(D_METHOD("get_cubic_interpolation"), &PathFollow2D::get_cubic_interpolation);
ClassDB::bind_method(D_METHOD("set_loop", "loop"), &PathFollow2D::set_loop);
ClassDB::bind_method(D_METHOD("has_loop"), &PathFollow2D::has_loop);
ClassDB::bind_method(D_METHOD("set_lookahead", "lookahead"), &PathFollow2D::set_lookahead);
ClassDB::bind_method(D_METHOD("get_lookahead"), &PathFollow2D::get_lookahead);
ADD_PROPERTY(PropertyInfo(Variant::REAL, "offset", PROPERTY_HINT_RANGE, "0,10000,0.01,or_lesser,or_greater"), "set_offset", "get_offset");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "unit_offset", PROPERTY_HINT_RANGE, "0,1,0.0001,or_lesser,or_greater", PROPERTY_USAGE_EDITOR), "set_unit_offset", "get_unit_offset");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "h_offset"), "set_h_offset", "get_h_offset");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "v_offset"), "set_v_offset", "get_v_offset");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "rotate"), "set_rotate", "is_rotating");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "cubic_interp"), "set_cubic_interpolation", "get_cubic_interpolation");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "loop"), "set_loop", "has_loop");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "lookahead", PROPERTY_HINT_RANGE, "0.001,1024.0,0.001"), "set_lookahead", "get_lookahead");
}
void PathFollow2D::set_offset(float p_offset) {
ERR_FAIL_COND(!isfinite(p_offset));
offset = p_offset;
if (path) {
if (path->get_curve().is_valid()) {
float path_length = path->get_curve()->get_baked_length();
if (loop) {
offset = Math::fposmod(offset, path_length);
if (!Math::is_zero_approx(p_offset) && Math::is_zero_approx(offset)) {
offset = path_length;
}
} else {
offset = CLAMP(offset, 0, path_length);
}
}
_update_transform();
}
_change_notify("offset");
_change_notify("unit_offset");
}
void PathFollow2D::set_h_offset(float p_h_offset) {
h_offset = p_h_offset;
if (path) {
_update_transform();
}
}
float PathFollow2D::get_h_offset() const {
return h_offset;
}
void PathFollow2D::set_v_offset(float p_v_offset) {
v_offset = p_v_offset;
if (path) {
_update_transform();
}
}
float PathFollow2D::get_v_offset() const {
return v_offset;
}
float PathFollow2D::get_offset() const {
return offset;
}
void PathFollow2D::set_unit_offset(float p_unit_offset) {
if (path && path->get_curve().is_valid() && path->get_curve()->get_baked_length()) {
set_offset(p_unit_offset * path->get_curve()->get_baked_length());
}
}
float PathFollow2D::get_unit_offset() const {
if (path && path->get_curve().is_valid() && path->get_curve()->get_baked_length()) {
return get_offset() / path->get_curve()->get_baked_length();
} else {
return 0;
}
}
void PathFollow2D::set_lookahead(float p_lookahead) {
lookahead = p_lookahead;
}
float PathFollow2D::get_lookahead() const {
return lookahead;
}
void PathFollow2D::set_rotate(bool p_rotate) {
rotate = p_rotate;
_update_transform();
}
bool PathFollow2D::is_rotating() const {
return rotate;
}
void PathFollow2D::set_loop(bool p_loop) {
loop = p_loop;
}
bool PathFollow2D::has_loop() const {
return loop;
}
PathFollow2D::PathFollow2D() {
offset = 0;
h_offset = 0;
v_offset = 0;
path = nullptr;
rotate = true;
cubic = true;
loop = true;
lookahead = 4;
}

View File

@ -28,7 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "polygon_2d_editor_plugin.h"
#include "paint_polygon_2d_editor_plugin.h"
#include "modules/modules_enabled.gen.h"
@ -36,7 +36,7 @@
#include "modules/skeleton_2d/nodes/skeleton_2d.h"
#endif
#include "canvas_item_editor_plugin.h"
#include "editor/plugins/canvas_item_editor_plugin.h"
#include "core/input/input.h"
#include "core/input/input_event.h"
#include "core/math/geometry.h"
@ -78,23 +78,25 @@
#include "scene/resources/texture.h"
#include "servers/rendering_server.h"
#include "../paint_polygon_2d.h"
class EditorNode;
class Node2D;
Node2D *Polygon2DEditor::_get_node() const {
Node2D *PaintPolygon2DEditor::_get_node() const {
return node;
}
void Polygon2DEditor::_set_node(Node *p_polygon) {
node = Object::cast_to<Polygon2D>(p_polygon);
void PaintPolygon2DEditor::_set_node(Node *p_polygon) {
node = Object::cast_to<PaintPolygon2D>(p_polygon);
_update_polygon_editing_state();
}
Vector2 Polygon2DEditor::_get_offset(int p_idx) const {
Vector2 PaintPolygon2DEditor::_get_offset(int p_idx) const {
return node->get_offset();
}
int Polygon2DEditor::_get_polygon_count() const {
int PaintPolygon2DEditor::_get_polygon_count() const {
if (node->get_internal_vertex_count() > 0) {
return 0; //do not edit if internal vertices exist
} else {
@ -102,7 +104,7 @@ int Polygon2DEditor::_get_polygon_count() const {
}
}
void Polygon2DEditor::_notification(int p_what) {
void PaintPolygon2DEditor::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
@ -139,11 +141,11 @@ void Polygon2DEditor::_notification(int p_what) {
}
}
void Polygon2DEditor::_sync_bones() {
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 Polygon2D does not point to a Skeleton2D node"));
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());
@ -154,7 +156,7 @@ void Polygon2DEditor::_sync_bones() {
node->clear_bones();
if (!skeleton) {
error->set_text(TTR("The skeleton property of the Polygon2D does not point to a Skeleton2D node"));
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++) {
@ -195,7 +197,7 @@ void Polygon2DEditor::_sync_bones() {
#endif
}
void Polygon2DEditor::_update_bone_list() {
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));
@ -233,11 +235,11 @@ void Polygon2DEditor::_update_bone_list() {
uv_edit_draw->update();
}
void Polygon2DEditor::_bone_paint_selected(int p_index) {
void PaintPolygon2DEditor::_bone_paint_selected(int p_index) {
uv_edit_draw->update();
}
void Polygon2DEditor::_uv_edit_mode_select(int p_mode) {
void PaintPolygon2DEditor::_uv_edit_mode_select(int p_mode) {
if (p_mode == 0) { //uv
uv_button[UV_MODE_CREATE]->hide();
@ -307,13 +309,13 @@ void Polygon2DEditor::_uv_edit_mode_select(int p_mode) {
uv_edit_draw->update();
}
void Polygon2DEditor::_uv_edit_popup_hide() {
void PaintPolygon2DEditor::_uv_edit_popup_hide() {
EditorSettings::get_singleton()->set("interface/dialogs/uv_editor_bounds", uv_edit->get_rect());
_cancel_editing();
}
void Polygon2DEditor::_menu_option(int p_option) {
void PaintPolygon2DEditor::_menu_option(int p_option) {
switch (p_option) {
case MODE_EDIT_UV: {
if (node->get_texture().is_null()) {
@ -388,7 +390,7 @@ void Polygon2DEditor::_menu_option(int p_option) {
}
}
void Polygon2DEditor::_cancel_editing() {
void PaintPolygon2DEditor::_cancel_editing() {
if (uv_create) {
uv_drag = false;
uv_create = false;
@ -412,7 +414,7 @@ void Polygon2DEditor::_cancel_editing() {
polygon_create.clear();
}
void Polygon2DEditor::_update_polygon_editing_state() {
void PaintPolygon2DEditor::_update_polygon_editing_state() {
if (!_get_node()) {
return;
}
@ -424,7 +426,7 @@ void Polygon2DEditor::_update_polygon_editing_state() {
}
}
void Polygon2DEditor::_commit_action() {
void PaintPolygon2DEditor::_commit_action() {
// Makes that undo/redoing actions made outside of the UV editor still affect its polygon.
undo_redo->add_do_method(uv_edit_draw, "update");
undo_redo->add_undo_method(uv_edit_draw, "update");
@ -433,42 +435,42 @@ void Polygon2DEditor::_commit_action() {
undo_redo->commit_action();
}
void Polygon2DEditor::_set_use_snap(bool p_use) {
void PaintPolygon2DEditor::_set_use_snap(bool p_use) {
use_snap = p_use;
EditorSettings::get_singleton()->set_project_metadata("polygon_2d_uv_editor", "snap_enabled", p_use);
}
void Polygon2DEditor::_set_show_grid(bool p_show) {
void PaintPolygon2DEditor::_set_show_grid(bool p_show) {
snap_show_grid = p_show;
EditorSettings::get_singleton()->set_project_metadata("polygon_2d_uv_editor", "show_grid", p_show);
uv_edit_draw->update();
}
void Polygon2DEditor::_set_snap_off_x(float p_val) {
void PaintPolygon2DEditor::_set_snap_off_x(float p_val) {
snap_offset.x = p_val;
EditorSettings::get_singleton()->set_project_metadata("polygon_2d_uv_editor", "snap_offset", snap_offset);
uv_edit_draw->update();
}
void Polygon2DEditor::_set_snap_off_y(float p_val) {
void PaintPolygon2DEditor::_set_snap_off_y(float p_val) {
snap_offset.y = p_val;
EditorSettings::get_singleton()->set_project_metadata("polygon_2d_uv_editor", "snap_offset", snap_offset);
uv_edit_draw->update();
}
void Polygon2DEditor::_set_snap_step_x(float p_val) {
void PaintPolygon2DEditor::_set_snap_step_x(float p_val) {
snap_step.x = p_val;
EditorSettings::get_singleton()->set_project_metadata("polygon_2d_uv_editor", "snap_step", snap_step);
uv_edit_draw->update();
}
void Polygon2DEditor::_set_snap_step_y(float p_val) {
void PaintPolygon2DEditor::_set_snap_step_y(float p_val) {
snap_step.y = p_val;
EditorSettings::get_singleton()->set_project_metadata("polygon_2d_uv_editor", "snap_step", snap_step);
uv_edit_draw->update();
}
void Polygon2DEditor::_uv_mode(int p_mode) {
void PaintPolygon2DEditor::_uv_mode(int p_mode) {
polygon_create.clear();
uv_drag = false;
uv_create = false;
@ -479,7 +481,7 @@ void Polygon2DEditor::_uv_mode(int p_mode) {
}
}
void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
void PaintPolygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
if (!_get_node()) {
return;
}
@ -969,7 +971,7 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
}
}
void Polygon2DEditor::_uv_scroll_changed(float) {
void PaintPolygon2DEditor::_uv_scroll_changed(float) {
if (updating_uv_scroll) {
return;
}
@ -980,7 +982,7 @@ void Polygon2DEditor::_uv_scroll_changed(float) {
uv_edit_draw->update();
}
void Polygon2DEditor::_uv_draw() {
void PaintPolygon2DEditor::_uv_draw() {
if (!uv_edit->is_visible() || !_get_node()) {
return;
}
@ -1241,26 +1243,26 @@ void Polygon2DEditor::_uv_draw() {
updating_uv_scroll = false;
}
void Polygon2DEditor::_bind_methods() {
ClassDB::bind_method(D_METHOD("_uv_mode"), &Polygon2DEditor::_uv_mode);
ClassDB::bind_method(D_METHOD("_uv_draw"), &Polygon2DEditor::_uv_draw);
ClassDB::bind_method(D_METHOD("_uv_input"), &Polygon2DEditor::_uv_input);
ClassDB::bind_method(D_METHOD("_uv_scroll_changed"), &Polygon2DEditor::_uv_scroll_changed);
ClassDB::bind_method(D_METHOD("_set_use_snap"), &Polygon2DEditor::_set_use_snap);
ClassDB::bind_method(D_METHOD("_set_show_grid"), &Polygon2DEditor::_set_show_grid);
ClassDB::bind_method(D_METHOD("_set_snap_off_x"), &Polygon2DEditor::_set_snap_off_x);
ClassDB::bind_method(D_METHOD("_set_snap_off_y"), &Polygon2DEditor::_set_snap_off_y);
ClassDB::bind_method(D_METHOD("_set_snap_step_x"), &Polygon2DEditor::_set_snap_step_x);
ClassDB::bind_method(D_METHOD("_set_snap_step_y"), &Polygon2DEditor::_set_snap_step_y);
ClassDB::bind_method(D_METHOD("_uv_edit_mode_select"), &Polygon2DEditor::_uv_edit_mode_select);
ClassDB::bind_method(D_METHOD("_uv_edit_popup_hide"), &Polygon2DEditor::_uv_edit_popup_hide);
ClassDB::bind_method(D_METHOD("_sync_bones"), &Polygon2DEditor::_sync_bones);
ClassDB::bind_method(D_METHOD("_update_bone_list"), &Polygon2DEditor::_update_bone_list);
ClassDB::bind_method(D_METHOD("_update_polygon_editing_state"), &Polygon2DEditor::_update_polygon_editing_state);
ClassDB::bind_method(D_METHOD("_bone_paint_selected"), &Polygon2DEditor::_bone_paint_selected);
void PaintPolygon2DEditor::_bind_methods() {
ClassDB::bind_method(D_METHOD("_uv_mode"), &PaintPolygon2DEditor::_uv_mode);
ClassDB::bind_method(D_METHOD("_uv_draw"), &PaintPolygon2DEditor::_uv_draw);
ClassDB::bind_method(D_METHOD("_uv_input"), &PaintPolygon2DEditor::_uv_input);
ClassDB::bind_method(D_METHOD("_uv_scroll_changed"), &PaintPolygon2DEditor::_uv_scroll_changed);
ClassDB::bind_method(D_METHOD("_set_use_snap"), &PaintPolygon2DEditor::_set_use_snap);
ClassDB::bind_method(D_METHOD("_set_show_grid"), &PaintPolygon2DEditor::_set_show_grid);
ClassDB::bind_method(D_METHOD("_set_snap_off_x"), &PaintPolygon2DEditor::_set_snap_off_x);
ClassDB::bind_method(D_METHOD("_set_snap_off_y"), &PaintPolygon2DEditor::_set_snap_off_y);
ClassDB::bind_method(D_METHOD("_set_snap_step_x"), &PaintPolygon2DEditor::_set_snap_step_x);
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 Polygon2DEditor::snap_point(Vector2 p_target) const {
Vector2 PaintPolygon2DEditor::snap_point(Vector2 p_target) const {
if (use_snap) {
p_target.x = Math::snap_scalar(snap_offset.x * uv_draw_zoom - uv_draw_ofs.x, snap_step.x * uv_draw_zoom, p_target.x);
p_target.y = Math::snap_scalar(snap_offset.y * uv_draw_zoom - uv_draw_ofs.y, snap_step.y * uv_draw_zoom, p_target.y);
@ -1269,7 +1271,7 @@ Vector2 Polygon2DEditor::snap_point(Vector2 p_target) const {
return p_target;
}
Polygon2DEditor::Polygon2DEditor(EditorNode *p_editor) :
PaintPolygon2DEditor::PaintPolygon2DEditor(EditorNode *p_editor) :
AbstractPolygon2DEditor(p_editor) {
node = nullptr;
snap_offset = EditorSettings::get_singleton()->get_project_metadata("polygon_2d_uv_editor", "snap_offset", Vector2());
@ -1526,6 +1528,6 @@ Polygon2DEditor::Polygon2DEditor(EditorNode *p_editor) :
uv_edit_draw->set_clip_contents(true);
}
Polygon2DEditorPlugin::Polygon2DEditorPlugin(EditorNode *p_node) :
AbstractPolygon2DEditorPlugin(p_node, memnew(Polygon2DEditor(p_node)), "Polygon2D") {
PaintPolygon2DEditorPlugin::PaintPolygon2DEditorPlugin(EditorNode *p_node) :
AbstractPolygon2DEditorPlugin(p_node, memnew(PaintPolygon2DEditor(p_node)), "PaintPolygon2D") {
}

View File

@ -1,5 +1,6 @@
#ifndef POLYGON_2D_EDITOR_PLUGIN_H
#define POLYGON_2D_EDITOR_PLUGIN_H
#ifndef PAINT_POLYGON_2D_EDITOR_PLUGIN_H
#define PAINT_POLYGON_2D_EDITOR_PLUGIN_H
/*************************************************************************/
/* polygon_2d_editor_plugin.h */
/*************************************************************************/
@ -51,16 +52,17 @@ class MenuButton;
class Node2D;
class Node;
class Panel;
class Polygon2D;
class PaintPolygon2D;
class ScrollContainer;
class SpinBox;
class TextureRect;
class ToolButton;
class VBoxContainer;
class VScrollBar;
class PaintPolygon2D;
class Polygon2DEditor : public AbstractPolygon2DEditor {
GDCLASS(Polygon2DEditor, AbstractPolygon2DEditor);
class PaintPolygon2DEditor : public AbstractPolygon2DEditor {
GDCLASS(PaintPolygon2DEditor, AbstractPolygon2DEditor);
enum Mode {
MODE_EDIT_UV = MODE_CONT,
@ -88,7 +90,7 @@ class Polygon2DEditor : public AbstractPolygon2DEditor {
ToolButton *uv_edit_mode[4];
Ref<ButtonGroup> uv_edit_group;
Polygon2D *node;
PaintPolygon2D *node;
UVMode uv_mode;
AcceptDialog *uv_edit;
@ -185,14 +187,14 @@ protected:
Vector2 snap_point(Vector2 p_target) const;
public:
Polygon2DEditor(EditorNode *p_editor);
PaintPolygon2DEditor(EditorNode *p_editor);
};
class Polygon2DEditorPlugin : public AbstractPolygon2DEditorPlugin {
GDCLASS(Polygon2DEditorPlugin, AbstractPolygon2DEditorPlugin);
class PaintPolygon2DEditorPlugin : public AbstractPolygon2DEditorPlugin {
GDCLASS(PaintPolygon2DEditorPlugin, AbstractPolygon2DEditorPlugin);
public:
Polygon2DEditorPlugin(EditorNode *p_node);
PaintPolygon2DEditorPlugin(EditorNode *p_node);
};
#endif // POLYGON_2D_EDITOR_PLUGIN_H

View File

@ -28,7 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "polygon_2d.h"
#include "paint_polygon_2d.h"
#include "core/math/geometry.h"
@ -39,31 +39,31 @@
#endif
#ifdef TOOLS_ENABLED
Dictionary Polygon2D::_edit_get_state() const {
Dictionary PaintPolygon2D::_edit_get_state() const {
Dictionary state = Node2D::_edit_get_state();
state["offset"] = offset;
return state;
}
void Polygon2D::_edit_set_state(const Dictionary &p_state) {
void PaintPolygon2D::_edit_set_state(const Dictionary &p_state) {
Node2D::_edit_set_state(p_state);
set_offset(p_state["offset"]);
}
void Polygon2D::_edit_set_pivot(const Point2 &p_pivot) {
void PaintPolygon2D::_edit_set_pivot(const Point2 &p_pivot) {
set_position(get_transform().xform(p_pivot));
set_offset(get_offset() - p_pivot);
}
Point2 Polygon2D::_edit_get_pivot() const {
Point2 PaintPolygon2D::_edit_get_pivot() const {
return Vector2();
}
bool Polygon2D::_edit_use_pivot() const {
bool PaintPolygon2D::_edit_use_pivot() const {
return true;
}
Rect2 Polygon2D::_edit_get_rect() const {
Rect2 PaintPolygon2D::_edit_get_rect() const {
if (rect_cache_dirty) {
int l = polygon.size();
PoolVector<Vector2>::Read r = polygon.read();
@ -82,11 +82,11 @@ Rect2 Polygon2D::_edit_get_rect() const {
return item_rect;
}
bool Polygon2D::_edit_use_rect() const {
bool PaintPolygon2D::_edit_use_rect() const {
return polygon.size() > 0;
}
bool Polygon2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {
bool PaintPolygon2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {
Vector<Vector2> polygon2d = Variant(polygon);
if (internal_vertices > 0) {
polygon2d.resize(polygon2d.size() - internal_vertices);
@ -95,11 +95,11 @@ bool Polygon2D::_edit_is_selected_on_click(const Point2 &p_point, double p_toler
}
#endif
void Polygon2D::_skeleton_bone_setup_changed() {
void PaintPolygon2D::_skeleton_bone_setup_changed() {
update();
}
void Polygon2D::_notification(int p_what) {
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.
@ -107,7 +107,7 @@ void Polygon2D::_notification(int p_what) {
} break;
case NOTIFICATION_EXIT_TREE: {
// Always detach skeleton when exiting the tree, so skeletons don't inform
// Polygon2Ds outside the tree that they have moved (this would be useless work).
// 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: {
@ -127,7 +127,7 @@ void Polygon2D::_notification(int p_what) {
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 Polygon2D and the skeleton.
// 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();
@ -376,59 +376,59 @@ void Polygon2D::_notification(int p_what) {
}
}
void Polygon2D::set_polygon(const PoolVector<Vector2> &p_polygon) {
void PaintPolygon2D::set_polygon(const PoolVector<Vector2> &p_polygon) {
polygon = p_polygon;
rect_cache_dirty = true;
update();
}
PoolVector<Vector2> Polygon2D::get_polygon() const {
PoolVector<Vector2> PaintPolygon2D::get_polygon() const {
return polygon;
}
void Polygon2D::set_internal_vertex_count(int p_count) {
void PaintPolygon2D::set_internal_vertex_count(int p_count) {
internal_vertices = p_count;
}
int Polygon2D::get_internal_vertex_count() const {
int PaintPolygon2D::get_internal_vertex_count() const {
return internal_vertices;
}
void Polygon2D::set_uv(const PoolVector<Vector2> &p_uv) {
void PaintPolygon2D::set_uv(const PoolVector<Vector2> &p_uv) {
uv = p_uv;
update();
}
PoolVector<Vector2> Polygon2D::get_uv() const {
PoolVector<Vector2> PaintPolygon2D::get_uv() const {
return uv;
}
void Polygon2D::set_polygons(const Array &p_polygons) {
void PaintPolygon2D::set_polygons(const Array &p_polygons) {
polygons = p_polygons;
update();
}
Array Polygon2D::get_polygons() const {
Array PaintPolygon2D::get_polygons() const {
return polygons;
}
void Polygon2D::set_color(const Color &p_color) {
void PaintPolygon2D::set_color(const Color &p_color) {
color = p_color;
update();
}
Color Polygon2D::get_color() const {
Color PaintPolygon2D::get_color() const {
return color;
}
void Polygon2D::set_vertex_colors(const PoolVector<Color> &p_colors) {
void PaintPolygon2D::set_vertex_colors(const PoolVector<Color> &p_colors) {
vertex_colors = p_colors;
update();
}
PoolVector<Color> Polygon2D::get_vertex_colors() const {
PoolVector<Color> PaintPolygon2D::get_vertex_colors() const {
return vertex_colors;
}
void Polygon2D::set_texture(const Ref<Texture> &p_texture) {
void PaintPolygon2D::set_texture(const Ref<Texture> &p_texture) {
texture = p_texture;
/*if (texture.is_valid()) {
@ -441,124 +441,124 @@ void Polygon2D::set_texture(const Ref<Texture> &p_texture) {
}*/
update();
}
Ref<Texture> Polygon2D::get_texture() const {
Ref<Texture> PaintPolygon2D::get_texture() const {
return texture;
}
void Polygon2D::set_texture_offset(const Vector2 &p_offset) {
void PaintPolygon2D::set_texture_offset(const Vector2 &p_offset) {
tex_ofs = p_offset;
update();
}
Vector2 Polygon2D::get_texture_offset() const {
Vector2 PaintPolygon2D::get_texture_offset() const {
return tex_ofs;
}
void Polygon2D::set_texture_rotation(float p_rot) {
void PaintPolygon2D::set_texture_rotation(float p_rot) {
tex_rot = p_rot;
update();
}
float Polygon2D::get_texture_rotation() const {
float PaintPolygon2D::get_texture_rotation() const {
return tex_rot;
}
void Polygon2D::set_texture_rotation_degrees(float p_rot) {
void PaintPolygon2D::set_texture_rotation_degrees(float p_rot) {
set_texture_rotation(Math::deg2rad(p_rot));
}
float Polygon2D::get_texture_rotation_degrees() const {
float PaintPolygon2D::get_texture_rotation_degrees() const {
return Math::rad2deg(get_texture_rotation());
}
void Polygon2D::set_texture_scale(const Size2 &p_scale) {
void PaintPolygon2D::set_texture_scale(const Size2 &p_scale) {
tex_scale = p_scale;
update();
}
Size2 Polygon2D::get_texture_scale() const {
Size2 PaintPolygon2D::get_texture_scale() const {
return tex_scale;
}
void Polygon2D::set_invert(bool p_invert) {
void PaintPolygon2D::set_invert(bool p_invert) {
invert = p_invert;
update();
}
bool Polygon2D::get_invert() const {
bool PaintPolygon2D::get_invert() const {
return invert;
}
void Polygon2D::set_antialiased(bool p_antialiased) {
void PaintPolygon2D::set_antialiased(bool p_antialiased) {
antialiased = p_antialiased;
update();
}
bool Polygon2D::get_antialiased() const {
bool PaintPolygon2D::get_antialiased() const {
return antialiased;
}
void Polygon2D::set_invert_border(float p_invert_border) {
void PaintPolygon2D::set_invert_border(float p_invert_border) {
invert_border = p_invert_border;
update();
}
float Polygon2D::get_invert_border() const {
float PaintPolygon2D::get_invert_border() const {
return invert_border;
}
void Polygon2D::set_offset(const Vector2 &p_offset) {
void PaintPolygon2D::set_offset(const Vector2 &p_offset) {
offset = p_offset;
rect_cache_dirty = true;
update();
_change_notify("offset");
}
Vector2 Polygon2D::get_offset() const {
Vector2 PaintPolygon2D::get_offset() const {
return offset;
}
void Polygon2D::add_bone(const NodePath &p_path, const PoolVector<float> &p_weights) {
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 Polygon2D::get_bone_count() const {
int PaintPolygon2D::get_bone_count() const {
return bone_weights.size();
}
NodePath Polygon2D::get_bone_path(int p_index) const {
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> Polygon2D::get_bone_weights(int p_index) const {
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 Polygon2D::erase_bone(int p_idx) {
void PaintPolygon2D::erase_bone(int p_idx) {
ERR_FAIL_INDEX(p_idx, bone_weights.size());
bone_weights.remove(p_idx);
}
void Polygon2D::clear_bones() {
void PaintPolygon2D::clear_bones() {
bone_weights.clear();
}
void Polygon2D::set_bone_weights(int p_index, const PoolVector<float> &p_weights) {
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 Polygon2D::set_bone_path(int p_index, const NodePath &p_path) {
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 Polygon2D::_get_bones() const {
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 Polygon2D.
// 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 Polygon2D::_set_bones(const Array &p_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) {
@ -567,7 +567,7 @@ void Polygon2D::_set_bones(const Array &p_bones) {
}
}
void Polygon2D::set_skeleton(const NodePath &p_skeleton) {
void PaintPolygon2D::set_skeleton(const NodePath &p_skeleton) {
if (skeleton == p_skeleton) {
return;
}
@ -575,72 +575,72 @@ void Polygon2D::set_skeleton(const NodePath &p_skeleton) {
update();
}
NodePath Polygon2D::get_skeleton() const {
NodePath PaintPolygon2D::get_skeleton() const {
return skeleton;
}
void Polygon2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_polygon", "polygon"), &Polygon2D::set_polygon);
ClassDB::bind_method(D_METHOD("get_polygon"), &Polygon2D::get_polygon);
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);
ClassDB::bind_method(D_METHOD("set_uv", "uv"), &Polygon2D::set_uv);
ClassDB::bind_method(D_METHOD("get_uv"), &Polygon2D::get_uv);
ClassDB::bind_method(D_METHOD("set_uv", "uv"), &PaintPolygon2D::set_uv);
ClassDB::bind_method(D_METHOD("get_uv"), &PaintPolygon2D::get_uv);
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("set_color", "color"), &PaintPolygon2D::set_color);
ClassDB::bind_method(D_METHOD("get_color"), &PaintPolygon2D::get_color);
ClassDB::bind_method(D_METHOD("set_polygons", "polygons"), &Polygon2D::set_polygons);
ClassDB::bind_method(D_METHOD("get_polygons"), &Polygon2D::get_polygons);
ClassDB::bind_method(D_METHOD("set_polygons", "polygons"), &PaintPolygon2D::set_polygons);
ClassDB::bind_method(D_METHOD("get_polygons"), &PaintPolygon2D::get_polygons);
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("set_vertex_colors", "vertex_colors"), &PaintPolygon2D::set_vertex_colors);
ClassDB::bind_method(D_METHOD("get_vertex_colors"), &PaintPolygon2D::get_vertex_colors);
ClassDB::bind_method(D_METHOD("set_texture", "texture"), &Polygon2D::set_texture);
ClassDB::bind_method(D_METHOD("get_texture"), &Polygon2D::get_texture);
ClassDB::bind_method(D_METHOD("set_texture", "texture"), &PaintPolygon2D::set_texture);
ClassDB::bind_method(D_METHOD("get_texture"), &PaintPolygon2D::get_texture);
ClassDB::bind_method(D_METHOD("set_texture_offset", "texture_offset"), &Polygon2D::set_texture_offset);
ClassDB::bind_method(D_METHOD("get_texture_offset"), &Polygon2D::get_texture_offset);
ClassDB::bind_method(D_METHOD("set_texture_offset", "texture_offset"), &PaintPolygon2D::set_texture_offset);
ClassDB::bind_method(D_METHOD("get_texture_offset"), &PaintPolygon2D::get_texture_offset);
ClassDB::bind_method(D_METHOD("set_texture_rotation", "texture_rotation"), &Polygon2D::set_texture_rotation);
ClassDB::bind_method(D_METHOD("get_texture_rotation"), &Polygon2D::get_texture_rotation);
ClassDB::bind_method(D_METHOD("set_texture_rotation", "texture_rotation"), &PaintPolygon2D::set_texture_rotation);
ClassDB::bind_method(D_METHOD("get_texture_rotation"), &PaintPolygon2D::get_texture_rotation);
ClassDB::bind_method(D_METHOD("set_texture_rotation_degrees", "texture_rotation"), &Polygon2D::set_texture_rotation_degrees);
ClassDB::bind_method(D_METHOD("get_texture_rotation_degrees"), &Polygon2D::get_texture_rotation_degrees);
ClassDB::bind_method(D_METHOD("set_texture_rotation_degrees", "texture_rotation"), &PaintPolygon2D::set_texture_rotation_degrees);
ClassDB::bind_method(D_METHOD("get_texture_rotation_degrees"), &PaintPolygon2D::get_texture_rotation_degrees);
ClassDB::bind_method(D_METHOD("set_texture_scale", "texture_scale"), &Polygon2D::set_texture_scale);
ClassDB::bind_method(D_METHOD("get_texture_scale"), &Polygon2D::get_texture_scale);
ClassDB::bind_method(D_METHOD("set_texture_scale", "texture_scale"), &PaintPolygon2D::set_texture_scale);
ClassDB::bind_method(D_METHOD("get_texture_scale"), &PaintPolygon2D::get_texture_scale);
ClassDB::bind_method(D_METHOD("set_invert", "invert"), &Polygon2D::set_invert);
ClassDB::bind_method(D_METHOD("get_invert"), &Polygon2D::get_invert);
ClassDB::bind_method(D_METHOD("set_invert", "invert"), &PaintPolygon2D::set_invert);
ClassDB::bind_method(D_METHOD("get_invert"), &PaintPolygon2D::get_invert);
ClassDB::bind_method(D_METHOD("set_antialiased", "antialiased"), &Polygon2D::set_antialiased);
ClassDB::bind_method(D_METHOD("get_antialiased"), &Polygon2D::get_antialiased);
ClassDB::bind_method(D_METHOD("set_antialiased", "antialiased"), &PaintPolygon2D::set_antialiased);
ClassDB::bind_method(D_METHOD("get_antialiased"), &PaintPolygon2D::get_antialiased);
ClassDB::bind_method(D_METHOD("set_invert_border", "invert_border"), &Polygon2D::set_invert_border);
ClassDB::bind_method(D_METHOD("get_invert_border"), &Polygon2D::get_invert_border);
ClassDB::bind_method(D_METHOD("set_invert_border", "invert_border"), &PaintPolygon2D::set_invert_border);
ClassDB::bind_method(D_METHOD("get_invert_border"), &PaintPolygon2D::get_invert_border);
ClassDB::bind_method(D_METHOD("set_offset", "offset"), &Polygon2D::set_offset);
ClassDB::bind_method(D_METHOD("get_offset"), &Polygon2D::get_offset);
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"), &Polygon2D::add_bone);
ClassDB::bind_method(D_METHOD("get_bone_count"), &Polygon2D::get_bone_count);
ClassDB::bind_method(D_METHOD("get_bone_path", "index"), &Polygon2D::get_bone_path);
ClassDB::bind_method(D_METHOD("get_bone_weights", "index"), &Polygon2D::get_bone_weights);
ClassDB::bind_method(D_METHOD("erase_bone", "index"), &Polygon2D::erase_bone);
ClassDB::bind_method(D_METHOD("clear_bones"), &Polygon2D::clear_bones);
ClassDB::bind_method(D_METHOD("set_bone_path", "index", "path"), &Polygon2D::set_bone_path);
ClassDB::bind_method(D_METHOD("set_bone_weights", "index", "weights"), &Polygon2D::set_bone_weights);
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"), &Polygon2D::set_skeleton);
ClassDB::bind_method(D_METHOD("get_skeleton"), &Polygon2D::get_skeleton);
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"), &Polygon2D::set_internal_vertex_count);
ClassDB::bind_method(D_METHOD("get_internal_vertex_count"), &Polygon2D::get_internal_vertex_count);
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"), &Polygon2D::_set_bones);
ClassDB::bind_method(D_METHOD("_get_bones"), &Polygon2D::_get_bones);
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"), &Polygon2D::_skeleton_bone_setup_changed);
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");
@ -668,7 +668,7 @@ void Polygon2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "internal_vertex_count", PROPERTY_HINT_RANGE, "0,1000"), "set_internal_vertex_count", "get_internal_vertex_count");
}
Polygon2D::Polygon2D() {
PaintPolygon2D::PaintPolygon2D() {
invert = false;
invert_border = 100;
antialiased = false;
@ -681,7 +681,7 @@ Polygon2D::Polygon2D() {
current_skeleton_id = 0;
}
Polygon2D::~Polygon2D() {
PaintPolygon2D::~PaintPolygon2D() {
// Most definitely don't want to leave references to this deleted canvas item
// in the skeleton.
if (get_canvas_item().is_valid()) {

View File

@ -1,5 +1,5 @@
#ifndef POLYGON_2D_H
#define POLYGON_2D_H
#ifndef PAINT_POLYGON_2D_H
#define PAINT_POLYGON_2D_H
/*************************************************************************/
/* polygon_2d.h */
@ -31,10 +31,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "scene/2d/node_2d.h"
#include "../paint_node.h"
class Polygon2D : public Node2D {
GDCLASS(Polygon2D, Node2D);
class PaintPolygon2D : public PaintNode {
GDCLASS(PaintPolygon2D, PaintNode);
PoolVector<Vector2> polygon;
PoolVector<Vector2> uv;
@ -146,8 +146,8 @@ public:
void set_skeleton(const NodePath &p_skeleton);
NodePath get_skeleton() const;
Polygon2D();
virtual ~Polygon2D();
PaintPolygon2D();
virtual ~PaintPolygon2D();
};
#endif // POLYGON_2D_H

View File

@ -48,8 +48,13 @@ SOFTWARE.
#include "nodes/paint_node.h"
#include "nodes/paint_project.h"
#include "nodes/curve_2d/paint_curve_2d.h"
#include "nodes/polygon_2d/paint_polygon_2d.h"
#ifdef TOOLS_ENABLED
#include "editor/paint_editor_plugin.h"
#include "nodes/curve_2d/editor/paint_curve_2d_editor_plugin.h"
#include "nodes/polygon_2d/editor/paint_polygon_2d_editor_plugin.h"
#endif
void register_paint_types(ModuleRegistrationLevel p_level) {
@ -79,11 +84,16 @@ void register_paint_types(ModuleRegistrationLevel p_level) {
ClassDB::register_class<PaintNode>();
ClassDB::register_class<PaintCanvas>();
ClassDB::register_class<PaintProject>();
ClassDB::register_class<PaintCurve2D>();
ClassDB::register_class<PaintPolygon2D>();
}
#ifdef TOOLS_ENABLED
if (p_level == MODULE_REGISTRATION_LEVEL_EDITOR) {
EditorPlugins::add_by_type<PaintEditorPlugin>();
EditorPlugins::add_by_type<PaintPolygon2DEditorPlugin>();
EditorPlugins::add_by_type<PaintCurve2DEditorPlugin>();
}
#endif
}