More work on World override support.

This commit is contained in:
Relintai 2022-08-29 22:51:09 +02:00
parent 49af677ca8
commit 4303dfb5c0
6 changed files with 58 additions and 31 deletions

View File

@ -34,7 +34,7 @@
#include "core/math/transform_interpolator.h" #include "core/math/transform_interpolator.h"
#include "core/object/message_queue.h" #include "core/object/message_queue.h"
#include "scene/main/scene_tree.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/resources/world_3d.h"
#include "scene/scene_string_names.h" #include "scene/scene_string_names.h"
#include "servers/rendering_server_callbacks.h" #include "servers/rendering_server_callbacks.h"
@ -186,14 +186,6 @@ void Spatial::_notification(int p_what) {
} break; } break;
case NOTIFICATION_ENTER_WORLD: { case NOTIFICATION_ENTER_WORLD: {
data.inside_world = true; data.inside_world = true;
data.viewport = nullptr;
Node *parent = get_parent();
while (parent && !data.viewport) {
data.viewport = Object::cast_to<Viewport>(parent);
parent = parent->get_parent();
}
ERR_FAIL_COND(!data.viewport);
if (get_script_instance()) { if (get_script_instance()) {
get_script_instance()->call_multilevel(SceneStringNames::get_singleton()->_enter_world, nullptr, 0); 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); get_script_instance()->call_multilevel(SceneStringNames::get_singleton()->_exit_world, nullptr, 0);
} }
data.viewport = nullptr;
data.inside_world = false; data.inside_world = false;
} break; } break;
@ -703,9 +694,9 @@ bool Spatial::is_set_as_toplevel() const {
Ref<World3D> Spatial::get_world_3d() const { Ref<World3D> Spatial::get_world_3d() const {
ERR_FAIL_COND_V(!is_inside_world(), Ref<World3D>()); ERR_FAIL_COND_V(!is_inside_world(), Ref<World3D>());
ERR_FAIL_COND_V(!data.viewport, Ref<World3D>()); ERR_FAIL_COND_V(!get_world(), Ref<World3D>());
return data.viewport->find_world_3d(); return get_world()->find_world_3d();
} }
void Spatial::_propagate_visibility_changed() { void Spatial::_propagate_visibility_changed() {
@ -1024,7 +1015,6 @@ Spatial::Spatial() :
data.toplevel = false; data.toplevel = false;
data.toplevel_active = false; data.toplevel_active = false;
data.scale = Vector3(1, 1, 1); data.scale = Vector3(1, 1, 1);
data.viewport = nullptr;
data.inside_world = false; data.inside_world = false;
data.visible = true; data.visible = true;
data.disable_scale = false; data.disable_scale = false;

View File

@ -81,8 +81,6 @@ class Spatial : public Node {
mutable int dirty; mutable int dirty;
Viewport *viewport;
bool toplevel_active : 1; bool toplevel_active : 1;
bool toplevel : 1; bool toplevel : 1;
bool inside_world : 1; bool inside_world : 1;

View File

@ -301,7 +301,7 @@ void Viewport::_notification(int p_what) {
parent = nullptr; parent = nullptr;
} }
_on_world_override_changed(this); _on_after_world_override_changed();
add_to_group("_viewports"); add_to_group("_viewports");
@ -788,15 +788,18 @@ bool Viewport::is_audio_listener_2d() const {
Listener2D *Viewport::get_listener_2d() const { Listener2D *Viewport::get_listener_2d() const {
return listener_2d; 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) { if (w) {
// return; 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(); current_canvas = find_world_2d()->get_canvas();
RenderingServer::get_singleton()->viewport_set_scenario(viewport, find_world_3d()->get_scenario()); RenderingServer::get_singleton()->viewport_set_scenario(viewport, find_world_3d()->get_scenario());
RenderingServer::get_singleton()->viewport_attach_canvas(viewport, current_canvas); 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()) { if (get_tree()->is_debugging_collisions_hint()) {
//2D //2D
Physics2DServer::get_singleton()->space_set_debug_contacts(find_world_2d()->get_space(), get_tree()->get_collision_debug_contact_count()); 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()); RenderingServer::get_singleton()->canvas_item_set_parent(contact_2d_debug, find_world_2d()->get_canvas());
//3D //3D
PhysicsServer::get_singleton()->space_set_debug_contacts(find_world_3d()->get_space(), get_tree()->get_collision_debug_contact_count()); 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_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_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()); 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_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_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); //RenderingServer::get_singleton()->instance_geometry_set_flag(contact_3d_debug_instance, RS::INSTANCE_FLAG_VISIBLE_IN_ALL_ROOMS, true);

View File

@ -311,7 +311,9 @@ protected:
void _on_set_use_own_world_3d(bool p_use_own_world_3d); void _on_set_use_own_world_3d(bool p_use_own_world_3d);
void _on_set_world_3d(const Ref<World3D> &p_old_world); void _on_set_world_3d(const Ref<World3D> &p_old_world);
void _on_set_world_2d(const Ref<World2D> &p_old_world_2d); void _on_set_world_2d(const Ref<World2D> &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: private:
friend class ViewportTexture; friend class ViewportTexture;

View File

@ -112,6 +112,24 @@ bool World::get_override_in_parent_viewport() {
return _override_in_parent_viewport; return _override_in_parent_viewport;
} }
void World::set_override_in_parent_viewport(const bool value) { 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; _override_in_parent_viewport = value;
} }
@ -156,11 +174,13 @@ World *World::get_override_world_or_this() {
return _override_world; return _override_world;
} }
void World::set_override_world(World *p_world) { void World::set_override_world(World *p_world) {
if (p_world == _override_world) { if (p_world == _override_world || p_world == this) {
return; return;
} }
World *old_world = _override_world; _on_before_world_override_changed();
World *old_world = get_override_world();
if (old_world) { if (old_world) {
old_world->_remove_overridden_world(this); old_world->_remove_overridden_world(this);
@ -172,7 +192,7 @@ void World::set_override_world(World *p_world) {
_override_world->_add_overridden_world(this); _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) { void World::set_override_world_bind(Node *p_world) {
World *w = Object::cast_to<World>(p_world); World *w = Object::cast_to<World>(p_world);
@ -279,7 +299,9 @@ void World::_on_set_world_3d(const Ref<World3D> &p_old_world) {
void World::_on_set_world_2d(const Ref<World2D> &p_old_world_2d) { void World::_on_set_world_2d(const Ref<World2D> &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) { void World::_notification(int p_what) {

View File

@ -44,7 +44,9 @@ protected:
virtual void _on_set_use_own_world_3d(bool p_use_own_world_3d); virtual void _on_set_use_own_world_3d(bool p_use_own_world_3d);
virtual void _on_set_world_3d(const Ref<World3D> &p_old_world); virtual void _on_set_world_3d(const Ref<World3D> &p_old_world);
virtual void _on_set_world_2d(const Ref<World2D> &p_old_world_2d); virtual void _on_set_world_2d(const Ref<World2D> &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_enter_world(Node *p_node);
void _propagate_exit_world(Node *p_node); void _propagate_exit_world(Node *p_node);