summaryrefslogtreecommitdiff
path: root/scene/3d/node_3d.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/3d/node_3d.cpp')
-rw-r--r--scene/3d/node_3d.cpp62
1 files changed, 59 insertions, 3 deletions
diff --git a/scene/3d/node_3d.cpp b/scene/3d/node_3d.cpp
index e96e4df55c..e96b8ee1f9 100644
--- a/scene/3d/node_3d.cpp
+++ b/scene/3d/node_3d.cpp
@@ -32,6 +32,7 @@
#include "core/config/engine.h"
#include "core/object/message_queue.h"
+#include "scene/3d/visual_instance_3d.h"
#include "scene/main/scene_tree.h"
#include "scene/main/window.h"
#include "scene/scene_string_names.h"
@@ -148,6 +149,7 @@ void Node3D::_notification(int p_what) {
_notify_dirty();
notification(NOTIFICATION_ENTER_WORLD);
+ _update_visibility_parent(true);
} break;
case NOTIFICATION_EXIT_TREE: {
@@ -161,6 +163,7 @@ void Node3D::_notification(int p_what) {
data.parent = nullptr;
data.C = nullptr;
data.top_level_active = false;
+ _update_visibility_parent(true);
} break;
case NOTIFICATION_ENTER_WORLD: {
data.inside_world = true;
@@ -282,8 +285,12 @@ Transform3D Node3D::get_local_gizmo_transform() const {
}
#endif
-Node3D *Node3D::get_parent_spatial() const {
- return data.parent;
+Node3D *Node3D::get_parent_node_3d() const {
+ if (data.top_level) {
+ return nullptr;
+ }
+
+ return Object::cast_to<Node3D>(get_parent());
}
Transform3D Node3D::get_relative_transform(const Node *p_parent) const {
@@ -690,6 +697,51 @@ void Node3D::force_update_transform() {
notification(NOTIFICATION_TRANSFORM_CHANGED);
}
+void Node3D::_update_visibility_parent(bool p_update_root) {
+ RID new_parent;
+
+ if (!visibility_parent_path.is_empty()) {
+ if (!p_update_root) {
+ return;
+ }
+ Node *parent = get_node_or_null(visibility_parent_path);
+ ERR_FAIL_COND_MSG(!parent, "Can't find visibility parent node at path: " + visibility_parent_path);
+ ERR_FAIL_COND_MSG(parent == this, "The visibility parent can't be the same node.");
+ GeometryInstance3D *gi = Object::cast_to<GeometryInstance3D>(parent);
+ ERR_FAIL_COND_MSG(!gi, "The visibility parent node must be a GeometryInstance3D, at path: " + visibility_parent_path);
+ new_parent = gi ? gi->get_instance() : RID();
+ } else if (data.parent) {
+ new_parent = data.parent->data.visibility_parent;
+ }
+
+ if (new_parent == data.visibility_parent) {
+ return;
+ }
+
+ data.visibility_parent = new_parent;
+
+ VisualInstance3D *vi = Object::cast_to<VisualInstance3D>(this);
+ if (vi) {
+ RS::get_singleton()->instance_set_visibility_parent(vi->get_instance(), data.visibility_parent);
+ }
+
+ for (List<Node3D *>::Element *E = data.children.front(); E; E = E->next()) {
+ Node3D *c = E->get();
+ c->_update_visibility_parent(false);
+ }
+}
+
+void Node3D::set_visibility_parent(const NodePath &p_path) {
+ visibility_parent_path = p_path;
+ if (is_inside_tree()) {
+ _update_visibility_parent(true);
+ }
+}
+
+NodePath Node3D::get_visibility_parent() const {
+ return visibility_parent_path;
+}
+
void Node3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_transform", "local"), &Node3D::set_transform);
ClassDB::bind_method(D_METHOD("get_transform"), &Node3D::get_transform);
@@ -703,7 +755,7 @@ void Node3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_scale"), &Node3D::get_scale);
ClassDB::bind_method(D_METHOD("set_global_transform", "global"), &Node3D::set_global_transform);
ClassDB::bind_method(D_METHOD("get_global_transform"), &Node3D::get_global_transform);
- ClassDB::bind_method(D_METHOD("get_parent_spatial"), &Node3D::get_parent_spatial);
+ ClassDB::bind_method(D_METHOD("get_parent_node_3d"), &Node3D::get_parent_node_3d);
ClassDB::bind_method(D_METHOD("set_ignore_transform_notification", "enabled"), &Node3D::set_ignore_transform_notification);
ClassDB::bind_method(D_METHOD("set_as_top_level", "enable"), &Node3D::set_as_top_level);
ClassDB::bind_method(D_METHOD("is_set_as_top_level"), &Node3D::is_set_as_top_level);
@@ -713,6 +765,9 @@ void Node3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("force_update_transform"), &Node3D::force_update_transform);
+ ClassDB::bind_method(D_METHOD("set_visibility_parent", "path"), &Node3D::set_visibility_parent);
+ ClassDB::bind_method(D_METHOD("get_visibility_parent"), &Node3D::get_visibility_parent);
+
ClassDB::bind_method(D_METHOD("_update_gizmo"), &Node3D::_update_gizmo);
ClassDB::bind_method(D_METHOD("update_gizmo"), &Node3D::update_gizmo);
@@ -768,6 +823,7 @@ void Node3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM3D, "transform", PROPERTY_HINT_NONE, ""), "set_transform", "get_transform");
ADD_GROUP("Visibility", "");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "visible"), "set_visible", "is_visible");
+ ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "visibility_parent", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "GeometryInstance3D"), "set_visibility_parent", "get_visibility_parent");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "gizmo", PROPERTY_HINT_RESOURCE_TYPE, "Node3DGizmo", 0), "set_gizmo", "get_gizmo");
ADD_SIGNAL(MethodInfo("visibility_changed"));