Browse Source

Merge pull request #101342 from KoBeWi/roundabout_solution

Round AtlasTexture size
Thaddeus Crews 3 weeks ago
parent
commit
7716a4cba0
3 changed files with 13 additions and 10 deletions
  1. 1 0
      doc/classes/AtlasTexture.xml
  2. 10 9
      scene/resources/atlas_texture.cpp
  3. 2 1
      scene/resources/atlas_texture.h

+ 1 - 0
doc/classes/AtlasTexture.xml

@@ -22,6 +22,7 @@
 		</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]. 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.
+			[b]Note:[/b] The image size is always an integer, so the actual region size is rounded down.
 		</member>
 		<member name="resource_local_to_scene" type="bool" setter="set_local_to_scene" getter="is_local_to_scene" overrides="Resource" default="false" />
 	</members>

+ 10 - 9
scene/resources/atlas_texture.cpp

@@ -31,24 +31,24 @@
 #include "atlas_texture.h"
 
 int AtlasTexture::get_width() const {
-	if (region.size.width == 0) {
+	if (rounded_region.size.width == 0) {
 		if (atlas.is_valid()) {
 			return atlas->get_width();
 		}
 		return 1;
 	} else {
-		return region.size.width + margin.size.width;
+		return rounded_region.size.width + margin.size.width;
 	}
 }
 
 int AtlasTexture::get_height() const {
-	if (region.size.height == 0) {
+	if (rounded_region.size.height == 0) {
 		if (atlas.is_valid()) {
 			return atlas->get_height();
 		}
 		return 1;
 	} else {
-		return region.size.height + margin.size.height;
+		return rounded_region.size.height + margin.size.height;
 	}
 }
 
@@ -94,6 +94,7 @@ void AtlasTexture::set_region(const Rect2 &p_region) {
 		return;
 	}
 	region = p_region;
+	rounded_region = Rect2(p_region.position, p_region.size.floor());
 	emit_changed();
 }
 
@@ -123,7 +124,7 @@ bool AtlasTexture::has_filter_clip() const {
 }
 
 Rect2 AtlasTexture::_get_region_rect() const {
-	Rect2 rc = region;
+	Rect2 rc = rounded_region;
 	if (atlas.is_valid()) {
 		if (rc.size.width == 0) {
 			rc.size.width = atlas->get_width();
@@ -196,14 +197,14 @@ bool AtlasTexture::get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect,
 
 	Rect2 src = p_src_rect;
 	if (src.size == Size2()) {
-		src.size = region.size;
+		src.size = rounded_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);
+	src.position += (rounded_region.position - margin.position);
 	Rect2 src_clipped = _get_region_rect().intersection(src);
 	if (src_clipped.size == Size2()) {
 		return false;
@@ -227,8 +228,8 @@ bool AtlasTexture::is_pixel_opaque(int p_x, int p_y) const {
 		return true;
 	}
 
-	int x = p_x + region.position.x - margin.position.x;
-	int y = p_y + region.position.y - margin.position.y;
+	int x = p_x + rounded_region.position.x - margin.position.x;
+	int y = p_y + rounded_region.position.y - margin.position.y;
 
 	// Margin edge may outside of atlas.
 	if (x < 0 || x >= atlas->get_width()) {

+ 2 - 1
scene/resources/atlas_texture.h

@@ -40,7 +40,8 @@ class AtlasTexture : public Texture2D {
 
 protected:
 	Ref<Texture2D> atlas;
-	Rect2 region;
+	Rect2 region; // Only for property value.
+	Rect2 rounded_region; // Region with rounded size (image size is always integer).
 	Rect2 margin;
 	bool filter_clip = false;