From 4303dfb5c0bfe904e16197fcf4bf28c3f49c4483 Mon Sep 17 00:00:00 2001 From: Relintai Date: Mon, 29 Aug 2022 22:51:09 +0200 Subject: [PATCH] More work on World override support. --- scene/3d/spatial.cpp | 16 +++------------- scene/3d/spatial.h | 2 -- scene/main/viewport.cpp | 33 +++++++++++++++++++++++---------- scene/main/viewport.h | 4 +++- scene/main/world.cpp | 30 ++++++++++++++++++++++++++---- scene/main/world.h | 4 +++- 6 files changed, 58 insertions(+), 31 deletions(-) diff --git a/scene/3d/spatial.cpp b/scene/3d/spatial.cpp index 2532b00a5..e0dd270f6 100644 --- a/scene/3d/spatial.cpp +++ b/scene/3d/spatial.cpp @@ -34,7 +34,7 @@ #include "core/math/transform_interpolator.h" #include "core/object/message_queue.h" #include "scene/main/scene_tree.h" -#include "scene/main/viewport.h" +#include "scene/main/world.h" #include "scene/resources/world_3d.h" #include "scene/scene_string_names.h" #include "servers/rendering_server_callbacks.h" @@ -186,14 +186,6 @@ void Spatial::_notification(int p_what) { } break; case NOTIFICATION_ENTER_WORLD: { data.inside_world = true; - data.viewport = nullptr; - Node *parent = get_parent(); - while (parent && !data.viewport) { - data.viewport = Object::cast_to(parent); - parent = parent->get_parent(); - } - - ERR_FAIL_COND(!data.viewport); if (get_script_instance()) { get_script_instance()->call_multilevel(SceneStringNames::get_singleton()->_enter_world, nullptr, 0); @@ -225,7 +217,6 @@ void Spatial::_notification(int p_what) { get_script_instance()->call_multilevel(SceneStringNames::get_singleton()->_exit_world, nullptr, 0); } - data.viewport = nullptr; data.inside_world = false; } break; @@ -703,9 +694,9 @@ bool Spatial::is_set_as_toplevel() const { Ref Spatial::get_world_3d() const { ERR_FAIL_COND_V(!is_inside_world(), Ref()); - ERR_FAIL_COND_V(!data.viewport, Ref()); + ERR_FAIL_COND_V(!get_world(), Ref()); - return data.viewport->find_world_3d(); + return get_world()->find_world_3d(); } void Spatial::_propagate_visibility_changed() { @@ -1024,7 +1015,6 @@ Spatial::Spatial() : data.toplevel = false; data.toplevel_active = false; data.scale = Vector3(1, 1, 1); - data.viewport = nullptr; data.inside_world = false; data.visible = true; data.disable_scale = false; diff --git a/scene/3d/spatial.h b/scene/3d/spatial.h index c170a9d5c..96b6070ac 100644 --- a/scene/3d/spatial.h +++ b/scene/3d/spatial.h @@ -81,8 +81,6 @@ class Spatial : public Node { mutable int dirty; - Viewport *viewport; - bool toplevel_active : 1; bool toplevel : 1; bool inside_world : 1; diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 0218ec1b6..e8a944168 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -301,7 +301,7 @@ void Viewport::_notification(int p_what) { parent = nullptr; } - _on_world_override_changed(this); + _on_after_world_override_changed(); add_to_group("_viewports"); @@ -788,15 +788,18 @@ bool Viewport::is_audio_listener_2d() const { Listener2D *Viewport::get_listener_2d() const { return listener_2d; } -void Viewport::_on_world_override_changed(World *p_old_world) { - //ERR_FAIL_COND(!p_old_world); - //World *active_world = get_active_world(); +void Viewport::_on_before_world_override_changed() { + World *w = get_override_world_or_this(); - //if (!active_world) { - // return; - //} + if (w) { + RenderingServer::get_singleton()->viewport_set_scenario(viewport, RID()); + RenderingServer::get_singleton()->viewport_remove_canvas(viewport, current_canvas); + w->find_world_2d()->_remove_viewport(this); + } +} +void Viewport::_on_after_world_override_changed() { current_canvas = find_world_2d()->get_canvas(); RenderingServer::get_singleton()->viewport_set_scenario(viewport, find_world_3d()->get_scenario()); RenderingServer::get_singleton()->viewport_attach_canvas(viewport, current_canvas); @@ -809,18 +812,28 @@ void Viewport::_on_world_override_changed(World *p_old_world) { if (get_tree()->is_debugging_collisions_hint()) { //2D Physics2DServer::get_singleton()->space_set_debug_contacts(find_world_2d()->get_space(), get_tree()->get_collision_debug_contact_count()); - contact_2d_debug = RID_PRIME(RenderingServer::get_singleton()->canvas_item_create()); + + if (contact_2d_debug != RID()) { + contact_2d_debug = RID_PRIME(RenderingServer::get_singleton()->canvas_item_create()); + } + RenderingServer::get_singleton()->canvas_item_set_parent(contact_2d_debug, find_world_2d()->get_canvas()); //3D PhysicsServer::get_singleton()->space_set_debug_contacts(find_world_3d()->get_space(), get_tree()->get_collision_debug_contact_count()); - contact_3d_debug_multimesh = RID_PRIME(RenderingServer::get_singleton()->multimesh_create()); + if (contact_3d_debug_multimesh != RID()) { + contact_3d_debug_multimesh = RID_PRIME(RenderingServer::get_singleton()->multimesh_create()); + } + RenderingServer::get_singleton()->multimesh_allocate(contact_3d_debug_multimesh, get_tree()->get_collision_debug_contact_count(), RS::MULTIMESH_TRANSFORM_3D, RS::MULTIMESH_COLOR_8BIT); RenderingServer::get_singleton()->multimesh_set_visible_instances(contact_3d_debug_multimesh, 0); RenderingServer::get_singleton()->multimesh_set_mesh(contact_3d_debug_multimesh, get_tree()->get_debug_contact_mesh()->get_rid()); - contact_3d_debug_instance = RID_PRIME(RenderingServer::get_singleton()->instance_create()); + if (contact_3d_debug_instance != RID()) { + contact_3d_debug_instance = RID_PRIME(RenderingServer::get_singleton()->instance_create()); + } + RenderingServer::get_singleton()->instance_set_base(contact_3d_debug_instance, contact_3d_debug_multimesh); RenderingServer::get_singleton()->instance_set_scenario(contact_3d_debug_instance, find_world_3d()->get_scenario()); //RenderingServer::get_singleton()->instance_geometry_set_flag(contact_3d_debug_instance, RS::INSTANCE_FLAG_VISIBLE_IN_ALL_ROOMS, true); diff --git a/scene/main/viewport.h b/scene/main/viewport.h index 0f3ef697d..63b90757d 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -311,7 +311,9 @@ protected: 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); - void _on_world_override_changed(World *p_old_world); + + void _on_before_world_override_changed(); + void _on_after_world_override_changed(); private: friend class ViewportTexture; diff --git a/scene/main/world.cpp b/scene/main/world.cpp index 8c9841e2f..89d4976ad 100644 --- a/scene/main/world.cpp +++ b/scene/main/world.cpp @@ -112,6 +112,24 @@ bool World::get_override_in_parent_viewport() { return _override_in_parent_viewport; } void World::set_override_in_parent_viewport(const bool value) { + if (_override_in_parent_viewport == value) { + return; + } + + if (is_inside_tree()) { + World *w = get_viewport(); + + if (w) { + if (_override_in_parent_viewport) { + if (w->get_override_world() == this) { + w->set_override_world(NULL); + } + } else { + w->set_override_world(this); + } + } + } + _override_in_parent_viewport = value; } @@ -156,11 +174,13 @@ World *World::get_override_world_or_this() { return _override_world; } void World::set_override_world(World *p_world) { - if (p_world == _override_world) { + if (p_world == _override_world || p_world == this) { return; } - World *old_world = _override_world; + _on_before_world_override_changed(); + + World *old_world = get_override_world(); if (old_world) { old_world->_remove_overridden_world(this); @@ -172,7 +192,7 @@ void World::set_override_world(World *p_world) { _override_world->_add_overridden_world(this); } - _on_world_override_changed(old_world); + _on_after_world_override_changed(); } void World::set_override_world_bind(Node *p_world) { World *w = Object::cast_to(p_world); @@ -279,7 +299,9 @@ void World::_on_set_world_3d(const Ref &p_old_world) { void World::_on_set_world_2d(const Ref &p_old_world_2d) { } -void World::_on_world_override_changed(World *p_old_world) { +void World::_on_before_world_override_changed() { +} +void World::_on_after_world_override_changed() { } void World::_notification(int p_what) { diff --git a/scene/main/world.h b/scene/main/world.h index e7ad88d18..c27b5e81e 100644 --- a/scene/main/world.h +++ b/scene/main/world.h @@ -44,7 +44,9 @@ protected: 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); - virtual void _on_world_override_changed(World *p_old_world); + + virtual void _on_before_world_override_changed(); + virtual void _on_after_world_override_changed(); void _propagate_enter_world(Node *p_node); void _propagate_exit_world(Node *p_node);