Merge pull request #89901 from jsjtxietian/path3d
Fix Path3D picking working incorrectly when viewport is in half resolution
This commit is contained in:
commit
3fa6ec7285
3 changed files with 46 additions and 33 deletions
|
@ -691,11 +691,11 @@ Vector3 Node3DEditorViewport::_get_camera_position() const {
|
||||||
return _get_camera_transform().origin;
|
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();
|
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());
|
return camera->project_ray_origin(p_pos / subviewport_container->get_stretch_shrink());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -703,7 +703,7 @@ Vector3 Node3DEditorViewport::_get_camera_normal() const {
|
||||||
return -_get_camera_transform().basis.get_column(2);
|
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());
|
return camera->project_ray_normal(p_pos / subviewport_container->get_stretch_shrink());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -769,8 +769,8 @@ void Node3DEditorViewport::_select_clicked(bool p_allow_locked) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectID Node3DEditorViewport::_select_ray(const Point2 &p_pos) const {
|
ObjectID Node3DEditorViewport::_select_ray(const Point2 &p_pos) const {
|
||||||
Vector3 ray = _get_ray(p_pos);
|
Vector3 ray = get_ray(p_pos);
|
||||||
Vector3 pos = _get_ray_pos(p_pos);
|
Vector3 pos = get_ray_pos(p_pos);
|
||||||
Vector2 shrinked_pos = p_pos / subviewport_container->get_stretch_shrink();
|
Vector2 shrinked_pos = p_pos / subviewport_container->get_stretch_shrink();
|
||||||
|
|
||||||
if (viewport->get_debug_draw() == Viewport::DEBUG_DRAW_SDFGI_PROBES) {
|
if (viewport->get_debug_draw() == Viewport::DEBUG_DRAW_SDFGI_PROBES) {
|
||||||
|
@ -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) {
|
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 ray = get_ray(p_pos);
|
||||||
Vector3 pos = _get_ray_pos(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());
|
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;
|
HashSet<Node3D *> found_nodes;
|
||||||
|
@ -1153,8 +1153,8 @@ void Node3DEditorViewport::_update_name() {
|
||||||
|
|
||||||
void Node3DEditorViewport::_compute_edit(const Point2 &p_point) {
|
void Node3DEditorViewport::_compute_edit(const Point2 &p_point) {
|
||||||
_edit.original_local = spatial_editor->are_local_coords_enabled();
|
_edit.original_local = spatial_editor->are_local_coords_enabled();
|
||||||
_edit.click_ray = _get_ray(p_point);
|
_edit.click_ray = get_ray(p_point);
|
||||||
_edit.click_ray_pos = _get_ray_pos(p_point);
|
_edit.click_ray_pos = get_ray_pos(p_point);
|
||||||
_edit.plane = TRANSFORM_VIEW;
|
_edit.plane = TRANSFORM_VIEW;
|
||||||
spatial_editor->update_transform_gizmo();
|
spatial_editor->update_transform_gizmo();
|
||||||
_edit.center = spatial_editor->get_gizmo_transform().origin;
|
_edit.center = spatial_editor->get_gizmo_transform().origin;
|
||||||
|
@ -1233,8 +1233,8 @@ bool Node3DEditorViewport::_transform_gizmo_select(const Vector2 &p_screenpos, b
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3 ray_pos = _get_ray_pos(p_screenpos);
|
Vector3 ray_pos = get_ray_pos(p_screenpos);
|
||||||
Vector3 ray = _get_ray(p_screenpos);
|
Vector3 ray = get_ray(p_screenpos);
|
||||||
|
|
||||||
Transform3D gt = spatial_editor->get_gizmo_transform();
|
Transform3D gt = spatial_editor->get_gizmo_transform();
|
||||||
|
|
||||||
|
@ -3115,7 +3115,7 @@ void Node3DEditorViewport::_draw() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_edit.mode == TRANSFORM_ROTATE && _edit.show_rotation_line) {
|
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;
|
Color handle_color;
|
||||||
switch (_edit.plane) {
|
switch (_edit.plane) {
|
||||||
|
@ -4087,8 +4087,8 @@ Vector3 Node3DEditorViewport::_get_instance_position(const Point2 &p_pos) const
|
||||||
const float MAX_DISTANCE = 50.0;
|
const float MAX_DISTANCE = 50.0;
|
||||||
const float FALLBACK_DISTANCE = 5.0;
|
const float FALLBACK_DISTANCE = 5.0;
|
||||||
|
|
||||||
Vector3 world_ray = _get_ray(p_pos);
|
Vector3 world_ray = get_ray(p_pos);
|
||||||
Vector3 world_pos = _get_ray_pos(p_pos);
|
Vector3 world_pos = get_ray_pos(p_pos);
|
||||||
|
|
||||||
PhysicsDirectSpaceState3D *ss = get_tree()->get_root()->get_world_3d()->get_direct_space_state();
|
PhysicsDirectSpaceState3D *ss = get_tree()->get_root()->get_world_3d()->get_direct_space_state();
|
||||||
|
|
||||||
|
@ -4250,8 +4250,8 @@ bool Node3DEditorViewport::_apply_preview_material(ObjectID p_target, const Poin
|
||||||
Ref<Mesh> mesh = mesh_instance->get_mesh();
|
Ref<Mesh> mesh = mesh_instance->get_mesh();
|
||||||
int surface_count = mesh->get_surface_count();
|
int surface_count = mesh->get_surface_count();
|
||||||
|
|
||||||
Vector3 world_ray = _get_ray(p_point);
|
Vector3 world_ray = get_ray(p_point);
|
||||||
Vector3 world_pos = _get_ray_pos(p_point);
|
Vector3 world_pos = get_ray_pos(p_point);
|
||||||
|
|
||||||
int closest_surface = -1;
|
int closest_surface = -1;
|
||||||
float closest_dist = 1e20;
|
float closest_dist = 1e20;
|
||||||
|
@ -4698,8 +4698,8 @@ void Node3DEditorViewport::apply_transform(Vector3 p_motion, double p_snap) {
|
||||||
|
|
||||||
// Update the current transform operation in response to an input.
|
// Update the current transform operation in response to an input.
|
||||||
void Node3DEditorViewport::update_transform(bool p_shift) {
|
void Node3DEditorViewport::update_transform(bool p_shift) {
|
||||||
Vector3 ray_pos = _get_ray_pos(_edit.mouse_pos);
|
Vector3 ray_pos = get_ray_pos(_edit.mouse_pos);
|
||||||
Vector3 ray = _get_ray(_edit.mouse_pos);
|
Vector3 ray = get_ray(_edit.mouse_pos);
|
||||||
double snap = EDITOR_GET("interface/inspector/default_float_step");
|
double snap = EDITOR_GET("interface/inspector/default_float_step");
|
||||||
int snap_step_decimals = Math::range_step_decimals(snap);
|
int snap_step_decimals = Math::range_step_decimals(snap);
|
||||||
|
|
||||||
|
|
|
@ -271,9 +271,7 @@ private:
|
||||||
void _select_clicked(bool p_allow_locked);
|
void _select_clicked(bool p_allow_locked);
|
||||||
ObjectID _select_ray(const Point2 &p_pos) const;
|
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);
|
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;
|
Transform3D _get_camera_transform() const;
|
||||||
int get_selected_count() const;
|
int get_selected_count() const;
|
||||||
void cancel_transform();
|
void cancel_transform();
|
||||||
|
@ -481,6 +479,10 @@ public:
|
||||||
void reset();
|
void reset();
|
||||||
bool is_freelook_active() const { return freelook_active; }
|
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 focus_selection();
|
||||||
|
|
||||||
void assign_pending_data_pointers(
|
void assign_pending_data_pointers(
|
||||||
|
|
|
@ -473,6 +473,17 @@ EditorPlugin::AfterGUIInput Path3DEditorPlugin::forward_3d_gui_input(Camera3D *p
|
||||||
if (mb.is_valid()) {
|
if (mb.is_valid()) {
|
||||||
Point2 mbpos(mb->get_position().x, mb->get_position().y);
|
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()) {
|
if (!mb->is_pressed()) {
|
||||||
set_handle_clicked(false);
|
set_handle_clicked(false);
|
||||||
}
|
}
|
||||||
|
@ -489,14 +500,14 @@ EditorPlugin::AfterGUIInput Path3DEditorPlugin::forward_3d_gui_input(Camera3D *p
|
||||||
const Vector3 *r = v3a.ptr();
|
const Vector3 *r = v3a.ptr();
|
||||||
float closest_d = 1e20;
|
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
|
return EditorPlugin::AFTER_GUI_INPUT_PASS; //nope, existing
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < c->get_point_count() - 1; i++) {
|
for (int i = 0; i < c->get_point_count() - 1; i++) {
|
||||||
//find the offset and point index of the place to break up
|
//find the offset and point index of the place to break up
|
||||||
int j = idx;
|
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
|
return EditorPlugin::AFTER_GUI_INPUT_PASS; //nope, existing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -508,16 +519,16 @@ EditorPlugin::AfterGUIInput Path3DEditorPlugin::forward_3d_gui_input(Camera3D *p
|
||||||
to = gt.xform(to);
|
to = gt.xform(to);
|
||||||
if (cdist > 0) {
|
if (cdist > 0) {
|
||||||
Vector2 s[2];
|
Vector2 s[2];
|
||||||
s[0] = p_camera->unproject_position(from);
|
s[0] = viewport->point_to_screen(from);
|
||||||
s[1] = p_camera->unproject_position(to);
|
s[1] = viewport->point_to_screen(to);
|
||||||
Vector2 inters = Geometry2D::get_closest_point_to_segment(mbpos, s);
|
Vector2 inters = Geometry2D::get_closest_point_to_segment(mbpos, s);
|
||||||
float d = inters.distance_to(mbpos);
|
float d = inters.distance_to(mbpos);
|
||||||
|
|
||||||
if (d < 10 && d < closest_d) {
|
if (d < 10 && d < closest_d) {
|
||||||
closest_d = d;
|
closest_d = d;
|
||||||
closest_seg = i;
|
closest_seg = i;
|
||||||
Vector3 ray_from = p_camera->project_ray_origin(mbpos);
|
Vector3 ray_from = viewport->get_ray_pos(mbpos);
|
||||||
Vector3 ray_dir = p_camera->project_ray_normal(mbpos);
|
Vector3 ray_dir = viewport->get_ray(mbpos);
|
||||||
|
|
||||||
Vector3 ra, rb;
|
Vector3 ra, rb;
|
||||||
Geometry3D::get_closest_points_between_segments(ray_from, ray_from + ray_dir * 4096, from, to, ra, rb);
|
Geometry3D::get_closest_points_between_segments(ray_from, ray_from + ray_dir * 4096, from, to, ra, rb);
|
||||||
|
@ -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));
|
origin = gt.xform(c->get_point_position(c->get_point_count() - 1));
|
||||||
}
|
}
|
||||||
Plane p(p_camera->get_transform().basis.get_column(2), origin);
|
Plane p(p_camera->get_transform().basis.get_column(2), origin);
|
||||||
Vector3 ray_from = p_camera->project_ray_origin(mbpos);
|
Vector3 ray_from = viewport->get_ray_pos(mbpos);
|
||||||
Vector3 ray_dir = p_camera->project_ray_normal(mbpos);
|
Vector3 ray_dir = viewport->get_ray(mbpos);
|
||||||
|
|
||||||
Vector3 inters;
|
Vector3 inters;
|
||||||
if (p.intersects_ray(ray_from, ray_dir, &inters)) {
|
if (p.intersects_ray(ray_from, ray_dir, &inters)) {
|
||||||
|
@ -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()))) {
|
} 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++) {
|
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 = viewport->point_to_screen(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_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 = p_camera->unproject_position(gt.xform(c->get_point_position(i) + c->get_point_in(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 = 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_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.
|
// Find the offset and point index of the place to break up.
|
||||||
// Also check for the control points.
|
// Also check for the control points.
|
||||||
|
|
Loading…
Add table
Reference in a new issue