Merge pull request #69239 from xiongyaohua/fix_69220

Fix `Curve3D::get_closest_point()` broken
This commit is contained in:
Rémi Verschelde 2022-12-03 12:45:27 +01:00
commit 33dd934111
No known key found for this signature in database
GPG Key ID: C3336907360768E1
2 changed files with 14 additions and 12 deletions

View File

@ -64,7 +64,7 @@
<return type="Vector3" /> <return type="Vector3" />
<param index="0" name="to_point" type="Vector3" /> <param index="0" name="to_point" type="Vector3" />
<description> <description>
Returns the closest baked point (in curve's local space) to [param to_point]. Returns the closest point on baked segments (in curve's local space) to [param to_point].
[param to_point] must be in this curve's local space. [param to_point] must be in this curve's local space.
</description> </description>
</method> </method>

View File

@ -1407,15 +1407,15 @@ void Curve3D::_bake_segment3d_even_length(RBMap<real_t, Vector3> &r_bake, real_t
Vector3 beg = p_a.bezier_interpolate(p_a + p_out, p_b + p_in, p_b, p_begin); Vector3 beg = p_a.bezier_interpolate(p_a + p_out, p_b + p_in, p_b, p_begin);
Vector3 end = p_a.bezier_interpolate(p_a + p_out, p_b + p_in, p_b, p_end); Vector3 end = p_a.bezier_interpolate(p_a + p_out, p_b + p_in, p_b, p_end);
size_t length = beg.distance_to(end); real_t length = beg.distance_to(end);
if (length > p_length && p_depth < p_max_depth) { if (length > p_length && p_depth < p_max_depth) {
real_t mp = (p_begin + p_end) * 0.5; real_t mp = (p_begin + p_end) * 0.5;
Vector3 mid = p_a.bezier_interpolate(p_a + p_out, p_b + p_in, p_b, mp); Vector3 mid = p_a.bezier_interpolate(p_a + p_out, p_b + p_in, p_b, mp);
r_bake[mp] = mid; r_bake[mp] = mid;
_bake_segment3d(r_bake, p_begin, mp, p_a, p_out, p_b, p_in, p_depth + 1, p_max_depth, p_length); _bake_segment3d_even_length(r_bake, p_begin, mp, p_a, p_out, p_b, p_in, p_depth + 1, p_max_depth, p_length);
_bake_segment3d(r_bake, mp, p_end, p_a, p_out, p_b, p_in, p_depth + 1, p_max_depth, p_length); _bake_segment3d_even_length(r_bake, mp, p_end, p_a, p_out, p_b, p_in, p_depth + 1, p_max_depth, p_length);
} }
} }
@ -1839,10 +1839,11 @@ Vector3 Curve3D::get_closest_point(const Vector3 &p_to_point) const {
real_t nearest_dist = -1.0f; real_t nearest_dist = -1.0f;
for (int i = 0; i < pc - 1; i++) { for (int i = 0; i < pc - 1; i++) {
const real_t interval = baked_dist_cache[i + 1] - baked_dist_cache[i];
Vector3 origin = r[i]; Vector3 origin = r[i];
Vector3 direction = (r[i + 1] - origin) / bake_interval; Vector3 direction = (r[i + 1] - origin) / interval;
real_t d = CLAMP((p_to_point - origin).dot(direction), 0.0f, bake_interval); real_t d = CLAMP((p_to_point - origin).dot(direction), 0.0f, interval);
Vector3 proj = origin + direction * d; Vector3 proj = origin + direction * d;
real_t dist = proj.distance_squared_to(p_to_point); real_t dist = proj.distance_squared_to(p_to_point);
@ -1875,13 +1876,16 @@ real_t Curve3D::get_closest_offset(const Vector3 &p_to_point) const {
real_t nearest = 0.0f; real_t nearest = 0.0f;
real_t nearest_dist = -1.0f; real_t nearest_dist = -1.0f;
real_t offset = 0.0f; real_t offset;
for (int i = 0; i < pc - 1; i++) { for (int i = 0; i < pc - 1; i++) {
Vector3 origin = r[i]; offset = baked_dist_cache[i];
Vector3 direction = (r[i + 1] - origin) / bake_interval;
real_t d = CLAMP((p_to_point - origin).dot(direction), 0.0f, bake_interval); const real_t interval = baked_dist_cache[i + 1] - baked_dist_cache[i];
Vector3 origin = r[i];
Vector3 direction = (r[i + 1] - origin) / interval;
real_t d = CLAMP((p_to_point - origin).dot(direction), 0.0f, interval);
Vector3 proj = origin + direction * d; Vector3 proj = origin + direction * d;
real_t dist = proj.distance_squared_to(p_to_point); real_t dist = proj.distance_squared_to(p_to_point);
@ -1890,8 +1894,6 @@ real_t Curve3D::get_closest_offset(const Vector3 &p_to_point) const {
nearest = offset + d; nearest = offset + d;
nearest_dist = dist; nearest_dist = dist;
} }
offset += bake_interval;
} }
return nearest; return nearest;