diff --git a/scene/main/node.cpp b/scene/main/node.cpp index e9d5f0f65..04d31668a 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -38,6 +38,7 @@ #include "scene/animation/scene_tree_tween.h" #include "scene/resources/packed_scene.h" #include "scene/scene_string_names.h" +#include "world.h" #include "viewport.h" #include "core/config/project_settings.h" @@ -72,6 +73,7 @@ void Node::_notification(int p_notification) { } break; case NOTIFICATION_ENTER_TREE: { ERR_FAIL_COND(!get_viewport()); + ERR_FAIL_COND(!get_world()); ERR_FAIL_COND(!get_tree()); if (data.pause_mode == PAUSE_MODE_INHERIT) { @@ -108,6 +110,7 @@ void Node::_notification(int p_notification) { } break; case NOTIFICATION_EXIT_TREE: { ERR_FAIL_COND(!get_viewport()); + ERR_FAIL_COND(!get_world()); ERR_FAIL_COND(!get_tree()); get_tree()->node_count--; @@ -263,6 +266,11 @@ void Node::_propagate_enter_tree() { data.viewport = data.parent->data.viewport; } + data.world = Object::cast_to(this); + if (!data.world && data.parent) { + data.world = data.parent->data.world; + } + data.inside_tree = true; for (Map::Element *E = data.grouped.front(); E; E = E->next()) { @@ -397,6 +405,7 @@ void Node::_propagate_exit_tree() { } data.viewport = nullptr; + data.world = nullptr; if (data.tree) { data.tree->tree_changed(); @@ -3262,6 +3271,7 @@ void Node::_bind_methods() { ClassDB::bind_method(D_METHOD("get_scene_instance_load_placeholder"), &Node::get_scene_instance_load_placeholder); ClassDB::bind_method(D_METHOD("get_viewport"), &Node::get_viewport); + ClassDB::bind_method(D_METHOD("get_world"), &Node::get_world); ClassDB::bind_method(D_METHOD("queue_free"), &Node::queue_delete); @@ -3463,6 +3473,7 @@ Node::Node() { data.parent_owned = false; data.in_constructor = true; data.viewport = nullptr; + data.world = nullptr; data.use_placeholder = false; data.display_folded = false; data.ready_first = true; diff --git a/scene/main/node.h b/scene/main/node.h index d6f9cd5a2..76de4deb3 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -37,6 +37,7 @@ #include "scene/main/scene_tree.h" class Viewport; +class World; class SceneState; class SceneTreeTween; @@ -111,6 +112,7 @@ private: #endif Viewport *viewport; + World *world; Map grouped; List::Element *OW; // owned element @@ -504,6 +506,10 @@ public: return data.viewport; } + _FORCE_INLINE_ World *get_world() const { + return data.world; + } + virtual String get_configuration_warning() const; void update_configuration_warning(); diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 54e1768d9..3ce8c620a 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -30,10 +30,11 @@ #include "viewport.h" +#include "core/config/project_settings.h" #include "core/core_string_names.h" #include "core/input/input.h" +#include "core/input/shortcut.h" #include "core/os/os.h" -#include "core/config/project_settings.h" #include "scene/2d/camera_2d.h" #include "scene/2d/collision_object_2d.h" #include "scene/2d/listener_2d.h" @@ -41,20 +42,18 @@ #include "scene/3d/collision_object.h" #include "scene/3d/listener.h" #include "scene/3d/spatial.h" -#include "scene/3d/world_environment_3d.h" #include "scene/gui/control.h" #include "scene/gui/label.h" #include "scene/gui/menu_button.h" #include "scene/gui/panel.h" #include "scene/gui/panel_container.h" #include "scene/gui/popup_menu.h" -#include "core/input/shortcut.h" #include "scene/gui/viewport_container.h" #include "scene/main/canvas_layer.h" #include "scene/main/timer.h" #include "scene/resources/mesh.h" -#include "scene/resources/world_3d.h" #include "scene/resources/world_2d.h" +#include "scene/resources/world_3d.h" #include "scene/scene_string_names.h" #include "servers/physics_2d_server.h" @@ -252,15 +251,7 @@ void Viewport::_own_world_3d_changed() { ERR_FAIL_COND(world_3d.is_null()); ERR_FAIL_COND(own_world_3d.is_null()); - if (is_inside_tree()) { - _propagate_exit_world(this); - } - - own_world_3d = world_3d->duplicate(); - - if (is_inside_tree()) { - _propagate_enter_world(this); - } + World::_own_world_3d_changed(); if (is_inside_tree()) { RenderingServer::get_singleton()->viewport_set_scenario(viewport, find_world_3d()->get_scenario()); @@ -269,6 +260,37 @@ void Viewport::_own_world_3d_changed() { _update_listener(); } +void Viewport::_on_set_use_own_world_3d(bool p_use_own_world_3d) { + if (is_inside_tree()) { + RenderingServer::get_singleton()->viewport_set_scenario(viewport, find_world_3d()->get_scenario()); + } + + _update_listener(); +} + +void Viewport::_on_set_world_3d(const Ref &p_old_world) { + if (is_inside_tree()) { + RenderingServer::get_singleton()->viewport_set_scenario(viewport, find_world_3d()->get_scenario()); + } + + _update_listener(); +} +void Viewport::_on_set_world_2d(const Ref &p_old_world_2d) { + if (is_inside_tree() && p_old_world_2d.is_valid()) { + Ref old_world_2d = p_old_world_2d; + old_world_2d->_remove_viewport(this); + RenderingServer::get_singleton()->viewport_remove_canvas(viewport, current_canvas); + } + + _update_listener_2d(); + + if (is_inside_tree()) { + current_canvas = find_world_2d()->get_canvas(); + RenderingServer::get_singleton()->viewport_attach_canvas(viewport, current_canvas); + find_world_2d()->_register_viewport(this, Rect2()); + } +} + void Viewport::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { @@ -1012,70 +1034,6 @@ bool Viewport::has_transparent_background() const { return transparent_bg; } -void Viewport::set_world_2d(const Ref &p_world_2d) { - if (world_2d == p_world_2d) { - return; - } - - if (parent && parent->find_world_2d() == p_world_2d) { - WARN_PRINT("Unable to use parent world as world_2d"); - return; - } - - if (is_inside_tree()) { - find_world_2d()->_remove_viewport(this); - RenderingServer::get_singleton()->viewport_remove_canvas(viewport, current_canvas); - } - - if (p_world_2d.is_valid()) { - world_2d = p_world_2d; - } else { - WARN_PRINT("Invalid world"); - world_2d = Ref(memnew(World2D)); - } - - _update_listener_2d(); - - if (is_inside_tree()) { - current_canvas = find_world_2d()->get_canvas(); - RenderingServer::get_singleton()->viewport_attach_canvas(viewport, current_canvas); - find_world_2d()->_register_viewport(this, Rect2()); - } -} - -Ref Viewport::find_world_2d() const { - if (world_2d.is_valid()) { - return world_2d; - } else if (parent) { - return parent->find_world_2d(); - } else { - return Ref(); - } -} - -void Viewport::_propagate_enter_world(Node *p_node) { - if (p_node != this) { - if (!p_node->is_inside_tree()) { //may not have entered scene yet - return; - } - - if (Object::cast_to(p_node) || Object::cast_to(p_node)) { - p_node->notification(Spatial::NOTIFICATION_ENTER_WORLD); - } else { - Viewport *v = Object::cast_to(p_node); - if (v) { - if (v->world_3d.is_valid() || v->own_world_3d.is_valid()) { - return; - } - } - } - } - - for (int i = 0; i < p_node->get_child_count(); i++) { - _propagate_enter_world(p_node->get_child(i)); - } -} - void Viewport::_propagate_viewport_notification(Node *p_node, int p_what) { p_node->notification(p_what); for (int i = 0; i < p_node->get_child_count(); i++) { @@ -1087,84 +1045,6 @@ void Viewport::_propagate_viewport_notification(Node *p_node, int p_what) { } } -void Viewport::_propagate_exit_world(Node *p_node) { - if (p_node != this) { - if (!p_node->is_inside_tree()) { //may have exited scene already - return; - } - - if (Object::cast_to(p_node) || Object::cast_to(p_node)) { - p_node->notification(Spatial::NOTIFICATION_EXIT_WORLD); - } else { - Viewport *v = Object::cast_to(p_node); - if (v) { - if (v->world_3d.is_valid() || v->own_world_3d.is_valid()) { - return; - } - } - } - } - - for (int i = 0; i < p_node->get_child_count(); i++) { - _propagate_exit_world(p_node->get_child(i)); - } -} - -void Viewport::set_world_3d(const Ref &p_world_3d) { - if (world_3d == p_world_3d) { - return; - } - - if (is_inside_tree()) { - _propagate_exit_world(this); - } - - if (own_world_3d.is_valid() && world_3d.is_valid()) { - world_3d->disconnect(CoreStringNames::get_singleton()->changed, this, "_own_world_3d_changed"); - } - - world_3d = p_world_3d; - - if (own_world_3d.is_valid()) { - if (world_3d.is_valid()) { - own_world_3d = world_3d->duplicate(); - world_3d->connect(CoreStringNames::get_singleton()->changed, this, "_own_world_3d_changed"); - } else { - own_world_3d = Ref(memnew(World3D)); - } - } - - if (is_inside_tree()) { - _propagate_enter_world(this); - } - - if (is_inside_tree()) { - RenderingServer::get_singleton()->viewport_set_scenario(viewport, find_world_3d()->get_scenario()); - } - - _update_listener(); -} - -Ref Viewport::get_world_3d() const { - return world_3d; -} - -Ref Viewport::get_world_2d() const { - return world_2d; -} - -Ref Viewport::find_world_3d() const { - if (own_world_3d.is_valid()) { - return own_world_3d; - } else if (world_3d.is_valid()) { - return world_3d; - } else if (parent) { - return parent->find_world_3d(); - } else { - return Ref(); - } -} - Listener *Viewport::get_listener() const { return listener; } @@ -2897,44 +2777,6 @@ void Viewport::unhandled_input(const Ref &p_event) { } } -void Viewport::set_use_own_world_3d(bool p_use_own_world_3d) { - if (p_use_own_world_3d == own_world_3d.is_valid()) { - return; - } - - if (is_inside_tree()) { - _propagate_exit_world(this); - } - - if (p_use_own_world_3d) { - if (world_3d.is_valid()) { - own_world_3d = world_3d->duplicate(); - world_3d->connect(CoreStringNames::get_singleton()->changed, this, "_own_world_3d_changed"); - } else { - own_world_3d = Ref(memnew(World3D)); - } - } else { - own_world_3d = Ref(); - if (world_3d.is_valid()) { - world_3d->disconnect(CoreStringNames::get_singleton()->changed, this, "_own_world_3d_changed"); - } - } - - if (is_inside_tree()) { - _propagate_enter_world(this); - } - - if (is_inside_tree()) { - RenderingServer::get_singleton()->viewport_set_scenario(viewport, find_world_3d()->get_scenario()); - } - - _update_listener(); -} - -bool Viewport::is_using_own_world_3d() const { - return own_world_3d.is_valid(); -} - void Viewport::set_attach_to_screen_rect(const Rect2 &p_rect) { RS::get_singleton()->viewport_attach_to_screen(viewport, p_rect); to_screen_rect = p_rect; @@ -3197,12 +3039,6 @@ void Viewport::_validate_property(PropertyInfo &property) const { void Viewport::_bind_methods() { ClassDB::bind_method(D_METHOD("set_size", "size"), &Viewport::set_size); ClassDB::bind_method(D_METHOD("get_size"), &Viewport::get_size); - ClassDB::bind_method(D_METHOD("set_world_2d", "world_2d"), &Viewport::set_world_2d); - ClassDB::bind_method(D_METHOD("get_world_2d"), &Viewport::get_world_2d); - ClassDB::bind_method(D_METHOD("find_world_2d"), &Viewport::find_world_2d); - ClassDB::bind_method(D_METHOD("set_world_3d", "world"), &Viewport::set_world_3d); - ClassDB::bind_method(D_METHOD("get_world_3d"), &Viewport::get_world_3d); - ClassDB::bind_method(D_METHOD("find_world_3d"), &Viewport::find_world_3d); ClassDB::bind_method(D_METHOD("set_canvas_transform", "xform"), &Viewport::set_canvas_transform); ClassDB::bind_method(D_METHOD("get_canvas_transform"), &Viewport::get_canvas_transform); @@ -3271,9 +3107,6 @@ void Viewport::_bind_methods() { ClassDB::bind_method(D_METHOD("update_worlds"), &Viewport::update_worlds); - ClassDB::bind_method(D_METHOD("set_use_own_world_3d", "enable"), &Viewport::set_use_own_world_3d); - ClassDB::bind_method(D_METHOD("is_using_own_world_3d"), &Viewport::is_using_own_world_3d); - ClassDB::bind_method(D_METHOD("get_camera"), &Viewport::get_camera); ClassDB::bind_method(D_METHOD("get_camera_2d"), &Viewport::get_camera_2d); @@ -3326,15 +3159,11 @@ void Viewport::_bind_methods() { ClassDB::bind_method(D_METHOD("_subwindow_visibility_changed"), &Viewport::_subwindow_visibility_changed); - ClassDB::bind_method(D_METHOD("_own_world_3d_changed"), &Viewport::_own_world_3d_changed); - ClassDB::bind_method(D_METHOD("_process_picking", "ignore_paused"), &Viewport::_process_picking); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "size"), "set_size", "get_size"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "size_override_stretch"), "set_size_override_stretch", "is_size_override_stretch_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "own_world_3d"), "set_use_own_world_3d", "is_using_own_world_3d"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "world", PROPERTY_HINT_RESOURCE_TYPE, "World3D"), "set_world_3d", "get_world_3d"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "world_2d", PROPERTY_HINT_RESOURCE_TYPE, "World2D", 0), "set_world_2d", "get_world_2d"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "transparent_bg"), "set_transparent_background", "has_transparent_background"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "handle_input_locally"), "set_handle_input_locally", "is_handling_input_locally"); ADD_GROUP("Rendering", ""); @@ -3425,8 +3254,6 @@ void Viewport::_subwindow_visibility_changed() { } Viewport::Viewport() { - world_2d = Ref(memnew(World2D)); - viewport = RID_PRIME(RenderingServer::get_singleton()->viewport_create()); texture_rid = RenderingServer::get_singleton()->viewport_get_texture(viewport); texture_flags = 0; diff --git a/scene/main/viewport.h b/scene/main/viewport.h index 33ec7f12f..61c8dd0c5 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -50,8 +50,6 @@ class Timer; class Viewport; class CollisionObject; class SceneTreeTimer; -class World3D; -class World2D; class ViewportTexture : public Texture { GDCLASS(ViewportTexture, Texture); @@ -183,14 +181,6 @@ public: Rect2 get_visible_rect() const; RID get_viewport_rid() const; - void set_world_3d(const Ref &p_world); - void set_world_2d(const Ref &p_world_2d); - Ref get_world_3d() const; - Ref find_world_3d() const; - - Ref get_world_2d() const; - Ref find_world_2d() const; - void enable_canvas_transform_override(bool p_enable); bool is_canvas_transform_override_enbled() const; @@ -252,9 +242,6 @@ public: Vector2 get_camera_coords(const Vector2 &p_viewport_coords) const; Vector2 get_camera_rect_size() const; - void set_use_own_world_3d(bool p_use_own_world_3d); - bool is_using_own_world_3d() const; - void input(const Ref &p_event); void unhandled_input(const Ref &p_event); @@ -320,6 +307,11 @@ protected: static void _bind_methods(); virtual void _validate_property(PropertyInfo &property) const; + void _own_world_3d_changed(); + void _on_set_use_own_world_3d(bool p_use_own_world_3d); + void _on_set_world_3d(const Ref &p_old_world); + void _on_set_world_2d(const Ref &p_old_world_2d); + private: friend class ViewportTexture; @@ -418,10 +410,6 @@ private: Map physics_2d_mouseover; - Ref world_2d; - Ref world_3d; - Ref own_world_3d; - StringName input_group; StringName gui_input_group; StringName unhandled_input_group; @@ -430,8 +418,6 @@ private: void _update_listener(); void _update_listener_2d(); - void _propagate_enter_world(Node *p_node); - void _propagate_exit_world(Node *p_node); void _propagate_viewport_notification(Node *p_node, int p_what); void _update_stretch_transform(); @@ -590,8 +576,6 @@ private: void _drop_physics_mouseover(bool p_paused_only = false); void _update_canvas_items(Node *p_node); - - void _own_world_3d_changed(); }; VARIANT_ENUM_CAST(Viewport::UpdateMode); diff --git a/scene/main/world.cpp b/scene/main/world.cpp index a4c967dc2..a4a8bcbc2 100644 --- a/scene/main/world.cpp +++ b/scene/main/world.cpp @@ -1,12 +1,236 @@ #include "world.h" +#include "core/core_string_names.h" +#include "scene/3d/spatial.h" +#include "scene/3d/world_environment_3d.h" +#include "scene/resources/world_2d.h" +#include "scene/resources/world_3d.h" + +void World::set_use_own_world_3d(bool p_use_own_world_3d) { + if (p_use_own_world_3d == own_world_3d.is_valid()) { + return; + } + + if (is_inside_tree()) { + _propagate_exit_world(this); + } + + if (p_use_own_world_3d) { + if (world_3d.is_valid()) { + own_world_3d = world_3d->duplicate(); + world_3d->connect(CoreStringNames::get_singleton()->changed, this, "_own_world_3d_changed"); + } else { + own_world_3d = Ref(memnew(World3D)); + } + } else { + own_world_3d = Ref(); + if (world_3d.is_valid()) { + world_3d->disconnect(CoreStringNames::get_singleton()->changed, this, "_own_world_3d_changed"); + } + } + + if (is_inside_tree()) { + _propagate_enter_world(this); + } + + _on_set_use_own_world_3d(p_use_own_world_3d); +} + +bool World::is_using_own_world_3d() const { + return own_world_3d.is_valid(); +} + +void World::set_world_2d(const Ref &p_world_2d) { + if (world_2d == p_world_2d) { + return; + } + + if (_parent_world && _parent_world->find_world_2d() == p_world_2d) { + WARN_PRINT("Unable to use parent world as world_2d"); + return; + } + + Ref old_world; + + if (is_inside_tree()) { + old_world = find_world_2d(); + } + + if (p_world_2d.is_valid()) { + world_2d = p_world_2d; + } else { + WARN_PRINT("Invalid world"); + world_2d = Ref(memnew(World2D)); + } + + _on_set_world_2d(old_world); +} + +Ref World::find_world_2d() const { + if (world_2d.is_valid()) { + return world_2d; + } else if (_parent_world) { + return _parent_world->find_world_2d(); + } else { + return Ref(); + } +} + +void World::set_world_3d(const Ref &p_world_3d) { + if (world_3d == p_world_3d) { + return; + } + + if (is_inside_tree()) { + _propagate_exit_world(this); + } + + Ref old_world = world_3d; + + if (own_world_3d.is_valid() && world_3d.is_valid()) { + world_3d->disconnect(CoreStringNames::get_singleton()->changed, this, "_own_world_3d_changed"); + } + + world_3d = p_world_3d; + + if (own_world_3d.is_valid()) { + if (world_3d.is_valid()) { + own_world_3d = world_3d->duplicate(); + world_3d->connect(CoreStringNames::get_singleton()->changed, this, "_own_world_3d_changed"); + } else { + own_world_3d = Ref(memnew(World3D)); + } + } + + if (is_inside_tree()) { + _propagate_enter_world(this); + } + + _on_set_world_3d(old_world); +} + +Ref World::get_world_3d() const { + return world_3d; +} + +Ref World::get_world_2d() const { + return world_2d; +} + +Ref World::find_world_3d() const { + if (own_world_3d.is_valid()) { + return own_world_3d; + } else if (world_3d.is_valid()) { + return world_3d; + } else if (_parent_world) { + return _parent_world->find_world_3d(); + } else { + return Ref(); + } +} + +void World::_propagate_enter_world(Node *p_node) { + if (p_node != this) { + if (!p_node->is_inside_tree()) { //may not have entered scene yet + return; + } + + if (Object::cast_to(p_node) || Object::cast_to(p_node)) { + p_node->notification(Spatial::NOTIFICATION_ENTER_WORLD); + } else { + World *v = Object::cast_to(p_node); + if (v) { + if (v->world_3d.is_valid() || v->own_world_3d.is_valid()) { + return; + } + } + } + } + + for (int i = 0; i < p_node->get_child_count(); i++) { + _propagate_enter_world(p_node->get_child(i)); + } +} + +void World::_propagate_exit_world(Node *p_node) { + if (p_node != this) { + if (!p_node->is_inside_tree()) { //may have exited scene already + return; + } + + if (Object::cast_to(p_node) || Object::cast_to(p_node)) { + p_node->notification(Spatial::NOTIFICATION_EXIT_WORLD); + } else { + World *v = Object::cast_to(p_node); + if (v) { + if (v->world_3d.is_valid() || v->own_world_3d.is_valid()) { + return; + } + } + } + } + + for (int i = 0; i < p_node->get_child_count(); i++) { + _propagate_exit_world(p_node->get_child(i)); + } +} + +void World::_own_world_3d_changed() { + ERR_FAIL_COND(world_3d.is_null()); + ERR_FAIL_COND(own_world_3d.is_null()); + + if (is_inside_tree()) { + _propagate_exit_world(this); + } + + own_world_3d = world_3d->duplicate(); + + if (is_inside_tree()) { + _propagate_enter_world(this); + } +} + +void World::_on_set_use_own_world_3d(bool p_use_own_world_3d) { +} + +void World::_on_set_world_3d(const Ref &p_old_world) { +} +void World::_on_set_world_2d(const Ref &p_old_world_2d) { +} + World::World() { + world_2d = Ref(memnew(World2D)); } World::~World() { } void World::_notification(int p_what) { + switch (p_what) { + case NOTIFICATION_ENTER_TREE: { + if (get_parent()) { + _parent_world = get_parent()->get_world(); + } else { + _parent_world = nullptr; + } + } break; + } } void World::_bind_methods() { + ClassDB::bind_method(D_METHOD("get_world_2d"), &World::get_world_2d); + ClassDB::bind_method(D_METHOD("set_world_2d", "world_2d"), &World::set_world_2d); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "world_2d", PROPERTY_HINT_RESOURCE_TYPE, "World2D", 0), "set_world_2d", "get_world_2d"); + + ClassDB::bind_method(D_METHOD("get_world_3d"), &World::get_world_3d); + ClassDB::bind_method(D_METHOD("set_world_3d", "world"), &World::set_world_3d); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "world", PROPERTY_HINT_RESOURCE_TYPE, "World3D"), "set_world_3d", "get_world_3d"); + + ClassDB::bind_method(D_METHOD("set_use_own_world_3d", "enable"), &World::set_use_own_world_3d); + ClassDB::bind_method(D_METHOD("is_using_own_world_3d"), &World::is_using_own_world_3d); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "own_world_3d"), "set_use_own_world_3d", "is_using_own_world_3d"); + + ClassDB::bind_method(D_METHOD("find_world_2d"), &World::find_world_2d); + ClassDB::bind_method(D_METHOD("find_world_3d"), &World::find_world_3d); + + ClassDB::bind_method(D_METHOD("_own_world_3d_changed"), &World::_own_world_3d_changed); } \ No newline at end of file diff --git a/scene/main/world.h b/scene/main/world.h index 94258a2a8..8f54de328 100644 --- a/scene/main/world.h +++ b/scene/main/world.h @@ -1,12 +1,29 @@ #ifndef WORLD_H #define WORLD_H +#include "core/object/reference.h" + #include "node.h" +class World3D; +class World2D; + class World : public Node { GDCLASS(World, Node); public: + void set_world_3d(const Ref &p_world); + void set_world_2d(const Ref &p_world_2d); + + Ref get_world_3d() const; + Ref find_world_3d() const; + + Ref get_world_2d() const; + Ref find_world_2d() const; + + void set_use_own_world_3d(bool p_use_own_world_3d); + bool is_using_own_world_3d() const; + World(); ~World(); @@ -14,6 +31,20 @@ protected: void _notification(int p_what); static void _bind_methods(); + + virtual void _own_world_3d_changed(); + virtual void _on_set_use_own_world_3d(bool p_use_own_world_3d); + virtual void _on_set_world_3d(const Ref &p_old_world); + virtual void _on_set_world_2d(const Ref &p_old_world_2d); + + void _propagate_enter_world(Node *p_node); + void _propagate_exit_world(Node *p_node); + + Ref world_2d; + Ref world_3d; + Ref own_world_3d; + + World *_parent_world; }; #endif