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.cpp155
1 files changed, 99 insertions, 56 deletions
diff --git a/scene/3d/node_3d.cpp b/scene/3d/node_3d.cpp
index 4575716f7a..d6c6ec75b4 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"
@@ -48,7 +49,7 @@
a) If above is invalid, don't keep invalidating upwards
2) If a node sets a GLOBAL, it is converted to LOCAL (and forces validation of everything pending below)
- drawback: setting/reading globals is useful and used very very often, and using affine inverses is slow
+ drawback: setting/reading globals is useful and used very often, and using affine inverses is slow
---
@@ -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;
@@ -223,7 +226,7 @@ void Node3D::_notification(int p_what) {
}
}
-void Node3D::set_transform(const Transform &p_transform) {
+void Node3D::set_transform(const Transform3D &p_transform) {
data.local_transform = p_transform;
data.dirty |= DIRTY_VECTORS;
_propagate_transform_changed(this);
@@ -232,8 +235,8 @@ void Node3D::set_transform(const Transform &p_transform) {
}
}
-void Node3D::set_global_transform(const Transform &p_transform) {
- Transform xform =
+void Node3D::set_global_transform(const Transform3D &p_transform) {
+ Transform3D xform =
(data.parent && !data.top_level_active) ?
data.parent->get_global_transform().affine_inverse() * p_transform :
p_transform;
@@ -241,16 +244,15 @@ void Node3D::set_global_transform(const Transform &p_transform) {
set_transform(xform);
}
-Transform Node3D::get_transform() const {
+Transform3D Node3D::get_transform() const {
if (data.dirty & DIRTY_LOCAL) {
_update_local_transform();
}
return data.local_transform;
}
-
-Transform Node3D::get_global_transform() const {
- ERR_FAIL_COND_V(!is_inside_tree(), Transform());
+Transform3D Node3D::get_global_transform() const {
+ ERR_FAIL_COND_V(!is_inside_tree(), Transform3D());
if (data.dirty & DIRTY_GLOBAL) {
if (data.dirty & DIRTY_LOCAL) {
@@ -274,25 +276,28 @@ Transform Node3D::get_global_transform() const {
}
#ifdef TOOLS_ENABLED
-Transform Node3D::get_global_gizmo_transform() const {
+Transform3D Node3D::get_global_gizmo_transform() const {
return get_global_transform();
}
-Transform Node3D::get_local_gizmo_transform() const {
+Transform3D Node3D::get_local_gizmo_transform() const {
return get_transform();
}
#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());
}
-Transform Node3D::get_relative_transform(const Node *p_parent) const {
- if (p_parent == this) {
- return Transform();
- }
+Transform3D Node3D::get_relative_transform(const Node *p_parent) const {
+ if (p_parent == this)
+ return Transform3D();
- ERR_FAIL_COND_V(!data.parent, Transform());
+ ERR_FAIL_COND_V(!data.parent, Transform3D());
if (p_parent == data.parent) {
return get_transform();
@@ -301,8 +306,8 @@ Transform Node3D::get_relative_transform(const Node *p_parent) const {
}
}
-void Node3D::set_translation(const Vector3 &p_translation) {
- data.local_transform.origin = p_translation;
+void Node3D::set_position(const Vector3 &p_position) {
+ data.local_transform.origin = p_position;
_propagate_transform_changed(this);
if (data.notify_local_transform) {
notification(NOTIFICATION_LOCAL_TRANSFORM_CHANGED);
@@ -323,10 +328,6 @@ void Node3D::set_rotation(const Vector3 &p_euler_rad) {
}
}
-void Node3D::set_rotation_degrees(const Vector3 &p_euler_deg) {
- set_rotation(p_euler_deg * (Math_PI / 180.0));
-}
-
void Node3D::set_scale(const Vector3 &p_scale) {
if (data.dirty & DIRTY_VECTORS) {
data.rotation = data.local_transform.basis.get_rotation();
@@ -341,7 +342,7 @@ void Node3D::set_scale(const Vector3 &p_scale) {
}
}
-Vector3 Node3D::get_translation() const {
+Vector3 Node3D::get_position() const {
return data.local_transform.origin;
}
@@ -356,10 +357,6 @@ Vector3 Node3D::get_rotation() const {
return data.rotation;
}
-Vector3 Node3D::get_rotation_degrees() const {
- return get_rotation() * (180.0 / Math_PI);
-}
-
Vector3 Node3D::get_scale() const {
if (data.dirty & DIRTY_VECTORS) {
data.scale = data.local_transform.basis.get_scale();
@@ -557,87 +554,87 @@ bool Node3D::is_visible() const {
}
void Node3D::rotate_object_local(const Vector3 &p_axis, float p_angle) {
- Transform t = get_transform();
+ Transform3D t = get_transform();
t.basis.rotate_local(p_axis, p_angle);
set_transform(t);
}
void Node3D::rotate(const Vector3 &p_axis, float p_angle) {
- Transform t = get_transform();
+ Transform3D t = get_transform();
t.basis.rotate(p_axis, p_angle);
set_transform(t);
}
void Node3D::rotate_x(float p_angle) {
- Transform t = get_transform();
+ Transform3D t = get_transform();
t.basis.rotate(Vector3(1, 0, 0), p_angle);
set_transform(t);
}
void Node3D::rotate_y(float p_angle) {
- Transform t = get_transform();
+ Transform3D t = get_transform();
t.basis.rotate(Vector3(0, 1, 0), p_angle);
set_transform(t);
}
void Node3D::rotate_z(float p_angle) {
- Transform t = get_transform();
+ Transform3D t = get_transform();
t.basis.rotate(Vector3(0, 0, 1), p_angle);
set_transform(t);
}
void Node3D::translate(const Vector3 &p_offset) {
- Transform t = get_transform();
+ Transform3D t = get_transform();
t.translate(p_offset);
set_transform(t);
}
void Node3D::translate_object_local(const Vector3 &p_offset) {
- Transform t = get_transform();
+ Transform3D t = get_transform();
- Transform s;
+ Transform3D s;
s.translate(p_offset);
set_transform(t * s);
}
void Node3D::scale(const Vector3 &p_ratio) {
- Transform t = get_transform();
+ Transform3D t = get_transform();
t.basis.scale(p_ratio);
set_transform(t);
}
void Node3D::scale_object_local(const Vector3 &p_scale) {
- Transform t = get_transform();
+ Transform3D t = get_transform();
t.basis.scale_local(p_scale);
set_transform(t);
}
void Node3D::global_rotate(const Vector3 &p_axis, float p_angle) {
- Transform t = get_global_transform();
+ Transform3D t = get_global_transform();
t.basis.rotate(p_axis, p_angle);
set_global_transform(t);
}
void Node3D::global_scale(const Vector3 &p_scale) {
- Transform t = get_global_transform();
+ Transform3D t = get_global_transform();
t.basis.scale(p_scale);
set_global_transform(t);
}
void Node3D::global_translate(const Vector3 &p_offset) {
- Transform t = get_global_transform();
+ Transform3D t = get_global_transform();
t.origin += p_offset;
set_global_transform(t);
}
void Node3D::orthonormalize() {
- Transform t = get_transform();
+ Transform3D t = get_transform();
t.orthonormalize();
set_transform(t);
}
void Node3D::set_identity() {
- set_transform(Transform());
+ set_transform(Transform3D());
}
void Node3D::look_at(const Vector3 &p_target, const Vector3 &p_up) {
@@ -649,7 +646,7 @@ void Node3D::look_at_from_position(const Vector3 &p_pos, const Vector3 &p_target
ERR_FAIL_COND_MSG(p_pos == p_target, "Node origin and target are in the same position, look_at() failed.");
ERR_FAIL_COND_MSG(p_up.cross(p_target - p_pos) == Vector3(), "Up vector and direction between node origin and target are aligned, look_at() failed.");
- Transform lookat;
+ Transform3D lookat;
lookat.origin = p_pos;
Vector3 original_scale(get_scale());
@@ -692,20 +689,63 @@ 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);
- ClassDB::bind_method(D_METHOD("set_translation", "translation"), &Node3D::set_translation);
- ClassDB::bind_method(D_METHOD("get_translation"), &Node3D::get_translation);
+ ClassDB::bind_method(D_METHOD("set_position", "position"), &Node3D::set_position);
+ ClassDB::bind_method(D_METHOD("get_position"), &Node3D::get_position);
ClassDB::bind_method(D_METHOD("set_rotation", "euler"), &Node3D::set_rotation);
ClassDB::bind_method(D_METHOD("get_rotation"), &Node3D::get_rotation);
- ClassDB::bind_method(D_METHOD("set_rotation_degrees", "euler_degrees"), &Node3D::set_rotation_degrees);
- ClassDB::bind_method(D_METHOD("get_rotation_degrees"), &Node3D::get_rotation_degrees);
ClassDB::bind_method(D_METHOD("set_scale", "scale"), &Node3D::set_scale);
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);
@@ -715,6 +755,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);
@@ -758,19 +801,19 @@ void Node3D::_bind_methods() {
BIND_CONSTANT(NOTIFICATION_EXIT_WORLD);
BIND_CONSTANT(NOTIFICATION_VISIBILITY_CHANGED);
- //ADD_PROPERTY( PropertyInfo(Variant::TRANSFORM,"transform/global",PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR ), "set_global_transform", "get_global_transform") ;
+ //ADD_PROPERTY( PropertyInfo(Variant::TRANSFORM3D,"transform/global",PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR ), "set_global_transform", "get_global_transform") ;
ADD_GROUP("Transform", "");
- ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "global_transform", PROPERTY_HINT_NONE, "", 0), "set_global_transform", "get_global_transform");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "translation", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_translation", "get_translation");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "rotation_degrees", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_rotation_degrees", "get_rotation_degrees");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "rotation", PROPERTY_HINT_NONE, "", 0), "set_rotation", "get_rotation");
+ ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM3D, "global_transform", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "set_global_transform", "get_global_transform");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "position", PROPERTY_HINT_RANGE, "-99999,99999,0,or_greater,or_lesser,noslider,suffix:m", PROPERTY_USAGE_EDITOR), "set_position", "get_position");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "rotation", PROPERTY_HINT_RANGE, "-360,360,0.1,or_lesser,or_greater,radians", PROPERTY_USAGE_EDITOR), "set_rotation", "get_rotation");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "scale", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_scale", "get_scale");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "top_level"), "set_as_top_level", "is_set_as_top_level");
ADD_GROUP("Matrix", "");
- ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "transform", PROPERTY_HINT_NONE, ""), "set_transform", "get_transform");
+ 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::OBJECT, "gizmo", PROPERTY_HINT_RESOURCE_TYPE, "Node3DGizmo", 0), "set_gizmo", "get_gizmo");
+ 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", PROPERTY_USAGE_NONE), "set_gizmo", "get_gizmo");
ADD_SIGNAL(MethodInfo("visibility_changed"));
}