mirror of
				https://github.com/godotengine/godot.git
				synced 2025-10-31 13:41:03 +00:00 
			
		
		
		
	Merge pull request #23407 from bojidar-bg/3281-ysort-recursive
Y-Sort children together in nested YSorts
This commit is contained in:
		
						commit
						8e4837f357
					
				
					 2 changed files with 62 additions and 12 deletions
				
			
		|  | @ -51,6 +51,23 @@ void VisualServerCanvas::_render_canvas_item_tree(Item *p_canvas_item, const Tra | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| void _collect_ysort_children(VisualServerCanvas::Item *p_canvas_item, Transform2D p_transform, VisualServerCanvas::Item **r_items, Transform2D *r_extra_transforms, int &r_index) { | ||||
| 	int child_item_count = p_canvas_item->child_items.size(); | ||||
| 	VisualServerCanvas::Item **child_items = p_canvas_item->child_items.ptrw(); | ||||
| 	for (int i = 0; i < child_item_count; i++) { | ||||
| 		if (r_items) { | ||||
| 			r_items[r_index] = child_items[i]; | ||||
| 			child_items[i]->ysort_xform = p_transform; | ||||
| 			child_items[i]->ysort_pos = p_transform.xform(child_items[i]->xform.elements[2]); | ||||
| 		} | ||||
| 
 | ||||
| 		r_index++; | ||||
| 
 | ||||
| 		if (child_items[i]->sort_y) | ||||
| 			_collect_ysort_children(child_items[i], p_transform * child_items[i]->xform, r_items, r_extra_transforms, r_index); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void VisualServerCanvas::_render_canvas_item(Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, int p_z, RasterizerCanvas::Item **z_list, RasterizerCanvas::Item **z_last_list, Item *p_canvas_clip, Item *p_material_owner) { | ||||
| 
 | ||||
| 	Item *ci = p_canvas_item; | ||||
|  | @ -58,10 +75,10 @@ void VisualServerCanvas::_render_canvas_item(Item *p_canvas_item, const Transfor | |||
| 	if (!ci->visible) | ||||
| 		return; | ||||
| 
 | ||||
| 	if (p_canvas_item->children_order_dirty) { | ||||
| 	if (ci->children_order_dirty) { | ||||
| 
 | ||||
| 		p_canvas_item->child_items.sort_custom<ItemIndexSort>(); | ||||
| 		p_canvas_item->children_order_dirty = false; | ||||
| 		ci->child_items.sort_custom<ItemIndexSort>(); | ||||
| 		ci->children_order_dirty = false; | ||||
| 	} | ||||
| 
 | ||||
| 	Rect2 rect = ci->get_rect(); | ||||
|  | @ -82,8 +99,8 @@ void VisualServerCanvas::_render_canvas_item(Item *p_canvas_item, const Transfor | |||
| 		return; | ||||
| 
 | ||||
| 	int child_item_count = ci->child_items.size(); | ||||
| 	Item **child_items = (Item **)alloca(child_item_count * sizeof(Item *)); | ||||
| 	copymem(child_items, ci->child_items.ptr(), child_item_count * sizeof(Item *)); | ||||
| 	Item **child_items = ci->child_items.ptrw(); | ||||
| 	Transform2D *child_extra_transforms = NULL; | ||||
| 
 | ||||
| 	if (ci->clip) { | ||||
| 		if (p_canvas_clip != NULL) { | ||||
|  | @ -99,6 +116,17 @@ void VisualServerCanvas::_render_canvas_item(Item *p_canvas_item, const Transfor | |||
| 
 | ||||
| 	if (ci->sort_y) { | ||||
| 
 | ||||
| 		if (ci->ysort_children_count == -1) { | ||||
| 			ci->ysort_children_count = 0; | ||||
| 			_collect_ysort_children(ci, Transform2D(), NULL, NULL, 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(), child_items, child_extra_transforms, i); | ||||
| 
 | ||||
| 		SortArray<Item *, ItemPtrSort> sorter; | ||||
| 		sorter.sort(child_items, child_item_count); | ||||
| 	} | ||||
|  | @ -110,9 +138,13 @@ void VisualServerCanvas::_render_canvas_item(Item *p_canvas_item, const Transfor | |||
| 
 | ||||
| 	for (int i = 0; i < child_item_count; i++) { | ||||
| 
 | ||||
| 		if (!child_items[i]->behind) | ||||
| 		if (!child_items[i]->behind || (ci->sort_y && child_items[i]->sort_y)) | ||||
| 			continue; | ||||
| 		_render_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); | ||||
| 		if (ci->sort_y) { | ||||
| 			_render_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, p_material_owner); | ||||
| 		} else { | ||||
| 			_render_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); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if (ci->copy_back_buffer) { | ||||
|  | @ -148,9 +180,13 @@ void VisualServerCanvas::_render_canvas_item(Item *p_canvas_item, const Transfor | |||
| 
 | ||||
| 	for (int i = 0; i < child_item_count; i++) { | ||||
| 
 | ||||
| 		if (child_items[i]->behind) | ||||
| 		if (child_items[i]->behind || (ci->sort_y && child_items[i]->sort_y)) | ||||
| 			continue; | ||||
| 		_render_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); | ||||
| 		if (ci->sort_y) { | ||||
| 			_render_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, p_material_owner); | ||||
| 		} else { | ||||
| 			_render_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); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
|  | @ -300,6 +336,7 @@ void VisualServerCanvas::canvas_item_set_parent(RID p_item, RID p_parent) { | |||
| 
 | ||||
| 			Item *item_owner = canvas_item_owner.get(canvas_item->parent); | ||||
| 			item_owner->child_items.erase(canvas_item); | ||||
| 			item_owner->ysort_children_count = -1; | ||||
| 		} | ||||
| 
 | ||||
| 		canvas_item->parent = RID(); | ||||
|  | @ -319,6 +356,12 @@ void VisualServerCanvas::canvas_item_set_parent(RID p_item, RID p_parent) { | |||
| 			item_owner->child_items.push_back(canvas_item); | ||||
| 			item_owner->children_order_dirty = true; | ||||
| 
 | ||||
| 			Item *ysort_owner = item_owner; | ||||
| 			while (ysort_owner && ysort_owner->sort_y) { | ||||
| 				item_owner->ysort_children_count = -1; | ||||
| 				ysort_owner = canvas_item_owner.getornull(ysort_owner->parent); | ||||
| 			} | ||||
| 
 | ||||
| 		} else { | ||||
| 
 | ||||
| 			ERR_EXPLAIN("Invalid parent"); | ||||
|  | @ -826,6 +869,7 @@ void VisualServerCanvas::canvas_item_set_sort_children_by_y(RID p_item, bool p_e | |||
| 	ERR_FAIL_COND(!canvas_item); | ||||
| 
 | ||||
| 	canvas_item->sort_y = p_enable; | ||||
| 	canvas_item->ysort_children_count = -1; | ||||
| } | ||||
| void VisualServerCanvas::canvas_item_set_z_index(RID p_item, int p_z) { | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Rémi Verschelde
						Rémi Verschelde