Deleted YSort, moved its functionality directly into Node2D.
YSort now has a compatibility alias to Node2D. Updated TileMap to use the existing Node2D y_sort_enabled property instead of its own property. Updated Node2D doc to include the new y_sort_enabled member. Updated TileMap doc to remove its mention of cell_y_sort. Deleted YSort doc.
This commit is contained in:
parent
8363ee6f8d
commit
9f4bf5ec80
@ -150,6 +150,10 @@
|
||||
<member name="transform" type="Transform2D" setter="set_transform" getter="get_transform">
|
||||
Local [Transform2D].
|
||||
</member>
|
||||
<member name="y_sort_enabled" type="bool" setter="set_y_sort_enabled" getter="is_y_sort_enabled" default="false">
|
||||
If [code]true[/code], child nodes with the lowest Y position are drawn before those with a higher Y position. If [code]false[/code], Y-sorting is disabled. Y-sorting only affects children that inherit from [CanvasItem].
|
||||
You can nest nodes with Y-sorting. Child Y-sorted nodes are sorted in the same space as the parent Y-sort. This feature allows you to organize a scene better or divide it into multiple ones without changing your scene tree.
|
||||
</member>
|
||||
<member name="z_as_relative" type="bool" setter="set_z_as_relative" getter="is_z_relative" default="true">
|
||||
If [code]true[/code], the node's Z index is relative to its parent's Z index. If this node's Z index is 2 and its parent's effective Z index is 3, then this node's effective Z index will be 2 + 3 = 5.
|
||||
</member>
|
||||
|
@ -1,21 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<class name="YSort" inherits="Node2D" version="4.0">
|
||||
<brief_description>
|
||||
Sort all child nodes based on their Y positions.
|
||||
</brief_description>
|
||||
<description>
|
||||
Sort all child nodes based on their Y positions. The child node must inherit from [CanvasItem] for it to be sorted. Nodes that have a higher Y position will be drawn later, so they will appear on top of nodes that have a lower Y position.
|
||||
Nesting of YSort nodes is possible. Children YSort nodes will be sorted in the same space as the parent YSort, allowing to better organize a scene or divide it in multiple ones, yet keep the unique sorting.
|
||||
</description>
|
||||
<tutorials>
|
||||
</tutorials>
|
||||
<methods>
|
||||
</methods>
|
||||
<members>
|
||||
<member name="sort_enabled" type="bool" setter="set_sort_enabled" getter="is_sort_enabled" default="true">
|
||||
If [code]true[/code], child nodes are sorted, otherwise sorting is disabled.
|
||||
</member>
|
||||
</members>
|
||||
<constants>
|
||||
</constants>
|
||||
</class>
|
@ -391,6 +391,15 @@ Point2 Node2D::to_global(Point2 p_local) const {
|
||||
return get_global_transform().xform(p_local);
|
||||
}
|
||||
|
||||
void Node2D::set_y_sort_enabled(bool p_enabled) {
|
||||
y_sort_enabled = p_enabled;
|
||||
RS::get_singleton()->canvas_item_set_sort_children_by_y(get_canvas_item(), y_sort_enabled);
|
||||
}
|
||||
|
||||
bool Node2D::is_y_sort_enabled() const {
|
||||
return y_sort_enabled;
|
||||
}
|
||||
|
||||
void Node2D::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_position", "position"), &Node2D::set_position);
|
||||
ClassDB::bind_method(D_METHOD("set_rotation", "radians"), &Node2D::set_rotation);
|
||||
@ -437,6 +446,9 @@ void Node2D::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_z_as_relative", "enable"), &Node2D::set_z_as_relative);
|
||||
ClassDB::bind_method(D_METHOD("is_z_relative"), &Node2D::is_z_relative);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_y_sort_enabled", "enabled"), &Node2D::set_y_sort_enabled);
|
||||
ClassDB::bind_method(D_METHOD("is_y_sort_enabled"), &Node2D::is_y_sort_enabled);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_relative_transform_to_parent", "parent"), &Node2D::get_relative_transform_to_parent);
|
||||
|
||||
ADD_GROUP("Transform", "");
|
||||
@ -454,7 +466,8 @@ void Node2D::_bind_methods() {
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "global_scale", PROPERTY_HINT_NONE, "", 0), "set_global_scale", "get_global_scale");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "global_transform", PROPERTY_HINT_NONE, "", 0), "set_global_transform", "get_global_transform");
|
||||
|
||||
ADD_GROUP("Z Index", "");
|
||||
ADD_GROUP("Ordering", "");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "z_index", PROPERTY_HINT_RANGE, itos(RS::CANVAS_ITEM_Z_MIN) + "," + itos(RS::CANVAS_ITEM_Z_MAX) + ",1"), "set_z_index", "get_z_index");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "z_as_relative"), "set_z_as_relative", "is_z_relative");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "y_sort_enabled"), "set_y_sort_enabled", "is_y_sort_enabled");
|
||||
}
|
||||
|
@ -42,6 +42,7 @@ class Node2D : public CanvasItem {
|
||||
real_t skew = 0.0;
|
||||
int z_index = 0;
|
||||
bool z_relative = true;
|
||||
bool y_sort_enabled = false;
|
||||
|
||||
Transform2D _mat;
|
||||
|
||||
@ -117,6 +118,9 @@ public:
|
||||
void set_z_as_relative(bool p_enabled);
|
||||
bool is_z_relative() const;
|
||||
|
||||
virtual void set_y_sort_enabled(bool p_enabled);
|
||||
virtual bool is_y_sort_enabled() const;
|
||||
|
||||
Transform2D get_relative_transform_to_parent(const Node *p_parent) const;
|
||||
|
||||
Transform2D get_transform() const override;
|
||||
|
@ -334,6 +334,12 @@ TileMap::VisibilityMode TileMap::get_navigation_visibility_mode() {
|
||||
return show_navigation;
|
||||
}
|
||||
|
||||
void TileMap::set_y_sort_enabled(bool p_enable) {
|
||||
Node2D::set_y_sort_enabled(p_enable);
|
||||
_recreate_quadrants();
|
||||
emit_signal("changed");
|
||||
}
|
||||
|
||||
void TileMap::update_dirty_quadrants() {
|
||||
if (!pending_update) {
|
||||
return;
|
||||
|
@ -279,6 +279,7 @@ public:
|
||||
int get_effective_quadrant_size() const;
|
||||
|
||||
void update_dirty_quadrants();
|
||||
virtual void set_y_sort_enabled(bool p_enable) override;
|
||||
|
||||
Vector2 map_to_world(const Vector2i &p_pos) const;
|
||||
Vector2i world_to_map(const Vector2 &p_pos) const;
|
||||
|
@ -1,52 +0,0 @@
|
||||
/*************************************************************************/
|
||||
/* y_sort.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "y_sort.h"
|
||||
|
||||
void YSort::set_sort_enabled(bool p_enabled) {
|
||||
sort_enabled = p_enabled;
|
||||
RS::get_singleton()->canvas_item_set_sort_children_by_y(get_canvas_item(), sort_enabled);
|
||||
}
|
||||
|
||||
bool YSort::is_sort_enabled() const {
|
||||
return sort_enabled;
|
||||
}
|
||||
|
||||
void YSort::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_sort_enabled", "enabled"), &YSort::set_sort_enabled);
|
||||
ClassDB::bind_method(D_METHOD("is_sort_enabled"), &YSort::is_sort_enabled);
|
||||
|
||||
ADD_GROUP("Sort", "sort_");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sort_enabled"), "set_sort_enabled", "is_sort_enabled");
|
||||
}
|
||||
|
||||
YSort::YSort() {
|
||||
RS::get_singleton()->canvas_item_set_sort_children_by_y(get_canvas_item(), true);
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
/*************************************************************************/
|
||||
/* y_sort.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#ifndef Y_SORT_H
|
||||
#define Y_SORT_H
|
||||
|
||||
#include "scene/2d/node_2d.h"
|
||||
|
||||
class YSort : public Node2D {
|
||||
GDCLASS(YSort, Node2D);
|
||||
bool sort_enabled = true;
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
void set_sort_enabled(bool p_enabled);
|
||||
bool is_sort_enabled() const;
|
||||
YSort();
|
||||
};
|
||||
|
||||
#endif // Y_SORT_H
|
@ -65,7 +65,6 @@
|
||||
#include "scene/2d/tile_map.h"
|
||||
#include "scene/2d/touch_screen_button.h"
|
||||
#include "scene/2d/visibility_notifier_2d.h"
|
||||
#include "scene/2d/y_sort.h"
|
||||
#include "scene/animation/animation_blend_space_1d.h"
|
||||
#include "scene/animation/animation_blend_space_2d.h"
|
||||
#include "scene/animation/animation_blend_tree.h"
|
||||
@ -643,7 +642,6 @@ void register_scene_types() {
|
||||
ClassDB::register_class<DirectionalLight2D>();
|
||||
ClassDB::register_class<LightOccluder2D>();
|
||||
ClassDB::register_class<OccluderPolygon2D>();
|
||||
ClassDB::register_class<YSort>();
|
||||
ClassDB::register_class<BackBufferCopy>();
|
||||
|
||||
OS::get_singleton()->yield(); //may take time to init
|
||||
@ -820,6 +818,7 @@ void register_scene_types() {
|
||||
ClassDB::add_compatibility_class("ToolButton", "Button");
|
||||
ClassDB::add_compatibility_class("Navigation3D", "Node3D");
|
||||
ClassDB::add_compatibility_class("Navigation2D", "Node2D");
|
||||
ClassDB::add_compatibility_class("YSort", "Node2D");
|
||||
|
||||
// Renamed in 4.0.
|
||||
// Keep alphabetical ordering to easily locate classes and avoid duplicates.
|
||||
|
@ -3870,8 +3870,8 @@ void TileSetPluginAtlasRendering::tilemap_notification(TileMap *p_tile_map, int
|
||||
} break;
|
||||
case CanvasItem::NOTIFICATION_DRAW: {
|
||||
Ref<TileSet> tile_set = p_tile_map->get_tileset();
|
||||
if (tile_set.is_valid()) {
|
||||
RenderingServer::get_singleton()->canvas_item_set_sort_children_by_y(p_tile_map->get_canvas_item(), tile_set->is_y_sorting());
|
||||
if (tile_set.is_valid() || p_tile_map->is_y_sort_enabled()) {
|
||||
RenderingServer::get_singleton()->canvas_item_set_sort_children_by_y(p_tile_map->get_canvas_item(), tile_set->is_y_sorting() || p_tile_map->is_y_sort_enabled());
|
||||
}
|
||||
} break;
|
||||
}
|
||||
|
@ -44,10 +44,10 @@ void RendererCanvasCull::_render_canvas_item_tree(RID p_to_render_target, Canvas
|
||||
memset(z_last_list, 0, z_range * sizeof(RendererCanvasRender::Item *));
|
||||
|
||||
for (int i = 0; i < p_child_item_count; i++) {
|
||||
_cull_canvas_item(p_child_items[i].item, p_transform, p_clip_rect, Color(1, 1, 1, 1), 0, z_list, z_last_list, nullptr, nullptr);
|
||||
_cull_canvas_item(p_child_items[i].item, p_transform, p_clip_rect, Color(1, 1, 1, 1), 0, z_list, z_last_list, nullptr, nullptr, true);
|
||||
}
|
||||
if (p_canvas_item) {
|
||||
_cull_canvas_item(p_canvas_item, p_transform, p_clip_rect, Color(1, 1, 1, 1), 0, z_list, z_last_list, nullptr, nullptr);
|
||||
_cull_canvas_item(p_canvas_item, p_transform, p_clip_rect, Color(1, 1, 1, 1), 0, z_list, z_last_list, nullptr, nullptr, true);
|
||||
}
|
||||
|
||||
RendererCanvasRender::Item *list = nullptr;
|
||||
@ -104,98 +104,7 @@ void _mark_ysort_dirty(RendererCanvasCull::Item *ysort_owner, RID_PtrOwner<Rende
|
||||
} while (ysort_owner && ysort_owner->sort_y);
|
||||
}
|
||||
|
||||
void RendererCanvasCull::_cull_canvas_item(Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, int p_z, RendererCanvasRender::Item **z_list, RendererCanvasRender::Item **z_last_list, Item *p_canvas_clip, Item *p_material_owner) {
|
||||
Item *ci = p_canvas_item;
|
||||
|
||||
if (!ci->visible) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ci->children_order_dirty) {
|
||||
ci->child_items.sort_custom<ItemIndexSort>();
|
||||
ci->children_order_dirty = false;
|
||||
}
|
||||
|
||||
Rect2 rect = ci->get_rect();
|
||||
Transform2D xform = ci->xform;
|
||||
if (snapping_2d_transforms_to_pixel) {
|
||||
xform.elements[2] = xform.elements[2].floor();
|
||||
}
|
||||
xform = p_transform * xform;
|
||||
|
||||
Rect2 global_rect = xform.xform(rect);
|
||||
global_rect.position += p_clip_rect.position;
|
||||
|
||||
if (ci->use_parent_material && p_material_owner) {
|
||||
ci->material_owner = p_material_owner;
|
||||
} else {
|
||||
p_material_owner = ci;
|
||||
ci->material_owner = nullptr;
|
||||
}
|
||||
|
||||
Color modulate(ci->modulate.r * p_modulate.r, ci->modulate.g * p_modulate.g, ci->modulate.b * p_modulate.b, ci->modulate.a * p_modulate.a);
|
||||
|
||||
if (modulate.a < 0.007) {
|
||||
return;
|
||||
}
|
||||
|
||||
int child_item_count = ci->child_items.size();
|
||||
Item **child_items = ci->child_items.ptrw();
|
||||
|
||||
if (ci->clip) {
|
||||
if (p_canvas_clip != nullptr) {
|
||||
ci->final_clip_rect = p_canvas_clip->final_clip_rect.intersection(global_rect);
|
||||
} else {
|
||||
ci->final_clip_rect = global_rect;
|
||||
}
|
||||
ci->final_clip_rect.position = ci->final_clip_rect.position.round();
|
||||
ci->final_clip_rect.size = ci->final_clip_rect.size.round();
|
||||
ci->final_clip_owner = ci;
|
||||
|
||||
} else {
|
||||
ci->final_clip_owner = p_canvas_clip;
|
||||
}
|
||||
|
||||
if (ci->sort_y) {
|
||||
if (ci->ysort_children_count == -1) {
|
||||
ci->ysort_children_count = 0;
|
||||
_collect_ysort_children(ci, Transform2D(), p_material_owner, nullptr, ci->ysort_children_count);
|
||||
}
|
||||
|
||||
child_item_count = ci->ysort_children_count;
|
||||
child_items = (Item **)alloca(child_item_count * sizeof(Item *));
|
||||
|
||||
int i = 0;
|
||||
_collect_ysort_children(ci, Transform2D(), p_material_owner, child_items, i);
|
||||
|
||||
SortArray<Item *, ItemPtrSort> sorter;
|
||||
sorter.sort(child_items, child_item_count);
|
||||
}
|
||||
|
||||
if (ci->z_relative) {
|
||||
p_z = CLAMP(p_z + ci->z_index, RS::CANVAS_ITEM_Z_MIN, RS::CANVAS_ITEM_Z_MAX);
|
||||
} else {
|
||||
p_z = ci->z_index;
|
||||
}
|
||||
|
||||
RendererCanvasRender::Item *canvas_group_from = nullptr;
|
||||
bool use_canvas_group = ci->canvas_group != nullptr && (ci->canvas_group->fit_empty || ci->commands != nullptr);
|
||||
if (use_canvas_group) {
|
||||
int zidx = p_z - RS::CANVAS_ITEM_Z_MIN;
|
||||
canvas_group_from = z_last_list[zidx];
|
||||
}
|
||||
|
||||
for (int i = 0; i < child_item_count; i++) {
|
||||
if ((!child_items[i]->behind && !use_canvas_group) || (ci->sort_y && child_items[i]->sort_y)) {
|
||||
continue;
|
||||
}
|
||||
if (ci->sort_y) {
|
||||
_cull_canvas_item(child_items[i], xform * child_items[i]->ysort_xform, p_clip_rect, modulate, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, (Item *)child_items[i]->material_owner);
|
||||
} else {
|
||||
_cull_canvas_item(child_items[i], xform, p_clip_rect, modulate, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, p_material_owner);
|
||||
}
|
||||
}
|
||||
|
||||
void _attach_canvas_item_for_draw(RendererCanvasCull::Item *ci, RendererCanvasCull::Item *p_canvas_clip, RendererCanvasRender::Item **z_list, RendererCanvasRender::Item **z_last_list, const Transform2D &xform, const Rect2 &p_clip_rect, Rect2 global_rect, const Color &modulate, int p_z, RendererCanvasCull::Item *p_material_owner, bool use_canvas_group, RendererCanvasRender::Item *canvas_group_from) {
|
||||
if (ci->copy_back_buffer) {
|
||||
ci->copy_back_buffer->screen_rect = xform.xform(ci->copy_back_buffer->rect).intersection(p_clip_rect);
|
||||
}
|
||||
@ -229,7 +138,7 @@ void RendererCanvasCull::_cull_canvas_item(Item *p_canvas_item, const Transform2
|
||||
// We have two choices now, if user has drawn something, we must assume users wants to draw the "mask", so compute the size based on this.
|
||||
// If nothing has been drawn, we just take it over and draw it ourselves.
|
||||
if (ci->canvas_group->fit_empty && (ci->commands == nullptr ||
|
||||
(ci->commands->next == nullptr && ci->commands->type == Item::Command::TYPE_RECT && (static_cast<Item::CommandRect *>(ci->commands)->flags & RendererCanvasRender::CANVAS_RECT_IS_GROUP)))) {
|
||||
(ci->commands->next == nullptr && ci->commands->type == RendererCanvasCull::Item::Command::TYPE_RECT && (static_cast<RendererCanvasCull::Item::CommandRect *>(ci->commands)->flags & RendererCanvasRender::CANVAS_RECT_IS_GROUP)))) {
|
||||
// No commands, or sole command is the one used to draw, so we (re)create the draw command.
|
||||
ci->clear();
|
||||
|
||||
@ -291,15 +200,117 @@ void RendererCanvasCull::_cull_canvas_item(Item *p_canvas_item, const Transform2
|
||||
|
||||
ci->next = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < child_item_count; i++) {
|
||||
if (child_items[i]->behind || use_canvas_group || (ci->sort_y && child_items[i]->sort_y)) {
|
||||
continue;
|
||||
}
|
||||
if (ci->sort_y) {
|
||||
_cull_canvas_item(child_items[i], xform * child_items[i]->ysort_xform, p_clip_rect, modulate, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, (Item *)child_items[i]->material_owner);
|
||||
void RendererCanvasCull::_cull_canvas_item(Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, int p_z, RendererCanvasRender::Item **z_list, RendererCanvasRender::Item **z_last_list, Item *p_canvas_clip, Item *p_material_owner, bool allow_y_sort) {
|
||||
Item *ci = p_canvas_item;
|
||||
|
||||
if (!ci->visible) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ci->children_order_dirty) {
|
||||
ci->child_items.sort_custom<ItemIndexSort>();
|
||||
ci->children_order_dirty = false;
|
||||
}
|
||||
|
||||
Rect2 rect = ci->get_rect();
|
||||
Transform2D xform = ci->xform;
|
||||
if (snapping_2d_transforms_to_pixel) {
|
||||
xform.elements[2] = xform.elements[2].floor();
|
||||
}
|
||||
xform = p_transform * xform;
|
||||
|
||||
Rect2 global_rect = xform.xform(rect);
|
||||
global_rect.position += p_clip_rect.position;
|
||||
|
||||
if (ci->use_parent_material && p_material_owner) {
|
||||
ci->material_owner = p_material_owner;
|
||||
} else {
|
||||
p_material_owner = ci;
|
||||
ci->material_owner = nullptr;
|
||||
}
|
||||
|
||||
Color modulate(ci->modulate.r * p_modulate.r, ci->modulate.g * p_modulate.g, ci->modulate.b * p_modulate.b, ci->modulate.a * p_modulate.a);
|
||||
|
||||
if (modulate.a < 0.007) {
|
||||
return;
|
||||
}
|
||||
|
||||
int child_item_count = ci->child_items.size();
|
||||
Item **child_items = ci->child_items.ptrw();
|
||||
|
||||
if (ci->clip) {
|
||||
if (p_canvas_clip != nullptr) {
|
||||
ci->final_clip_rect = p_canvas_clip->final_clip_rect.intersection(global_rect);
|
||||
} else {
|
||||
_cull_canvas_item(child_items[i], xform, p_clip_rect, modulate, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, p_material_owner);
|
||||
ci->final_clip_rect = global_rect;
|
||||
}
|
||||
ci->final_clip_rect.position = ci->final_clip_rect.position.round();
|
||||
ci->final_clip_rect.size = ci->final_clip_rect.size.round();
|
||||
ci->final_clip_owner = ci;
|
||||
|
||||
} else {
|
||||
ci->final_clip_owner = p_canvas_clip;
|
||||
}
|
||||
|
||||
if (ci->z_relative) {
|
||||
p_z = CLAMP(p_z + ci->z_index, RS::CANVAS_ITEM_Z_MIN, RS::CANVAS_ITEM_Z_MAX);
|
||||
} else {
|
||||
p_z = ci->z_index;
|
||||
}
|
||||
|
||||
if (ci->sort_y) {
|
||||
if (allow_y_sort) {
|
||||
if (ci->ysort_children_count == -1) {
|
||||
ci->ysort_children_count = 0;
|
||||
_collect_ysort_children(ci, Transform2D(), p_material_owner, nullptr, ci->ysort_children_count);
|
||||
}
|
||||
|
||||
child_item_count = ci->ysort_children_count + 1;
|
||||
child_items = (Item **)alloca(child_item_count * sizeof(Item *));
|
||||
|
||||
child_items[0] = ci;
|
||||
int i = 1;
|
||||
_collect_ysort_children(ci, Transform2D(), p_material_owner, child_items, i);
|
||||
ci->ysort_xform = ci->xform.affine_inverse();
|
||||
|
||||
SortArray<Item *, ItemPtrSort> sorter;
|
||||
sorter.sort(child_items, child_item_count);
|
||||
|
||||
for (i = 0; i < child_item_count; i++) {
|
||||
_cull_canvas_item(child_items[i], xform * child_items[i]->ysort_xform, p_clip_rect, modulate, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, (Item *)child_items[i]->material_owner, false);
|
||||
}
|
||||
} else {
|
||||
RendererCanvasRender::Item *canvas_group_from = nullptr;
|
||||
bool use_canvas_group = ci->canvas_group != nullptr && (ci->canvas_group->fit_empty || ci->commands != nullptr);
|
||||
if (use_canvas_group) {
|
||||
int zidx = p_z - RS::CANVAS_ITEM_Z_MIN;
|
||||
canvas_group_from = z_last_list[zidx];
|
||||
}
|
||||
|
||||
_attach_canvas_item_for_draw(ci, p_canvas_clip, z_list, z_last_list, xform, p_clip_rect, global_rect, modulate, p_z, p_material_owner, use_canvas_group, canvas_group_from);
|
||||
}
|
||||
} else {
|
||||
RendererCanvasRender::Item *canvas_group_from = nullptr;
|
||||
bool use_canvas_group = ci->canvas_group != nullptr && (ci->canvas_group->fit_empty || ci->commands != nullptr);
|
||||
if (use_canvas_group) {
|
||||
int zidx = p_z - RS::CANVAS_ITEM_Z_MIN;
|
||||
canvas_group_from = z_last_list[zidx];
|
||||
}
|
||||
|
||||
for (int i = 0; i < child_item_count; i++) {
|
||||
if (!child_items[i]->behind && !use_canvas_group) {
|
||||
continue;
|
||||
}
|
||||
_cull_canvas_item(child_items[i], xform, p_clip_rect, modulate, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, p_material_owner, true);
|
||||
}
|
||||
_attach_canvas_item_for_draw(ci, p_canvas_clip, z_list, z_last_list, xform, p_clip_rect, global_rect, modulate, p_z, p_material_owner, use_canvas_group, canvas_group_from);
|
||||
for (int i = 0; i < child_item_count; i++) {
|
||||
if (child_items[i]->behind || use_canvas_group) {
|
||||
continue;
|
||||
}
|
||||
_cull_canvas_item(child_items[i], xform, p_clip_rect, modulate, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, p_material_owner, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -158,7 +158,7 @@ public:
|
||||
|
||||
private:
|
||||
void _render_canvas_item_tree(RID p_to_render_target, Canvas::ChildItem *p_child_items, int p_child_item_count, Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, RendererCanvasRender::Light *p_lights, RendererCanvasRender::Light *p_directional_lights, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel);
|
||||
void _cull_canvas_item(Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, int p_z, RendererCanvasRender::Item **z_list, RendererCanvasRender::Item **z_last_list, Item *p_canvas_clip, Item *p_material_owner);
|
||||
void _cull_canvas_item(Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, int p_z, RendererCanvasRender::Item **z_list, RendererCanvasRender::Item **z_last_list, Item *p_canvas_clip, Item *p_material_owner, bool allow_y_sort);
|
||||
|
||||
RendererCanvasRender::Item **z_list;
|
||||
RendererCanvasRender::Item **z_last_list;
|
||||
|
Loading…
Reference in New Issue
Block a user