Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Path3D picking working incorrectly when viewport is in half resolution #89901

Merged
merged 1 commit into from
Mar 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 18 additions & 18 deletions editor/plugins/node_3d_editor_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -691,19 +691,19 @@ Vector3 Node3DEditorViewport::_get_camera_position() const {
return _get_camera_transform().origin;
}

Point2 Node3DEditorViewport::_point_to_screen(const Vector3 &p_point) {
Point2 Node3DEditorViewport::point_to_screen(const Vector3 &p_point) {
return camera->unproject_position(p_point) * subviewport_container->get_stretch_shrink();
}

Vector3 Node3DEditorViewport::_get_ray_pos(const Vector2 &p_pos) const {
Vector3 Node3DEditorViewport::get_ray_pos(const Vector2 &p_pos) const {
return camera->project_ray_origin(p_pos / subviewport_container->get_stretch_shrink());
}

Vector3 Node3DEditorViewport::_get_camera_normal() const {
return -_get_camera_transform().basis.get_column(2);
}

Vector3 Node3DEditorViewport::_get_ray(const Vector2 &p_pos) const {
Vector3 Node3DEditorViewport::get_ray(const Vector2 &p_pos) const {
return camera->project_ray_normal(p_pos / subviewport_container->get_stretch_shrink());
}

Expand Down Expand Up @@ -769,8 +769,8 @@ void Node3DEditorViewport::_select_clicked(bool p_allow_locked) {
}

ObjectID Node3DEditorViewport::_select_ray(const Point2 &p_pos) const {
Vector3 ray = _get_ray(p_pos);
Vector3 pos = _get_ray_pos(p_pos);
Vector3 ray = get_ray(p_pos);
Vector3 pos = get_ray_pos(p_pos);
Vector2 shrinked_pos = p_pos / subviewport_container->get_stretch_shrink();

if (viewport->get_debug_draw() == Viewport::DEBUG_DRAW_SDFGI_PROBES) {
Expand Down Expand Up @@ -837,8 +837,8 @@ ObjectID Node3DEditorViewport::_select_ray(const Point2 &p_pos) const {
}

void Node3DEditorViewport::_find_items_at_pos(const Point2 &p_pos, Vector<_RayResult> &r_results, bool p_include_locked_nodes) {
Vector3 ray = _get_ray(p_pos);
Vector3 pos = _get_ray_pos(p_pos);
Vector3 ray = get_ray(p_pos);
Vector3 pos = get_ray_pos(p_pos);

Vector<ObjectID> instances = RenderingServer::get_singleton()->instances_cull_ray(pos, pos + ray * camera->get_far(), get_tree()->get_root()->get_world_3d()->get_scenario());
HashSet<Node3D *> found_nodes;
Expand Down Expand Up @@ -1153,8 +1153,8 @@ void Node3DEditorViewport::_update_name() {

void Node3DEditorViewport::_compute_edit(const Point2 &p_point) {
_edit.original_local = spatial_editor->are_local_coords_enabled();
_edit.click_ray = _get_ray(p_point);
_edit.click_ray_pos = _get_ray_pos(p_point);
_edit.click_ray = get_ray(p_point);
_edit.click_ray_pos = get_ray_pos(p_point);
_edit.plane = TRANSFORM_VIEW;
spatial_editor->update_transform_gizmo();
_edit.center = spatial_editor->get_gizmo_transform().origin;
Expand Down Expand Up @@ -1233,8 +1233,8 @@ bool Node3DEditorViewport::_transform_gizmo_select(const Vector2 &p_screenpos, b
return false;
}

Vector3 ray_pos = _get_ray_pos(p_screenpos);
Vector3 ray = _get_ray(p_screenpos);
Vector3 ray_pos = get_ray_pos(p_screenpos);
Vector3 ray = get_ray(p_screenpos);

Transform3D gt = spatial_editor->get_gizmo_transform();

Expand Down Expand Up @@ -3115,7 +3115,7 @@ void Node3DEditorViewport::_draw() {
}

if (_edit.mode == TRANSFORM_ROTATE && _edit.show_rotation_line) {
Point2 center = _point_to_screen(_edit.center);
Point2 center = point_to_screen(_edit.center);

Color handle_color;
switch (_edit.plane) {
Expand Down Expand Up @@ -4087,8 +4087,8 @@ Vector3 Node3DEditorViewport::_get_instance_position(const Point2 &p_pos) const
const float MAX_DISTANCE = 50.0;
const float FALLBACK_DISTANCE = 5.0;

Vector3 world_ray = _get_ray(p_pos);
Vector3 world_pos = _get_ray_pos(p_pos);
Vector3 world_ray = get_ray(p_pos);
Vector3 world_pos = get_ray_pos(p_pos);

PhysicsDirectSpaceState3D *ss = get_tree()->get_root()->get_world_3d()->get_direct_space_state();

Expand Down Expand Up @@ -4250,8 +4250,8 @@ bool Node3DEditorViewport::_apply_preview_material(ObjectID p_target, const Poin
Ref<Mesh> mesh = mesh_instance->get_mesh();
int surface_count = mesh->get_surface_count();

Vector3 world_ray = _get_ray(p_point);
Vector3 world_pos = _get_ray_pos(p_point);
Vector3 world_ray = get_ray(p_point);
Vector3 world_pos = get_ray_pos(p_point);

int closest_surface = -1;
float closest_dist = 1e20;
Expand Down Expand Up @@ -4698,8 +4698,8 @@ void Node3DEditorViewport::apply_transform(Vector3 p_motion, double p_snap) {

// Update the current transform operation in response to an input.
void Node3DEditorViewport::update_transform(bool p_shift) {
Vector3 ray_pos = _get_ray_pos(_edit.mouse_pos);
Vector3 ray = _get_ray(_edit.mouse_pos);
Vector3 ray_pos = get_ray_pos(_edit.mouse_pos);
Vector3 ray = get_ray(_edit.mouse_pos);
double snap = EDITOR_GET("interface/inspector/default_float_step");
int snap_step_decimals = Math::range_step_decimals(snap);

Expand Down
8 changes: 5 additions & 3 deletions editor/plugins/node_3d_editor_plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -271,9 +271,7 @@ class Node3DEditorViewport : public Control {
void _select_clicked(bool p_allow_locked);
ObjectID _select_ray(const Point2 &p_pos) const;
void _find_items_at_pos(const Point2 &p_pos, Vector<_RayResult> &r_results, bool p_include_locked);
Vector3 _get_ray_pos(const Vector2 &p_pos) const;
Vector3 _get_ray(const Vector2 &p_pos) const;
Point2 _point_to_screen(const Vector3 &p_point);

Transform3D _get_camera_transform() const;
int get_selected_count() const;
void cancel_transform();
Expand Down Expand Up @@ -481,6 +479,10 @@ class Node3DEditorViewport : public Control {
void reset();
bool is_freelook_active() const { return freelook_active; }

Vector3 get_ray_pos(const Vector2 &p_pos) const;
Vector3 get_ray(const Vector2 &p_pos) const;
Point2 point_to_screen(const Vector3 &p_point);

void focus_selection();

void assign_pending_data_pointers(
Expand Down
35 changes: 23 additions & 12 deletions editor/plugins/path_3d_editor_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,17 @@ EditorPlugin::AfterGUIInput Path3DEditorPlugin::forward_3d_gui_input(Camera3D *p
if (mb.is_valid()) {
Point2 mbpos(mb->get_position().x, mb->get_position().y);

Node3DEditorViewport *viewport = nullptr;
for (uint32_t i = 0; i < Node3DEditor::VIEWPORTS_COUNT; i++) {
Node3DEditorViewport *vp = Node3DEditor::get_singleton()->get_editor_viewport(i);
if (vp->get_camera_3d() == p_camera) {
viewport = vp;
break;
}
}

ERR_FAIL_NULL_V(viewport, EditorPlugin::AFTER_GUI_INPUT_PASS);

if (!mb->is_pressed()) {
set_handle_clicked(false);
}
Expand All @@ -489,14 +500,14 @@ EditorPlugin::AfterGUIInput Path3DEditorPlugin::forward_3d_gui_input(Camera3D *p
const Vector3 *r = v3a.ptr();
float closest_d = 1e20;

if (p_camera->unproject_position(gt.xform(c->get_point_position(0))).distance_to(mbpos) < click_dist) {
if (viewport->point_to_screen(gt.xform(c->get_point_position(0))).distance_to(mbpos) < click_dist) {
return EditorPlugin::AFTER_GUI_INPUT_PASS; //nope, existing
}

for (int i = 0; i < c->get_point_count() - 1; i++) {
//find the offset and point index of the place to break up
int j = idx;
if (p_camera->unproject_position(gt.xform(c->get_point_position(i + 1))).distance_to(mbpos) < click_dist) {
if (viewport->point_to_screen(gt.xform(c->get_point_position(i + 1))).distance_to(mbpos) < click_dist) {
return EditorPlugin::AFTER_GUI_INPUT_PASS; //nope, existing
}

Expand All @@ -508,16 +519,16 @@ EditorPlugin::AfterGUIInput Path3DEditorPlugin::forward_3d_gui_input(Camera3D *p
to = gt.xform(to);
if (cdist > 0) {
Vector2 s[2];
s[0] = p_camera->unproject_position(from);
s[1] = p_camera->unproject_position(to);
s[0] = viewport->point_to_screen(from);
s[1] = viewport->point_to_screen(to);
Vector2 inters = Geometry2D::get_closest_point_to_segment(mbpos, s);
float d = inters.distance_to(mbpos);

if (d < 10 && d < closest_d) {
closest_d = d;
closest_seg = i;
Vector3 ray_from = p_camera->project_ray_origin(mbpos);
Vector3 ray_dir = p_camera->project_ray_normal(mbpos);
Vector3 ray_from = viewport->get_ray_pos(mbpos);
Vector3 ray_dir = viewport->get_ray(mbpos);

Vector3 ra, rb;
Geometry3D::get_closest_points_between_segments(ray_from, ray_from + ray_dir * 4096, from, to, ra, rb);
Expand Down Expand Up @@ -557,8 +568,8 @@ EditorPlugin::AfterGUIInput Path3DEditorPlugin::forward_3d_gui_input(Camera3D *p
origin = gt.xform(c->get_point_position(c->get_point_count() - 1));
}
Plane p(p_camera->get_transform().basis.get_column(2), origin);
Vector3 ray_from = p_camera->project_ray_origin(mbpos);
Vector3 ray_dir = p_camera->project_ray_normal(mbpos);
Vector3 ray_from = viewport->get_ray_pos(mbpos);
Vector3 ray_dir = viewport->get_ray(mbpos);

Vector3 inters;
if (p.intersects_ray(ray_from, ray_dir, &inters)) {
Expand All @@ -574,10 +585,10 @@ EditorPlugin::AfterGUIInput Path3DEditorPlugin::forward_3d_gui_input(Camera3D *p

} else if (mb->is_pressed() && ((mb->get_button_index() == MouseButton::LEFT && curve_del->is_pressed()) || (mb->get_button_index() == MouseButton::RIGHT && curve_edit->is_pressed()))) {
for (int i = 0; i < c->get_point_count(); i++) {
real_t dist_to_p = p_camera->unproject_position(gt.xform(c->get_point_position(i))).distance_to(mbpos);
real_t dist_to_p_out = p_camera->unproject_position(gt.xform(c->get_point_position(i) + c->get_point_out(i))).distance_to(mbpos);
real_t dist_to_p_in = p_camera->unproject_position(gt.xform(c->get_point_position(i) + c->get_point_in(i))).distance_to(mbpos);
real_t dist_to_p_up = p_camera->unproject_position(gt.xform(c->get_point_position(i) + c->get_point_baked_posture(i, true).get_column(1) * disk_size)).distance_to(mbpos);
real_t dist_to_p = viewport->point_to_screen(gt.xform(c->get_point_position(i))).distance_to(mbpos);
real_t dist_to_p_out = viewport->point_to_screen(gt.xform(c->get_point_position(i) + c->get_point_out(i))).distance_to(mbpos);
real_t dist_to_p_in = viewport->point_to_screen(gt.xform(c->get_point_position(i) + c->get_point_in(i))).distance_to(mbpos);
real_t dist_to_p_up = viewport->point_to_screen(gt.xform(c->get_point_position(i) + c->get_point_baked_posture(i, true).get_column(1) * disk_size)).distance_to(mbpos);

// Find the offset and point index of the place to break up.
// Also check for the control points.
Expand Down
Loading