Viewport environment is updated properly when set to own world

When own_world property is set, the viewport stores a unique resource for the world. With this change it keeps being updated from changes made to the world property instead of storing a default empty world with environment settings that can't be modified.

Fixes #23412
This commit is contained in:
PouleyKetchoupp 2019-11-29 07:41:25 +01:00
parent 7735af7e76
commit dc13750189
3 changed files with 61 additions and 3 deletions

View file

@ -30,6 +30,7 @@
#include "viewport.h"
#include "core/core_string_names.h"
#include "core/os/input.h"
#include "core/os/os.h"
#include "core/project_settings.h"
@ -251,6 +252,27 @@ void Viewport::_collision_object_input_event(CollisionObject *p_object, Camera *
physics_last_id = id;
}
void Viewport::_own_world_changed() {
ERR_FAIL_COND(world.is_null());
ERR_FAIL_COND(own_world.is_null());
if (is_inside_tree()) {
_propagate_exit_world(this);
}
own_world = world->duplicate();
if (is_inside_tree()) {
_propagate_enter_world(this);
}
if (is_inside_tree()) {
VisualServer::get_singleton()->viewport_set_scenario(viewport, find_world()->get_scenario());
}
_update_listener();
}
void Viewport::_notification(int p_what) {
switch (p_what) {
@ -1105,8 +1127,21 @@ void Viewport::set_world(const Ref<World> &p_world) {
if (is_inside_tree())
_propagate_exit_world(this);
if (own_world.is_valid() && world.is_valid()) {
world->disconnect(CoreStringNames::get_singleton()->changed, this, "_own_world_changed");
}
world = p_world;
if (own_world.is_valid()) {
if (world.is_valid()) {
own_world = world->duplicate();
world->connect(CoreStringNames::get_singleton()->changed, this, "_own_world_changed");
} else {
own_world = Ref<World>(memnew(World));
}
}
if (is_inside_tree())
_propagate_enter_world(this);
@ -2825,10 +2860,19 @@ void Viewport::set_use_own_world(bool p_world) {
if (is_inside_tree())
_propagate_exit_world(this);
if (!p_world)
if (!p_world) {
own_world = Ref<World>();
else
own_world = Ref<World>(memnew(World));
if (world.is_valid()) {
world->disconnect(CoreStringNames::get_singleton()->changed, this, "_own_world_changed");
}
} else {
if (world.is_valid()) {
own_world = world->duplicate();
world->connect(CoreStringNames::get_singleton()->changed, this, "_own_world_changed");
} else {
own_world = Ref<World>(memnew(World));
}
}
if (is_inside_tree())
_propagate_enter_world(this);
@ -3177,6 +3221,8 @@ void Viewport::_bind_methods() {
ClassDB::bind_method(D_METHOD("_subwindow_visibility_changed"), &Viewport::_subwindow_visibility_changed);
ClassDB::bind_method(D_METHOD("_own_world_changed"), &Viewport::_own_world_changed);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "arvr"), "set_use_arvr", "use_arvr");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "size"), "set_size", "get_size");

View file

@ -406,6 +406,8 @@ private:
void _update_canvas_items(Node *p_node);
void _own_world_changed();
protected:
void _notification(int p_what);
static void _bind_methods();

View file

@ -268,12 +268,17 @@ RID World::get_scenario() const {
}
void World::set_environment(const Ref<Environment> &p_environment) {
if (environment == p_environment) {
return;
}
environment = p_environment;
if (environment.is_valid())
VS::get_singleton()->scenario_set_environment(scenario, environment->get_rid());
else
VS::get_singleton()->scenario_set_environment(scenario, RID());
emit_changed();
}
Ref<Environment> World::get_environment() const {
@ -282,12 +287,17 @@ Ref<Environment> World::get_environment() const {
}
void World::set_fallback_environment(const Ref<Environment> &p_environment) {
if (fallback_environment == p_environment) {
return;
}
fallback_environment = p_environment;
if (fallback_environment.is_valid())
VS::get_singleton()->scenario_set_fallback_environment(scenario, p_environment->get_rid());
else
VS::get_singleton()->scenario_set_fallback_environment(scenario, RID());
emit_changed();
}
Ref<Environment> World::get_fallback_environment() const {