Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add closed property to Line2D #79182

Merged
merged 1 commit into from
Sep 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions doc/classes/Line2D.xml
Original file line number Diff line number Diff line change
Expand Up @@ -63,16 +63,21 @@
[b]Note:[/b] [Line2D] is not accelerated by batching when being anti-aliased.
</member>
<member name="begin_cap_mode" type="int" setter="set_begin_cap_mode" getter="get_begin_cap_mode" enum="Line2D.LineCapMode" default="0">
The style of the beginning of the polyline. Use [enum LineCapMode] constants.
The style of the beginning of the polyline, if [member closed] is [code]false[/code]. Use [enum LineCapMode] constants.
</member>
<member name="closed" type="bool" setter="set_closed" getter="is_closed" default="false">
If [code]true[/code] and the polyline has more than 2 points, the last point and the first one will be connected by a segment.
[b]Note:[/b] The shape of the closing segment is not guaranteed to be seamless if a [member width_curve] is provided.
[b]Note:[/b] The joint between the closing segment and the first segment is drawn first and it samples the [member gradient] and the [member width_curve] at the beginning. This is an implementation detail that might change in a future version.
</member>
<member name="default_color" type="Color" setter="set_default_color" getter="get_default_color" default="Color(1, 1, 1, 1)">
The color of the polyline. Will not be used if a gradient is set.
</member>
<member name="end_cap_mode" type="int" setter="set_end_cap_mode" getter="get_end_cap_mode" enum="Line2D.LineCapMode" default="0">
The style of the end of the polyline. Use [enum LineCapMode] constants.
The style of the end of the polyline, if [member closed] is [code]false[/code]. Use [enum LineCapMode] constants.
</member>
<member name="gradient" type="Gradient" setter="set_gradient" getter="get_gradient">
The gradient is drawn through the whole line from start to finish. The default color will not be used if a gradient is set.
The gradient is drawn through the whole line from start to finish. The [member default_color] will not be used if this property is set.
</member>
<member name="joint_mode" type="int" setter="set_joint_mode" getter="get_joint_mode" enum="Line2D.LineJointMode" default="0">
The style of the connections between segments of the polyline. Use [enum LineJointMode] constants.
Expand All @@ -93,7 +98,7 @@
The style to render the [member texture] of the polyline. Use [enum LineTextureMode] constants.
</member>
<member name="width" type="float" setter="set_width" getter="get_width" default="10.0">
The polyline's width
The polyline's width.
</member>
<member name="width_curve" type="Curve" setter="set_curve" getter="get_curve">
The polyline's width curve. The width of the polyline over its length will be equivalent to the value of the width curve over its domain.
Expand Down
63 changes: 33 additions & 30 deletions scene/2d/line_2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,12 @@ Rect2 Line2D::_edit_get_rect() const {
return Rect2(0, 0, 0, 0);
}
Vector2 d = Vector2(_width, _width);
Rect2 aabb = Rect2(_points[0] - d, 2 * d);
Rect2 bounding_rect = Rect2(_points[0] - d, 2 * d);
kleonc marked this conversation as resolved.
Show resolved Hide resolved
for (int i = 1; i < _points.size(); i++) {
aabb.expand_to(_points[i] - d);
aabb.expand_to(_points[i] + d);
bounding_rect.expand_to(_points[i] - d);
bounding_rect.expand_to(_points[i] + d);
}
return aabb;
return bounding_rect;
}

