1
0
mirror of https://github.com/godotengine/godot.git synced 2026-01-06 19:41:11 +00:00

Merge pull request #103993 from aaronfranke/geometry-segment

Directly use segment points in Geometry2D/3D function parameters
This commit is contained in:
Thaddeus Crews
2025-04-01 08:01:34 -05:00
30 changed files with 205 additions and 224 deletions

View File

@@ -707,12 +707,12 @@ AbstractPolygon2DEditor::PosVertex AbstractPolygon2DEditor::closest_edge_point(c
const int n_segments = n_points - (_is_line() ? 1 : 0);
for (int i = 0; i < n_segments; i++) {
Vector2 segment[2] = { xform.xform(points[i] + offset),
xform.xform(points[(i + 1) % n_points] + offset) };
const Vector2 segment_a = xform.xform(points[i] + offset);
const Vector2 segment_b = xform.xform(points[(i + 1) % n_points] + offset);
Vector2 cp = Geometry2D::get_closest_point_to_segment(p_pos, segment);
Vector2 cp = Geometry2D::get_closest_point_to_segment(p_pos, segment_a, segment_b);
if (cp.distance_squared_to(segment[0]) < eps2 || cp.distance_squared_to(segment[1]) < eps2) {
if (cp.distance_squared_to(segment_a) < eps2 || cp.distance_squared_to(segment_b) < eps2) {
continue; //not valid to reuse point
}

View File

@@ -232,11 +232,7 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv
// First find closest lines using point-to-segment distance.
for (int i = 0; i < transition_lines.size(); i++) {
Vector2 s[2] = {
transition_lines[i].from,
transition_lines[i].to
};
Vector2 cpoint = Geometry2D::get_closest_point_to_segment(mb->get_position(), s);
Vector2 cpoint = Geometry2D::get_closest_point_to_segment(mb->get_position(), transition_lines[i].from, transition_lines[i].to);
float d = cpoint.distance_to(mb->get_position());
if (d > transition_lines[i].width) {
@@ -545,11 +541,7 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv
int closest = -1;
float closest_d = 1e20;
for (int i = 0; i < transition_lines.size(); i++) {
Vector2 s[2] = {
transition_lines[i].from,
transition_lines[i].to
};
Vector2 cpoint = Geometry2D::get_closest_point_to_segment(mm->get_position(), s);
Vector2 cpoint = Geometry2D::get_closest_point_to_segment(mm->get_position(), transition_lines[i].from, transition_lines[i].to);
float d = cpoint.distance_to(mm->get_position());
if (d > transition_lines[i].width) {
continue;

View File

@@ -466,13 +466,11 @@ EditorPlugin::AfterGUIInput NavigationObstacle3DEditorPlugin::forward_3d_gui_inp
Vector2 closest_edge_point;
real_t closest_dist = 1e10;
for (int i = 0; i < obstacle_vertices.size(); i++) {
Vector2 points[2] = {
p_camera->unproject_position(gt.xform(obstacle_vertices[i])),
p_camera->unproject_position(gt.xform(obstacle_vertices[(i + 1) % obstacle_vertices.size()]))
};
const Vector2 a = p_camera->unproject_position(gt.xform(obstacle_vertices[i]));
const Vector2 b = p_camera->unproject_position(gt.xform(obstacle_vertices[(i + 1) % obstacle_vertices.size()]));
Vector2 cp = Geometry2D::get_closest_point_to_segment(mouse_position, points);
if (cp.distance_squared_to(points[0]) < grab_threshold || cp.distance_squared_to(points[1]) < grab_threshold) {
Vector2 cp = Geometry2D::get_closest_point_to_segment(mouse_position, a, b);
if (cp.distance_squared_to(a) < grab_threshold || cp.distance_squared_to(b) < grab_threshold) {
continue; // Skip edge as clicked point is too close to existing vertex.
}
@@ -548,13 +546,11 @@ EditorPlugin::AfterGUIInput NavigationObstacle3DEditorPlugin::forward_3d_gui_inp
Vector2 closest_pos;
real_t closest_dist = 1e10;
for (int i = 0; i < obstacle_vertices.size(); i++) {
Vector2 points[2] = {
p_camera->unproject_position(gt.xform(obstacle_vertices[i])),
p_camera->unproject_position(gt.xform(obstacle_vertices[(i + 1) % obstacle_vertices.size()]))
};
const Vector2 a = p_camera->unproject_position(gt.xform(obstacle_vertices[i]));
const Vector2 b = p_camera->unproject_position(gt.xform(obstacle_vertices[(i + 1) % obstacle_vertices.size()]));
Vector2 cp = Geometry2D::get_closest_point_to_segment(mouse_position, points);
if (cp.distance_squared_to(points[0]) < CMP_EPSILON2 || cp.distance_squared_to(points[1]) < CMP_EPSILON2) {
Vector2 cp = Geometry2D::get_closest_point_to_segment(mouse_position, a, b);
if (cp.distance_squared_to(a) < CMP_EPSILON2 || cp.distance_squared_to(b) < CMP_EPSILON2) {
continue; //not valid to reuse point
}

View File

@@ -715,21 +715,20 @@ bool EditorNode3DGizmo::intersect_ray(Camera3D *p_camera, const Point2 &p_point,
float cpd = 1e20;
for (int i = 0; i < vc / 2; i++) {
Vector3 a = t.xform(vptr[i * 2 + 0]);
Vector3 b = t.xform(vptr[i * 2 + 1]);
Vector2 s[2];
s[0] = p_camera->unproject_position(a);
s[1] = p_camera->unproject_position(b);
const Vector3 a = t.xform(vptr[i * 2 + 0]);
const Vector3 b = t.xform(vptr[i * 2 + 1]);
const Vector2 segment_a = p_camera->unproject_position(a);
const Vector2 segment_b = p_camera->unproject_position(b);
Vector2 p = Geometry2D::get_closest_point_to_segment(p_point, s);
Vector2 p = Geometry2D::get_closest_point_to_segment(p_point, segment_a, segment_b);
float pd = p.distance_to(p_point);
if (pd < cpd) {
float d = s[0].distance_to(s[1]);
float d = segment_a.distance_to(segment_b);
Vector3 tcp;
if (d > 0) {
float d2 = s[0].distance_to(p) / d;
float d2 = segment_a.distance_to(p) / d;
tcp = a + (b - a) * d2;
} else {

View File

@@ -620,10 +620,9 @@ EditorPlugin::AfterGUIInput Path3DEditorPlugin::forward_3d_gui_input(Camera3D *p
from = gt.xform(from);
to = gt.xform(to);
if (cdist > 0) {
Vector2 s[2];
s[0] = viewport->point_to_screen(from);
s[1] = viewport->point_to_screen(to);
Vector2 inters = Geometry2D::get_closest_point_to_segment(mbpos, s);
const Vector2 segment_a = viewport->point_to_screen(from);
const Vector2 segment_b = viewport->point_to_screen(to);
Vector2 inters = Geometry2D::get_closest_point_to_segment(mbpos, segment_a, segment_b);
float d = inters.distance_to(mbpos);
if (d < 10 && d < closest_d) {

View File

@@ -200,13 +200,11 @@ EditorPlugin::AfterGUIInput Polygon3DEditor::forward_3d_gui_input(Camera3D *p_ca
Vector2 closest_pos;
real_t closest_dist = 1e10;
for (int i = 0; i < poly.size(); i++) {
Vector2 points[2] = {
p_camera->unproject_position(gt.xform(Vector3(poly[i].x, poly[i].y, depth))),
p_camera->unproject_position(gt.xform(Vector3(poly[(i + 1) % poly.size()].x, poly[(i + 1) % poly.size()].y, depth)))
};
const Vector2 segment_a = p_camera->unproject_position(gt.xform(Vector3(poly[i].x, poly[i].y, depth)));
const Vector2 segment_b = p_camera->unproject_position(gt.xform(Vector3(poly[(i + 1) % poly.size()].x, poly[(i + 1) % poly.size()].y, depth)));
Vector2 cp = Geometry2D::get_closest_point_to_segment(gpoint, points);
if (cp.distance_squared_to(points[0]) < CMP_EPSILON2 || cp.distance_squared_to(points[1]) < CMP_EPSILON2) {
Vector2 cp = Geometry2D::get_closest_point_to_segment(gpoint, segment_a, segment_b);
if (cp.distance_squared_to(segment_a) < CMP_EPSILON2 || cp.distance_squared_to(segment_b) < CMP_EPSILON2) {
continue; //not valid to reuse point
}

View File

@@ -438,8 +438,9 @@ void GenericTilePolygonEditor::_grab_polygon_segment_point(Vector2 p_pos, const
for (unsigned int i = 0; i < polygons.size(); i++) {
const Vector<Vector2> &polygon = polygons[i];
for (int j = 0; j < polygon.size(); j++) {
Vector2 segment[2] = { polygon[j], polygon[(j + 1) % polygon.size()] };
Vector2 closest_point = Geometry2D::get_closest_point_to_segment(point, segment);
const Vector2 segment_a = polygon[j];
const Vector2 segment_b = polygon[(j + 1) % polygon.size()];
Vector2 closest_point = Geometry2D::get_closest_point_to_segment(point, segment_a, segment_b);
float distance = closest_point.distance_to(point);
if (distance < grab_threshold / editor_zoom_widget->get_zoom() && distance < closest_distance) {
r_polygon_index = i;
@@ -474,8 +475,9 @@ void GenericTilePolygonEditor::_snap_to_tile_shape(Point2 &r_point, float &r_cur
// Snap to edges if we did not snap to vertices.
if (!snapped) {
for (int i = 0; i < polygon.size(); i++) {
Point2 segment[2] = { polygon[i], polygon[(i + 1) % polygon.size()] };
Point2 point = Geometry2D::get_closest_point_to_segment(r_point, segment);
const Vector2 segment_a = polygon[i];
const Vector2 segment_b = polygon[(i + 1) % polygon.size()];
Point2 point = Geometry2D::get_closest_point_to_segment(r_point, segment_a, segment_b);
float distance = r_point.distance_to(point);
if (distance < p_snap_dist && distance < r_current_snapped_dist) {
snapped_point = point;