diff --git a/scene/3d/camera.cpp b/scene/3d/camera.cpp index bd03681b4..23ccc1dad 100644 --- a/scene/3d/camera.cpp +++ b/scene/3d/camera.cpp @@ -157,12 +157,12 @@ void Camera::_notification(int p_what) { } break; case NOTIFICATION_BECAME_CURRENT: { if (viewport) { - viewport->find_world_3d()->_register_camera(this); + viewport->_world_3d_register_camera(this); } } break; case NOTIFICATION_LOST_CURRENT: { if (viewport) { - viewport->find_world_3d()->_remove_camera(this); + viewport->_world_3d_remove_camera(this); } } break; } diff --git a/scene/main/world.cpp b/scene/main/world.cpp index c2a15687f..8a46040cc 100644 --- a/scene/main/world.cpp +++ b/scene/main/world.cpp @@ -2,6 +2,7 @@ #include "core/config/engine.h" #include "core/core_string_names.h" +#include "scene/3d/camera.h" #include "scene/3d/spatial.h" #include "scene/3d/world_environment_3d.h" #include "scene/resources/world_2d.h" @@ -164,6 +165,28 @@ Ref World::find_world_3d() const { } } +Ref World::find_world_2d_no_override() const { + if (world_2d.is_valid()) { + return world_2d; + } else if (_parent_world) { + return _parent_world->find_world_2d(); + } else { + return Ref(); + } +} + +Ref World::find_world_3d_no_override() 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(); + } +} + World *World::get_override_world() { return _override_world; } @@ -192,6 +215,8 @@ void World::set_override_world(World *p_world) { old_world->_remove_overridden_world(this); } + _clear_override_cameras(); + _override_world = p_world; if (_override_world) { @@ -204,6 +229,7 @@ void World::set_override_world(World *p_world) { if (old_world_3d != new_world_3d) { if (new_world_3d.is_valid()) { old_world_3d->move_cameras_into(new_world_3d); + } else { ERR_PRINT("!new_world_3d.is_valid()"); } @@ -212,6 +238,10 @@ void World::set_override_world(World *p_world) { ERR_PRINT("!old_world_3d.is_valid()"); } + if (_override_world) { + _add_override_cameras_into(_override_world); + } + _on_after_world_override_changed(); } void World::set_override_world_bind(Node *p_world) { @@ -324,6 +354,63 @@ void World::update_worlds() { find_world_3d()->_update(get_tree()->get_frame()); } +void World::_world_3d_register_camera(Camera *p_camera) { + if (_override_world) { + _override_world->_world_3d_register_camera_as_override(p_camera); + } + + _world_3d_register_camera_no_override(p_camera); +} + +void World::_world_3d_remove_camera(Camera *p_camera) { + if (_override_world) { + _override_world->_world_3d_remove_camera_as_override(p_camera); + } + + _world_3d_remove_camera_no_override(p_camera); +} + +void World::_world_3d_register_camera_no_override(Camera *p_camera) { + find_world_3d_no_override()->_register_camera(p_camera); +} + +void World::_world_3d_remove_camera_no_override(Camera *p_camera) { + find_world_3d_no_override()->_remove_camera(p_camera); +} + +void World::_world_3d_register_camera_as_override(Camera *p_camera) { + find_world_3d_no_override()->_register_camera(p_camera); + + _override_cameras.push_back(p_camera); +} + +void World::_world_3d_remove_camera_as_override(Camera *p_camera) { + find_world_3d_no_override()->_remove_camera(p_camera); + + _override_cameras.erase(p_camera); +} + +void World::_clear_override_cameras() { + while (_override_cameras.size() > 0) { + _world_3d_remove_camera_as_override(_override_cameras[0]); + } +} + +void World::_add_override_cameras_into(World *p_from) { + Ref w3d = find_world_3d_no_override(); + + ERR_FAIL_COND(!w3d.is_valid()); + + List cameras; + w3d->get_camera_list(&cameras); + + for (List::Element *E = cameras.front(); E; E = E->next()) { + Camera *cam = E->get(); + + _world_3d_register_camera_as_override(cam); + } +} + World::World() { world_2d = Ref(memnew(World2D)); _override_world = NULL; diff --git a/scene/main/world.h b/scene/main/world.h index 3aadb225c..ae93ad4ba 100644 --- a/scene/main/world.h +++ b/scene/main/world.h @@ -6,6 +6,7 @@ #include "node.h" +class Camera; class World3D; class World2D; @@ -27,6 +28,8 @@ public: Ref find_world_2d() const; Ref find_world_3d() const; + Ref find_world_2d_no_override() const; + Ref find_world_3d_no_override() const; World *get_override_world(); World *get_override_world_or_this(); @@ -56,6 +59,15 @@ public: void update_worlds(); + void _world_3d_register_camera(Camera *p_camera); + void _world_3d_remove_camera(Camera *p_camera); + void _world_3d_register_camera_no_override(Camera *p_camera); + void _world_3d_remove_camera_no_override(Camera *p_camera); + void _world_3d_register_camera_as_override(Camera *p_camera); + void _world_3d_remove_camera_as_override(Camera *p_camera); + void _clear_override_cameras(); + void _add_override_cameras_into(World *p_from); + World(); ~World(); @@ -88,6 +100,7 @@ protected: World *_override_world; Vector _overriding_worlds; + Vector _override_cameras; }; #endif diff --git a/scene/resources/world_3d.cpp b/scene/resources/world_3d.cpp index 1989de0ce..cf054bcd2 100644 --- a/scene/resources/world_3d.cpp +++ b/scene/resources/world_3d.cpp @@ -30,9 +30,9 @@ #include "world_3d.h" -#include "core/math/projection.h" -#include "core/math/octree.h" #include "core/config/project_settings.h" +#include "core/math/octree.h" +#include "core/math/projection.h" #include "scene/3d/camera.h" #include "scene/3d/visibility_notifier.h" #include "scene/scene_string_names.h"