Przeglądaj źródła

Merge pull request #33987 from nekomatata/own-world-environment

Viewport environment is updated properly when set to own world
Rémi Verschelde 5 lat temu
rodzic
commit
ce75a2f33d
3 zmienionych plików z 61 dodań i 3 usunięć
  1. 49 3
      scene/main/viewport.cpp
  2. 2 0
      scene/main/viewport.h
  3. 10 0
      scene/resources/world.cpp

+ 49 - 3
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);
 
@@ -2826,10 +2861,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);
@@ -3178,6 +3222,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");

+ 2 - 0
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();

+ 10 - 0
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 {