瀏覽代碼

Fix using Viewport::warp_mouse within Viewports

Markus Sauermann 3 年之前
父節點
當前提交
ffe42171a5
共有 4 個文件被更改,包括 35 次插入1 次删除
  1. 20 1
      scene/main/viewport.cpp
  2. 4 0
      scene/main/viewport.h
  3. 9 0
      scene/main/window.cpp
  4. 2 0
      scene/main/window.h

+ 20 - 1
scene/main/viewport.cpp

@@ -1125,7 +1125,8 @@ Vector2 Viewport::get_mouse_position() const {
 }
 
 void Viewport::warp_mouse(const Vector2 &p_position) {
-	Vector2 gpos = (get_final_transform().affine_inverse() * _get_input_pre_xform()).affine_inverse().xform(p_position);
+	Transform2D xform = get_screen_transform();
+	Vector2 gpos = xform.xform(p_position).round();
 	Input::get_singleton()->warp_mouse(gpos);
 }
 
@@ -3134,6 +3135,10 @@ Viewport::SDFScale Viewport::get_sdf_scale() const {
 	return sdf_scale;
 }
 
+Transform2D Viewport::get_screen_transform() const {
+	return _get_input_pre_xform().affine_inverse() * get_final_transform();
+}
+
 #ifndef _3D_DISABLED
 AudioListener3D *Viewport::get_audio_listener_3d() const {
 	return audio_listener_3d;
@@ -3992,6 +3997,20 @@ Transform2D SubViewport::_stretch_transform() {
 	return transform;
 }
 
+Transform2D SubViewport::get_screen_transform() const {
+	Transform2D container_transform = Transform2D();
+	SubViewportContainer *c = Object::cast_to<SubViewportContainer>(get_parent());
+	if (c) {
+		if (c->is_stretch_enabled()) {
+			container_transform.scale(Vector2(c->get_stretch_shrink(), c->get_stretch_shrink()));
+		}
+		container_transform = c->get_viewport()->get_screen_transform() * c->get_global_transform_with_canvas() * container_transform;
+	} else {
+		WARN_PRINT_ONCE("SubViewport is not a child of a SubViewportContainer. get_screen_transform doesn't return the actual screen position.");
+	}
+	return container_transform * Viewport::get_screen_transform();
+}
+
 void SubViewport::_notification(int p_what) {
 	switch (p_what) {
 		case NOTIFICATION_ENTER_TREE: {

+ 4 - 0
scene/main/viewport.h

@@ -609,6 +609,8 @@ public:
 
 	void pass_mouse_focus_to(Viewport *p_viewport, Control *p_control);
 
+	virtual Transform2D get_screen_transform() const;
+
 #ifndef _3D_DISABLED
 	bool use_xr = false;
 	friend class AudioListener3D;
@@ -732,6 +734,8 @@ public:
 	void set_clear_mode(ClearMode p_mode);
 	ClearMode get_clear_mode() const;
 
+	virtual Transform2D get_screen_transform() const override;
+
 	SubViewport();
 	~SubViewport();
 };

+ 9 - 0
scene/main/window.cpp

@@ -1452,6 +1452,15 @@ void Window::_validate_property(PropertyInfo &property) const {
 	}
 }
 
+Transform2D Window::get_screen_transform() const {
+	Transform2D embedder_transform = Transform2D();
+	if (_get_embedder()) {
+		embedder_transform.translate(get_position());
+		embedder_transform = _get_embedder()->get_screen_transform() * embedder_transform;
+	}
+	return embedder_transform * Viewport::get_screen_transform();
+}
+
 void Window::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("set_title", "title"), &Window::set_title);
 	ClassDB::bind_method(D_METHOD("get_title"), &Window::get_title);

+ 2 - 0
scene/main/window.h

@@ -291,6 +291,8 @@ public:
 	Ref<Font> get_theme_default_font() const;
 	int get_theme_default_font_size() const;
 
+	virtual Transform2D get_screen_transform() const override;
+
 	Rect2i get_parent_rect() const;
 	virtual DisplayServer::WindowID get_window_id() const override;