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/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<Viewport>(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<World3D> Spatial::get_world_3d() const {
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() {
@ -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;

View File

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

View File

@ -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);

View File

@ -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<World3D> &p_old_world);
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:
friend class ViewportTexture;

View File

@ -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<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_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) {

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_world_3d(const Ref<World3D> &p_old_world);
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_exit_world(Node *p_node);