summaryrefslogtreecommitdiff
path: root/scene/3d/path_3d.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/3d/path_3d.cpp')
-rw-r--r--scene/3d/path_3d.cpp55
1 files changed, 32 insertions, 23 deletions
diff --git a/scene/3d/path_3d.cpp b/scene/3d/path_3d.cpp
index de115b35e3..9ea37e4bfa 100644
--- a/scene/3d/path_3d.cpp
+++ b/scene/3d/path_3d.cpp
@@ -30,18 +30,15 @@
#include "path_3d.h"
-#include "core/config/engine.h"
-#include "scene/scene_string_names.h"
-
void Path3D::_notification(int p_what) {
}
void Path3D::_curve_changed() {
if (is_inside_tree() && Engine::get_singleton()->is_editor_hint()) {
- update_gizmo();
+ update_gizmos();
}
if (is_inside_tree()) {
- emit_signal("curve_changed");
+ emit_signal(SNAME("curve_changed"));
}
// update the configuration warnings of all children of type PathFollow
@@ -94,17 +91,24 @@ void PathFollow3D::_update_transform(bool p_update_xyz_rot) {
return;
}
- float bl = c->get_baked_length();
+ real_t bl = c->get_baked_length();
if (bl == 0.0) {
return;
}
- float bi = c->get_bake_interval();
- float o_next = offset + bi;
+ real_t bi = c->get_bake_interval();
+ real_t o_next = offset + bi;
+ real_t o_prev = offset - bi;
if (loop) {
o_next = Math::fposmod(o_next, bl);
- } else if (rotation_mode == ROTATION_ORIENTED && o_next >= bl) {
- o_next = bl;
+ o_prev = Math::fposmod(o_prev, bl);
+ } else if (rotation_mode == ROTATION_ORIENTED) {
+ if (o_next >= bl) {
+ o_next = bl;
+ }
+ if (o_prev <= 0) {
+ o_prev = 0;
+ }
}
Vector3 pos = c->interpolate_baked(offset, cubic);
@@ -115,6 +119,11 @@ void PathFollow3D::_update_transform(bool p_update_xyz_rot) {
if (rotation_mode == ROTATION_ORIENTED) {
Vector3 forward = c->interpolate_baked(o_next, cubic) - pos;
+ // Try with the previous position
+ if (forward.length_squared() < CMP_EPSILON2) {
+ forward = pos - c->interpolate_baked(o_prev, cubic);
+ }
+
if (forward.length_squared() < CMP_EPSILON2) {
forward = Vector3(0, 0, 1);
} else {
@@ -157,8 +166,8 @@ void PathFollow3D::_update_transform(bool p_update_xyz_rot) {
Vector3 t_cur = (c->interpolate_baked(offset + delta_offset, cubic) - pos).normalized();
Vector3 axis = t_prev.cross(t_cur);
- float dot = t_prev.dot(t_cur);
- float angle = Math::acos(CLAMP(dot, -1, 1));
+ real_t dot = t_prev.dot(t_cur);
+ real_t angle = Math::acos(CLAMP(dot, -1, 1));
if (likely(!Math::is_zero_approx(angle))) {
if (rotation_mode == ROTATION_Y) {
@@ -177,7 +186,7 @@ void PathFollow3D::_update_transform(bool p_update_xyz_rot) {
}
// do the additional tilting
- float tilt_angle = c->interpolate_baked_tilt(offset);
+ real_t tilt_angle = c->interpolate_baked_tilt(offset);
Vector3 tilt_axis = t_cur; // not sure what tilt is supposed to do, is this correct??
if (likely(!Math::is_zero_approx(Math::abs(tilt_angle)))) {
@@ -232,7 +241,7 @@ bool PathFollow3D::get_cubic_interpolation() const {
void PathFollow3D::_validate_property(PropertyInfo &property) const {
if (property.name == "offset") {
- float max = 10000;
+ real_t max = 10000;
if (path && path->get_curve().is_valid()) {
max = path->get_curve()->get_baked_length();
}
@@ -295,13 +304,13 @@ void PathFollow3D::_bind_methods() {
BIND_ENUM_CONSTANT(ROTATION_ORIENTED);
}
-void PathFollow3D::set_offset(float p_offset) {
+void PathFollow3D::set_offset(real_t p_offset) {
delta_offset = p_offset - offset;
offset = p_offset;
if (path) {
if (path->get_curve().is_valid()) {
- float path_length = path->get_curve()->get_baked_length();
+ real_t path_length = path->get_curve()->get_baked_length();
if (loop) {
offset = Math::fposmod(offset, path_length);
@@ -317,39 +326,39 @@ void PathFollow3D::set_offset(float p_offset) {
}
}
-void PathFollow3D::set_h_offset(float p_h_offset) {
+void PathFollow3D::set_h_offset(real_t p_h_offset) {
h_offset = p_h_offset;
if (path) {
_update_transform();
}
}
-float PathFollow3D::get_h_offset() const {
+real_t PathFollow3D::get_h_offset() const {
return h_offset;
}
-void PathFollow3D::set_v_offset(float p_v_offset) {
+void PathFollow3D::set_v_offset(real_t p_v_offset) {
v_offset = p_v_offset;
if (path) {
_update_transform();
}
}
-float PathFollow3D::get_v_offset() const {
+real_t PathFollow3D::get_v_offset() const {
return v_offset;
}
-float PathFollow3D::get_offset() const {
+real_t PathFollow3D::get_offset() const {
return offset;
}
-void PathFollow3D::set_unit_offset(float p_unit_offset) {
+void PathFollow3D::set_unit_offset(real_t 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 PathFollow3D::get_unit_offset() const {
+real_t PathFollow3D::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 {