From 9be2f7090a4c5213765c7d2a11d8a431e4a5b6c7 Mon Sep 17 00:00:00 2001 From: Radiant Date: Thu, 2 May 2024 16:25:48 +0300 Subject: [PATCH] Implement offset_rect property to MobileVRInterface to allow changing screen area. --- .../doc_classes/MobileVRInterface.xml | 3 +++ modules/mobile_vr/mobile_vr_interface.cpp | 20 ++++++++++++++++--- modules/mobile_vr/mobile_vr_interface.h | 5 +++++ 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/modules/mobile_vr/doc_classes/MobileVRInterface.xml b/modules/mobile_vr/doc_classes/MobileVRInterface.xml index 1be8cc828da..83380541426 100644 --- a/modules/mobile_vr/doc_classes/MobileVRInterface.xml +++ b/modules/mobile_vr/doc_classes/MobileVRInterface.xml @@ -34,6 +34,9 @@ The k2 lens factor, see k1. + + Set the offset rect relative to the area being rendered. A length of 1 represents the whole rendering area on that axis. + The oversample setting. Because of the lens distortion we have to render our buffers at a higher resolution then the screen can natively handle. A value between 1.5 and 2.0 often provides good results but at the cost of performance. diff --git a/modules/mobile_vr/mobile_vr_interface.cpp b/modules/mobile_vr/mobile_vr_interface.cpp index 94a3f0777ea..8086975a1f5 100644 --- a/modules/mobile_vr/mobile_vr_interface.cpp +++ b/modules/mobile_vr/mobile_vr_interface.cpp @@ -230,6 +230,9 @@ void MobileVRInterface::_bind_methods() { ClassDB::bind_method(D_METHOD("set_display_to_lens", "display_to_lens"), &MobileVRInterface::set_display_to_lens); ClassDB::bind_method(D_METHOD("get_display_to_lens"), &MobileVRInterface::get_display_to_lens); + ClassDB::bind_method(D_METHOD("set_offset_rect", "offset_rect"), &MobileVRInterface::set_offset_rect); + ClassDB::bind_method(D_METHOD("get_offset_rect"), &MobileVRInterface::get_offset_rect); + ClassDB::bind_method(D_METHOD("set_oversample", "oversample"), &MobileVRInterface::set_oversample); ClassDB::bind_method(D_METHOD("get_oversample"), &MobileVRInterface::get_oversample); @@ -243,6 +246,7 @@ void MobileVRInterface::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "iod", PROPERTY_HINT_RANGE, "4.0,10.0,0.1"), "set_iod", "get_iod"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "display_width", PROPERTY_HINT_RANGE, "5.0,25.0,0.1"), "set_display_width", "get_display_width"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "display_to_lens", PROPERTY_HINT_RANGE, "5.0,25.0,0.1"), "set_display_to_lens", "get_display_to_lens"); + ADD_PROPERTY(PropertyInfo(Variant::RECT2, "offset_rect"), "set_offset_rect", "get_offset_rect"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "oversample", PROPERTY_HINT_RANGE, "1.0,2.0,0.1"), "set_oversample", "get_oversample"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "k1", PROPERTY_HINT_RANGE, "0.1,10.0,0.0001"), "set_k1", "get_k1"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "k2", PROPERTY_HINT_RANGE, "0.1,10.0,0.0001"), "set_k2", "get_k2"); @@ -256,6 +260,14 @@ double MobileVRInterface::get_eye_height() const { return eye_height; } +void MobileVRInterface::set_offset_rect(const Rect2 &p_offset_rect) { + offset_rect = p_offset_rect; +} + +Rect2 MobileVRInterface::get_offset_rect() const { + return offset_rect; +} + void MobileVRInterface::set_iod(const double p_iod) { intraocular_dist = p_iod; }; @@ -483,6 +495,8 @@ Vector MobileVRInterface::post_draw_viewport(RID p_render_target, // Because we are rendering to our device we must use our main viewport! ERR_FAIL_COND_V(p_screen_rect == Rect2(), blit_to_screen); + Rect2 modified_screen_rect = Rect2(p_screen_rect.position + offset_rect.position * p_screen_rect.size, p_screen_rect.size * offset_rect.size); + // and add our blits BlitToScreen blit; blit.render_target = p_render_target; @@ -494,16 +508,16 @@ Vector MobileVRInterface::post_draw_viewport(RID p_render_target, blit.lens_distortion.aspect_ratio = aspect; // left eye - blit.dst_rect = p_screen_rect; + blit.dst_rect = modified_screen_rect; blit.dst_rect.size.width *= 0.5; blit.multi_view.layer = 0; blit.lens_distortion.eye_center.x = ((-intraocular_dist / 2.0) + (display_width / 4.0)) / (display_width / 2.0); blit_to_screen.push_back(blit); // right eye - blit.dst_rect = p_screen_rect; + blit.dst_rect = modified_screen_rect; blit.dst_rect.size.width *= 0.5; - blit.dst_rect.position.x = blit.dst_rect.size.width; + blit.dst_rect.position.x += blit.dst_rect.size.width; blit.multi_view.layer = 1; blit.lens_distortion.eye_center.x = ((intraocular_dist / 2.0) - (display_width / 4.0)) / (display_width / 2.0); blit_to_screen.push_back(blit); diff --git a/modules/mobile_vr/mobile_vr_interface.h b/modules/mobile_vr/mobile_vr_interface.h index f680d8aa115..e1d43fff741 100644 --- a/modules/mobile_vr/mobile_vr_interface.h +++ b/modules/mobile_vr/mobile_vr_interface.h @@ -62,6 +62,8 @@ private: double display_to_lens = 4.0; double oversample = 1.5; + Rect2 offset_rect = Rect2(0, 0, 1, 1); // Full screen rect. + double k1 = 0.215; double k2 = 0.215; double aspect = 1.0; @@ -121,6 +123,9 @@ public: void set_display_width(const double p_display_width); double get_display_width() const; + void set_offset_rect(const Rect2 &p_offset_rect); + Rect2 get_offset_rect() const; + void set_display_to_lens(const double p_display_to_lens); double get_display_to_lens() const;