|
@@ -157,6 +157,7 @@ void Spatial::_notification(int p_what) {
|
|
} else {
|
|
} else {
|
|
data.C = nullptr;
|
|
data.C = nullptr;
|
|
}
|
|
}
|
|
|
|
+ _update_visible_in_tree();
|
|
|
|
|
|
if (data.toplevel && !Engine::get_singleton()->is_editor_hint()) {
|
|
if (data.toplevel && !Engine::get_singleton()->is_editor_hint()) {
|
|
if (data.parent) {
|
|
if (data.parent) {
|
|
@@ -216,6 +217,8 @@ void Spatial::_notification(int p_what) {
|
|
data.parent = nullptr;
|
|
data.parent = nullptr;
|
|
data.C = nullptr;
|
|
data.C = nullptr;
|
|
data.toplevel_active = false;
|
|
data.toplevel_active = false;
|
|
|
|
+
|
|
|
|
+ _update_visible_in_tree();
|
|
_disable_client_physics_interpolation();
|
|
_disable_client_physics_interpolation();
|
|
} break;
|
|
} break;
|
|
case NOTIFICATION_ENTER_WORLD: {
|
|
case NOTIFICATION_ENTER_WORLD: {
|
|
@@ -732,6 +735,36 @@ Ref<World> Spatial::get_world() const {
|
|
return data.viewport->find_world();
|
|
return data.viewport->find_world();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+void Spatial::_update_visible_in_tree() {
|
|
|
|
+ Spatial *parent = get_parent_spatial();
|
|
|
|
+
|
|
|
|
+ bool propagate_visible = parent ? parent->data.visible_in_tree : true;
|
|
|
|
+
|
|
|
|
+ // Only propagate visible when entering tree if we are visible.
|
|
|
|
+ propagate_visible &= is_visible();
|
|
|
|
+
|
|
|
|
+ _propagate_visible_in_tree(propagate_visible);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void Spatial::_propagate_visible_in_tree(bool p_visible_in_tree) {
|
|
|
|
+ // If any node is invisible, the propagation changes to invisible below.
|
|
|
|
+ p_visible_in_tree &= is_visible();
|
|
|
|
+
|
|
|
|
+ // No change.
|
|
|
|
+ if (data.visible_in_tree == p_visible_in_tree) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ data.visible_in_tree = p_visible_in_tree;
|
|
|
|
+
|
|
|
|
+ for (int32_t n = 0; n < get_child_count(); n++) {
|
|
|
|
+ Spatial *s = Object::cast_to<Spatial>(get_child(n));
|
|
|
|
+ if (s) {
|
|
|
|
+ s->_propagate_visible_in_tree(p_visible_in_tree);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
void Spatial::_propagate_visibility_changed() {
|
|
void Spatial::_propagate_visibility_changed() {
|
|
notification(NOTIFICATION_VISIBILITY_CHANGED);
|
|
notification(NOTIFICATION_VISIBILITY_CHANGED);
|
|
emit_signal(SceneStringNames::get_singleton()->visibility_changed);
|
|
emit_signal(SceneStringNames::get_singleton()->visibility_changed);
|
|
@@ -791,6 +824,10 @@ void Spatial::show() {
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ bool parent_visible = get_parent_spatial() ? get_parent_spatial()->data.visible_in_tree : true;
|
|
|
|
+ if (parent_visible) {
|
|
|
|
+ _propagate_visible_in_tree(true);
|
|
|
|
+ }
|
|
_propagate_visibility_changed();
|
|
_propagate_visibility_changed();
|
|
}
|
|
}
|
|
|
|
|
|
@@ -805,10 +842,14 @@ void Spatial::hide() {
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ bool parent_visible = get_parent_spatial() ? get_parent_spatial()->data.visible_in_tree : true;
|
|
|
|
+ if (parent_visible) {
|
|
|
|
+ _propagate_visible_in_tree(false);
|
|
|
|
+ }
|
|
_propagate_visibility_changed();
|
|
_propagate_visibility_changed();
|
|
}
|
|
}
|
|
|
|
|
|
-bool Spatial::is_visible_in_tree() const {
|
|
|
|
|
|
+bool Spatial::_is_visible_in_tree_reference() const {
|
|
const Spatial *s = this;
|
|
const Spatial *s = this;
|
|
|
|
|
|
while (s) {
|
|
while (s) {
|
|
@@ -1121,6 +1162,7 @@ Spatial::Spatial() :
|
|
data.viewport = nullptr;
|
|
data.viewport = nullptr;
|
|
data.inside_world = false;
|
|
data.inside_world = false;
|
|
data.visible = true;
|
|
data.visible = true;
|
|
|
|
+ data.visible_in_tree = true;
|
|
data.disable_scale = false;
|
|
data.disable_scale = false;
|
|
data.vi_visible = true;
|
|
data.vi_visible = true;
|
|
data.merging_allowed = true;
|
|
data.merging_allowed = true;
|