From 31940c784a6c33de1c9e59004a8982b348ee3c36 Mon Sep 17 00:00:00 2001 From: lawnjelly Date: Sat, 24 Aug 2024 14:22:07 +0100 Subject: [PATCH 1/3] Safe `Camera::unproject_position()` `unproject_position()` can fail in some circumstances, and this needs to be conveyed to calling code. --- editor/spatial_editor_gizmos.cpp | 13 +++++-- scene/3d/camera.cpp | 66 ++++++++++++++++++++++++++++---- scene/3d/camera.h | 1 + 3 files changed, 70 insertions(+), 10 deletions(-) diff --git a/editor/spatial_editor_gizmos.cpp b/editor/spatial_editor_gizmos.cpp index 4546c0742cd8..a4b7f25d4358 100644 --- a/editor/spatial_editor_gizmos.cpp +++ b/editor/spatial_editor_gizmos.cpp @@ -586,7 +586,10 @@ bool EditorSpatialGizmo::intersect_ray(Camera *p_camera, const Point2 &p_point, for (int i = 0; i < handles.size(); i++) { Vector3 hpos = t.xform(handles[i]); - Vector2 p = p_camera->unproject_position(hpos); + Vector2 p; + if (!p_camera->safe_unproject_position(hpos, p)) { + continue; + } if (p.distance_to(p_point) < HANDLE_HALF_SIZE) { real_t dp = p_camera->get_transform().origin.distance_to(hpos); @@ -665,8 +668,12 @@ bool EditorSpatialGizmo::intersect_ray(Camera *p_camera, const Point2 &p_point, Vector3 a = t.xform(vptr[i * 2 + 0]); Vector3 b = t.xform(vptr[i * 2 + 1]); Vector2 s[2]; - s[0] = p_camera->unproject_position(a); - s[1] = p_camera->unproject_position(b); + if (!p_camera->safe_unproject_position(a, s[0])) { + continue; + } + if (!p_camera->safe_unproject_position(b, s[1])) { + continue; + } Vector2 p = Geometry::get_closest_point_to_segment_2d(p_point, s); diff --git a/scene/3d/camera.cpp b/scene/3d/camera.cpp index e85b1eb50be3..218e3dcb3bee 100644 --- a/scene/3d/camera.cpp +++ b/scene/3d/camera.cpp @@ -465,8 +465,8 @@ Vector Camera::get_near_plane_points() const { return points; } -Point2 Camera::unproject_position(const Vector3 &p_pos) const { - ERR_FAIL_COND_V_MSG(!is_inside_tree(), Vector2(), "Camera is not inside scene."); +bool Camera::safe_unproject_position(const Vector3 &p_pos, Point2 &r_result) const { + ERR_FAIL_COND_V_MSG(!is_inside_tree(), false, "Camera is not inside scene."); Size2 viewport_size = get_viewport()->get_visible_rect().size; @@ -478,19 +478,71 @@ Point2 Camera::unproject_position(const Vector3 &p_pos) const { cm.set_perspective(fov, viewport_size.aspect(), near, far, keep_aspect == KEEP_WIDTH); } + // These are homogeneous coordinates, as Godot 3 has no Vector4. + // The 1.0 will later become w, the perspective divide. Plane p(get_camera_transform().xform_inv(p_pos), 1.0); p = cm.xform4(p); - // Prevent divide by zero. - // TODO : Investigate, this was causing Nans. - ERR_FAIL_COND_V(p.d == 0, Point2()); + // If p.d is zero, there is a potential divide by zero ahead. + // This can occur if the test point is exactly on the focal plane + // with a perspective camera matrix (i.e. behind the near plane). + + // There are two possibilities here: + // Either the test point is exactly at the origin, in which case the unprojected + // point should theoretically be the center of the viewport, OR + // infinity distance from the center of the viewport. + + // We should also handle the case where the test point is CLOSE + // to the focal plane. + // This can cause returned unprojected results near infinity. + // The epsilon chosen here must be small, but still allow for near planes quite close to zero. + + // Here we return false and let the calling routine handle this error condition. + if (Math::absf(p.d) < CMP_EPSILON) { + // Bodge some kind of result at infinity from the viewport center. + r_result = Point2(); + + // The viewport size here is irrelevant, we just want a high number + // (representing infinity) but not actually close to infinity to prevent + // knock on bugs if later maths later does something with these values. + // Suffice is for them to be WAY off the main viewport. + const float SOME_HIGH_VALUE = 100000.0f; + if (p.normal.x > 0) { + r_result.x = SOME_HIGH_VALUE; + } else if (p.normal.x < 0) { + r_result.x = -SOME_HIGH_VALUE; + } + if (p.normal.y > 0) { + r_result.y = SOME_HIGH_VALUE; + } else if (p.normal.y < 0) { + r_result.y = -SOME_HIGH_VALUE; + } + + return false; + } p.normal /= p.d; + r_result.x = (p.normal.x * 0.5 + 0.5) * viewport_size.x; + r_result.y = (-p.normal.y * 0.5 + 0.5) * viewport_size.y; + + return true; +} + +Point2 Camera::unproject_position(const Vector3 &p_pos) const { + ERR_FAIL_COND_V_MSG(!is_inside_tree(), Point2(), "Camera is not inside scene."); + Point2 res; - res.x = (p.normal.x * 0.5 + 0.5) * viewport_size.x; - res.y = (-p.normal.y * 0.5 + 0.5) * viewport_size.y; + // Unproject can fail if the test point is on the camera matrix focal plane + // with a perspective transform. + // In this case, the unprojected point is potentially at infinity from the viewport + // center. + if (!safe_unproject_position(p_pos, res)) { +#ifdef DEV_ENABLED + WARN_PRINT_ONCE("Camera::unproject_position() unprojecting points on the focal plane is unreliable."); +#endif + } return res; } diff --git a/scene/3d/camera.h b/scene/3d/camera.h index e090185eeaee..afa95b046bbe 100644 --- a/scene/3d/camera.h +++ b/scene/3d/camera.h @@ -173,6 +173,7 @@ class Camera : public Spatial { virtual Vector3 project_ray_origin(const Point2 &p_pos) const; virtual Vector3 project_local_ray_normal(const Point2 &p_pos) const; virtual Point2 unproject_position(const Vector3 &p_pos) const; + bool safe_unproject_position(const Vector3 &p_pos, Point2 &r_result) const; bool is_position_behind(const Vector3 &p_pos) const; virtual Vector3 project_position(const Point2 &p_point, float p_z_depth) const; From c84cf04e95b2b2e3a7bfea52c5f8d4cbaf38bc20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Verschelde?= Date: Wed, 4 Sep 2024 11:35:41 +0200 Subject: [PATCH 2/3] PopupMenu: Update margins on visibility change Fixes #96149. Co-authored-by: Haoyu Qiu --- scene/gui/popup_menu.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index b91b2407da60..750c41c5b58e 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -646,6 +646,8 @@ void PopupMenu::_notification(int p_what) { case NOTIFICATION_POST_POPUP: { initial_button_mask = Input::get_singleton()->get_mouse_button_mask(); during_grabbed_click = (bool)initial_button_mask; + } break; + case NOTIFICATION_VISIBILITY_CHANGED: { // Set margin on the margin container Ref panel_style = get_stylebox("panel"); margin_container->add_constant_override("margin_top", panel_style->get_margin(Margin::MARGIN_TOP)); From e13584c9311c39e573160d921ce458799e4e4add Mon Sep 17 00:00:00 2001 From: lawnjelly Date: Wed, 4 Sep 2024 16:34:23 +0100 Subject: [PATCH 3/3] Update changelog for 3.6 stable --- CHANGELOG.md | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 00817129537f..324b35ba8e91 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,11 +11,17 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). #### 2D -- Add option in VisibilityEnabler2D to hide the parent for better performance ([GH-63193](https://github.com/godotengine/godot/pull/63193)). +- 2D physics interpolation ([GH-76252](https://github.com/godotengine/godot/pull/76252)). +- 2D hierarchical culling ([GH-68738](https://github.com/godotengine/godot/pull/68738)). - Add Gradient resource preview generator ([GH-68990](https://github.com/godotengine/godot/pull/68990)). #### 3D +- Tighter shadow culling ([GH-84745](https://github.com/godotengine/godot/pull/84745)). +- Mesh merging ([GH-61568](https://github.com/godotengine/godot/pull/61568)). +- Discrete level of detail ([GH-85437](https://github.com/godotengine/godot/pull/85437)). +- ORM materials ([GH-76023](https://github.com/godotengine/godot/pull/76023)). +- Vertex cache optimization ([GH-86339](https://github.com/godotengine/godot/pull/86339)). - Add rotation ability to material editor preview ([GH-49466](https://github.com/godotengine/godot/pull/49466)). - Automatically add root node when drag-and-dropping in 3D editor ([GH-55626](https://github.com/godotengine/godot/pull/55626)). - Add `TorusMesh` ([GH-64044](https://github.com/godotengine/godot/pull/64044)). @@ -34,10 +40,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Add ability to pick random value from array ([GH-67444](https://github.com/godotengine/godot/pull/67444)). - Expose `OS.read_string_from_stdin()` to the scripting API ([GH-70378](https://github.com/godotengine/godot/pull/70378)). - Add Color + alpha constructor for Color ([GH-74973](https://github.com/godotengine/godot/pull/74973)). +- Backport some multi-threading goodies ([GH-72251](https://github.com/godotengine/godot/pull/72251)). - Expose `determinant` in Transform2D ([GH-76323](https://github.com/godotengine/godot/pull/76323)). #### Editor +- View selected mesh stats ([GH-88207](https://github.com/godotengine/godot/pull/88207)). - Add support for documenting most editor settings in the class reference ([GH-48548](https://github.com/godotengine/godot/pull/48548)). - Add vector value linking ([GH-59125](https://github.com/godotengine/godot/pull/59125)). - Backport locale selection improvements ([GH-61878](https://github.com/godotengine/godot/pull/61878)). @@ -57,10 +65,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). #### GUI - Support multiline strings in buttons ([GH-41464](https://github.com/godotengine/godot/pull/41464)). -- Add dumb theme item cache to `Control` ([GH-64314](https://github.com/godotengine/godot/pull/64314)). - Support AtlasTexture in radial modes of TextureProgress ([GH-68246](https://github.com/godotengine/godot/pull/68246)). - Add alignment options to flow container ([GH-68556](https://github.com/godotengine/godot/pull/68556)). - Add `allow_search` property to ItemList and Tree ([GH-76753](https://github.com/godotengine/godot/pull/76753)). +- Add dumb theme item cache to `Control` ([GH-64314](https://github.com/godotengine/godot/pull/64314)). +- Add tab Metadata to Tabs & TabContainer ([GH-75959](https://github.com/godotengine/godot/pull/75959)). +- Backport video loop property and fix for initial black frame ([GH-77979](https://github.com/godotengine/godot/pull/77979)). #### Import @@ -70,6 +80,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Expose more compression formats in Image ([GH-76016](https://github.com/godotengine/godot/pull/76016)). - Implement physics support in the GLTF module ([GH-76453](https://github.com/godotengine/godot/pull/76453)). - Add vertex color support to OBJ importer ([GH-76671](https://github.com/godotengine/godot/pull/76671)). +- Implement loading DDS textures at run-time ([GH-69101](https://github.com/godotengine/godot/pull/69101)). #### Input @@ -101,11 +112,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). #### Porting - Add benchmark logic ([GH-71875](https://github.com/godotengine/godot/pull/71875)). +- Add `audio/general/text_to_speech` project setting to enable/disable TTS ([GH-77352](https://github.com/godotengine/godot/pull/77352)). - Android: Add cursor shape support ([GH-66945](https://github.com/godotengine/godot/pull/66945)). - Android: Implement file provider capabilities ([GH-72496](https://github.com/godotengine/godot/pull/72496)). - Android: Enable granular control of touchscreen related settings ([GH-73692](https://github.com/godotengine/godot/pull/73692)). - Android: Update the gradle build tasks to generate play store builds ([GH-74583](https://github.com/godotengine/godot/pull/74583)). +- Android: Allow concurrent buffering and dispatch of input events ([GH-76400](https://github.com/godotengine/godot/pull/76400)). - iOS: Swift runtime support for iOS Plugins ([GH-49828](https://github.com/godotengine/godot/pull/49828)). +- Android: Add Android editor setting to control the window used to run the project ([GH-77677](https://github.com/godotengine/godot/pull/77677)). - iOS: Add iOS UI Options ([GH-68189](https://github.com/godotengine/godot/pull/68189)). - iOS: Add ProMotion/High Refresh Rate support ([GH-68190](https://github.com/godotengine/godot/pull/68190)). - macOS: Simplify code signing options, add support for rcodesign tool for signing and notarization ([GH-66093](https://github.com/godotengine/godot/pull/66093)). @@ -115,6 +129,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). #### Rendering - Batching: Add MultiRect command ([GH-68960](https://github.com/godotengine/godot/pull/68960)). +- Backport additional spatial shader built-ins ([GH-63971](https://github.com/godotengine/godot/pull/63971)). #### Shaders @@ -126,6 +141,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). #### 2D - Remove error condition from `get_global_transform()` ([GH-67710](https://github.com/godotengine/godot/pull/67710)). +- Make autotiles fall back to the most similar bitmask ([GH-71533](https://github.com/godotengine/godot/pull/71533)). #### 3D @@ -140,6 +156,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Optimize `AudioServer::_driver_process()` ([GH-63430](https://github.com/godotengine/godot/pull/63430)). - Fix MIDI note-on events being converted to note-off events ([GH-66003](https://github.com/godotengine/godot/pull/66003)). +- PulseAudio: Remove `get_latency()` caching ([GH-80294](https://github.com/godotengine/godot/pull/80294)). #### Buildsystem @@ -160,10 +177,21 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Rework scene creation dialog ([GH-62746](https://github.com/godotengine/godot/pull/62746)). - Use `FlowContainer` to handle toolbar overflow more gracefully ([GH-63250](https://github.com/godotengine/godot/pull/63250)). - Overhaul CLI argument forwarding to processes started by the editor ([GH-64375](https://github.com/godotengine/godot/pull/64375)). +- Scene tree dock filter improvements ([GH-67347](https://github.com/godotengine/godot/pull/67347)). +- Faster editor grid ([GH-92725](https://github.com/godotengine/godot/pull/92725)). + +#### GDScript + +- Improve parser speed for very long scripts ([GH-74782](https://github.com/godotengine/godot/pull/74782), [GH-74794](https://github.com/godotengine/godot/pull/74794)). + +#### GUI + +- GUI: RichTextLabel: Cache text property when toggling BBCode ([GH-77403](https://github.com/godotengine/godot/pull/77403)). #### Mono (C#) - Deprecate string extensions that will be removed in 4.x ([GH-69304](https://github.com/godotengine/godot/pull/69304)). +- Print error when MethodBind call fails ([GH-79433](https://github.com/godotengine/godot/pull/79433)). #### Networking @@ -200,12 +228,26 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Fixed +#### 2D + +- Fix AnimatedSprite normal map loading ([GH-80406](https://github.com/godotengine/godot/pull/80406)). +- Fix viewport behaviour with physics interpolation ([GH-92152](https://github.com/godotengine/godot/pull/92152)). + +#### 3D + +- Fix OccluderPolyShape handles disappear after release click ([GH-79947](https://github.com/godotengine/godot/pull/79947)). +- Fix `merge_meshes()` functionality ([GH-92105](https://github.com/godotengine/godot/pull/92105)). + #### Animation - Create reset tracks with the right update mode ([GH-63119](https://github.com/godotengine/godot/pull/63119)). - Don't store frame of playing AnimatedSprite ([GH-66155](https://github.com/godotengine/godot/pull/66155)). - Fix animation signal `caches_cleared` firing timing ([GH-69474](https://github.com/godotengine/godot/pull/69474)). +#### Audio + +- Audio: Fix trim when importing WAV ([GH-78048](https://github.com/godotengine/godot/pull/78048)). + #### Core - Mark node groups as dirty for every children if parent is moved ([GH-61578](https://github.com/godotengine/godot/pull/61578)). @@ -215,6 +257,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Fix size error in `BitMap.opaque_to_polygons` ([GH-76544](https://github.com/godotengine/godot/pull/76544)). - Fix rendering tiles using nested AtlasTextures ([GH-76703](https://github.com/godotengine/godot/pull/76703)). - Make acos and asin safe ([GH-76902](https://github.com/godotengine/godot/pull/76902)). +- Fix overwriting of Spatial's local transform ([GH-78439](https://github.com/godotengine/godot/pull/78439)). +- Fix physics tick counter ([GH-92941](https://github.com/godotengine/godot/pull/92941)). +- Fix pausing behaviour with physics interpolation ([GH-93382](https://github.com/godotengine/godot/pull/93382)) #### GDScript @@ -235,15 +280,19 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Improve font glyph cache packing and texture update ([GH-67626](https://github.com/godotengine/godot/pull/67626)). - Fix `GridContainer` max row/column calculations not skipping hidden children ([GH-76833](https://github.com/godotengine/godot/pull/76833)). - Stop dragging when Slider changes editability ([GH-77245](https://github.com/godotengine/godot/pull/77245)). +- Fix `PopupMenu`'s automatic max height ([GH-77691](https://github.com/godotengine/godot/pull/77691)). #### Import - glTF import external images correctly ([GH-66889](https://github.com/godotengine/godot/pull/66889)). +- Bounds fixes in `TextureAtlas` import ([GH-77428](https://github.com/godotengine/godot/pull/77428)). #### Input - Fix mouse speed not changing fast enough ([GH-56765](https://github.com/godotengine/godot/pull/56765)). - Fix `InputEventAction`'s `is_match` method ignoring `exact_match` parameter ([GH-63109](https://github.com/godotengine/godot/pull/63109)). +- Fix just pressed and released with short presses ([GH-77040](https://github.com/godotengine/godot/pull/77040)). +- Prevent double input events on gamepad when running through steam input ([GH-79706](https://github.com/godotengine/godot/pull/79706)). #### Mono (C#) @@ -263,6 +312,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Android: Fix input ANR in the Godot Android editor ([GH-76981](https://github.com/godotengine/godot/pull/76981)). - Linux: Fix MIDI input with ALSA ([GH-54309](https://github.com/godotengine/godot/pull/54309)). - Linux: Don't use udev for joypad hotloading when running in a sandbox ([GH-76961](https://github.com/godotengine/godot/pull/76961)). +- Windows: Fix `ProjectSettings::localize_path` for Windows paths ([GH-80072](https://github.com/godotengine/godot/pull/80072)). #### Physics @@ -281,6 +331,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Fix shadows when using 2 directional lights ([GH-74539](https://github.com/godotengine/godot/pull/74539)). - Fixed whitescreen issue in GLES2 glow setting ([GH-74953](https://github.com/godotengine/godot/pull/74953)). - Fix Polygon2D skinned bounds (for culling) ([GH-75612](https://github.com/godotengine/godot/pull/75612)). +- Fix scene shader regression ([GH-92070](https://github.com/godotengine/godot/pull/92070)) +- Fix 2D skinning with physics interpolation ([GH-93309](https://github.com/godotengine/godot/pull/93309)) +- Fix `NODE_POSITION_VIEW` shader built-in ([GH-76226](https://github.com/godotengine/godot/pull/76226)). #### XR