summaryrefslogtreecommitdiff
path: root/scene
diff options
context:
space:
mode:
Diffstat (limited to 'scene')
-rw-r--r--scene/2d/path_2d.cpp46
-rw-r--r--scene/2d/path_2d.h5
-rw-r--r--scene/2d/physics_body_2d.cpp5
-rw-r--r--scene/gui/text_edit.cpp2
-rwxr-xr-xscene/main/node.cpp42
-rw-r--r--scene/main/node.h10
6 files changed, 70 insertions, 40 deletions
diff --git a/scene/2d/path_2d.cpp b/scene/2d/path_2d.cpp
index 8413be1ca9..55c055e34f 100644
--- a/scene/2d/path_2d.cpp
+++ b/scene/2d/path_2d.cpp
@@ -107,28 +107,39 @@ void PathFollow2D::_update_transform() {
if (!c.is_valid())
return;
+ if (delta_offset == 0) {
+ return;
+ }
+
float o = offset;
if (loop)
o = Math::fposmod(o, c->get_baked_length());
Vector2 pos = c->interpolate_baked(o, cubic);
+ Vector2 offset = Vector2(h_offset, v_offset);
+
+ Transform2D t = get_transform();
+ t.set_origin(pos);
+
if (rotate) {
- Vector2 n = (c->interpolate_baked(o + lookahead, cubic) - pos).normalized();
- Vector2 t = -n.tangent();
- pos += n * h_offset;
- pos += t * v_offset;
+ Vector2 t_prev = (pos - c->interpolate_baked(o - delta_offset, cubic)).normalized();
+ Vector2 t_cur = (c->interpolate_baked(o + delta_offset, cubic) - pos).normalized();
+
+ float dot = t_prev.dot(t_cur);
+ float angle = Math::acos(CLAMP(dot, -1, 1));
+
+ t.rotate(angle);
- set_rotation(t.angle());
+ t.translate(offset);
} else {
- pos.x += h_offset;
- pos.y += v_offset;
+ t.set_origin(t.get_origin() + offset);
}
- set_position(pos);
+ set_transform(t);
}
void PathFollow2D::_notification(int p_what) {
@@ -176,8 +187,6 @@ bool PathFollow2D::_set(const StringName &p_name, const Variant &p_value) {
set_cubic_interpolation(p_value);
} else if (String(p_name) == "loop") {
set_loop(p_value);
- } else if (String(p_name) == "lookahead") {
- set_lookahead(p_value);
} else
return false;
@@ -200,8 +209,6 @@ bool PathFollow2D::_get(const StringName &p_name, Variant &r_ret) const {
r_ret = cubic;
} else if (String(p_name) == "loop") {
r_ret = loop;
- } else if (String(p_name) == "lookahead") {
- r_ret = lookahead;
} else
return false;
@@ -219,7 +226,6 @@ void PathFollow2D::_get_property_list(List<PropertyInfo> *p_list) const {
p_list->push_back(PropertyInfo(Variant::BOOL, "rotate"));
p_list->push_back(PropertyInfo(Variant::BOOL, "cubic_interp"));
p_list->push_back(PropertyInfo(Variant::BOOL, "loop"));
- p_list->push_back(PropertyInfo(Variant::REAL, "lookahead", PROPERTY_HINT_RANGE, "0.001,1024.0,0.001"));
}
String PathFollow2D::get_configuration_warning() const {
@@ -259,7 +265,7 @@ void PathFollow2D::_bind_methods() {
}
void PathFollow2D::set_offset(float p_offset) {
-
+ delta_offset = p_offset - offset;
offset = p_offset;
if (path)
_update_transform();
@@ -310,16 +316,6 @@ float PathFollow2D::get_unit_offset() const {
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;
@@ -344,11 +340,11 @@ bool PathFollow2D::has_loop() const {
PathFollow2D::PathFollow2D() {
offset = 0;
+ delta_offset = 0;
h_offset = 0;
v_offset = 0;
path = NULL;
rotate = true;
cubic = true;
loop = true;
- lookahead = 4;
}
diff --git a/scene/2d/path_2d.h b/scene/2d/path_2d.h
index 88a0abdea9..f5ba3a3d32 100644
--- a/scene/2d/path_2d.h
+++ b/scene/2d/path_2d.h
@@ -60,9 +60,9 @@ public:
private:
Path2D *path;
real_t offset;
+ real_t delta_offset; // change in offset since last _update_transform
real_t h_offset;
real_t v_offset;
- real_t lookahead;
bool cubic;
bool loop;
bool rotate;
@@ -90,9 +90,6 @@ public:
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;
diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp
index 1287a800e3..1f6127e6eb 100644
--- a/scene/2d/physics_body_2d.cpp
+++ b/scene/2d/physics_body_2d.cpp
@@ -1028,7 +1028,10 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const
on_floor = true;
floor_velocity = collision.collider_vel;
- if (collision.travel.length() < 1 && ABS((lv.x - floor_velocity.x)) < p_slope_stop_min_velocity) {
+ Vector2 rel_v = lv - floor_velocity;
+ Vector2 hv = rel_v - p_floor_direction * p_floor_direction.dot(rel_v);
+
+ if (collision.travel.length() < 1 && hv.length() < p_slope_stop_min_velocity) {
Transform2D gt = get_global_transform();
gt.elements[2] -= collision.travel;
set_global_transform(gt);
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index a1ecf291c1..c9af7eed0d 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -5342,7 +5342,7 @@ void TextEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_line", "line"), &TextEdit::get_line);
ClassDB::bind_method(D_METHOD("cursor_set_column", "column", "adjust_viewport"), &TextEdit::cursor_set_column, DEFVAL(true));
- ClassDB::bind_method(D_METHOD("cursor_set_line", "line", "adjust_viewport, can_be_hidden"), &TextEdit::cursor_set_line, DEFVAL(true), DEFVAL(true));
+ ClassDB::bind_method(D_METHOD("cursor_set_line", "line", "adjust_viewport", "can_be_hidden"), &TextEdit::cursor_set_line, DEFVAL(true), DEFVAL(true));
ClassDB::bind_method(D_METHOD("cursor_get_column"), &TextEdit::cursor_get_column);
ClassDB::bind_method(D_METHOD("cursor_get_line"), &TextEdit::cursor_get_line);
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index 2bf45f1189..253084dd99 100755
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -2067,7 +2067,7 @@ int Node::get_position_in_parent() const {
return data.pos;
}
-Node *Node::_duplicate(int p_flags) const {
+Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const {
Node *node = NULL;
@@ -2084,7 +2084,12 @@ Node *Node::_duplicate(int p_flags) const {
Ref<PackedScene> res = ResourceLoader::load(get_filename());
ERR_FAIL_COND_V(res.is_null(), NULL);
- node = res->instance();
+ PackedScene::GenEditState ges = PackedScene::GEN_EDIT_STATE_DISABLED;
+#ifdef TOOLS_ENABLED
+ if (p_flags & DUPLICATE_FROM_EDITOR)
+ ges = PackedScene::GEN_EDIT_STATE_INSTANCE;
+#endif
+ node = res->instance(ges);
ERR_FAIL_COND_V(!node, NULL);
instanced = true;
@@ -2099,10 +2104,6 @@ Node *Node::_duplicate(int p_flags) const {
ERR_FAIL_COND_V(!node, NULL);
}
- if (get_filename() != "") { //an instance
- node->set_filename(get_filename());
- }
-
List<PropertyInfo> plist;
get_property_list(&plist);
@@ -2138,11 +2139,21 @@ Node *Node::_duplicate(int p_flags) const {
node->set_name(get_name());
+#ifdef TOOLS_ENABLED
+ if ((p_flags & DUPLICATE_FROM_EDITOR) && r_duplimap)
+ r_duplimap->insert(this, node);
+#endif
+
if (p_flags & DUPLICATE_GROUPS) {
List<GroupInfo> gi;
get_groups(&gi);
for (List<GroupInfo>::Element *E = gi.front(); E; E = E->next()) {
+#ifdef TOOLS_ENABLED
+ if ((p_flags & DUPLICATE_FROM_EDITOR) && !E->get().persistent)
+ continue;
+#endif
+
node->add_to_group(E->get().name, E->get().persistent);
}
}
@@ -2154,7 +2165,7 @@ Node *Node::_duplicate(int p_flags) const {
if (instanced && get_child(i)->data.owner == this)
continue; //part of instance
- Node *dup = get_child(i)->duplicate(p_flags);
+ Node *dup = get_child(i)->_duplicate(p_flags, r_duplimap);
if (!dup) {
memdelete(node);
@@ -2178,6 +2189,20 @@ Node *Node::duplicate(int p_flags) const {
return dupe;
}
+#ifdef TOOLS_ENABLED
+Node *Node::duplicate_from_editor(Map<const Node *, Node *> &r_duplimap) const {
+
+ Node *dupe = _duplicate(DUPLICATE_SIGNALS | DUPLICATE_GROUPS | DUPLICATE_SCRIPTS | DUPLICATE_USE_INSTANCING | DUPLICATE_FROM_EDITOR, &r_duplimap);
+
+ // Duplication of signals must happen after all the node descendants have been copied,
+ // because re-targeting of connections from some descendant to another is not possible
+ // if the emitter node comes later in tree order than the receiver
+ _duplicate_signals(this, dupe);
+
+ return dupe;
+}
+#endif
+
void Node::_duplicate_and_reown(Node *p_new_parent, const Map<Node *, Node *> &p_reown_map) const {
if (get_owner() != get_parent()->get_owner())
@@ -2325,6 +2350,9 @@ Node *Node::duplicate_and_reown(const Map<Node *, Node *> &p_reown_map) const {
get_child(i)->_duplicate_and_reown(node, p_reown_map);
}
+ // Duplication of signals must happen after all the node descendants have been copied,
+ // because re-targeting of connections from some descendant to another is not possible
+ // if the emitter node comes later in tree order than the receiver
_duplicate_signals(this, node);
return node;
}
diff --git a/scene/main/node.h b/scene/main/node.h
index c43e96063f..bd0b18c87a 100644
--- a/scene/main/node.h
+++ b/scene/main/node.h
@@ -58,7 +58,10 @@ public:
DUPLICATE_SIGNALS = 1,
DUPLICATE_GROUPS = 2,
DUPLICATE_SCRIPTS = 4,
- DUPLICATE_USE_INSTANCING = 8
+ DUPLICATE_USE_INSTANCING = 8,
+#ifdef TOOLS_ENABLED
+ DUPLICATE_FROM_EDITOR = 16,
+#endif
};
enum RPCMode {
@@ -169,7 +172,7 @@ private:
void _duplicate_signals(const Node *p_original, Node *p_copy) const;
void _duplicate_and_reown(Node *p_new_parent, const Map<Node *, Node *> &p_reown_map) const;
- Node *_duplicate(int p_flags) const;
+ Node *_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap = NULL) const;
Array _get_children() const;
Array _get_groups() const;
@@ -326,6 +329,9 @@ public:
Node *duplicate(int p_flags = DUPLICATE_GROUPS | DUPLICATE_SIGNALS | DUPLICATE_SCRIPTS) const;
Node *duplicate_and_reown(const Map<Node *, Node *> &p_reown_map) const;
+#ifdef TOOLS_ENABLED
+ Node *duplicate_from_editor(Map<const Node *, Node *> &r_duplimap) const;
+#endif
//Node *clone_tree() const;