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

Fix PathFollow3D update issues #80233

Merged
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
56 changes: 38 additions & 18 deletions scene/3d/path_3d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,13 +165,14 @@ void Path3D::_curve_changed() {
emit_signal(SNAME("curve_changed"));
}

// update the configuration warnings of all children of type PathFollow
// previously used for PathFollowOriented (now enforced orientation is done in PathFollow)
// Update the configuration warnings of all children of type PathFollow
// previously used for PathFollowOriented (now enforced orientation is done in PathFollow). Also trigger transform update on PathFollow3Ds in deferred mode.
if (is_inside_tree()) {
for (int i = 0; i < get_child_count(); i++) {
PathFollow3D *child = Object::cast_to<PathFollow3D>(get_child(i));
if (child) {
child->update_configuration_warnings();
child->update_transform();
}
}
}
Expand Down Expand Up @@ -207,9 +208,24 @@ void Path3D::_bind_methods() {
ADD_SIGNAL(MethodInfo("curve_changed"));
}

//////////////
// Update transform, in deferred mode by default to avoid superfluity.
void PathFollow3D::update_transform(bool p_immediate) {
transform_dirty = true;

if (p_immediate) {
_update_transform();
} else {
callable_mp(this, &PathFollow3D::_update_transform).call_deferred();
}
}

// Update transform immediately .
void PathFollow3D::_update_transform() {
if (!transform_dirty) {
return;
}
transform_dirty = false;

void PathFollow3D::_update_transform(bool p_update_xyz_rot) {
if (!path) {
return;
}
Expand All @@ -231,23 +247,25 @@ void PathFollow3D::_update_transform(bool p_update_xyz_rot) {
t.origin = pos;
} else {
t = c->sample_baked_with_rotation(progress, cubic, false);
Vector3 tangent = -t.basis.get_column(2); // Retain tangent for applying tilt.
t = PathFollow3D::correct_posture(t, rotation_mode);

// Switch Z+ and Z- if necessary.
if (use_model_front) {
t.basis *= Basis::from_scale(Vector3(-1.0, 1.0, -1.0));
}
Vector3 forward = t.basis.get_column(2); // Retain tangent for applying tilt
t = PathFollow3D::correct_posture(t, rotation_mode);

// Apply tilt *after* correct_posture
// Apply tilt *after* correct_posture().
if (tilt_enabled) {
const real_t tilt = c->sample_baked_tilt(progress);

const Basis twist(forward, tilt);
const Basis twist(tangent, tilt);
t.basis = twist * t.basis;
}
}

// Apply offset and scale.
Vector3 scale = get_transform().basis.get_scale();

t.translate_local(Vector3(h_offset, v_offset, 0));
t.basis.scale_local(scale);

Expand All @@ -261,7 +279,7 @@ void PathFollow3D::_notification(int p_what) {
if (parent) {
path = Object::cast_to<Path3D>(parent);
if (path) {
_update_transform(false);
update_transform();
}
}
} break;
Expand Down Expand Up @@ -316,11 +334,10 @@ Transform3D PathFollow3D::correct_posture(Transform3D p_transform, PathFollow3D:
// Clear rotation.
t.basis = Basis();
} else if (p_rotation_mode == PathFollow3D::ROTATION_ORIENTED) {
// Y-axis always straight up.
Vector3 up(0.0, 1.0, 0.0);
Vector3 forward = t.basis.get_column(2);
Vector3 tangent = -t.basis.get_column(2);

t.basis = Basis::looking_at(-forward, up);
// Y-axis points up by default.
t.basis = Basis::looking_at(tangent);
} else {
// Lock some euler axes.
Vector3 euler = t.basis.get_euler_normalized(EulerOrder::YXZ);
Expand Down Expand Up @@ -405,14 +422,14 @@ void PathFollow3D::set_progress(real_t p_progress) {
}
}

_update_transform();
update_transform();
}
}

void PathFollow3D::set_h_offset(real_t p_h_offset) {
h_offset = p_h_offset;
if (path) {
_update_transform();
update_transform();
}
}

Expand All @@ -423,7 +440,7 @@ real_t PathFollow3D::get_h_offset() const {
void PathFollow3D::set_v_offset(real_t p_v_offset) {
v_offset = p_v_offset;
if (path) {
_update_transform();
update_transform();
}
}

Expand Down Expand Up @@ -453,7 +470,7 @@ void PathFollow3D::set_rotation_mode(RotationMode p_rotation_mode) {
rotation_mode = p_rotation_mode;

update_configuration_warnings();
_update_transform();
update_transform();
}

PathFollow3D::RotationMode PathFollow3D::get_rotation_mode() const {
Expand All @@ -462,6 +479,7 @@ PathFollow3D::RotationMode PathFollow3D::get_rotation_mode() const {

void PathFollow3D::set_use_model_front(bool p_use_model_front) {
use_model_front = p_use_model_front;
update_transform();
}

bool PathFollow3D::is_using_model_front() const {
Expand All @@ -470,6 +488,7 @@ bool PathFollow3D::is_using_model_front() const {

void PathFollow3D::set_loop(bool p_loop) {
loop = p_loop;
update_transform();
}

bool PathFollow3D::has_loop() const {
Expand All @@ -478,6 +497,7 @@ bool PathFollow3D::has_loop() const {

void PathFollow3D::set_tilt_enabled(bool p_enabled) {
tilt_enabled = p_enabled;
update_transform();
}

bool PathFollow3D::is_tilt_enabled() const {
Expand Down
14 changes: 8 additions & 6 deletions scene/3d/path_3d.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,6 @@ class PathFollow3D : public Node3D {
ROTATION_ORIENTED
};

bool use_model_front = false;

static Transform3D correct_posture(Transform3D p_transform, PathFollow3D::RotationMode p_rotation_mode);

private:
Path3D *path = nullptr;
real_t progress = 0.0;
Expand All @@ -84,14 +80,16 @@ class PathFollow3D : public Node3D {
bool cubic = true;
bool loop = true;
bool tilt_enabled = true;
bool transform_dirty = true;
bool use_model_front = false;
RotationMode rotation_mode = ROTATION_XYZ;

void _update_transform(bool p_update_xyz_rot = true);

protected:
void _validate_property(PropertyInfo &p_property) const;

void _notification(int p_what);
void _update_transform();

static void _bind_methods();

public:
Expand Down Expand Up @@ -124,6 +122,10 @@ class PathFollow3D : public Node3D {

PackedStringArray get_configuration_warnings() const override;

void update_transform(bool p_immediate = false);

static Transform3D correct_posture(Transform3D p_transform, PathFollow3D::RotationMode p_rotation_mode);

PathFollow3D() {}
};

Expand Down
Loading