summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPouleyKetchoupp <pouleyketchoup@gmail.com>2019-11-29 07:41:25 +0100
committerPouleyKetchoupp <pouleyketchoup@gmail.com>2019-11-29 11:50:10 +0100
commitdc13750189090e6df5608b260e2eaa3e29eb3665 (patch)
tree188300406e123685c6d7ac781bbbeef8be6d34f0
parent7735af7e768e16efb4b3b6de1c72c3dfb50c9412 (diff)
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
-rw-r--r--scene/main/viewport.cpp52
-rw-r--r--scene/main/viewport.h2
-rw-r--r--scene/resources/world.cpp10
3 files changed, 61 insertions, 3 deletions
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 3ad44a4a2e..8c957f0129 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -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");
diff --git a/scene/main/viewport.h b/scene/main/viewport.h
index 3c3b436ca1..ddaa45a6be 100644
--- a/scene/main/viewport.h
+++ b/scene/main/viewport.h
@@ -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();
diff --git a/scene/resources/world.cpp b/scene/resources/world.cpp
index 2c22f45f9d..e734b7d9f3 100644
--- a/scene/resources/world.cpp
+++ b/scene/resources/world.cpp
@@ -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 {