Fix Curve3D::get_closest_point() broken
The problem is caused by calling adaptive tessellation baking function by mistake, which produce too few points for straight lines. Calling the even length tessellation fix the problem. The code for `get_closest_point()` and `get_closest_offset()` are also updated. They used to assume bake interval to be exact, which is no longer true. The out dated document for `get_closest_point()` is also updated.
This commit is contained in:
parent
30800d20f4
commit
69f84563a3
2 changed files with 14 additions and 12 deletions
|
@ -64,7 +64,7 @@
|
|||
<return type="Vector3" />
|
||||
<param index="0" name="to_point" type="Vector3" />
|
||||
<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.
|
||||
</description>
|
||||
</method>
|
||||
|
|
|
@ -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 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) {
|
||||
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);
|
||||
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(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, 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, 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;
|
||||
|
||||
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 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;
|
||||
|
||||
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_dist = -1.0f;
|
||||
real_t offset = 0.0f;
|
||||
real_t offset;
|
||||
|
||||
for (int i = 0; i < pc - 1; i++) {
|
||||
Vector3 origin = r[i];
|
||||
Vector3 direction = (r[i + 1] - origin) / bake_interval;
|
||||
offset = baked_dist_cache[i];
|
||||
|
||||
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;
|
||||
|
||||
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_dist = dist;
|
||||
}
|
||||
|
||||
offset += bake_interval;
|
||||
}
|
||||
|
||||
return nearest;
|
||||
|
|
Loading…
Reference in a new issue