Skip to content

Commit

Permalink
some improvments to line2d from godot4 upstream
Browse files Browse the repository at this point in the history
  • Loading branch information
ppiecuch committed Oct 16, 2023
1 parent 15c1306 commit 03c8509
Show file tree
Hide file tree
Showing 8 changed files with 237 additions and 266 deletions.
7 changes: 5 additions & 2 deletions core/math/vector2.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ struct _NO_DISCARD_CLASS_ Vector2 {

_FORCE_INLINE_ static Vector2 linear_interpolate(const Vector2 &p_a, const Vector2 &p_b, real_t p_weight);
_FORCE_INLINE_ Vector2 linear_interpolate(const Vector2 &p_to, real_t p_weight) const;
_FORCE_INLINE_ Vector2 lerp(const Vector2 &p_to, real_t p_weight) const { return linear_interpolate(p_to, p_weight); }
_FORCE_INLINE_ Vector2 slerp(const Vector2 &p_to, real_t p_weight) const;
Vector2 cubic_interpolate(const Vector2 &p_b, const Vector2 &p_pre_a, const Vector2 &p_post_b, real_t p_weight) const;
Vector2 move_toward(const Vector2 &p_to, const real_t p_delta) const;
Expand Down Expand Up @@ -178,10 +179,12 @@ struct _NO_DISCARD_CLASS_ Vector2 {

Vector2 rotated_around(const Vector2 &p_origin, real_t p_radians) const;
Vector2 rotated(real_t p_by) const;
Vector2 tangent() const {
_FORCE_INLINE_ Vector2 orthogonal() const {
return Vector2(y, -x);
}

_FORCE_INLINE_ Vector2 tangent() const {
return orthogonal();
}
Vector2 sign() const;
Vector2 floor() const;
Vector2 ceil() const;
Expand Down
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] Due to how it works, built-in antialiasing will not look correct for translucent lines and may not work on certain platforms. As a workaround, install the [url=https://github.com/godot-extended-libraries/godot-antialiased-line2d]Antialiased Line2D[/url] add-on then create an AntialiasedLine2D node. That node relies on a texture with custom mipmaps to perform antialiasing. 2D batching is also still supported with those antialiased lines.
</member>
<member name="begin_cap_mode" type="int" setter="set_begin_cap_mode" getter="get_begin_cap_mode" enum="Line2D.LineCapMode" default="0">
Controls the style of the line's first point. 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.
</member>
<member name="default_color" type="Color" setter="set_default_color" getter="get_default_color" default="Color( 0.4, 0.5, 1, 1 )">
The line's color. 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">
Controls the style of the line's last point. 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 for the points between the start and the end.
Expand All @@ -94,7 +99,7 @@
The style to render the [code]texture[/code] on the line. Use [enum LineTextureMode] constants.
</member>
<member name="width" type="float" setter="set_width" getter="get_width" default="10.0">
The line's width.
The polyline's width.
</member>
<member name="width_curve" type="Curve" setter="set_curve" getter="get_curve">
The line's width varies with the curve. The original width is simply multiply by the value of the Curve.
Expand Down
8 changes: 8 additions & 0 deletions modules/gdextensions/common/gd_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,14 @@
#define nullref(pClass) Ref<pClass>()
#define selfref(pClass) Ref<pClass>(this)

#define copyarray(fr, to) \
{ \
to.resize(fr.size()); \
for (int i = 0; i < fr.size(); ++i) { \
to.set(i, fr[i]); \
} \
}

String string_ellipsis(const Ref<Font> &p_font, const String &p_text, real_t p_max_width);
String string_format(const char *p_format, ...);
String string_format(const char *p_format, va_list p_list);
Expand Down
75 changes: 40 additions & 35 deletions scene/2d/line_2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ Line2D::Line2D() {
_joint_mode = LINE_JOINT_SHARP;
_begin_cap_mode = LINE_CAP_NONE;
_end_cap_mode = LINE_CAP_NONE;
_closed = false;
_width = 10;
_default_color = Color(0.4, 0.5, 1);
_texture_mode = LINE_TEXTURE_NONE;
Expand All @@ -57,12 +58,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);
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 @@ -74,41 +75,58 @@ bool Line2D::_edit_is_selected_on_click(const Point2 &p_point, double p_toleranc
PoolVector<Vector2>::Read points = _points.read();
for (int i = 0; i < _points.size() - 1; i++) {
Vector2 p = Geometry::get_closest_point_to_segment_2d(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 = Geometry::get_closest_point_to_segment_2d(p_point, closing_segment);
if (p_point.distance_to(p) <= d) {
return true;
}
}

return false;
}
#endif
#endif // TOOLS_ENABLED

void Line2D::set_points(const PoolVector<Vector2> &p_points) {
_points = p_points;
update();
}

void Line2D::set_closed(bool p_closed) {
if (_closed != p_closed) {
_closed = p_closed;
update();
}
}

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

void Line2D::set_width(float p_width) {
if (p_width < 0.0) {
p_width = 0.0;
if (p_width < 0) {
p_width = 0;
}
if (_width != p_width) {
_width = p_width;
update();
}
_width = p_width;
update();
}

float Line2D::get_width() const {
return _width;
}

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

_curve = p_curve;

// Connect to the curve so the line will update when it is changed
if (_curve.is_valid()) {
_curve->connect(CoreStringNames::get_singleton()->changed, this, "_curve_changed");
}
Expand Down Expand Up @@ -171,14 +189,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(CoreStringNames::get_singleton()->changed, this, "_gradient_changed");
}

_gradient = p_gradient;

// Connect to the gradient so the line will update when the ColorRamp is changed
if (_gradient.is_valid()) {
_gradient->connect(CoreStringNames::get_singleton()->changed, this, "_gradient_changed");
}
Expand All @@ -191,14 +207,12 @@ Ref<Gradient> Line2D::get_gradient() const {
}

void Line2D::set_texture(const Ref<Texture> &p_texture) {
// Cleanup previous connection if any
if (_texture.is_valid()) {
_texture->disconnect(CoreStringNames::get_singleton()->changed, this, "_texture_changed");
}

_texture = p_texture;

// Connect to the gradient so the line will update when the ColorRamp is changed
if (_texture.is_valid()) {
_texture->connect(CoreStringNames::get_singleton()->changed, this, "_texture_changed");
}
Expand Down Expand Up @@ -255,8 +269,8 @@ void Line2D::_notification(int p_what) {
}

void Line2D::set_sharp_limit(float p_limit) {
if (p_limit < 0.f) {
p_limit = 0.f;
if (p_limit < 0) {
p_limit = 0;
}
_sharp_limit = p_limit;
update();
Expand Down Expand Up @@ -296,25 +310,13 @@ bool Line2D::get_debug_mode() const {
#endif

void Line2D::_draw() {
if (_points.size() <= 1 || _width == 0.f) {
if (_points.size() <= 1 || _width == 0) {
return;
}

// TODO Is this really needed?
// Copy points for faster access
Vector<Vector2> points;
points.resize(_points.size());
int len = points.size();
{
PoolVector<Vector2>::Read points_read = _points.read();
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;
LineBuilder lb; // TODO Maybe have it as member rather than copying parameters and allocating memory?
lb.points = _points;
lb.closed = _closed;
lb.default_color = _default_color;
lb.gradient = *_gradient;
lb.texture_mode = _texture_mode;
Expand Down Expand Up @@ -403,6 +405,8 @@ 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 @@ -443,6 +447,7 @@ void Line2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_debug_mode"), &Line2D::get_debug_mode);
#endif
ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR2_ARRAY, "points"), "set_points", "get_points");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "closed"), "set_closed", "is_closed");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "width"), "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 @@ -133,6 +136,7 @@ class Line2D : public Node2D {
LineJointMode _joint_mode;
LineCapMode _begin_cap_mode;
LineCapMode _end_cap_mode;
bool _closed;
float _width;
Ref<Curve> _curve;
Color _default_color;
Expand Down
Loading

0 comments on commit 03c8509

Please sign in to comment.