diff options
author | Michael Alexsander <michaelalexsander@protonmail.com> | 2024-09-18 18:07:18 -0300 |
---|---|---|
committer | Michael Alexsander <michaelalexsander@protonmail.com> | 2024-10-30 11:42:17 -0300 |
commit | 16524a8a01408480ce2063461c8c042bc4eb3fa8 (patch) | |
tree | f82806e99d030ed26ddec9347681430db49fe199 /scene/main | |
parent | 8004c7524fb9f43425c4d6f614410a76678e0f7c (diff) | |
download | redot-engine-16524a8a01408480ce2063461c8c042bc4eb3fa8.tar.gz |
Add "Game" editor for better runtime debugging
Diffstat (limited to 'scene/main')
-rw-r--r-- | scene/main/node.cpp | 13 | ||||
-rw-r--r-- | scene/main/node.h | 3 | ||||
-rw-r--r-- | scene/main/scene_tree.cpp | 27 | ||||
-rw-r--r-- | scene/main/scene_tree.h | 3 | ||||
-rw-r--r-- | scene/main/viewport.cpp | 83 | ||||
-rw-r--r-- | scene/main/viewport.h | 8 |
6 files changed, 133 insertions, 4 deletions
diff --git a/scene/main/node.cpp b/scene/main/node.cpp index d921cc5b67..8dc7b4a87c 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -184,6 +184,7 @@ void Node::_notification(int p_notification) { } } break; + case NOTIFICATION_SUSPENDED: case NOTIFICATION_PAUSED: { if (is_physics_interpolated_and_enabled() && is_inside_tree()) { reset_physics_interpolation(); @@ -695,6 +696,16 @@ void Node::_propagate_pause_notification(bool p_enable) { data.blocked--; } +void Node::_propagate_suspend_notification(bool p_enable) { + notification(p_enable ? NOTIFICATION_SUSPENDED : NOTIFICATION_UNSUSPENDED); + + data.blocked++; + for (KeyValue<StringName, Node *> &KV : data.children) { + KV.value->_propagate_suspend_notification(p_enable); + } + data.blocked--; +} + Node::ProcessMode Node::get_process_mode() const { return data.process_mode; } @@ -850,7 +861,7 @@ bool Node::can_process_notification(int p_what) const { bool Node::can_process() const { ERR_FAIL_COND_V(!is_inside_tree(), false); - return _can_process(get_tree()->is_paused()); + return !get_tree()->is_suspended() && _can_process(get_tree()->is_paused()); } bool Node::_can_process(bool p_paused) const { diff --git a/scene/main/node.h b/scene/main/node.h index 799478fa35..e2f3ce9b78 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -300,6 +300,7 @@ private: void _set_tree(SceneTree *p_tree); void _propagate_pause_notification(bool p_enable); + void _propagate_suspend_notification(bool p_enable); _FORCE_INLINE_ bool _can_process(bool p_paused) const; _FORCE_INLINE_ bool _is_enabled() const; @@ -439,6 +440,8 @@ public: // Editor specific node notifications NOTIFICATION_EDITOR_PRE_SAVE = 9001, NOTIFICATION_EDITOR_POST_SAVE = 9002, + NOTIFICATION_SUSPENDED = 9003, + NOTIFICATION_UNSUSPENDED = 9004 }; /* NODE/TREE */ diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index 71d91b970e..60cecfcfe7 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -954,11 +954,14 @@ Ref<ArrayMesh> SceneTree::get_debug_contact_mesh() { void SceneTree::set_pause(bool p_enabled) { ERR_FAIL_COND_MSG(!Thread::is_main_thread(), "Pause can only be set from the main thread."); + ERR_FAIL_COND_MSG(suspended, "Pause state cannot be modified while suspended."); if (p_enabled == paused) { return; } + paused = p_enabled; + #ifndef _3D_DISABLED PhysicsServer3D::get_singleton()->set_active(!p_enabled); #endif // _3D_DISABLED @@ -972,6 +975,30 @@ bool SceneTree::is_paused() const { return paused; } +void SceneTree::set_suspend(bool p_enabled) { + ERR_FAIL_COND_MSG(!Thread::is_main_thread(), "Suspend can only be set from the main thread."); + + if (p_enabled == suspended) { + return; + } + + suspended = p_enabled; + + Engine::get_singleton()->set_freeze_time_scale(p_enabled); + +#ifndef _3D_DISABLED + PhysicsServer3D::get_singleton()->set_active(!p_enabled && !paused); +#endif // _3D_DISABLED + PhysicsServer2D::get_singleton()->set_active(!p_enabled && !paused); + if (get_root()) { + get_root()->_propagate_suspend_notification(p_enabled); + } +} + +bool SceneTree::is_suspended() const { + return suspended; +} + void SceneTree::_process_group(ProcessGroup *p_group, bool p_physics) { // When reading this function, keep in mind that this code must work in a way where // if any node is removed, this needs to continue working. diff --git a/scene/main/scene_tree.h b/scene/main/scene_tree.h index 7e44541105..291e4a5a0c 100644 --- a/scene/main/scene_tree.h +++ b/scene/main/scene_tree.h @@ -143,6 +143,7 @@ private: bool debug_navigation_hint = false; #endif bool paused = false; + bool suspended = false; HashMap<StringName, Group> group_map; bool _quit = false; @@ -343,6 +344,8 @@ public: void set_pause(bool p_enabled); bool is_paused() const; + void set_suspend(bool p_enabled); + bool is_suspended() const; #ifdef DEBUG_ENABLED void set_debug_collisions_hint(bool p_enabled); diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 54f66e8d4e..5a90eb8f3e 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -3123,7 +3123,7 @@ void Viewport::push_input(const Ref<InputEvent> &p_event, bool p_local_coords) { ERR_FAIL_COND(!is_inside_tree()); ERR_FAIL_COND(p_event.is_null()); - if (disable_input) { + if (disable_input || disable_input_override) { return; } @@ -3195,7 +3195,7 @@ void Viewport::push_unhandled_input(const Ref<InputEvent> &p_event, bool p_local local_input_handled = false; - if (disable_input || !_can_consume_input_events()) { + if (disable_input || disable_input_override || !_can_consume_input_events()) { return; } @@ -3298,7 +3298,7 @@ void Viewport::set_disable_input(bool p_disable) { if (p_disable == disable_input) { return; } - if (p_disable) { + if (p_disable && !disable_input_override) { _drop_mouse_focus(); _mouse_leave_viewport(); _gui_cancel_tooltip(); @@ -3311,6 +3311,19 @@ bool Viewport::is_input_disabled() const { return disable_input; } +void Viewport::set_disable_input_override(bool p_disable) { + ERR_MAIN_THREAD_GUARD; + if (p_disable == disable_input_override) { + return; + } + if (p_disable && !disable_input) { + _drop_mouse_focus(); + _mouse_leave_viewport(); + _gui_cancel_tooltip(); + } + disable_input_override = p_disable; +} + Variant Viewport::gui_get_drag_data() const { ERR_READ_THREAD_GUARD_V(Variant()); return get_section_root_viewport()->gui.drag_data; @@ -4237,6 +4250,22 @@ void Viewport::set_camera_3d_override_orthogonal(real_t p_size, real_t p_z_near, } } +HashMap<StringName, real_t> Viewport::get_camera_3d_override_properties() const { + HashMap<StringName, real_t> props; + + props["size"] = 0; + props["fov"] = 0; + props["z_near"] = 0; + props["z_far"] = 0; + ERR_READ_THREAD_GUARD_V(props); + + props["size"] = camera_3d_override.size; + props["fov"] = camera_3d_override.fov; + props["z_near"] = camera_3d_override.z_near; + props["z_far"] = camera_3d_override.z_far; + return props; +} + void Viewport::set_disable_3d(bool p_disable) { ERR_MAIN_THREAD_GUARD; disable_3d = p_disable; @@ -4270,6 +4299,54 @@ Transform3D Viewport::get_camera_3d_override_transform() const { return Transform3D(); } +Vector3 Viewport::camera_3d_override_project_ray_normal(const Point2 &p_pos) const { + ERR_READ_THREAD_GUARD_V(Vector3()); + Vector3 ray = camera_3d_override_project_local_ray_normal(p_pos); + return camera_3d_override.transform.basis.xform(ray).normalized(); +} + +Vector3 Viewport::camera_3d_override_project_local_ray_normal(const Point2 &p_pos) const { + ERR_READ_THREAD_GUARD_V(Vector3()); + Size2 viewport_size = get_camera_rect_size(); + Vector2 cpos = get_camera_coords(p_pos); + Vector3 ray; + + if (camera_3d_override.projection == Camera3DOverrideData::PROJECTION_ORTHOGONAL) { + ray = Vector3(0, 0, -1); + } else { + Projection cm; + cm.set_perspective(camera_3d_override.fov, get_visible_rect().size.aspect(), camera_3d_override.z_near, camera_3d_override.z_far, false); + + Vector2 screen_he = cm.get_viewport_half_extents(); + ray = Vector3(((cpos.x / viewport_size.width) * 2.0 - 1.0) * screen_he.x, ((1.0 - (cpos.y / viewport_size.height)) * 2.0 - 1.0) * screen_he.y, -camera_3d_override.z_near).normalized(); + } + + return ray; +} + +Vector3 Viewport::camera_3d_override_project_ray_origin(const Point2 &p_pos) const { + ERR_READ_THREAD_GUARD_V(Vector3()); + Size2 viewport_size = get_camera_rect_size(); + Vector2 cpos = get_camera_coords(p_pos); + ERR_FAIL_COND_V(viewport_size.y == 0, Vector3()); + + if (camera_3d_override.projection == Camera3DOverrideData::PROJECTION_ORTHOGONAL) { + Vector2 pos = cpos / viewport_size; + real_t vsize, hsize; + hsize = camera_3d_override.size * viewport_size.aspect(); + vsize = camera_3d_override.size; + + Vector3 ray; + ray.x = pos.x * (hsize)-hsize / 2; + ray.y = (1.0 - pos.y) * (vsize)-vsize / 2; + ray.z = -camera_3d_override.z_near; + ray = camera_3d_override.transform.xform(ray); + return ray; + } else { + return camera_3d_override.transform.origin; + }; +} + Ref<World3D> Viewport::get_world_3d() const { ERR_READ_THREAD_GUARD_V(Ref<World3D>()); return world_3d; diff --git a/scene/main/viewport.h b/scene/main/viewport.h index a18dc1f6f0..92691ccbec 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -401,6 +401,7 @@ private: DefaultCanvasItemTextureRepeat default_canvas_item_texture_repeat = DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_DISABLED; bool disable_input = false; + bool disable_input_override = false; void _gui_call_input(Control *p_control, const Ref<InputEvent> &p_input); void _gui_call_notification(Control *p_control, int p_what); @@ -580,6 +581,8 @@ public: void set_disable_input(bool p_disable); bool is_input_disabled() const; + void set_disable_input_override(bool p_disable); + Vector2 get_mouse_position() const; void warp_mouse(const Vector2 &p_position); virtual void update_mouse_cursor_state(); @@ -770,6 +773,11 @@ public: void set_camera_3d_override_perspective(real_t p_fovy_degrees, real_t p_z_near, real_t p_z_far); void set_camera_3d_override_orthogonal(real_t p_size, real_t p_z_near, real_t p_z_far); + HashMap<StringName, real_t> get_camera_3d_override_properties() const; + + Vector3 camera_3d_override_project_ray_normal(const Point2 &p_pos) const; + Vector3 camera_3d_override_project_ray_origin(const Point2 &p_pos) const; + Vector3 camera_3d_override_project_local_ray_normal(const Point2 &p_pos) const; void set_disable_3d(bool p_disable); bool is_3d_disabled() const; |