diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 1ee6a8dca7f1..c8d2d71c2afa 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -1068,32 +1068,6 @@ void Viewport::canvas_parent_mark_dirty(Node *p_node) { } } -void Viewport::_update_audio_listener_2d() { - if (AudioServer::get_singleton()) { - AudioServer::get_singleton()->notify_listener_changed(); - } -} - -void Viewport::set_as_audio_listener_2d(bool p_enable) { - ERR_MAIN_THREAD_GUARD; - if (p_enable == is_audio_listener_2d_enabled) { - return; - } - - is_audio_listener_2d_enabled = p_enable; - _update_audio_listener_2d(); -} - -bool Viewport::is_audio_listener_2d() const { - ERR_READ_THREAD_GUARD_V(false); - return is_audio_listener_2d_enabled; -} - -AudioListener2D *Viewport::get_audio_listener_2d() const { - ERR_READ_THREAD_GUARD_V(nullptr); - return audio_listener_2d; -} - void Viewport::enable_canvas_transform_override(bool p_enable) { ERR_MAIN_THREAD_GUARD; if (override_canvas_transform == p_enable) { @@ -1162,25 +1136,6 @@ Transform2D Viewport::get_global_canvas_transform() const { return global_canvas_transform; } -void Viewport::_camera_2d_set(Camera2D *p_camera_2d) { - camera_2d = p_camera_2d; -} - -void Viewport::_audio_listener_2d_set(AudioListener2D *p_listener) { - if (audio_listener_2d == p_listener) { - return; - } else if (audio_listener_2d) { - audio_listener_2d->clear_current(); - } - audio_listener_2d = p_listener; -} - -void Viewport::_audio_listener_2d_remove(AudioListener2D *p_listener) { - if (audio_listener_2d == p_listener) { - audio_listener_2d = nullptr; - } -} - void Viewport::_canvas_layer_add(CanvasLayer *p_canvas_layer) { canvas_layers.insert(p_canvas_layer); } @@ -1272,40 +1227,11 @@ Ref Viewport::get_world_2d() const { return world_2d; } -Camera2D *Viewport::get_camera_2d() const { - ERR_READ_THREAD_GUARD_V(nullptr); - return camera_2d; -} - Transform2D Viewport::get_final_transform() const { ERR_READ_THREAD_GUARD_V(Transform2D()); return stretch_transform * global_canvas_transform; } -void Viewport::assign_next_enabled_camera_2d(const StringName &p_camera_group) { - ERR_MAIN_THREAD_GUARD; - List camera_list; - get_tree()->get_nodes_in_group(p_camera_group, &camera_list); - - Camera2D *new_camera = nullptr; - for (Node *E : camera_list) { - Camera2D *cam = Object::cast_to(E); - if (!cam) { - continue; // Non-camera node (e.g. ParallaxBackground). - } - - if (cam->is_enabled()) { - new_camera = cam; - break; - } - } - - _camera_2d_set(new_camera); - if (!camera_2d) { - set_canvas_transform(Transform2D()); - } -} - void Viewport::_update_canvas_items(Node *p_node) { if (p_node != this) { Window *w = Object::cast_to(p_node); @@ -2644,76 +2570,6 @@ void Viewport::_drop_physics_mouseover(bool p_paused_only) { #endif // _3D_DISABLED } -void Viewport::_cleanup_mouseover_colliders(bool p_clean_all_frames, bool p_paused_only, uint64_t p_frame_reference) { - List to_erase; - List to_mouse_exit; - - for (const KeyValue &E : physics_2d_mouseover) { - if (!p_clean_all_frames && E.value == p_frame_reference) { - continue; - } - - Object *o = ObjectDB::get_instance(E.key); - if (o) { - CollisionObject2D *co = Object::cast_to(o); - if (co && co->is_inside_tree()) { - if (p_clean_all_frames && p_paused_only && co->can_process()) { - continue; - } - to_mouse_exit.push_back(E.key); - } - } - to_erase.push_back(E.key); - } - - while (to_erase.size()) { - physics_2d_mouseover.erase(to_erase.front()->get()); - to_erase.pop_front(); - } - - // Per-shape. - List> shapes_to_erase; - List> shapes_to_mouse_exit; - - for (KeyValue, uint64_t> &E : physics_2d_shape_mouseover) { - if (!p_clean_all_frames && E.value == p_frame_reference) { - continue; - } - - Object *o = ObjectDB::get_instance(E.key.first); - if (o) { - CollisionObject2D *co = Object::cast_to(o); - if (co && co->is_inside_tree()) { - if (p_clean_all_frames && p_paused_only && co->can_process()) { - continue; - } - shapes_to_mouse_exit.push_back(E.key); - } - } - shapes_to_erase.push_back(E.key); - } - - while (shapes_to_erase.size()) { - physics_2d_shape_mouseover.erase(shapes_to_erase.front()->get()); - shapes_to_erase.pop_front(); - } - - while (to_mouse_exit.size()) { - Object *o = ObjectDB::get_instance(to_mouse_exit.front()->get()); - CollisionObject2D *co = Object::cast_to(o); - co->_mouse_exit(); - to_mouse_exit.pop_front(); - } - - while (shapes_to_mouse_exit.size()) { - Pair e = shapes_to_mouse_exit.front()->get(); - Object *o = ObjectDB::get_instance(e.first); - CollisionObject2D *co = Object::cast_to(o); - co->_mouse_shape_exit(e.second); - shapes_to_mouse_exit.pop_front(); - } -} - void Viewport::_gui_grab_click_focus(Control *p_control) { gui.mouse_click_grabber = p_control; callable_mp(this, &Viewport::_post_gui_grab_click_focus).call_deferred(); @@ -4065,6 +3921,150 @@ bool Viewport::get_canvas_cull_mask_bit(uint32_t p_layer) const { return (canvas_cull_mask & (1 << p_layer)); } +void Viewport::_update_audio_listener_2d() { + if (AudioServer::get_singleton()) { + AudioServer::get_singleton()->notify_listener_changed(); + } +} + +void Viewport::_audio_listener_2d_set(AudioListener2D *p_audio_listener) { + if (audio_listener_2d == p_audio_listener) { + return; + } else if (audio_listener_2d) { + audio_listener_2d->clear_current(); + } + audio_listener_2d = p_audio_listener; +} + +void Viewport::_audio_listener_2d_remove(AudioListener2D *p_audio_listener) { + if (audio_listener_2d == p_audio_listener) { + audio_listener_2d = nullptr; + } +} + +void Viewport::_camera_2d_set(Camera2D *p_camera_2d) { + camera_2d = p_camera_2d; +} + +void Viewport::_cleanup_mouseover_colliders(bool p_clean_all_frames, bool p_paused_only, uint64_t p_frame_reference) { + List to_erase; + List to_mouse_exit; + + for (const KeyValue &E : physics_2d_mouseover) { + if (!p_clean_all_frames && E.value == p_frame_reference) { + continue; + } + + Object *o = ObjectDB::get_instance(E.key); + if (o) { + CollisionObject2D *co = Object::cast_to(o); + if (co && co->is_inside_tree()) { + if (p_clean_all_frames && p_paused_only && co->can_process()) { + continue; + } + to_mouse_exit.push_back(E.key); + } + } + to_erase.push_back(E.key); + } + + while (to_erase.size()) { + physics_2d_mouseover.erase(to_erase.front()->get()); + to_erase.pop_front(); + } + + // Per-shape. + List> shapes_to_erase; + List> shapes_to_mouse_exit; + + for (KeyValue, uint64_t> &E : physics_2d_shape_mouseover) { + if (!p_clean_all_frames && E.value == p_frame_reference) { + continue; + } + + Object *o = ObjectDB::get_instance(E.key.first); + if (o) { + CollisionObject2D *co = Object::cast_to(o); + if (co && co->is_inside_tree()) { + if (p_clean_all_frames && p_paused_only && co->can_process()) { + continue; + } + shapes_to_mouse_exit.push_back(E.key); + } + } + shapes_to_erase.push_back(E.key); + } + + while (shapes_to_erase.size()) { + physics_2d_shape_mouseover.erase(shapes_to_erase.front()->get()); + shapes_to_erase.pop_front(); + } + + while (to_mouse_exit.size()) { + Object *o = ObjectDB::get_instance(to_mouse_exit.front()->get()); + CollisionObject2D *co = Object::cast_to(o); + co->_mouse_exit(); + to_mouse_exit.pop_front(); + } + + while (shapes_to_mouse_exit.size()) { + Pair e = shapes_to_mouse_exit.front()->get(); + Object *o = ObjectDB::get_instance(e.first); + CollisionObject2D *co = Object::cast_to(o); + co->_mouse_shape_exit(e.second); + shapes_to_mouse_exit.pop_front(); + } +} + +AudioListener2D *Viewport::get_audio_listener_2d() const { + ERR_READ_THREAD_GUARD_V(nullptr); + return audio_listener_2d; +} + +void Viewport::set_as_audio_listener_2d(bool p_enable) { + ERR_MAIN_THREAD_GUARD; + if (p_enable == is_audio_listener_2d_enabled) { + return; + } + + is_audio_listener_2d_enabled = p_enable; + _update_audio_listener_2d(); +} + +bool Viewport::is_audio_listener_2d() const { + ERR_READ_THREAD_GUARD_V(false); + return is_audio_listener_2d_enabled; +} + +Camera2D *Viewport::get_camera_2d() const { + ERR_READ_THREAD_GUARD_V(nullptr); + return camera_2d; +} + +void Viewport::assign_next_enabled_camera_2d(const StringName &p_camera_group) { + ERR_MAIN_THREAD_GUARD; + List camera_list; + get_tree()->get_nodes_in_group(p_camera_group, &camera_list); + + Camera2D *new_camera = nullptr; + for (Node *E : camera_list) { + Camera2D *cam = Object::cast_to(E); + if (!cam) { + continue; // Non-camera node (e.g. ParallaxBackground). + } + + if (cam->is_enabled()) { + new_camera = cam; + break; + } + } + + _camera_2d_set(new_camera); + if (!camera_2d) { + set_canvas_transform(Transform2D()); + } +} + #ifndef _3D_DISABLED AudioListener3D *Viewport::get_audio_listener_3d() const { ERR_READ_THREAD_GUARD_V(nullptr); @@ -4640,10 +4640,6 @@ void Viewport::_bind_methods() { ClassDB::bind_method(D_METHOD("push_unhandled_input", "event", "in_local_coords"), &Viewport::push_unhandled_input, DEFVAL(false)); #endif // DISABLE_DEPRECATED - ClassDB::bind_method(D_METHOD("get_camera_2d"), &Viewport::get_camera_2d); - ClassDB::bind_method(D_METHOD("set_as_audio_listener_2d", "enable"), &Viewport::set_as_audio_listener_2d); - ClassDB::bind_method(D_METHOD("is_audio_listener_2d"), &Viewport::is_audio_listener_2d); - ClassDB::bind_method(D_METHOD("get_mouse_position"), &Viewport::get_mouse_position); ClassDB::bind_method(D_METHOD("warp_mouse", "position"), &Viewport::warp_mouse); ClassDB::bind_method(D_METHOD("update_mouse_cursor_state"), &Viewport::update_mouse_cursor_state); @@ -4712,6 +4708,10 @@ void Viewport::_bind_methods() { ClassDB::bind_method(D_METHOD("_process_picking"), &Viewport::_process_picking); + ClassDB::bind_method(D_METHOD("set_as_audio_listener_2d", "enable"), &Viewport::set_as_audio_listener_2d); + ClassDB::bind_method(D_METHOD("is_audio_listener_2d"), &Viewport::is_audio_listener_2d); + ClassDB::bind_method(D_METHOD("get_camera_2d"), &Viewport::get_camera_2d); + #ifndef _3D_DISABLED ClassDB::bind_method(D_METHOD("set_world_3d", "world_3d"), &Viewport::set_world_3d); ClassDB::bind_method(D_METHOD("get_world_3d"), &Viewport::get_world_3d); @@ -4786,7 +4786,7 @@ void Viewport::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "audio_listener_enable_2d"), "set_as_audio_listener_2d", "is_audio_listener_2d"); #ifndef _3D_DISABLED ADD_PROPERTY(PropertyInfo(Variant::BOOL, "audio_listener_enable_3d"), "set_as_audio_listener_3d", "is_audio_listener_3d"); -#endif +#endif // _3D_DISABLED ADD_GROUP("Physics", "physics_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "physics_object_picking"), "set_physics_object_picking", "get_physics_object_picking"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "physics_object_picking_sort"), "set_physics_object_picking_sort", "get_physics_object_picking_sort"); diff --git a/scene/main/viewport.h b/scene/main/viewport.h index 2904e3e15615..29ccdc5426bc 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -218,17 +218,12 @@ class Viewport : public Node { Viewport *parent = nullptr; Viewport *gui_parent = nullptr; // Whose gui.tooltip_popup it is. - AudioListener2D *audio_listener_2d = nullptr; - Camera2D *camera_2d = nullptr; HashSet canvas_layers; RID viewport; RID current_canvas; RID subwindow_canvas; - bool is_audio_listener_2d_enabled = false; - RID internal_audio_listener_2d; - bool override_canvas_transform = false; Transform2D canvas_transform_override; @@ -267,13 +262,6 @@ class Viewport : public Node { bool handle_input_locally = true; bool local_input_handled = false; - // Collider to frame - HashMap physics_2d_mouseover; - // Collider & shape to frame - HashMap, uint64_t, PairHash> physics_2d_shape_mouseover; - // Cleans up colliders corresponding to old frames or all of them. - void _cleanup_mouseover_colliders(bool p_clean_all_frames, bool p_paused_only, uint64_t p_frame_reference = 0); - Ref world_2d; StringName input_group; @@ -447,13 +435,6 @@ class Viewport : public Node { bool _gui_drop(Control *p_at_control, Point2 p_at_pos, bool p_just_check); - friend class AudioListener2D; - void _audio_listener_2d_set(AudioListener2D *p_listener); - void _audio_listener_2d_remove(AudioListener2D *p_listener); - - friend class Camera2D; - void _camera_2d_set(Camera2D *p_camera_2d); - friend class CanvasLayer; void _canvas_layer_add(CanvasLayer *p_canvas_layer); void _canvas_layer_remove(CanvasLayer *p_canvas_layer); @@ -483,6 +464,7 @@ class Viewport : public Node { uint64_t event_count = 0; void _process_dirty_canvas_parent_orders(); + void _propagate_world_2d_changed(Node *p_node); protected: void _set_size(const Size2i &p_size, const Size2i &p_size_2d_override, bool p_allocated); @@ -494,6 +476,7 @@ class Viewport : public Node { void _notification(int p_what); void _process_picking(); static void _bind_methods(); + void _validate_property(PropertyInfo &p_property) const; public: void canvas_parent_mark_dirty(Node *p_node); @@ -501,11 +484,6 @@ class Viewport : public Node { uint64_t get_processed_events_count() const { return event_count; } - AudioListener2D *get_audio_listener_2d() const; - Camera2D *get_camera_2d() const; - void set_as_audio_listener_2d(bool p_enable); - bool is_audio_listener_2d() const; - void update_canvas_items(); Rect2 get_visible_rect() const; @@ -528,7 +506,6 @@ class Viewport : public Node { Transform2D get_global_canvas_transform() const; virtual Transform2D get_final_transform() const; - void assign_next_enabled_camera_2d(const StringName &p_camera_group); void gui_set_root_order_dirty(); @@ -689,16 +666,43 @@ class Viewport : public Node { virtual bool is_attached_in_viewport() const { return false; }; virtual bool is_sub_viewport() const { return false; }; +private: + // 2D audio, camera, and physics. (don't put World2D here because World2D is needed for Control nodes). + friend class AudioListener2D; // Needs _audio_listener_2d_set and _audio_listener_2d_remove + AudioListener2D *audio_listener_2d = nullptr; + void _audio_listener_2d_set(AudioListener2D *p_audio_listener); + void _audio_listener_2d_remove(AudioListener2D *p_audio_listener); + bool is_audio_listener_2d_enabled = false; + RID internal_audio_listener_2d; + + friend class Camera2D; // Needs _camera_2d_set + Camera2D *camera_2d = nullptr; + void _camera_2d_set(Camera2D *p_camera_2d); + + // Collider to frame + HashMap physics_2d_mouseover; + // Collider & shape to frame + HashMap, uint64_t, PairHash> physics_2d_shape_mouseover; + // Cleans up colliders corresponding to old frames or all of them. + void _cleanup_mouseover_colliders(bool p_clean_all_frames, bool p_paused_only, uint64_t p_frame_reference = 0); + +public: + AudioListener2D *get_audio_listener_2d() const; + void set_as_audio_listener_2d(bool p_enable); + bool is_audio_listener_2d() const; + + Camera2D *get_camera_2d() const; + void assign_next_enabled_camera_2d(const StringName &p_camera_group); + #ifndef _3D_DISABLED +private: + // 3D audio, camera, physics, and world. bool use_xr = false; friend class AudioListener3D; AudioListener3D *audio_listener_3d = nullptr; HashSet audio_listener_3d_set; bool is_audio_listener_3d_enabled = false; RID internal_audio_listener_3d; - AudioListener3D *get_audio_listener_3d() const; - void set_as_audio_listener_3d(bool p_enable); - bool is_audio_listener_3d() const; void _update_audio_listener_3d(); void _listener_transform_3d_changed_notify(); void _audio_listener_3d_set(AudioListener3D *p_listener); @@ -729,13 +733,24 @@ class Viewport : public Node { friend class Camera3D; Camera3D *camera_3d = nullptr; HashSet camera_3d_set; - Camera3D *get_camera_3d() const; void _camera_3d_transform_changed_notify(); void _camera_3d_set(Camera3D *p_camera); bool _camera_3d_add(Camera3D *p_camera); //true if first void _camera_3d_remove(Camera3D *p_camera); void _camera_3d_make_next_current(Camera3D *p_exclude); + Ref world_3d; + Ref own_world_3d; + void _own_world_3d_changed(); + void _propagate_enter_world_3d(Node *p_node); + void _propagate_exit_world_3d(Node *p_node); + +public: + AudioListener3D *get_audio_listener_3d() const; + void set_as_audio_listener_3d(bool p_enable); + bool is_audio_listener_3d() const; + + Camera3D *get_camera_3d() const; void enable_camera_3d_override(bool p_enable); bool is_camera_3d_override_enabled() const; @@ -748,24 +763,16 @@ class Viewport : public Node { void set_disable_3d(bool p_disable); bool is_3d_disabled() const; - Ref world_3d; - Ref own_world_3d; void set_world_3d(const Ref &p_world_3d); Ref get_world_3d() const; Ref find_world_3d() const; - void _own_world_3d_changed(); void set_use_own_world_3d(bool p_use_own_world_3d); bool is_using_own_world_3d() const; - void _propagate_enter_world_3d(Node *p_node); - void _propagate_exit_world_3d(Node *p_node); void set_use_xr(bool p_use_xr); bool is_using_xr(); #endif // _3D_DISABLED - void _propagate_world_2d_changed(Node *p_node); - - void _validate_property(PropertyInfo &p_property) const; Viewport(); ~Viewport(); };