bool Line2D::_edit_use_rect() const {
Expand All @@ -59,7 +59,14 @@ bool Line2D::_edit_is_selected_on_click(const Point2 &p_point, double p_toleranc
const Vector2 *points = _points.ptr();
for (int i = 0; i < _points.size() - 1; i++) {
Vector2 p = Geometry2D::get_closest_point_to_segment(p_point, &points[i]);
if (p.distance_to(p_point) <= d) {
if (p_point.distance_to(p) <= d) {
return true;
}
}
if (_closed && _points.size() > 2) {
const Vector2 closing_segment[2] = { points[0], points[_points.size() - 1] };
Vector2 p = Geometry2D::get_closest_point_to_segment(p_point, closing_segment);
if (p_point.distance_to(p) <= d) {
return true;
}
}
Expand All @@ -73,6 +80,15 @@ void Line2D::set_points(const Vector<Vector2> &p_points) {
queue_redraw();
}

void Line2D::set_closed(bool p_closed) {
_closed = p_closed;
queue_redraw();
}

bool Line2D::is_closed() const {
return _closed;
}

void Line2D::set_width(float p_width) {
if (p_width < 0.0) {
p_width = 0.0;
Expand All @@ -86,14 +102,12 @@ float Line2D::get_width() const {
}

void Line2D::set_curve(const Ref<Curve> &p_curve) {
// Cleanup previous connection if any
if (_curve.is_valid()) {
_curve->disconnect_changed(callable_mp(this, &Line2D::_curve_changed));
}

_curve = p_curve;

// Connect to the curve so the line will update when it is changed
if (_curve.is_valid()) {
_curve->connect_changed(callable_mp(this, &Line2D::_curve_changed));
}
Expand Down Expand Up @@ -156,14 +170,12 @@ Color Line2D::get_default_color() const {
}

void Line2D::set_gradient(const Ref<Gradient> &p_gradient) {
// Cleanup previous connection if any
if (_gradient.is_valid()) {
_gradient->disconnect_changed(callable_mp(this, &Line2D::_gradient_changed));
}

_gradient = p_gradient;

// Connect to the gradient so the line will update when the Gradient is changed
if (_gradient.is_valid()) {
_gradient->connect_changed(callable_mp(this, &Line2D::_gradient_changed));
}
Expand Down Expand Up @@ -264,20 +276,10 @@ void Line2D::_draw() {
return;
}

// TODO Is this really needed?
// Copy points for faster access
Vector<Vector2> points;
points.resize(len);
{
const Vector2 *points_read = _points.ptr();
for (int i = 0; i < len; ++i) {
points.write[i] = points_read[i];
}
}

// TODO Maybe have it as member rather than copying parameters and allocating memory?
LineBuilder lb;
lb.points = points;
lb.points = _points;
lb.closed = _closed;
lb.default_color = _default_color;
lb.gradient = *_gradient;
lb.texture_mode = _texture_mode;
Expand Down Expand Up @@ -306,23 +308,20 @@ void Line2D::_draw() {
lb.uvs, Vector<int>(), Vector<float>(),
texture_rid);

// DEBUG
// Draw wireframe
// if(lb.indices.size() % 3 == 0) {
// Color col(0,0,0);
// for(int i = 0; i < lb.indices.size(); i += 3) {
// int vi = lb.indices[i];
// int lbvsize = lb.vertices.size();
// DEBUG: Draw wireframe
// if (lb.indices.size() % 3 == 0) {
// Color col(0, 0, 0);
// for (int i = 0; i < lb.indices.size(); i += 3) {
// Vector2 a = lb.vertices[lb.indices[i]];
// Vector2 b = lb.vertices[lb.indices[i+1]];
// Vector2 c = lb.vertices[lb.indices[i+2]];
// draw_line(a, b, col);
// draw_line(b, c, col);
// draw_line(c, a, col);
// }
// for(int i = 0; i < lb.vertices.size(); ++i) {
// for (int i = 0; i < lb.vertices.size(); ++i) {
// Vector2 p = lb.vertices[i];
// draw_rect(Rect2(p.x-1, p.y-1, 2, 2), Color(0,0,0,0.5));
// draw_rect(Rect2(p.x - 1, p.y - 1, 2, 2), Color(0, 0, 0, 0.5));
// }
// }
}
Expand Down Expand Up @@ -350,6 +349,9 @@ void Line2D::_bind_methods() {

ClassDB::bind_method(D_METHOD("clear_points"), &Line2D::clear_points);

ClassDB::bind_method(D_METHOD("set_closed", "closed"), &Line2D::set_closed);
ClassDB::bind_method(D_METHOD("is_closed"), &Line2D::is_closed);

ClassDB::bind_method(D_METHOD("set_width", "width"), &Line2D::set_width);
ClassDB::bind_method(D_METHOD("get_width"), &Line2D::get_width);

Expand Down Expand Up @@ -387,6 +389,7 @@ void Line2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_antialiased"), &Line2D::get_antialiased);

ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR2_ARRAY, "points"), "set_points", "get_points");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "closed"), "set_closed", "is_closed");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "width", PROPERTY_HINT_NONE, "suffix:px"), "set_width", "get_width");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "width_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_curve", "get_curve");
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "default_color"), "set_default_color", "get_default_color");
Expand Down
4 changes: 4 additions & 0 deletions scene/2d/line_2d.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ class Line2D : public Node2D {
void add_point(Vector2 pos, int atpos = -1);
void remove_point(int i);

void set_closed(bool p_closed);
bool is_closed() const;

void set_width(float width);
float get_width() const;

Expand Down Expand Up @@ -127,6 +130,7 @@ class Line2D : public Node2D {
LineJointMode _joint_mode = LINE_JOINT_SHARP;
LineCapMode _begin_cap_mode = LINE_CAP_NONE;
LineCapMode _end_cap_mode = LINE_CAP_NONE;
bool _closed = false;
float _width = 10.0;
Ref<Curve> _curve;
Color _default_color = Color(1, 1, 1);
Expand Down
Loading