You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-11 13:10:58 +00:00
Fix freelook in 3D when multiple viewports are open
This commit is contained in:
@@ -1671,6 +1671,33 @@ void Node3DEditorViewport::_list_select(Ref<InputEventMouseButton> b) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper function to redirect mouse events to the active freelook viewport
|
||||||
|
static bool _redirect_freelook_input(const Ref<InputEvent> &p_event, Node3DEditorViewport *p_exclude_viewport = nullptr) {
|
||||||
|
if (Input::get_singleton()->get_mouse_mode() != Input::MOUSE_MODE_CAPTURED) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node3DEditor *editor = Node3DEditor::get_singleton();
|
||||||
|
if (!editor->get_freelook_viewport()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node3DEditorViewport *freelook_vp = editor->get_freelook_viewport();
|
||||||
|
if (freelook_vp == p_exclude_viewport) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ref<InputEventMouse> mouse_event = p_event;
|
||||||
|
if (!mouse_event.is_valid()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Control *target_surface = freelook_vp->get_surface();
|
||||||
|
|
||||||
|
target_surface->emit_signal(SceneStringName(gui_input), p_event);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// This is only active during instant transforms,
|
// This is only active during instant transforms,
|
||||||
// to capture and wrap mouse events outside the control.
|
// to capture and wrap mouse events outside the control.
|
||||||
void Node3DEditorViewport::input(const Ref<InputEvent> &p_event) {
|
void Node3DEditorViewport::input(const Ref<InputEvent> &p_event) {
|
||||||
@@ -1688,6 +1715,10 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
|
|||||||
return; //do NONE
|
return; //do NONE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_redirect_freelook_input(p_event, this)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
EditorPlugin::AfterGUIInput after = EditorPlugin::AFTER_GUI_INPUT_PASS;
|
EditorPlugin::AfterGUIInput after = EditorPlugin::AFTER_GUI_INPUT_PASS;
|
||||||
{
|
{
|
||||||
EditorNode *en = EditorNode::get_singleton();
|
EditorNode *en = EditorNode::get_singleton();
|
||||||
@@ -2702,6 +2733,8 @@ void Node3DEditorViewport::set_freelook_active(bool active_now) {
|
|||||||
|
|
||||||
previous_mouse_position = get_local_mouse_position();
|
previous_mouse_position = get_local_mouse_position();
|
||||||
|
|
||||||
|
spatial_editor->set_freelook_viewport(this);
|
||||||
|
|
||||||
// Hide mouse like in an FPS (warping doesn't work)
|
// Hide mouse like in an FPS (warping doesn't work)
|
||||||
Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_CAPTURED);
|
Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_CAPTURED);
|
||||||
|
|
||||||
@@ -2709,6 +2742,8 @@ void Node3DEditorViewport::set_freelook_active(bool active_now) {
|
|||||||
// Sync camera cursor to cursor to "cut" interpolation jumps due to changing referential
|
// Sync camera cursor to cursor to "cut" interpolation jumps due to changing referential
|
||||||
cursor = camera_cursor;
|
cursor = camera_cursor;
|
||||||
|
|
||||||
|
spatial_editor->set_freelook_viewport(nullptr);
|
||||||
|
|
||||||
// Restore mouse
|
// Restore mouse
|
||||||
Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE);
|
Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE);
|
||||||
|
|
||||||
@@ -5990,6 +6025,10 @@ Node3DEditorViewport::~Node3DEditorViewport() {
|
|||||||
void Node3DEditorViewportContainer::gui_input(const Ref<InputEvent> &p_event) {
|
void Node3DEditorViewportContainer::gui_input(const Ref<InputEvent> &p_event) {
|
||||||
ERR_FAIL_COND(p_event.is_null());
|
ERR_FAIL_COND(p_event.is_null());
|
||||||
|
|
||||||
|
if (_redirect_freelook_input(p_event)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Ref<InputEventMouseButton> mb = p_event;
|
Ref<InputEventMouseButton> mb = p_event;
|
||||||
|
|
||||||
if (mb.is_valid() && mb->get_button_index() == MouseButton::LEFT) {
|
if (mb.is_valid() && mb->get_button_index() == MouseButton::LEFT) {
|
||||||
@@ -6084,7 +6123,7 @@ void Node3DEditorViewportContainer::_notification(int p_what) {
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
case NOTIFICATION_DRAW: {
|
case NOTIFICATION_DRAW: {
|
||||||
if (mouseover) {
|
if (mouseover && Input::get_singleton()->get_mouse_mode() != Input::MOUSE_MODE_CAPTURED) {
|
||||||
Ref<Texture2D> h_grabber = get_theme_icon(SNAME("grabber"), SNAME("HSplitContainer"));
|
Ref<Texture2D> h_grabber = get_theme_icon(SNAME("grabber"), SNAME("HSplitContainer"));
|
||||||
Ref<Texture2D> v_grabber = get_theme_icon(SNAME("grabber"), SNAME("VSplitContainer"));
|
Ref<Texture2D> v_grabber = get_theme_icon(SNAME("grabber"), SNAME("VSplitContainer"));
|
||||||
|
|
||||||
|
|||||||
@@ -560,6 +560,7 @@ public:
|
|||||||
|
|
||||||
SubViewport *get_viewport_node() { return viewport; }
|
SubViewport *get_viewport_node() { return viewport; }
|
||||||
Camera3D *get_camera_3d() { return camera; } // return the default camera object.
|
Camera3D *get_camera_3d() { return camera; } // return the default camera object.
|
||||||
|
Control *get_surface() { return surface; }
|
||||||
|
|
||||||
Node3DEditorViewport(Node3DEditor *p_spatial_editor, int p_index);
|
Node3DEditorViewport(Node3DEditor *p_spatial_editor, int p_index);
|
||||||
~Node3DEditorViewport();
|
~Node3DEditorViewport();
|
||||||
@@ -825,6 +826,8 @@ private:
|
|||||||
|
|
||||||
Node3D *selected = nullptr;
|
Node3D *selected = nullptr;
|
||||||
|
|
||||||
|
Node3DEditorViewport *freelook_viewport = nullptr;
|
||||||
|
|
||||||
void _request_gizmo(Object *p_obj);
|
void _request_gizmo(Object *p_obj);
|
||||||
void _request_gizmo_for_id(ObjectID p_id);
|
void _request_gizmo_for_id(ObjectID p_id);
|
||||||
void _set_subgizmo_selection(Object *p_obj, Ref<Node3DGizmo> p_gizmo, int p_id, Transform3D p_transform = Transform3D());
|
void _set_subgizmo_selection(Object *p_obj, Ref<Node3DGizmo> p_gizmo, int p_id, Transform3D p_transform = Transform3D());
|
||||||
@@ -1025,6 +1028,9 @@ public:
|
|||||||
}
|
}
|
||||||
Node3DEditorViewport *get_last_used_viewport();
|
Node3DEditorViewport *get_last_used_viewport();
|
||||||
|
|
||||||
|
void set_freelook_viewport(Node3DEditorViewport *p_viewport) { freelook_viewport = p_viewport; }
|
||||||
|
Node3DEditorViewport *get_freelook_viewport() const { return freelook_viewport; }
|
||||||
|
|
||||||
void add_gizmo_plugin(Ref<EditorNode3DGizmoPlugin> p_plugin);
|
void add_gizmo_plugin(Ref<EditorNode3DGizmoPlugin> p_plugin);
|
||||||
void remove_gizmo_plugin(Ref<EditorNode3DGizmoPlugin> p_plugin);
|
void remove_gizmo_plugin(Ref<EditorNode3DGizmoPlugin> p_plugin);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user