Now CanvasItems work with World overrides aswell.

This commit is contained in:
Relintai 2022-08-30 01:40:03 +02:00
parent dd2fa3e6e3
commit 9b3714a274
11 changed files with 279 additions and 95 deletions

View File

@ -37,13 +37,13 @@
</description>
</signal>
<signal name="viewport_entered">
<argument index="0" name="viewport" type="Viewport" />
<argument index="0" name="viewport" type="World" />
<description>
Emitted when the VisibilityNotifier2D enters a [Viewport]'s view.
</description>
</signal>
<signal name="viewport_exited">
<argument index="0" name="viewport" type="Viewport" />
<argument index="0" name="viewport" type="World" />
<description>
Emitted when the VisibilityNotifier2D exits a [Viewport]'s view.
</description>

View File

@ -475,7 +475,7 @@ Transform2D CanvasItem::get_global_transform_with_canvas() const {
if (canvas_layer) {
return canvas_layer->get_transform() * get_global_transform();
} else if (is_inside_tree()) {
return get_viewport()->get_canvas_transform() * get_global_transform();
return get_world()->get_canvas_transform() * get_global_transform();
} else {
return get_global_transform();
}
@ -507,7 +507,7 @@ void CanvasItem::_toplevel_raise_self() {
if (canvas_layer) {
RenderingServer::get_singleton()->canvas_item_set_draw_index(canvas_item, canvas_layer->get_sort_index());
} else {
RenderingServer::get_singleton()->canvas_item_set_draw_index(canvas_item, get_viewport()->gui_get_canvas_sort_index());
RenderingServer::get_singleton()->canvas_item_set_draw_index(canvas_item, get_world()->gui_get_canvas_sort_index());
}
}
@ -532,7 +532,7 @@ void CanvasItem::_enter_canvas() {
if (canvas_layer) {
canvas = canvas_layer->get_canvas();
} else {
canvas = get_viewport()->find_world_2d()->get_canvas();
canvas = get_world()->find_world_2d()->get_canvas();
}
RenderingServer::get_singleton()->canvas_item_set_parent(canvas_item, canvas);
@ -543,7 +543,7 @@ void CanvasItem::_enter_canvas() {
if (canvas_layer) {
canvas_layer->reset_sort_index();
} else {
get_viewport()->gui_reset_canvas_sort_index();
get_world()->gui_reset_canvas_sort_index();
}
get_tree()->call_group_flags(SceneTree::GROUP_CALL_UNIQUE, canvas_group, "_toplevel_raise_self");
@ -949,7 +949,7 @@ void CanvasItem::_notify_transform(CanvasItem *p_node) {
Rect2 CanvasItem::get_viewport_rect() const {
ERR_FAIL_COND_V(!is_inside_tree(), Rect2());
return get_viewport()->get_visible_rect();
return get_world()->get_visible_rect();
}
RID CanvasItem::get_canvas() const {
@ -958,7 +958,7 @@ RID CanvasItem::get_canvas() const {
if (canvas_layer) {
return canvas_layer->get_canvas();
} else {
return get_viewport()->find_world_2d()->get_canvas();
return get_world()->find_world_2d()->get_canvas();
}
}
@ -984,8 +984,8 @@ Ref<World2D> CanvasItem::get_world_2d() const {
CanvasItem *tl = get_toplevel();
if (tl->get_viewport()) {
return tl->get_viewport()->find_world_2d();
if (tl->get_world()) {
return tl->get_world()->find_world_2d();
} else {
return Ref<World2D>();
}
@ -993,7 +993,7 @@ Ref<World2D> CanvasItem::get_world_2d() const {
RID CanvasItem::get_viewport_rid() const {
ERR_FAIL_COND_V(!is_inside_tree(), RID());
return get_viewport()->get_viewport_rid();
return get_world()->get_viewport_rid();
}
void CanvasItem::set_block_transform_notify(bool p_enable) {
@ -1224,7 +1224,7 @@ Transform2D CanvasItem::get_canvas_transform() const {
} else if (Object::cast_to<CanvasItem>(get_parent())) {
return Object::cast_to<CanvasItem>(get_parent())->get_canvas_transform();
} else {
return get_viewport()->get_canvas_transform();
return get_world()->get_canvas_transform();
}
}
@ -1232,14 +1232,14 @@ Transform2D CanvasItem::get_viewport_transform() const {
ERR_FAIL_COND_V(!is_inside_tree(), Transform2D());
if (canvas_layer) {
if (get_viewport()) {
return get_viewport()->get_final_transform() * canvas_layer->get_transform();
if (get_world()) {
return get_world()->get_final_transform() * canvas_layer->get_transform();
} else {
return canvas_layer->get_transform();
}
} else {
return get_viewport()->get_final_transform() * get_viewport()->get_canvas_transform();
return get_world()->get_final_transform() * get_world()->get_canvas_transform();
}
}

View File

@ -35,6 +35,7 @@
#include "scene/2d/physics_body_2d.h"
#include "scene/animation/animation_player.h"
#include "scene/main/viewport.h"
#include "scene/main/world.h"
#include "scene/resources/world_2d.h"
#include "scene/scene_string_names.h"
@ -48,32 +49,32 @@ bool VisibilityNotifier2D::_edit_use_rect() const {
}
#endif
void VisibilityNotifier2D::_enter_viewport(Viewport *p_viewport) {
ERR_FAIL_COND(viewports.has(p_viewport));
viewports.insert(p_viewport);
void VisibilityNotifier2D::_enter_world(World *p_world) {
ERR_FAIL_COND(worlds.has(p_world));
worlds.insert(p_world);
if (is_inside_tree() && Engine::get_singleton()->is_editor_hint()) {
return;
}
if (viewports.size() == 1) {
if (worlds.size() == 1) {
emit_signal(SceneStringNames::get_singleton()->screen_entered);
_screen_enter();
}
emit_signal(SceneStringNames::get_singleton()->viewport_entered, p_viewport);
emit_signal(SceneStringNames::get_singleton()->viewport_entered, p_world);
}
void VisibilityNotifier2D::_exit_viewport(Viewport *p_viewport) {
ERR_FAIL_COND(!viewports.has(p_viewport));
viewports.erase(p_viewport);
void VisibilityNotifier2D::_exit_world(World *p_world) {
ERR_FAIL_COND(!worlds.has(p_world));
worlds.erase(p_world);
if (is_inside_tree() && Engine::get_singleton()->is_editor_hint()) {
return;
}
emit_signal(SceneStringNames::get_singleton()->viewport_exited, p_viewport);
if (viewports.size() == 0) {
emit_signal(SceneStringNames::get_singleton()->viewport_exited, p_world);
if (worlds.size() == 0) {
emit_signal(SceneStringNames::get_singleton()->screen_exited);
_screen_exit();
@ -119,7 +120,7 @@ void VisibilityNotifier2D::_notification(int p_what) {
}
bool VisibilityNotifier2D::is_on_screen() const {
return viewports.size() > 0;
return worlds.size() > 0;
}
void VisibilityNotifier2D::_bind_methods() {
@ -129,8 +130,8 @@ void VisibilityNotifier2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::RECT2, "rect"), "set_rect", "get_rect");
ADD_SIGNAL(MethodInfo("viewport_entered", PropertyInfo(Variant::OBJECT, "viewport", PROPERTY_HINT_RESOURCE_TYPE, "Viewport")));
ADD_SIGNAL(MethodInfo("viewport_exited", PropertyInfo(Variant::OBJECT, "viewport", PROPERTY_HINT_RESOURCE_TYPE, "Viewport")));
ADD_SIGNAL(MethodInfo("viewport_entered", PropertyInfo(Variant::OBJECT, "world", PROPERTY_HINT_RESOURCE_TYPE, "World")));
ADD_SIGNAL(MethodInfo("viewport_exited", PropertyInfo(Variant::OBJECT, "world", PROPERTY_HINT_RESOURCE_TYPE, "World")));
ADD_SIGNAL(MethodInfo("screen_entered"));
ADD_SIGNAL(MethodInfo("screen_exited"));
}

View File

@ -36,15 +36,15 @@ class Viewport;
class VisibilityNotifier2D : public Node2D {
GDCLASS(VisibilityNotifier2D, Node2D);
Set<Viewport *> viewports;
Set<World *> worlds;
Rect2 rect;
protected:
friend struct SpatialIndexer2D;
void _enter_viewport(Viewport *p_viewport);
void _exit_viewport(Viewport *p_viewport);
void _enter_world(World *p_world);
void _exit_world(World *p_world);
virtual void _screen_enter() {}
virtual void _screen_exit() {}

View File

@ -216,19 +216,6 @@ void Viewport::_update_stretch_transform() {
_update_global_transform();
}
void Viewport::update_worlds() {
if (!is_inside_tree()) {
return;
}
Rect2 abstracted_rect = Rect2(Vector2(), get_visible_rect().size);
Rect2 xformed_rect = (global_canvas_transform * canvas_transform).affine_inverse().xform(abstracted_rect);
find_world_2d()->_update_viewport(this, xformed_rect);
find_world_2d()->_update();
find_world_3d()->_update(get_tree()->get_frame());
}
void Viewport::_collision_object_input_event(CollisionObject *p_object, Camera *p_camera, const Ref<InputEvent> &p_input_event, const Vector3 &p_pos, const Vector3 &p_normal, int p_shape) {
Transform object_transform = p_object->get_global_transform();
Transform camera_transform = p_camera->get_global_transform();
@ -278,7 +265,7 @@ void Viewport::_on_set_world_3d(const Ref<World3D> &p_old_world) {
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);
old_world_2d->_remove_world(this);
RenderingServer::get_singleton()->viewport_remove_canvas(viewport, current_canvas);
}
@ -287,7 +274,7 @@ void Viewport::_on_set_world_2d(const Ref<World2D> &p_old_world_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());
find_world_2d()->_register_world(this, Rect2());
}
}
@ -344,7 +331,7 @@ void Viewport::_notification(int p_what) {
case NOTIFICATION_EXIT_TREE: {
_gui_cancel_tooltip();
if (world_2d.is_valid()) {
world_2d->_remove_viewport(this);
world_2d->_remove_world(this);
}
RenderingServer::get_singleton()->viewport_set_scenario(viewport, RID());
@ -691,6 +678,10 @@ void Viewport::_process_picking(bool p_ignore_paused) {
}
RID Viewport::get_viewport_rid() const {
if (_override_world) {
return _override_world->get_viewport_rid();
}
return viewport;
}
@ -721,6 +712,10 @@ void Viewport::set_size(const Size2 &p_size) {
}
Rect2 Viewport::get_visible_rect() const {
if (_override_world) {
return _override_world->get_visible_rect();
}
Rect2 r;
if (size == Size2()) {
@ -795,7 +790,7 @@ void Viewport::_on_before_world_override_changed() {
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);
w->find_world_2d()->_remove_world(this);
}
}
@ -807,7 +802,7 @@ void Viewport::_on_after_world_override_changed() {
_update_listener();
_update_listener_2d();
find_world_2d()->_register_viewport(this, Rect2());
find_world_2d()->_register_world(this, Rect2());
if (get_tree()->is_debugging_collisions_hint()) {
//2D
@ -841,6 +836,10 @@ void Viewport::_on_after_world_override_changed() {
}
void Viewport::enable_canvas_transform_override(bool p_enable) {
if (_override_world) {
_override_world->enable_canvas_transform_override(p_enable);
}
if (override_canvas_transform == p_enable) {
return;
}
@ -854,10 +853,18 @@ void Viewport::enable_canvas_transform_override(bool p_enable) {
}
bool Viewport::is_canvas_transform_override_enbled() const {
if (_override_world) {
return _override_world->is_canvas_transform_override_enbled();
}
return override_canvas_transform;
}
void Viewport::set_canvas_transform_override(const Transform2D &p_transform) {
if (_override_world) {
_override_world->set_canvas_transform_override(p_transform);
}
if (canvas_transform_override == p_transform) {
return;
}
@ -869,10 +876,22 @@ void Viewport::set_canvas_transform_override(const Transform2D &p_transform) {
}
Transform2D Viewport::get_canvas_transform_override() const {
if (_override_world) {
return _override_world->get_canvas_transform_override();
}
if (_override_world) {
return _override_world->get_canvas_transform_override();
}
return canvas_transform_override;
}
void Viewport::set_canvas_transform(const Transform2D &p_transform) {
if (_override_world) {
_override_world->set_canvas_transform(p_transform);
}
canvas_transform = p_transform;
if (!override_canvas_transform) {
@ -881,6 +900,10 @@ void Viewport::set_canvas_transform(const Transform2D &p_transform) {
}
Transform2D Viewport::get_canvas_transform() const {
if (_override_world) {
return _override_world->get_canvas_transform();
}
return canvas_transform;
}
@ -891,12 +914,20 @@ void Viewport::_update_global_transform() {
}
void Viewport::set_global_canvas_transform(const Transform2D &p_transform) {
if (_override_world) {
_override_world->set_global_canvas_transform(p_transform);
}
global_canvas_transform = p_transform;
_update_global_transform();
}
Transform2D Viewport::get_global_canvas_transform() const {
if (_override_world) {
return _override_world->get_global_canvas_transform();
}
return global_canvas_transform;
}
@ -1160,6 +1191,10 @@ void Viewport::set_camera_override_orthogonal(float p_size, float p_z_near, floa
}
Transform2D Viewport::get_final_transform() const {
if (_override_world) {
return _override_world->get_final_transform();
}
return stretch_transform * global_canvas_transform;
}
@ -2906,9 +2941,17 @@ String Viewport::get_configuration_warning() const {
}
void Viewport::gui_reset_canvas_sort_index() {
if (_override_world) {
_override_world->gui_reset_canvas_sort_index();
}
gui.canvas_sort_index = 0;
}
int Viewport::gui_get_canvas_sort_index() {
if (_override_world) {
return _override_world->gui_get_canvas_sort_index();
}
return gui.canvas_sort_index++;
}
@ -3068,14 +3111,6 @@ 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_canvas_transform", "xform"), &Viewport::set_canvas_transform);
ClassDB::bind_method(D_METHOD("get_canvas_transform"), &Viewport::get_canvas_transform);
ClassDB::bind_method(D_METHOD("set_global_canvas_transform", "xform"), &Viewport::set_global_canvas_transform);
ClassDB::bind_method(D_METHOD("get_global_canvas_transform"), &Viewport::get_global_canvas_transform);
ClassDB::bind_method(D_METHOD("get_final_transform"), &Viewport::get_final_transform);
ClassDB::bind_method(D_METHOD("get_visible_rect"), &Viewport::get_visible_rect);
ClassDB::bind_method(D_METHOD("set_transparent_background", "enable"), &Viewport::set_transparent_background);
ClassDB::bind_method(D_METHOD("has_transparent_background"), &Viewport::has_transparent_background);
@ -3129,12 +3164,9 @@ void Viewport::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_physics_object_picking", "enable"), &Viewport::set_physics_object_picking);
ClassDB::bind_method(D_METHOD("get_physics_object_picking"), &Viewport::get_physics_object_picking);
ClassDB::bind_method(D_METHOD("get_viewport_rid"), &Viewport::get_viewport_rid);
ClassDB::bind_method(D_METHOD("input", "local_event"), &Viewport::input);
ClassDB::bind_method(D_METHOD("unhandled_input", "local_event"), &Viewport::unhandled_input);
ClassDB::bind_method(D_METHOD("update_worlds"), &Viewport::update_worlds);
ClassDB::bind_method(D_METHOD("get_camera"), &Viewport::get_camera);
ClassDB::bind_method(D_METHOD("get_camera_2d"), &Viewport::get_camera_2d);
@ -3224,8 +3256,6 @@ void Viewport::_bind_methods() {
ADD_PROPERTYI(PropertyInfo(Variant::INT, "shadow_atlas_quad_1", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"), "set_shadow_atlas_quadrant_subdiv", "get_shadow_atlas_quadrant_subdiv", 1);
ADD_PROPERTYI(PropertyInfo(Variant::INT, "shadow_atlas_quad_2", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"), "set_shadow_atlas_quadrant_subdiv", "get_shadow_atlas_quadrant_subdiv", 2);
ADD_PROPERTYI(PropertyInfo(Variant::INT, "shadow_atlas_quad_3", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"), "set_shadow_atlas_quadrant_subdiv", "get_shadow_atlas_quadrant_subdiv", 3);
ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "canvas_transform", PROPERTY_HINT_NONE, "", 0), "set_canvas_transform", "get_canvas_transform");
ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "global_canvas_transform", PROPERTY_HINT_NONE, "", 0), "set_global_canvas_transform", "get_global_canvas_transform");
ADD_SIGNAL(MethodInfo("size_changed"));
ADD_SIGNAL(MethodInfo("gui_focus_changed", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Control")));

View File

@ -500,8 +500,6 @@ private:
void _gui_input_event(Ref<InputEvent> p_event);
void _gui_cleanup_internal_state(Ref<InputEvent> p_event);
void update_worlds();
_FORCE_INLINE_ Transform2D _get_input_pre_xform() const;
void _vp_input(const Ref<InputEvent> &p_ev);

View File

@ -217,6 +217,108 @@ void World::set_override_world_bind(Node *p_world) {
set_override_world(w);
}
void World::gui_reset_canvas_sort_index() {
if (_override_world) {
_override_world->gui_reset_canvas_sort_index();
}
}
int World::gui_get_canvas_sort_index() {
if (_override_world) {
return _override_world->gui_get_canvas_sort_index();
}
return 0;
}
void World::enable_canvas_transform_override(bool p_enable) {
if (_override_world) {
_override_world->enable_canvas_transform_override(p_enable);
}
}
bool World::is_canvas_transform_override_enbled() const {
if (_override_world) {
return _override_world->is_canvas_transform_override_enbled();
}
return false;
}
void World::set_canvas_transform_override(const Transform2D &p_transform) {
if (_override_world) {
_override_world->set_canvas_transform_override(p_transform);
}
}
Transform2D World::get_canvas_transform_override() const {
if (_override_world) {
return _override_world->get_canvas_transform_override();
}
return Transform2D();
}
void World::set_canvas_transform(const Transform2D &p_transform) {
if (_override_world) {
_override_world->set_canvas_transform(p_transform);
}
}
Transform2D World::get_canvas_transform() const {
if (_override_world) {
return _override_world->get_canvas_transform();
}
return Transform2D();
}
void World::set_global_canvas_transform(const Transform2D &p_transform) {
if (_override_world) {
_override_world->set_global_canvas_transform(p_transform);
}
}
Transform2D World::get_global_canvas_transform() const {
if (_override_world) {
return _override_world->get_global_canvas_transform();
}
return Transform2D();
}
Transform2D World::get_final_transform() const {
if (_override_world) {
return _override_world->get_final_transform();
}
return Transform2D();
}
Rect2 World::get_visible_rect() const {
if (_override_world) {
return _override_world->get_visible_rect();
}
return Rect2();
}
RID World::get_viewport_rid() const {
if (_override_world) {
return _override_world->get_viewport_rid();
}
return RID();
}
void World::update_worlds() {
if (!is_inside_tree()) {
return;
}
Rect2 abstracted_rect = Rect2(Vector2(), get_visible_rect().size);
Rect2 xformed_rect = (get_global_canvas_transform() * get_canvas_transform()).affine_inverse().xform(abstracted_rect);
find_world_2d()->_update_world(this, xformed_rect);
find_world_2d()->_update();
find_world_3d()->_update(get_tree()->get_frame());
}
World::World() {
world_2d = Ref<World2D>(memnew(World2D));
_override_world = NULL;
@ -376,4 +478,19 @@ void World::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_override_world", "world"), &World::set_override_world_bind);
ClassDB::bind_method(D_METHOD("_own_world_3d_changed"), &World::_own_world_3d_changed);
ClassDB::bind_method(D_METHOD("set_canvas_transform", "xform"), &World::set_canvas_transform);
ClassDB::bind_method(D_METHOD("get_canvas_transform"), &World::get_canvas_transform);
ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "canvas_transform", PROPERTY_HINT_NONE, "", 0), "set_canvas_transform", "get_canvas_transform");
ClassDB::bind_method(D_METHOD("set_global_canvas_transform", "xform"), &World::set_global_canvas_transform);
ClassDB::bind_method(D_METHOD("get_global_canvas_transform"), &World::get_global_canvas_transform);
ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "global_canvas_transform", PROPERTY_HINT_NONE, "", 0), "set_global_canvas_transform", "get_global_canvas_transform");
ClassDB::bind_method(D_METHOD("get_final_transform"), &World::get_final_transform);
ClassDB::bind_method(D_METHOD("get_visible_rect"), &World::get_visible_rect);
ClassDB::bind_method(D_METHOD("get_viewport_rid"), &World::get_viewport_rid);
ClassDB::bind_method(D_METHOD("update_worlds"), &World::update_worlds);
}

View File

@ -33,6 +33,29 @@ public:
void set_override_world(World *p_world);
void set_override_world_bind(Node *p_world);
virtual void gui_reset_canvas_sort_index();
virtual int gui_get_canvas_sort_index();
virtual void enable_canvas_transform_override(bool p_enable);
virtual bool is_canvas_transform_override_enbled() const;
virtual void set_canvas_transform_override(const Transform2D &p_transform);
virtual Transform2D get_canvas_transform_override() const;
virtual void set_canvas_transform(const Transform2D &p_transform);
virtual Transform2D get_canvas_transform() const;
virtual void set_global_canvas_transform(const Transform2D &p_transform);
virtual Transform2D get_global_canvas_transform() const;
virtual Transform2D get_final_transform() const;
virtual Rect2 get_visible_rect() const;
virtual RID get_viewport_rid() const;
void update_worlds();
World();
~World();

View File

@ -34,6 +34,7 @@
#include "scene/2d/camera_2d.h"
#include "scene/2d/visibility_notifier_2d.h"
#include "scene/main/viewport.h"
#include "scene/main/world.h"
#include "servers/navigation_2d_server.h"
#include "servers/physics_2d_server.h"
#include "servers/rendering_server.h"
@ -80,12 +81,12 @@ struct SpatialIndexer2D {
Map<VisibilityNotifier2D *, Rect2> notifiers;
struct ViewportData {
struct WorldData {
Map<VisibilityNotifier2D *, uint64_t> notifiers;
Rect2 rect;
};
Map<Viewport *, ViewportData> viewports;
Map<World *, WorldData> worlds;
bool changed;
@ -147,8 +148,8 @@ struct SpatialIndexer2D {
_notifier_update_cells(p_notifier, E->get(), false);
notifiers.erase(p_notifier);
List<Viewport *> removed;
for (Map<Viewport *, ViewportData>::Element *F = viewports.front(); F; F = F->next()) {
List<World *> removed;
for (Map<World *, WorldData>::Element *F = worlds.front(); F; F = F->next()) {
Map<VisibilityNotifier2D *, uint64_t>::Element *G = F->get().notifiers.find(p_notifier);
if (G) {
@ -158,23 +159,23 @@ struct SpatialIndexer2D {
}
while (!removed.empty()) {
p_notifier->_exit_viewport(removed.front()->get());
p_notifier->_exit_world(removed.front()->get());
removed.pop_front();
}
changed = true;
}
void _add_viewport(Viewport *p_viewport, const Rect2 &p_rect) {
ERR_FAIL_COND(viewports.has(p_viewport));
ViewportData vd;
void _add_world(World *p_world, const Rect2 &p_rect) {
ERR_FAIL_COND(worlds.has(p_world));
WorldData vd;
vd.rect = p_rect;
viewports[p_viewport] = vd;
worlds[p_world] = vd;
changed = true;
}
void _update_viewport(Viewport *p_viewport, const Rect2 &p_rect) {
Map<Viewport *, ViewportData>::Element *E = viewports.find(p_viewport);
void _update_world(World *p_world, const Rect2 &p_rect) {
Map<World *, WorldData>::Element *E = worlds.find(p_world);
ERR_FAIL_COND(!E);
if (E->get().rect == p_rect) {
return;
@ -183,19 +184,19 @@ struct SpatialIndexer2D {
changed = true;
}
void _remove_viewport(Viewport *p_viewport) {
ERR_FAIL_COND(!viewports.has(p_viewport));
void _remove_world(World *p_world) {
ERR_FAIL_COND(!worlds.has(p_world));
List<VisibilityNotifier2D *> removed;
for (Map<VisibilityNotifier2D *, uint64_t>::Element *E = viewports[p_viewport].notifiers.front(); E; E = E->next()) {
for (Map<VisibilityNotifier2D *, uint64_t>::Element *E = worlds[p_world].notifiers.front(); E; E = E->next()) {
removed.push_back(E->key());
}
while (!removed.empty()) {
removed.front()->get()->_exit_viewport(p_viewport);
removed.front()->get()->_exit_world(p_world);
removed.pop_front();
}
viewports.erase(p_viewport);
worlds.erase(p_world);
}
void _update() {
@ -203,7 +204,7 @@ struct SpatialIndexer2D {
return;
}
for (Map<Viewport *, ViewportData>::Element *E = viewports.front(); E; E = E->next()) {
for (Map<World *, WorldData>::Element *E = worlds.front(); E; E = E->next()) {
Point2i begin = E->get().rect.position;
begin /= cell_size;
Point2i end = E->get().rect.position + E->get().rect.size;
@ -273,13 +274,13 @@ struct SpatialIndexer2D {
}
while (!added.empty()) {
added.front()->get()->_enter_viewport(E->key());
added.front()->get()->_enter_world(E->key());
added.pop_front();
}
while (!removed.empty()) {
E->get().notifiers.erase(removed.front()->get());
removed.front()->get()->_exit_viewport(E->key());
removed.front()->get()->_exit_world(E->key());
removed.pop_front();
}
}
@ -294,15 +295,15 @@ struct SpatialIndexer2D {
}
};
void World2D::_register_viewport(Viewport *p_viewport, const Rect2 &p_rect) {
indexer->_add_viewport(p_viewport, p_rect);
void World2D::_register_world(World *p_world, const Rect2 &p_rect) {
indexer->_add_world(p_world, p_rect);
}
void World2D::_update_viewport(Viewport *p_viewport, const Rect2 &p_rect) {
indexer->_update_viewport(p_viewport, p_rect);
void World2D::_update_world(World *p_world, const Rect2 &p_rect) {
indexer->_update_world(p_world, p_rect);
}
void World2D::_remove_viewport(Viewport *p_viewport) {
indexer->_remove_viewport(p_viewport);
void World2D::_remove_world(World *p_world) {
indexer->_remove_world(p_world);
}
void World2D::_register_notifier(VisibilityNotifier2D *p_notifier, const Rect2 &p_rect) {
@ -331,9 +332,19 @@ RID World2D::get_navigation_map() const {
return navigation_map;
}
void World2D::get_world_list(List<World *> *r_worlds) {
for (Map<World *, SpatialIndexer2D::WorldData>::Element *E = indexer->worlds.front(); E; E = E->next()) {
r_worlds->push_back(E->key());
}
}
void World2D::get_viewport_list(List<Viewport *> *r_viewports) {
for (Map<Viewport *, SpatialIndexer2D::ViewportData>::Element *E = indexer->viewports.front(); E; E = E->next()) {
r_viewports->push_back(E->key());
for (Map<World *, SpatialIndexer2D::WorldData>::Element *E = indexer->worlds.front(); E; E = E->next()) {
Viewport *w = Object::cast_to<Viewport>(E->key());
if (w) {
r_viewports->push_back(w);
}
}
}

View File

@ -36,6 +36,7 @@
class VisibilityNotifier2D;
class Viewport;
class World;
struct SpatialIndexer2D;
class World2D : public Resource {
@ -50,11 +51,12 @@ class World2D : public Resource {
protected:
static void _bind_methods();
friend class Viewport;
friend class World;
friend class VisibilityNotifier2D;
void _register_viewport(Viewport *p_viewport, const Rect2 &p_rect);
void _update_viewport(Viewport *p_viewport, const Rect2 &p_rect);
void _remove_viewport(Viewport *p_viewport);
void _register_world(World *p_world, const Rect2 &p_rect);
void _update_world(World *p_world, const Rect2 &p_rect);
void _remove_world(World *p_world);
void _register_notifier(VisibilityNotifier2D *p_notifier, const Rect2 &p_rect);
void _update_notifier(VisibilityNotifier2D *p_notifier, const Rect2 &p_rect);
@ -69,7 +71,8 @@ public:
Physics2DDirectSpaceState *get_direct_space_state();
void get_viewport_list(List<Viewport *> *r_viewports);
void get_world_list(List<World *> *r_worlds);
void get_viewport_list(List<Viewport *> *r_worlds);
World2D();
~World2D();

View File

@ -66,6 +66,7 @@ protected:
void _update_notifier(VisibilityNotifier *p_notifier, const AABB &p_rect);
void _remove_notifier(VisibilityNotifier *p_notifier);
friend class Viewport;
friend class World;
void _update(uint64_t p_frame);
public: