From ea30aabfb1fe24ea6e98db03452942a87c4d5f94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A3=8E=E9=9D=92=E5=B1=B1?= Date: Fri, 15 Dec 2023 20:51:44 +0100 Subject: [PATCH] Clear monitoring in `Area*` when its space changes to invalid So that it can work properly when the space changes to valid again. Change `space` in advance to prevent disabled areas from being queried again. --- scene/2d/area_2d.cpp | 8 +++----- scene/2d/area_2d.h | 3 ++- scene/2d/collision_object_2d.cpp | 8 ++++++++ scene/2d/collision_object_2d.h | 2 ++ scene/3d/area_3d.cpp | 10 ++++++---- scene/3d/area_3d.h | 2 ++ scene/3d/collision_object_3d.cpp | 7 +++++++ scene/3d/collision_object_3d.h | 2 ++ servers/physics_2d/godot_area_2d.h | 4 ++-- servers/physics_2d/godot_body_2d.cpp | 3 ++- servers/physics_2d/godot_collision_object_2d.cpp | 11 ++++++----- servers/physics_3d/godot_area_3d.h | 4 ++-- servers/physics_3d/godot_body_3d.cpp | 3 ++- servers/physics_3d/godot_collision_object_3d.cpp | 11 ++++++----- 14 files changed, 52 insertions(+), 26 deletions(-) diff --git a/scene/2d/area_2d.cpp b/scene/2d/area_2d.cpp index 3aa2a71a2cdc..2c4bf08f3439 100644 --- a/scene/2d/area_2d.cpp +++ b/scene/2d/area_2d.cpp @@ -384,11 +384,9 @@ void Area2D::_clear_monitoring() { } } -void Area2D::_notification(int p_what) { - switch (p_what) { - case NOTIFICATION_EXIT_TREE: { - _clear_monitoring(); - } break; +void Area2D::_space_changed(const RID &p_new_space) { + if (p_new_space.is_null()) { + _clear_monitoring(); } } diff --git a/scene/2d/area_2d.h b/scene/2d/area_2d.h index 421c29f7589f..9d6e04b706e6 100644 --- a/scene/2d/area_2d.h +++ b/scene/2d/area_2d.h @@ -133,10 +133,11 @@ class Area2D : public CollisionObject2D { StringName audio_bus; protected: - void _notification(int p_what); static void _bind_methods(); void _validate_property(PropertyInfo &p_property) const; + virtual void _space_changed(const RID &p_new_space) override; + public: void set_gravity_space_override_mode(SpaceOverride p_mode); SpaceOverride get_gravity_space_override_mode() const; diff --git a/scene/2d/collision_object_2d.cpp b/scene/2d/collision_object_2d.cpp index ab42c52913b4..2fbe4eb409a3 100644 --- a/scene/2d/collision_object_2d.cpp +++ b/scene/2d/collision_object_2d.cpp @@ -59,6 +59,7 @@ void CollisionObject2D::_notification(int p_what) { } else { PhysicsServer2D::get_singleton()->body_set_space(rid, space); } + _space_changed(space); } _update_pickable(); @@ -102,6 +103,7 @@ void CollisionObject2D::_notification(int p_what) { } else { PhysicsServer2D::get_singleton()->body_set_space(rid, RID()); } + _space_changed(RID()); } } @@ -125,6 +127,7 @@ void CollisionObject2D::_notification(int p_what) { } else { PhysicsServer2D::get_singleton()->body_set_space(rid, space); } + _space_changed(space); } break; case NOTIFICATION_DISABLED: { @@ -246,6 +249,7 @@ void CollisionObject2D::_apply_disabled() { } else { PhysicsServer2D::get_singleton()->body_set_space(rid, RID()); } + _space_changed(RID()); } } } break; @@ -272,6 +276,7 @@ void CollisionObject2D::_apply_enabled() { } else { PhysicsServer2D::get_singleton()->body_set_space(rid, space); } + _space_changed(space); } } break; @@ -569,6 +574,9 @@ void CollisionObject2D::set_body_mode(PhysicsServer2D::BodyMode p_mode) { PhysicsServer2D::get_singleton()->body_set_mode(rid, p_mode); } +void CollisionObject2D::_space_changed(const RID &p_new_space) { +} + void CollisionObject2D::_update_pickable() { if (!is_inside_tree()) { return; diff --git a/scene/2d/collision_object_2d.h b/scene/2d/collision_object_2d.h index 88429b145d05..780793f289bc 100644 --- a/scene/2d/collision_object_2d.h +++ b/scene/2d/collision_object_2d.h @@ -109,6 +109,8 @@ class CollisionObject2D : public Node2D { void set_body_mode(PhysicsServer2D::BodyMode p_mode); + virtual void _space_changed(const RID &p_new_space); + GDVIRTUAL3(_input_event, Viewport *, Ref, int) GDVIRTUAL0(_mouse_enter) GDVIRTUAL0(_mouse_exit) diff --git a/scene/3d/area_3d.cpp b/scene/3d/area_3d.cpp index beb6892435a4..585bce09fb92 100644 --- a/scene/3d/area_3d.cpp +++ b/scene/3d/area_3d.cpp @@ -347,12 +347,14 @@ void Area3D::_clear_monitoring() { } } +void Area3D::_space_changed(const RID &p_new_space) { + if (p_new_space.is_null()) { + _clear_monitoring(); + } +} + void Area3D::_notification(int p_what) { switch (p_what) { - case NOTIFICATION_EXIT_TREE: { - _clear_monitoring(); - } break; - case NOTIFICATION_ENTER_TREE: { _initialize_wind(); } break; diff --git a/scene/3d/area_3d.h b/scene/3d/area_3d.h index 86602d3192dd..05c558e8f023 100644 --- a/scene/3d/area_3d.h +++ b/scene/3d/area_3d.h @@ -149,6 +149,8 @@ class Area3D : public CollisionObject3D { static void _bind_methods(); void _validate_property(PropertyInfo &p_property) const; + virtual void _space_changed(const RID &p_new_space) override; + public: void set_gravity_space_override_mode(SpaceOverride p_mode); SpaceOverride get_gravity_space_override_mode() const; diff --git a/scene/3d/collision_object_3d.cpp b/scene/3d/collision_object_3d.cpp index bfe594adc234..4562ecfb5fa5 100644 --- a/scene/3d/collision_object_3d.cpp +++ b/scene/3d/collision_object_3d.cpp @@ -78,6 +78,7 @@ void CollisionObject3D::_notification(int p_what) { } else { PhysicsServer3D::get_singleton()->body_set_space(rid, space); } + _space_changed(space); } _update_pickable(); @@ -117,6 +118,7 @@ void CollisionObject3D::_notification(int p_what) { } else { PhysicsServer3D::get_singleton()->body_set_space(rid, RID()); } + _space_changed(RID()); } } @@ -244,6 +246,7 @@ void CollisionObject3D::_apply_disabled() { } else { PhysicsServer3D::get_singleton()->body_set_space(rid, RID()); } + _space_changed(RID()); } } } break; @@ -270,6 +273,7 @@ void CollisionObject3D::_apply_enabled() { } else { PhysicsServer3D::get_singleton()->body_set_space(rid, space); } + _space_changed(space); } } break; @@ -320,6 +324,9 @@ void CollisionObject3D::set_body_mode(PhysicsServer3D::BodyMode p_mode) { PhysicsServer3D::get_singleton()->body_set_mode(rid, p_mode); } +void CollisionObject3D::_space_changed(const RID &p_new_space) { +} + void CollisionObject3D::set_only_update_transform_changes(bool p_enable) { only_update_transform_changes = p_enable; } diff --git a/scene/3d/collision_object_3d.h b/scene/3d/collision_object_3d.h index ebcbb39e0db9..b51423f0215a 100644 --- a/scene/3d/collision_object_3d.h +++ b/scene/3d/collision_object_3d.h @@ -116,6 +116,8 @@ class CollisionObject3D : public Node3D { void set_body_mode(PhysicsServer3D::BodyMode p_mode); + virtual void _space_changed(const RID &p_new_space); + void set_only_update_transform_changes(bool p_enable); bool is_only_update_transform_changes_enabled() const; diff --git a/servers/physics_2d/godot_area_2d.h b/servers/physics_2d/godot_area_2d.h index 234e4eb9a9d2..d14ddb6a2eca 100644 --- a/servers/physics_2d/godot_area_2d.h +++ b/servers/physics_2d/godot_area_2d.h @@ -167,7 +167,7 @@ void GodotArea2D::add_body_to_query(GodotBody2D *p_body, uint32_t p_body_shape, void GodotArea2D::remove_body_from_query(GodotBody2D *p_body, uint32_t p_body_shape, uint32_t p_area_shape) { BodyKey bk(p_body, p_body_shape, p_area_shape); monitored_bodies[bk].dec(); - if (!monitor_query_list.in_list()) { + if (get_space() && !monitor_query_list.in_list()) { _queue_monitor_update(); } } @@ -183,7 +183,7 @@ void GodotArea2D::add_area_to_query(GodotArea2D *p_area, uint32_t p_area_shape, void GodotArea2D::remove_area_from_query(GodotArea2D *p_area, uint32_t p_area_shape, uint32_t p_self_shape) { BodyKey bk(p_area, p_area_shape, p_self_shape); monitored_areas[bk].dec(); - if (!monitor_query_list.in_list()) { + if (get_space() && !monitor_query_list.in_list()) { _queue_monitor_update(); } } diff --git a/servers/physics_2d/godot_body_2d.cpp b/servers/physics_2d/godot_body_2d.cpp index 12c3e1e5b43a..01996dc43c41 100644 --- a/servers/physics_2d/godot_body_2d.cpp +++ b/servers/physics_2d/godot_body_2d.cpp @@ -407,7 +407,8 @@ void GodotBody2D::set_space(GodotSpace2D *p_space) { if (get_space()) { _mass_properties_changed(); - if (active) { + + if (active && !active_list.in_list()) { get_space()->body_add_to_active_list(&active_list); } } diff --git a/servers/physics_2d/godot_collision_object_2d.cpp b/servers/physics_2d/godot_collision_object_2d.cpp index 4fb53a2d89cb..9851cac140a0 100644 --- a/servers/physics_2d/godot_collision_object_2d.cpp +++ b/servers/physics_2d/godot_collision_object_2d.cpp @@ -212,20 +212,21 @@ void GodotCollisionObject2D::_update_shapes_with_motion(const Vector2 &p_motion) } void GodotCollisionObject2D::_set_space(GodotSpace2D *p_space) { - if (space) { - space->remove_object(this); + GodotSpace2D *old_space = space; + space = p_space; + + if (old_space) { + old_space->remove_object(this); for (int i = 0; i < shapes.size(); i++) { Shape &s = shapes.write[i]; if (s.bpid) { - space->get_broadphase()->remove(s.bpid); + old_space->get_broadphase()->remove(s.bpid); s.bpid = 0; } } } - space = p_space; - if (space) { space->add_object(this); _update_shapes(); diff --git a/servers/physics_3d/godot_area_3d.h b/servers/physics_3d/godot_area_3d.h index f05d0f90197c..c3c9e494a43c 100644 --- a/servers/physics_3d/godot_area_3d.h +++ b/servers/physics_3d/godot_area_3d.h @@ -204,7 +204,7 @@ void GodotArea3D::add_body_to_query(GodotBody3D *p_body, uint32_t p_body_shape, void GodotArea3D::remove_body_from_query(GodotBody3D *p_body, uint32_t p_body_shape, uint32_t p_area_shape) { BodyKey bk(p_body, p_body_shape, p_area_shape); monitored_bodies[bk].dec(); - if (!monitor_query_list.in_list()) { + if (get_space() && !monitor_query_list.in_list()) { _queue_monitor_update(); } } @@ -220,7 +220,7 @@ void GodotArea3D::add_area_to_query(GodotArea3D *p_area, uint32_t p_area_shape, void GodotArea3D::remove_area_from_query(GodotArea3D *p_area, uint32_t p_area_shape, uint32_t p_self_shape) { BodyKey bk(p_area, p_area_shape, p_self_shape); monitored_areas[bk].dec(); - if (!monitor_query_list.in_list()) { + if (get_space() && !monitor_query_list.in_list()) { _queue_monitor_update(); } } diff --git a/servers/physics_3d/godot_body_3d.cpp b/servers/physics_3d/godot_body_3d.cpp index e102d0f3c910..407957b904de 100644 --- a/servers/physics_3d/godot_body_3d.cpp +++ b/servers/physics_3d/godot_body_3d.cpp @@ -454,7 +454,8 @@ void GodotBody3D::set_space(GodotSpace3D *p_space) { if (get_space()) { _mass_properties_changed(); - if (active) { + + if (active && !active_list.in_list()) { get_space()->body_add_to_active_list(&active_list); } } diff --git a/servers/physics_3d/godot_collision_object_3d.cpp b/servers/physics_3d/godot_collision_object_3d.cpp index 0d7fcb67f6a4..283614a43df6 100644 --- a/servers/physics_3d/godot_collision_object_3d.cpp +++ b/servers/physics_3d/godot_collision_object_3d.cpp @@ -210,20 +210,21 @@ void GodotCollisionObject3D::_update_shapes_with_motion(const Vector3 &p_motion) } void GodotCollisionObject3D::_set_space(GodotSpace3D *p_space) { - if (space) { - space->remove_object(this); + GodotSpace3D *old_space = space; + space = p_space; + + if (old_space) { + old_space->remove_object(this); for (int i = 0; i < shapes.size(); i++) { Shape &s = shapes.write[i]; if (s.bpid) { - space->get_broadphase()->remove(s.bpid); + old_space->get_broadphase()->remove(s.bpid); s.bpid = 0; } } } - space = p_space; - if (space) { space->add_object(this); _update_shapes();