From 10da06a32c6caae406981a70861b4ee30373e6aa Mon Sep 17 00:00:00 2001 From: kobewi Date: Sun, 14 Jul 2024 23:17:39 +0200 Subject: [PATCH] Fix empty region in AtlasTexture --- doc/classes/AtlasTexture.xml | 2 +- scene/resources/atlas_texture.cpp | 48 +++++++++++++++++-------------- scene/resources/atlas_texture.h | 2 ++ 3 files changed, 30 insertions(+), 22 deletions(-) diff --git a/doc/classes/AtlasTexture.xml b/doc/classes/AtlasTexture.xml index cea8e13f4c5..45877f40035 100644 --- a/doc/classes/AtlasTexture.xml +++ b/doc/classes/AtlasTexture.xml @@ -21,7 +21,7 @@ The margin around the [member region]. Useful for small adjustments. If the [member Rect2.size] of this property ("w" and "h" in the editor) is set, the drawn texture is resized to fit within the margin. - The region used to draw the [member atlas]. + The region used to draw the [member atlas]. If either dimension of the region's size is [code]0[/code], the value from [member atlas] size will be used for that axis instead. diff --git a/scene/resources/atlas_texture.cpp b/scene/resources/atlas_texture.cpp index 28e4186048e..ec0d2ac6fe0 100644 --- a/scene/resources/atlas_texture.cpp +++ b/scene/resources/atlas_texture.cpp @@ -122,6 +122,19 @@ bool AtlasTexture::has_filter_clip() const { return filter_clip; } +Rect2 AtlasTexture::_get_region_rect() const { + Rect2 rc = region; + if (atlas.is_valid()) { + if (rc.size.width == 0) { + rc.size.width = atlas->get_width(); + } + if (rc.size.height == 0) { + rc.size.height = atlas->get_height(); + } + } + return rc; +} + void AtlasTexture::_bind_methods() { ClassDB::bind_method(D_METHOD("set_atlas", "atlas"), &AtlasTexture::set_atlas); ClassDB::bind_method(D_METHOD("get_atlas"), &AtlasTexture::get_atlas); @@ -142,25 +155,15 @@ void AtlasTexture::_bind_methods() { } void AtlasTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose) const { - if (!atlas.is_valid()) { + if (atlas.is_null()) { return; } - - Rect2 rc = region; - - if (rc.size.width == 0) { - rc.size.width = atlas->get_width(); - } - - if (rc.size.height == 0) { - rc.size.height = atlas->get_height(); - } - + const Rect2 rc = _get_region_rect(); atlas->draw_rect_region(p_canvas_item, Rect2(p_pos + margin.position, rc.size), rc, p_modulate, p_transpose, filter_clip); } void AtlasTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose) const { - if (!atlas.is_valid()) { + if (atlas.is_null()) { return; } @@ -174,8 +177,8 @@ void AtlasTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile } void AtlasTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, bool p_clip_uv) const { - //this might not necessarily work well if using a rect, needs to be fixed properly - if (!atlas.is_valid()) { + // This might not necessarily work well if using a rect, needs to be fixed properly. + if (atlas.is_null()) { return; } @@ -195,10 +198,13 @@ bool AtlasTexture::get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, if (src.size == Size2()) { src.size = region.size; } + if (src.size == Size2() && atlas.is_valid()) { + src.size = atlas->get_size(); + } Vector2 scale = p_rect.size / src.size; src.position += (region.position - margin.position); - Rect2 src_clipped = region.intersection(src); + Rect2 src_clipped = _get_region_rect().intersection(src); if (src_clipped.size == Size2()) { return false; } @@ -217,14 +223,14 @@ bool AtlasTexture::get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, } bool AtlasTexture::is_pixel_opaque(int p_x, int p_y) const { - if (!atlas.is_valid()) { + if (atlas.is_null()) { return true; } int x = p_x + region.position.x - margin.position.x; int y = p_y + region.position.y - margin.position.y; - // margin edge may outside of atlas + // Margin edge may outside of atlas. if (x < 0 || x >= atlas->get_width()) { return false; } @@ -236,16 +242,16 @@ bool AtlasTexture::is_pixel_opaque(int p_x, int p_y) const { } Ref AtlasTexture::get_image() const { - if (atlas.is_null() || region.size.x <= 0 || region.size.y <= 0) { + if (atlas.is_null()) { return Ref(); } - Ref atlas_image = atlas->get_image(); + const Ref &atlas_image = atlas->get_image(); if (atlas_image.is_null()) { return Ref(); } - return atlas_image->get_region(region); + return atlas_image->get_region(_get_region_rect()); } AtlasTexture::AtlasTexture() {} diff --git a/scene/resources/atlas_texture.h b/scene/resources/atlas_texture.h index 5aba098d09d..0246a247433 100644 --- a/scene/resources/atlas_texture.h +++ b/scene/resources/atlas_texture.h @@ -37,6 +37,8 @@ class AtlasTexture : public Texture2D { GDCLASS(AtlasTexture, Texture2D); RES_BASE_EXTENSION("atlastex"); + Rect2 _get_region_rect() const; + protected: Ref atlas; Rect2 region;