mirror of
https://github.com/Relintai/pandemonium_engine.git
synced 2025-01-23 17:47:17 +01:00
Move World2D and World3D related things to World from Viewport.
This commit is contained in:
parent
f44f9f5c13
commit
68b21dc61f
@ -38,6 +38,7 @@
|
||||
#include "scene/animation/scene_tree_tween.h"
|
||||
#include "scene/resources/packed_scene.h"
|
||||
#include "scene/scene_string_names.h"
|
||||
#include "world.h"
|
||||
#include "viewport.h"
|
||||
|
||||
#include "core/config/project_settings.h"
|
||||
@ -72,6 +73,7 @@ void Node::_notification(int p_notification) {
|
||||
} break;
|
||||
case NOTIFICATION_ENTER_TREE: {
|
||||
ERR_FAIL_COND(!get_viewport());
|
||||
ERR_FAIL_COND(!get_world());
|
||||
ERR_FAIL_COND(!get_tree());
|
||||
|
||||
if (data.pause_mode == PAUSE_MODE_INHERIT) {
|
||||
@ -108,6 +110,7 @@ void Node::_notification(int p_notification) {
|
||||
} break;
|
||||
case NOTIFICATION_EXIT_TREE: {
|
||||
ERR_FAIL_COND(!get_viewport());
|
||||
ERR_FAIL_COND(!get_world());
|
||||
ERR_FAIL_COND(!get_tree());
|
||||
|
||||
get_tree()->node_count--;
|
||||
@ -263,6 +266,11 @@ void Node::_propagate_enter_tree() {
|
||||
data.viewport = data.parent->data.viewport;
|
||||
}
|
||||
|
||||
data.world = Object::cast_to<World>(this);
|
||||
if (!data.world && data.parent) {
|
||||
data.world = data.parent->data.world;
|
||||
}
|
||||
|
||||
data.inside_tree = true;
|
||||
|
||||
for (Map<StringName, GroupData>::Element *E = data.grouped.front(); E; E = E->next()) {
|
||||
@ -397,6 +405,7 @@ void Node::_propagate_exit_tree() {
|
||||
}
|
||||
|
||||
data.viewport = nullptr;
|
||||
data.world = nullptr;
|
||||
|
||||
if (data.tree) {
|
||||
data.tree->tree_changed();
|
||||
@ -3262,6 +3271,7 @@ void Node::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("get_scene_instance_load_placeholder"), &Node::get_scene_instance_load_placeholder);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_viewport"), &Node::get_viewport);
|
||||
ClassDB::bind_method(D_METHOD("get_world"), &Node::get_world);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("queue_free"), &Node::queue_delete);
|
||||
|
||||
@ -3463,6 +3473,7 @@ Node::Node() {
|
||||
data.parent_owned = false;
|
||||
data.in_constructor = true;
|
||||
data.viewport = nullptr;
|
||||
data.world = nullptr;
|
||||
data.use_placeholder = false;
|
||||
data.display_folded = false;
|
||||
data.ready_first = true;
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "scene/main/scene_tree.h"
|
||||
|
||||
class Viewport;
|
||||
class World;
|
||||
class SceneState;
|
||||
class SceneTreeTween;
|
||||
|
||||
@ -111,6 +112,7 @@ private:
|
||||
#endif
|
||||
|
||||
Viewport *viewport;
|
||||
World *world;
|
||||
|
||||
Map<StringName, GroupData> grouped;
|
||||
List<Node *>::Element *OW; // owned element
|
||||
@ -504,6 +506,10 @@ public:
|
||||
return data.viewport;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ World *get_world() const {
|
||||
return data.world;
|
||||
}
|
||||
|
||||
virtual String get_configuration_warning() const;
|
||||
|
||||
void update_configuration_warning();
|
||||
|
@ -30,10 +30,11 @@
|
||||
|
||||
#include "viewport.h"
|
||||
|
||||
#include "core/config/project_settings.h"
|
||||
#include "core/core_string_names.h"
|
||||
#include "core/input/input.h"
|
||||
#include "core/input/shortcut.h"
|
||||
#include "core/os/os.h"
|
||||
#include "core/config/project_settings.h"
|
||||
#include "scene/2d/camera_2d.h"
|
||||
#include "scene/2d/collision_object_2d.h"
|
||||
#include "scene/2d/listener_2d.h"
|
||||
@ -41,20 +42,18 @@
|
||||
#include "scene/3d/collision_object.h"
|
||||
#include "scene/3d/listener.h"
|
||||
#include "scene/3d/spatial.h"
|
||||
#include "scene/3d/world_environment_3d.h"
|
||||
#include "scene/gui/control.h"
|
||||
#include "scene/gui/label.h"
|
||||
#include "scene/gui/menu_button.h"
|
||||
#include "scene/gui/panel.h"
|
||||
#include "scene/gui/panel_container.h"
|
||||
#include "scene/gui/popup_menu.h"
|
||||
#include "core/input/shortcut.h"
|
||||
#include "scene/gui/viewport_container.h"
|
||||
#include "scene/main/canvas_layer.h"
|
||||
#include "scene/main/timer.h"
|
||||
#include "scene/resources/mesh.h"
|
||||
#include "scene/resources/world_3d.h"
|
||||
#include "scene/resources/world_2d.h"
|
||||
#include "scene/resources/world_3d.h"
|
||||
#include "scene/scene_string_names.h"
|
||||
#include "servers/physics_2d_server.h"
|
||||
|
||||
@ -252,15 +251,7 @@ void Viewport::_own_world_3d_changed() {
|
||||
ERR_FAIL_COND(world_3d.is_null());
|
||||
ERR_FAIL_COND(own_world_3d.is_null());
|
||||
|
||||
if (is_inside_tree()) {
|
||||
_propagate_exit_world(this);
|
||||
}
|
||||
|
||||
own_world_3d = world_3d->duplicate();
|
||||
|
||||
if (is_inside_tree()) {
|
||||
_propagate_enter_world(this);
|
||||
}
|
||||
World::_own_world_3d_changed();
|
||||
|
||||
if (is_inside_tree()) {
|
||||
RenderingServer::get_singleton()->viewport_set_scenario(viewport, find_world_3d()->get_scenario());
|
||||
@ -269,6 +260,37 @@ void Viewport::_own_world_3d_changed() {
|
||||
_update_listener();
|
||||
}
|
||||
|
||||
void Viewport::_on_set_use_own_world_3d(bool p_use_own_world_3d) {
|
||||
if (is_inside_tree()) {
|
||||
RenderingServer::get_singleton()->viewport_set_scenario(viewport, find_world_3d()->get_scenario());
|
||||
}
|
||||
|
||||
_update_listener();
|
||||
}
|
||||
|
||||
void Viewport::_on_set_world_3d(const Ref<World3D> &p_old_world) {
|
||||
if (is_inside_tree()) {
|
||||
RenderingServer::get_singleton()->viewport_set_scenario(viewport, find_world_3d()->get_scenario());
|
||||
}
|
||||
|
||||
_update_listener();
|
||||
}
|
||||
void Viewport::_on_set_world_2d(const Ref<World2D> &p_old_world_2d) {
|
||||
if (is_inside_tree() && p_old_world_2d.is_valid()) {
|
||||
Ref<World2D> old_world_2d = p_old_world_2d;
|
||||
old_world_2d->_remove_viewport(this);
|
||||
RenderingServer::get_singleton()->viewport_remove_canvas(viewport, current_canvas);
|
||||
}
|
||||
|
||||
_update_listener_2d();
|
||||
|
||||
if (is_inside_tree()) {
|
||||
current_canvas = find_world_2d()->get_canvas();
|
||||
RenderingServer::get_singleton()->viewport_attach_canvas(viewport, current_canvas);
|
||||
find_world_2d()->_register_viewport(this, Rect2());
|
||||
}
|
||||
}
|
||||
|
||||
void Viewport::_notification(int p_what) {
|
||||
switch (p_what) {
|
||||
case NOTIFICATION_ENTER_TREE: {
|
||||
@ -1012,70 +1034,6 @@ bool Viewport::has_transparent_background() const {
|
||||
return transparent_bg;
|
||||
}
|
||||
|
||||
void Viewport::set_world_2d(const Ref<World2D> &p_world_2d) {
|
||||
if (world_2d == p_world_2d) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (parent && parent->find_world_2d() == p_world_2d) {
|
||||
WARN_PRINT("Unable to use parent world as world_2d");
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_inside_tree()) {
|
||||
find_world_2d()->_remove_viewport(this);
|
||||
RenderingServer::get_singleton()->viewport_remove_canvas(viewport, current_canvas);
|
||||
}
|
||||
|
||||
if (p_world_2d.is_valid()) {
|
||||
world_2d = p_world_2d;
|
||||
} else {
|
||||
WARN_PRINT("Invalid world");
|
||||
world_2d = Ref<World2D>(memnew(World2D));
|
||||
}
|
||||
|
||||
_update_listener_2d();
|
||||
|
||||
if (is_inside_tree()) {
|
||||
current_canvas = find_world_2d()->get_canvas();
|
||||
RenderingServer::get_singleton()->viewport_attach_canvas(viewport, current_canvas);
|
||||
find_world_2d()->_register_viewport(this, Rect2());
|
||||
}
|
||||
}
|
||||
|
||||
Ref<World2D> Viewport::find_world_2d() const {
|
||||
if (world_2d.is_valid()) {
|
||||
return world_2d;
|
||||
} else if (parent) {
|
||||
return parent->find_world_2d();
|
||||
} else {
|
||||
return Ref<World2D>();
|
||||
}
|
||||
}
|
||||
|
||||
void Viewport::_propagate_enter_world(Node *p_node) {
|
||||
if (p_node != this) {
|
||||
if (!p_node->is_inside_tree()) { //may not have entered scene yet
|
||||
return;
|
||||
}
|
||||
|
||||
if (Object::cast_to<Spatial>(p_node) || Object::cast_to<WorldEnvironment3D>(p_node)) {
|
||||
p_node->notification(Spatial::NOTIFICATION_ENTER_WORLD);
|
||||
} else {
|
||||
Viewport *v = Object::cast_to<Viewport>(p_node);
|
||||
if (v) {
|
||||
if (v->world_3d.is_valid() || v->own_world_3d.is_valid()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < p_node->get_child_count(); i++) {
|
||||
_propagate_enter_world(p_node->get_child(i));
|
||||
}
|
||||
}
|
||||
|
||||
void Viewport::_propagate_viewport_notification(Node *p_node, int p_what) {
|
||||
p_node->notification(p_what);
|
||||
for (int i = 0; i < p_node->get_child_count(); i++) {
|
||||
@ -1087,84 +1045,6 @@ void Viewport::_propagate_viewport_notification(Node *p_node, int p_what) {
|
||||
}
|
||||
}
|
||||
|
||||
void Viewport::_propagate_exit_world(Node *p_node) {
|
||||
if (p_node != this) {
|
||||
if (!p_node->is_inside_tree()) { //may have exited scene already
|
||||
return;
|
||||
}
|
||||
|
||||
if (Object::cast_to<Spatial>(p_node) || Object::cast_to<WorldEnvironment3D>(p_node)) {
|
||||
p_node->notification(Spatial::NOTIFICATION_EXIT_WORLD);
|
||||
} else {
|
||||
Viewport *v = Object::cast_to<Viewport>(p_node);
|
||||
if (v) {
|
||||
if (v->world_3d.is_valid() || v->own_world_3d.is_valid()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < p_node->get_child_count(); i++) {
|
||||
_propagate_exit_world(p_node->get_child(i));
|
||||
}
|
||||
}
|
||||
|
||||
void Viewport::set_world_3d(const Ref<World3D> &p_world_3d) {
|
||||
if (world_3d == p_world_3d) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_inside_tree()) {
|
||||
_propagate_exit_world(this);
|
||||
}
|
||||
|
||||
if (own_world_3d.is_valid() && world_3d.is_valid()) {
|
||||
world_3d->disconnect(CoreStringNames::get_singleton()->changed, this, "_own_world_3d_changed");
|
||||
}
|
||||
|
||||
world_3d = p_world_3d;
|
||||
|
||||
if (own_world_3d.is_valid()) {
|
||||
if (world_3d.is_valid()) {
|
||||
own_world_3d = world_3d->duplicate();
|
||||
world_3d->connect(CoreStringNames::get_singleton()->changed, this, "_own_world_3d_changed");
|
||||
} else {
|
||||
own_world_3d = Ref<World3D>(memnew(World3D));
|
||||
}
|
||||
}
|
||||
|
||||
if (is_inside_tree()) {
|
||||
_propagate_enter_world(this);
|
||||
}
|
||||
|
||||
if (is_inside_tree()) {
|
||||
RenderingServer::get_singleton()->viewport_set_scenario(viewport, find_world_3d()->get_scenario());
|
||||
}
|
||||
|
||||
_update_listener();
|
||||
}
|
||||
|
||||
Ref<World3D> Viewport::get_world_3d() const {
|
||||
return world_3d;
|
||||
}
|
||||
|
||||
Ref<World2D> Viewport::get_world_2d() const {
|
||||
return world_2d;
|
||||
}
|
||||
|
||||
Ref<World3D> Viewport::find_world_3d() const {
|
||||
if (own_world_3d.is_valid()) {
|
||||
return own_world_3d;
|
||||
} else if (world_3d.is_valid()) {
|
||||
return world_3d;
|
||||
} else if (parent) {
|
||||
return parent->find_world_3d();
|
||||
} else {
|
||||
return Ref<World3D>();
|
||||
}
|
||||
}
|
||||
|
||||
Listener *Viewport::get_listener() const {
|
||||
return listener;
|
||||
}
|
||||
@ -2897,44 +2777,6 @@ void Viewport::unhandled_input(const Ref<InputEvent> &p_event) {
|
||||
}
|
||||
}
|
||||
|
||||
void Viewport::set_use_own_world_3d(bool p_use_own_world_3d) {
|
||||
if (p_use_own_world_3d == own_world_3d.is_valid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_inside_tree()) {
|
||||
_propagate_exit_world(this);
|
||||
}
|
||||
|
||||
if (p_use_own_world_3d) {
|
||||
if (world_3d.is_valid()) {
|
||||
own_world_3d = world_3d->duplicate();
|
||||
world_3d->connect(CoreStringNames::get_singleton()->changed, this, "_own_world_3d_changed");
|
||||
} else {
|
||||
own_world_3d = Ref<World3D>(memnew(World3D));
|
||||
}
|
||||
} else {
|
||||
own_world_3d = Ref<World3D>();
|
||||
if (world_3d.is_valid()) {
|
||||
world_3d->disconnect(CoreStringNames::get_singleton()->changed, this, "_own_world_3d_changed");
|
||||
}
|
||||
}
|
||||
|
||||
if (is_inside_tree()) {
|
||||
_propagate_enter_world(this);
|
||||
}
|
||||
|
||||
if (is_inside_tree()) {
|
||||
RenderingServer::get_singleton()->viewport_set_scenario(viewport, find_world_3d()->get_scenario());
|
||||
}
|
||||
|
||||
_update_listener();
|
||||
}
|
||||
|
||||
bool Viewport::is_using_own_world_3d() const {
|
||||
return own_world_3d.is_valid();
|
||||
}
|
||||
|
||||
void Viewport::set_attach_to_screen_rect(const Rect2 &p_rect) {
|
||||
RS::get_singleton()->viewport_attach_to_screen(viewport, p_rect);
|
||||
to_screen_rect = p_rect;
|
||||
@ -3197,12 +3039,6 @@ void Viewport::_validate_property(PropertyInfo &property) const {
|
||||
void Viewport::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_size", "size"), &Viewport::set_size);
|
||||
ClassDB::bind_method(D_METHOD("get_size"), &Viewport::get_size);
|
||||
ClassDB::bind_method(D_METHOD("set_world_2d", "world_2d"), &Viewport::set_world_2d);
|
||||
ClassDB::bind_method(D_METHOD("get_world_2d"), &Viewport::get_world_2d);
|
||||
ClassDB::bind_method(D_METHOD("find_world_2d"), &Viewport::find_world_2d);
|
||||
ClassDB::bind_method(D_METHOD("set_world_3d", "world"), &Viewport::set_world_3d);
|
||||
ClassDB::bind_method(D_METHOD("get_world_3d"), &Viewport::get_world_3d);
|
||||
ClassDB::bind_method(D_METHOD("find_world_3d"), &Viewport::find_world_3d);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_canvas_transform", "xform"), &Viewport::set_canvas_transform);
|
||||
ClassDB::bind_method(D_METHOD("get_canvas_transform"), &Viewport::get_canvas_transform);
|
||||
@ -3271,9 +3107,6 @@ void Viewport::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("update_worlds"), &Viewport::update_worlds);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_use_own_world_3d", "enable"), &Viewport::set_use_own_world_3d);
|
||||
ClassDB::bind_method(D_METHOD("is_using_own_world_3d"), &Viewport::is_using_own_world_3d);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_camera"), &Viewport::get_camera);
|
||||
ClassDB::bind_method(D_METHOD("get_camera_2d"), &Viewport::get_camera_2d);
|
||||
|
||||
@ -3326,15 +3159,11 @@ void Viewport::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("_subwindow_visibility_changed"), &Viewport::_subwindow_visibility_changed);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("_own_world_3d_changed"), &Viewport::_own_world_3d_changed);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("_process_picking", "ignore_paused"), &Viewport::_process_picking);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "size"), "set_size", "get_size");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "size_override_stretch"), "set_size_override_stretch", "is_size_override_stretch_enabled");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "own_world_3d"), "set_use_own_world_3d", "is_using_own_world_3d");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "world", PROPERTY_HINT_RESOURCE_TYPE, "World3D"), "set_world_3d", "get_world_3d");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "world_2d", PROPERTY_HINT_RESOURCE_TYPE, "World2D", 0), "set_world_2d", "get_world_2d");
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "transparent_bg"), "set_transparent_background", "has_transparent_background");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "handle_input_locally"), "set_handle_input_locally", "is_handling_input_locally");
|
||||
ADD_GROUP("Rendering", "");
|
||||
@ -3425,8 +3254,6 @@ void Viewport::_subwindow_visibility_changed() {
|
||||
}
|
||||
|
||||
Viewport::Viewport() {
|
||||
world_2d = Ref<World2D>(memnew(World2D));
|
||||
|
||||
viewport = RID_PRIME(RenderingServer::get_singleton()->viewport_create());
|
||||
texture_rid = RenderingServer::get_singleton()->viewport_get_texture(viewport);
|
||||
texture_flags = 0;
|
||||
|
@ -50,8 +50,6 @@ class Timer;
|
||||
class Viewport;
|
||||
class CollisionObject;
|
||||
class SceneTreeTimer;
|
||||
class World3D;
|
||||
class World2D;
|
||||
|
||||
class ViewportTexture : public Texture {
|
||||
GDCLASS(ViewportTexture, Texture);
|
||||
@ -183,14 +181,6 @@ public:
|
||||
Rect2 get_visible_rect() const;
|
||||
RID get_viewport_rid() const;
|
||||
|
||||
void set_world_3d(const Ref<World3D> &p_world);
|
||||
void set_world_2d(const Ref<World2D> &p_world_2d);
|
||||
Ref<World3D> get_world_3d() const;
|
||||
Ref<World3D> find_world_3d() const;
|
||||
|
||||
Ref<World2D> get_world_2d() const;
|
||||
Ref<World2D> find_world_2d() const;
|
||||
|
||||
void enable_canvas_transform_override(bool p_enable);
|
||||
bool is_canvas_transform_override_enbled() const;
|
||||
|
||||
@ -252,9 +242,6 @@ public:
|
||||
Vector2 get_camera_coords(const Vector2 &p_viewport_coords) const;
|
||||
Vector2 get_camera_rect_size() const;
|
||||
|
||||
void set_use_own_world_3d(bool p_use_own_world_3d);
|
||||
bool is_using_own_world_3d() const;
|
||||
|
||||
void input(const Ref<InputEvent> &p_event);
|
||||
void unhandled_input(const Ref<InputEvent> &p_event);
|
||||
|
||||
@ -320,6 +307,11 @@ protected:
|
||||
static void _bind_methods();
|
||||
virtual void _validate_property(PropertyInfo &property) const;
|
||||
|
||||
void _own_world_3d_changed();
|
||||
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);
|
||||
|
||||
private:
|
||||
friend class ViewportTexture;
|
||||
|
||||
@ -418,10 +410,6 @@ private:
|
||||
|
||||
Map<ObjectID, uint64_t> physics_2d_mouseover;
|
||||
|
||||
Ref<World2D> world_2d;
|
||||
Ref<World3D> world_3d;
|
||||
Ref<World3D> own_world_3d;
|
||||
|
||||
StringName input_group;
|
||||
StringName gui_input_group;
|
||||
StringName unhandled_input_group;
|
||||
@ -430,8 +418,6 @@ private:
|
||||
void _update_listener();
|
||||
void _update_listener_2d();
|
||||
|
||||
void _propagate_enter_world(Node *p_node);
|
||||
void _propagate_exit_world(Node *p_node);
|
||||
void _propagate_viewport_notification(Node *p_node, int p_what);
|
||||
|
||||
void _update_stretch_transform();
|
||||
@ -590,8 +576,6 @@ private:
|
||||
void _drop_physics_mouseover(bool p_paused_only = false);
|
||||
|
||||
void _update_canvas_items(Node *p_node);
|
||||
|
||||
void _own_world_3d_changed();
|
||||
};
|
||||
|
||||
VARIANT_ENUM_CAST(Viewport::UpdateMode);
|
||||
|
@ -1,12 +1,236 @@
|
||||
#include "world.h"
|
||||
|
||||
#include "core/core_string_names.h"
|
||||
#include "scene/3d/spatial.h"
|
||||
#include "scene/3d/world_environment_3d.h"
|
||||
#include "scene/resources/world_2d.h"
|
||||
#include "scene/resources/world_3d.h"
|
||||
|
||||
void World::set_use_own_world_3d(bool p_use_own_world_3d) {
|
||||
if (p_use_own_world_3d == own_world_3d.is_valid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_inside_tree()) {
|
||||
_propagate_exit_world(this);
|
||||
}
|
||||
|
||||
if (p_use_own_world_3d) {
|
||||
if (world_3d.is_valid()) {
|
||||
own_world_3d = world_3d->duplicate();
|
||||
world_3d->connect(CoreStringNames::get_singleton()->changed, this, "_own_world_3d_changed");
|
||||
} else {
|
||||
own_world_3d = Ref<World3D>(memnew(World3D));
|
||||
}
|
||||
} else {
|
||||
own_world_3d = Ref<World3D>();
|
||||
if (world_3d.is_valid()) {
|
||||
world_3d->disconnect(CoreStringNames::get_singleton()->changed, this, "_own_world_3d_changed");
|
||||
}
|
||||
}
|
||||
|
||||
if (is_inside_tree()) {
|
||||
_propagate_enter_world(this);
|
||||
}
|
||||
|
||||
_on_set_use_own_world_3d(p_use_own_world_3d);
|
||||
}
|
||||
|
||||
bool World::is_using_own_world_3d() const {
|
||||
return own_world_3d.is_valid();
|
||||
}
|
||||
|
||||
void World::set_world_2d(const Ref<World2D> &p_world_2d) {
|
||||
if (world_2d == p_world_2d) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_parent_world && _parent_world->find_world_2d() == p_world_2d) {
|
||||
WARN_PRINT("Unable to use parent world as world_2d");
|
||||
return;
|
||||
}
|
||||
|
||||
Ref<World2D> old_world;
|
||||
|
||||
if (is_inside_tree()) {
|
||||
old_world = find_world_2d();
|
||||
}
|
||||
|
||||
if (p_world_2d.is_valid()) {
|
||||
world_2d = p_world_2d;
|
||||
} else {
|
||||
WARN_PRINT("Invalid world");
|
||||
world_2d = Ref<World2D>(memnew(World2D));
|
||||
}
|
||||
|
||||
_on_set_world_2d(old_world);
|
||||
}
|
||||
|
||||
Ref<World2D> World::find_world_2d() const {
|
||||
if (world_2d.is_valid()) {
|
||||
return world_2d;
|
||||
} else if (_parent_world) {
|
||||
return _parent_world->find_world_2d();
|
||||
} else {
|
||||
return Ref<World2D>();
|
||||
}
|
||||
}
|
||||
|
||||
void World::set_world_3d(const Ref<World3D> &p_world_3d) {
|
||||
if (world_3d == p_world_3d) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_inside_tree()) {
|
||||
_propagate_exit_world(this);
|
||||
}
|
||||
|
||||
Ref<World3D> old_world = world_3d;
|
||||
|
||||
if (own_world_3d.is_valid() && world_3d.is_valid()) {
|
||||
world_3d->disconnect(CoreStringNames::get_singleton()->changed, this, "_own_world_3d_changed");
|
||||
}
|
||||
|
||||
world_3d = p_world_3d;
|
||||
|
||||
if (own_world_3d.is_valid()) {
|
||||
if (world_3d.is_valid()) {
|
||||
own_world_3d = world_3d->duplicate();
|
||||
world_3d->connect(CoreStringNames::get_singleton()->changed, this, "_own_world_3d_changed");
|
||||
} else {
|
||||
own_world_3d = Ref<World3D>(memnew(World3D));
|
||||
}
|
||||
}
|
||||
|
||||
if (is_inside_tree()) {
|
||||
_propagate_enter_world(this);
|
||||
}
|
||||
|
||||
_on_set_world_3d(old_world);
|
||||
}
|
||||
|
||||
Ref<World3D> World::get_world_3d() const {
|
||||
return world_3d;
|
||||
}
|
||||
|
||||
Ref<World2D> World::get_world_2d() const {
|
||||
return world_2d;
|
||||
}
|
||||
|
||||
Ref<World3D> World::find_world_3d() const {
|
||||
if (own_world_3d.is_valid()) {
|
||||
return own_world_3d;
|
||||
} else if (world_3d.is_valid()) {
|
||||
return world_3d;
|
||||
} else if (_parent_world) {
|
||||
return _parent_world->find_world_3d();
|
||||
} else {
|
||||
return Ref<World3D>();
|
||||
}
|
||||
}
|
||||
|
||||
void World::_propagate_enter_world(Node *p_node) {
|
||||
if (p_node != this) {
|
||||
if (!p_node->is_inside_tree()) { //may not have entered scene yet
|
||||
return;
|
||||
}
|
||||
|
||||
if (Object::cast_to<Spatial>(p_node) || Object::cast_to<WorldEnvironment3D>(p_node)) {
|
||||
p_node->notification(Spatial::NOTIFICATION_ENTER_WORLD);
|
||||
} else {
|
||||
World *v = Object::cast_to<World>(p_node);
|
||||
if (v) {
|
||||
if (v->world_3d.is_valid() || v->own_world_3d.is_valid()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < p_node->get_child_count(); i++) {
|
||||
_propagate_enter_world(p_node->get_child(i));
|
||||
}
|
||||
}
|
||||
|
||||
void World::_propagate_exit_world(Node *p_node) {
|
||||
if (p_node != this) {
|
||||
if (!p_node->is_inside_tree()) { //may have exited scene already
|
||||
return;
|
||||
}
|
||||
|
||||
if (Object::cast_to<Spatial>(p_node) || Object::cast_to<WorldEnvironment3D>(p_node)) {
|
||||
p_node->notification(Spatial::NOTIFICATION_EXIT_WORLD);
|
||||
} else {
|
||||
World *v = Object::cast_to<World>(p_node);
|
||||
if (v) {
|
||||
if (v->world_3d.is_valid() || v->own_world_3d.is_valid()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < p_node->get_child_count(); i++) {
|
||||
_propagate_exit_world(p_node->get_child(i));
|
||||
}
|
||||
}
|
||||
|
||||
void World::_own_world_3d_changed() {
|
||||
ERR_FAIL_COND(world_3d.is_null());
|
||||
ERR_FAIL_COND(own_world_3d.is_null());
|
||||
|
||||
if (is_inside_tree()) {
|
||||
_propagate_exit_world(this);
|
||||
}
|
||||
|
||||
own_world_3d = world_3d->duplicate();
|
||||
|
||||
if (is_inside_tree()) {
|
||||
_propagate_enter_world(this);
|
||||
}
|
||||
}
|
||||
|
||||
void World::_on_set_use_own_world_3d(bool p_use_own_world_3d) {
|
||||
}
|
||||
|
||||
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) {
|
||||
}
|
||||
|
||||
World::World() {
|
||||
world_2d = Ref<World2D>(memnew(World2D));
|
||||
}
|
||||
World::~World() {
|
||||
}
|
||||
|
||||
void World::_notification(int p_what) {
|
||||
switch (p_what) {
|
||||
case NOTIFICATION_ENTER_TREE: {
|
||||
if (get_parent()) {
|
||||
_parent_world = get_parent()->get_world();
|
||||
} else {
|
||||
_parent_world = nullptr;
|
||||
}
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void World::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("get_world_2d"), &World::get_world_2d);
|
||||
ClassDB::bind_method(D_METHOD("set_world_2d", "world_2d"), &World::set_world_2d);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "world_2d", PROPERTY_HINT_RESOURCE_TYPE, "World2D", 0), "set_world_2d", "get_world_2d");
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_world_3d"), &World::get_world_3d);
|
||||
ClassDB::bind_method(D_METHOD("set_world_3d", "world"), &World::set_world_3d);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "world", PROPERTY_HINT_RESOURCE_TYPE, "World3D"), "set_world_3d", "get_world_3d");
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_use_own_world_3d", "enable"), &World::set_use_own_world_3d);
|
||||
ClassDB::bind_method(D_METHOD("is_using_own_world_3d"), &World::is_using_own_world_3d);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "own_world_3d"), "set_use_own_world_3d", "is_using_own_world_3d");
|
||||
|
||||
ClassDB::bind_method(D_METHOD("find_world_2d"), &World::find_world_2d);
|
||||
ClassDB::bind_method(D_METHOD("find_world_3d"), &World::find_world_3d);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("_own_world_3d_changed"), &World::_own_world_3d_changed);
|
||||
}
|
@ -1,12 +1,29 @@
|
||||
#ifndef WORLD_H
|
||||
#define WORLD_H
|
||||
|
||||
#include "core/object/reference.h"
|
||||
|
||||
#include "node.h"
|
||||
|
||||
class World3D;
|
||||
class World2D;
|
||||
|
||||
class World : public Node {
|
||||
GDCLASS(World, Node);
|
||||
|
||||
public:
|
||||
void set_world_3d(const Ref<World3D> &p_world);
|
||||
void set_world_2d(const Ref<World2D> &p_world_2d);
|
||||
|
||||
Ref<World3D> get_world_3d() const;
|
||||
Ref<World3D> find_world_3d() const;
|
||||
|
||||
Ref<World2D> get_world_2d() const;
|
||||
Ref<World2D> find_world_2d() const;
|
||||
|
||||
void set_use_own_world_3d(bool p_use_own_world_3d);
|
||||
bool is_using_own_world_3d() const;
|
||||
|
||||
World();
|
||||
~World();
|
||||
|
||||
@ -14,6 +31,20 @@ protected:
|
||||
void _notification(int p_what);
|
||||
|
||||
static void _bind_methods();
|
||||
|
||||
virtual void _own_world_3d_changed();
|
||||
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);
|
||||
|
||||
void _propagate_enter_world(Node *p_node);
|
||||
void _propagate_exit_world(Node *p_node);
|
||||
|
||||
Ref<World2D> world_2d;
|
||||
Ref<World3D> world_3d;
|
||||
Ref<World3D> own_world_3d;
|
||||
|
||||
World *_parent_world;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user