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.
This commit is contained in:
风青山 2023-12-15 20:51:44 +01:00 committed by Yuri Sizov
parent f8a2a91936
commit ea30aabfb1
14 changed files with 52 additions and 26 deletions

View File

@ -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();
}
}

View File

@ -133,10 +133,11 @@ private:
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;

View File

@ -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;

View File

@ -109,6 +109,8 @@ protected:
void set_body_mode(PhysicsServer2D::BodyMode p_mode);
virtual void _space_changed(const RID &p_new_space);
GDVIRTUAL3(_input_event, Viewport *, Ref<InputEvent>, int)
GDVIRTUAL0(_mouse_enter)
GDVIRTUAL0(_mouse_exit)

View File

@ -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;

View File

@ -149,6 +149,8 @@ protected:
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;

View File

@ -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;
}

View File

@ -116,6 +116,8 @@ protected:
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;

View File

@ -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();
}
}

View File

@ -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);
}
}

View File

@ -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();

View File

@ -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();
}
}

View File

@ -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);
}
}

View File

@ -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();