Merge pull request #104221 from Teschnique/fix-issue-100590

Fix tangent baking for curves when cubic derivatives are 0
This commit is contained in:
Thaddeus Crews 2025-03-24 10:01:02 -05:00
commit f810c74c19
No known key found for this signature in database
GPG key ID: 62181B86FE9E5D84
2 changed files with 92 additions and 18 deletions

View file

@ -881,12 +881,22 @@ void Curve2D::_bake_segment2d_even_length(RBMap<real_t, Vector2> &r_bake, real_t
Vector2 Curve2D::_calculate_tangent(const Vector2 &p_begin, const Vector2 &p_control_1, const Vector2 &p_control_2, const Vector2 &p_end, const real_t p_t) {
// Handle corner cases.
if (Math::is_zero_approx(p_t - 0.0f) && p_control_1.is_equal_approx(p_begin)) {
return (p_end - p_begin).normalized();
}
if (Math::is_zero_approx(p_t - 1.0f) && p_control_2.is_equal_approx(p_end)) {
return (p_end - p_begin).normalized();
if (Math::is_zero_approx(p_t - 0.0f)) {
if (p_control_1.is_equal_approx(p_begin)) {
if (p_control_1.is_equal_approx(p_control_2)) {
return (p_end - p_begin).normalized();
} else {
return (p_control_2 - p_begin).normalized();
}
}
} else if (Math::is_zero_approx(p_t - 1.0f)) {
if (p_control_2.is_equal_approx(p_end)) {
if (p_control_2.is_equal_approx(p_control_1)) {
return (p_end - p_begin).normalized();
} else {
return (p_end - p_control_1).normalized();
}
}
}
return p_begin.bezier_derivative(p_control_1, p_control_2, p_end, p_t).normalized();
@ -1620,12 +1630,22 @@ void Curve3D::_bake_segment3d_even_length(RBMap<real_t, Vector3> &r_bake, real_t
Vector3 Curve3D::_calculate_tangent(const Vector3 &p_begin, const Vector3 &p_control_1, const Vector3 &p_control_2, const Vector3 &p_end, const real_t p_t) {
// Handle corner cases.
if (Math::is_zero_approx(p_t - 0.0f) && p_control_1.is_equal_approx(p_begin)) {
return (p_end - p_begin).normalized();
}
if (Math::is_zero_approx(p_t - 1.0f) && p_control_2.is_equal_approx(p_end)) {
return (p_end - p_begin).normalized();
if (Math::is_zero_approx(p_t - 0.0f)) {
if (p_control_1.is_equal_approx(p_begin)) {
if (p_control_1.is_equal_approx(p_control_2)) {
return (p_end - p_begin).normalized();
} else {
return (p_control_2 - p_begin).normalized();
}
}
} else if (Math::is_zero_approx(p_t - 1.0f)) {
if (p_control_2.is_equal_approx(p_end)) {
if (p_control_2.is_equal_approx(p_control_1)) {
return (p_end - p_begin).normalized();
} else {
return (p_end - p_control_1).normalized();
}
}
}
return p_begin.bezier_derivative(p_control_1, p_control_2, p_end, p_t).normalized();