You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-09 12:50:35 +00:00
Fix repeated updates of PathFollow3D Transform
Add optional parameter to specify whether applying rotation to the
PathFollow3D's Transform is necessary, preventing erroneous updates.
(cherry picked from commit be3a1769fe)
This commit is contained in:
committed by
Rémi Verschelde
parent
c55e68d311
commit
76a43c93cd
@@ -93,7 +93,7 @@ Path::Path() {
|
|||||||
|
|
||||||
//////////////
|
//////////////
|
||||||
|
|
||||||
void PathFollow::_update_transform() {
|
void PathFollow::_update_transform(bool p_update_xyz_rot) {
|
||||||
|
|
||||||
if (!path)
|
if (!path)
|
||||||
return;
|
return;
|
||||||
@@ -163,45 +163,47 @@ void PathFollow::_update_transform() {
|
|||||||
|
|
||||||
t.origin = pos;
|
t.origin = pos;
|
||||||
|
|
||||||
Vector3 t_prev = (pos - c->interpolate_baked(offset - delta_offset, cubic)).normalized();
|
if (p_update_xyz_rot) { // Only update rotation if some parameter has changed - i.e. not on addition to scene tree
|
||||||
Vector3 t_cur = (c->interpolate_baked(offset + delta_offset, cubic) - pos).normalized();
|
Vector3 t_prev = (pos - c->interpolate_baked(offset - delta_offset, cubic)).normalized();
|
||||||
|
Vector3 t_cur = (c->interpolate_baked(offset + delta_offset, cubic) - pos).normalized();
|
||||||
|
|
||||||
Vector3 axis = t_prev.cross(t_cur);
|
Vector3 axis = t_prev.cross(t_cur);
|
||||||
float dot = t_prev.dot(t_cur);
|
float dot = t_prev.dot(t_cur);
|
||||||
float angle = Math::acos(CLAMP(dot, -1, 1));
|
float angle = Math::acos(CLAMP(dot, -1, 1));
|
||||||
|
|
||||||
if (likely(!Math::is_zero_approx(angle))) {
|
if (likely(!Math::is_zero_approx(angle))) {
|
||||||
if (rotation_mode == ROTATION_Y) {
|
if (rotation_mode == ROTATION_Y) {
|
||||||
// assuming we're referring to global Y-axis. is this correct?
|
// assuming we're referring to global Y-axis. is this correct?
|
||||||
axis.x = 0;
|
axis.x = 0;
|
||||||
axis.z = 0;
|
axis.z = 0;
|
||||||
} else if (rotation_mode == ROTATION_XY) {
|
} else if (rotation_mode == ROTATION_XY) {
|
||||||
axis.z = 0;
|
axis.z = 0;
|
||||||
} else if (rotation_mode == ROTATION_XYZ) {
|
} else if (rotation_mode == ROTATION_XYZ) {
|
||||||
// all components are allowed
|
// all components are allowed
|
||||||
|
}
|
||||||
|
|
||||||
|
if (likely(!Math::is_zero_approx(axis.length()))) {
|
||||||
|
t.rotate_basis(axis.normalized(), angle);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (likely(!Math::is_zero_approx(axis.length()))) {
|
// do the additional tilting
|
||||||
t.rotate_basis(axis.normalized(), angle);
|
float tilt_angle = c->interpolate_baked_tilt(offset);
|
||||||
}
|
Vector3 tilt_axis = t_cur; // not sure what tilt is supposed to do, is this correct??
|
||||||
}
|
|
||||||
|
|
||||||
// do the additional tilting
|
if (likely(!Math::is_zero_approx(Math::abs(tilt_angle)))) {
|
||||||
float tilt_angle = c->interpolate_baked_tilt(offset);
|
if (rotation_mode == ROTATION_Y) {
|
||||||
Vector3 tilt_axis = t_cur; // not sure what tilt is supposed to do, is this correct??
|
tilt_axis.x = 0;
|
||||||
|
tilt_axis.z = 0;
|
||||||
|
} else if (rotation_mode == ROTATION_XY) {
|
||||||
|
tilt_axis.z = 0;
|
||||||
|
} else if (rotation_mode == ROTATION_XYZ) {
|
||||||
|
// all components are allowed
|
||||||
|
}
|
||||||
|
|
||||||
if (likely(!Math::is_zero_approx(Math::abs(tilt_angle)))) {
|
if (likely(!Math::is_zero_approx(tilt_axis.length()))) {
|
||||||
if (rotation_mode == ROTATION_Y) {
|
t.rotate_basis(tilt_axis.normalized(), tilt_angle);
|
||||||
tilt_axis.x = 0;
|
}
|
||||||
tilt_axis.z = 0;
|
|
||||||
} else if (rotation_mode == ROTATION_XY) {
|
|
||||||
tilt_axis.z = 0;
|
|
||||||
} else if (rotation_mode == ROTATION_XYZ) {
|
|
||||||
// all components are allowed
|
|
||||||
}
|
|
||||||
|
|
||||||
if (likely(!Math::is_zero_approx(tilt_axis.length()))) {
|
|
||||||
t.rotate_basis(tilt_axis.normalized(), tilt_angle);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -223,7 +225,7 @@ void PathFollow::_notification(int p_what) {
|
|||||||
if (parent) {
|
if (parent) {
|
||||||
path = Object::cast_to<Path>(parent);
|
path = Object::cast_to<Path>(parent);
|
||||||
if (path) {
|
if (path) {
|
||||||
_update_transform();
|
_update_transform(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ private:
|
|||||||
bool loop;
|
bool loop;
|
||||||
RotationMode rotation_mode;
|
RotationMode rotation_mode;
|
||||||
|
|
||||||
void _update_transform();
|
void _update_transform(bool p_update_xyz_rot = true);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void _validate_property(PropertyInfo &property) const;
|
virtual void _validate_property(PropertyInfo &property) const;
|
||||||
|
|||||||
Reference in New Issue
Block a user