瀏覽代碼

Fix empty region in AtlasTexture

kobewi 1 年之前
父節點
當前提交
10da06a32c
共有 3 個文件被更改,包括 30 次插入22 次删除
  1. 1 1
      doc/classes/AtlasTexture.xml
  2. 27 21
      scene/resources/atlas_texture.cpp
  3. 2 0
      scene/resources/atlas_texture.h

+ 1 - 1
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.
 		</member>
 		<member name="region" type="Rect2" setter="set_region" getter="get_region" default="Rect2(0, 0, 0, 0)">
-			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.
 		</member>
 		<member name="resource_local_to_scene" type="bool" setter="set_local_to_scene" getter="is_local_to_scene" overrides="Resource" default="false" />
 	</members>

+ 27 - 21
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<Image> AtlasTexture::get_image() const {
-	if (atlas.is_null() || region.size.x <= 0 || region.size.y <= 0) {
+	if (atlas.is_null()) {
 		return Ref<Image>();
 	}
 
-	Ref<Image> atlas_image = atlas->get_image();
+	const Ref<Image> &atlas_image = atlas->get_image();
 	if (atlas_image.is_null()) {
 		return Ref<Image>();
 	}
 
-	return atlas_image->get_region(region);
+	return atlas_image->get_region(_get_region_rect());
 }
 
 AtlasTexture::AtlasTexture() {}

+ 2 - 0
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<Texture2D> atlas;
 	Rect2 region;