Browse Source

Fix AtlasTexture + Sprite3D using the wrong UV region

- Change get_rect_region to return UV region instead of pixel rect
- Fixed atlas texture Sprite3D Y offsets being applied in the wrong direction and fixed Flip not adjusting the geometry.
- Changed get_rect_region name to get_rect_region_uv_rect
elasota 8 years ago
parent
commit
91140904cc
3 changed files with 46 additions and 28 deletions
  1. 30 22
      scene/3d/sprite_3d.cpp
  2. 14 4
      scene/resources/texture.cpp
  3. 2 2
      scene/resources/texture.h

+ 30 - 22
scene/3d/sprite_3d.cpp

@@ -347,8 +347,8 @@ void Sprite3D::_draw() {
 	Rect2i dst_rect(ofs, s);
 
 	Rect2 final_rect;
-	Rect2 final_src_rect;
-	if (!texture->get_rect_region(dst_rect, src_rect, final_rect, final_src_rect))
+	Rect2 final_uv_rect;
+	if (!texture->get_rect_region_uv_rect(dst_rect, src_rect, final_rect, final_uv_rect))
 		return;
 
 	if (final_rect.size.x == 0 || final_rect.size.y == 0)
@@ -368,10 +368,10 @@ void Sprite3D::_draw() {
 
 	};
 	Vector2 uvs[4] = {
-		final_src_rect.pos / tsize,
-		(final_src_rect.pos + Vector2(final_src_rect.size.x, 0)) / tsize,
-		(final_src_rect.pos + final_src_rect.size) / tsize,
-		(final_src_rect.pos + Vector2(0, final_src_rect.size.y)) / tsize,
+		final_uv_rect.pos,
+		final_uv_rect.pos + Vector2(final_uv_rect.size.x, 0),
+		final_uv_rect.pos + final_uv_rect.size,
+		final_uv_rect.pos + Vector2(0, final_uv_rect.size.y),
 	};
 
 	if (is_flipped_h()) {
@@ -629,7 +629,7 @@ void AnimatedSprite3D::_draw() {
 
 	Rect2 final_rect;
 	Rect2 final_src_rect;
-	if (!texture->get_rect_region(dst_rect,src_rect,final_rect,final_src_rect))
+	if (!texture->get_rect_region_uv_rect(dst_rect,src_rect,final_rect, final_uv_rect))
 		return;
 
 
@@ -651,10 +651,10 @@ void AnimatedSprite3D::_draw() {
 
 	};
 	Vector2 uvs[4]={
-		final_src_rect.pos / tsize,
-		(final_src_rect.pos+Vector2(final_src_rect.size.x,0)) / tsize,
-		(final_src_rect.pos+final_src_rect.size) / tsize,
-		(final_src_rect.pos+Vector2(0,final_src_rect.size.y)) / tsize,
+		final_src_rect.pos,
+		final_src_rect.pos+Vector2(final_src_rect.size.x,0),
+		final_src_rect.pos+final_src_rect.size,
+		final_src_rect.pos+Vector2(0,final_src_rect.size.y),
 	};
 
 	if (is_flipped_h()) {
@@ -839,20 +839,28 @@ void AnimatedSprite3D::_draw() {
 
 	src_rect.size = s;
 
-	Point2i ofs = get_offset();
-	if (is_centered())
-		ofs -= s / 2;
-
-	Rect2i dst_rect(ofs, s);
+	Rect2i dst_rect(0, 0, s.width, s.height);
 
 	Rect2 final_rect;
-	Rect2 final_src_rect;
-	if (!texture->get_rect_region(dst_rect, src_rect, final_rect, final_src_rect))
+	Rect2 final_uv_rect;
+	if (!texture->get_rect_region_uv_rect(dst_rect, src_rect, final_rect, final_uv_rect))
 		return;
 
 	if (final_rect.size.x == 0 || final_rect.size.y == 0)
 		return;
 
+	if (is_flipped_h())
+		final_rect.pos.x = dst_rect.size.x - final_rect.pos.x - final_rect.size.x;
+
+	if (!is_flipped_v())
+		final_rect.pos.y = dst_rect.size.y - final_rect.pos.y - final_rect.size.y;
+
+	Point2i ofs = get_offset();
+	if (is_centered())
+		ofs -= s / 2;
+
+	final_rect.pos += ofs;
+
 	Color color = _get_color_accum();
 	color.a *= get_opacity();
 
@@ -867,10 +875,10 @@ void AnimatedSprite3D::_draw() {
 
 	};
 	Vector2 uvs[4] = {
-		final_src_rect.pos / tsize,
-		(final_src_rect.pos + Vector2(final_src_rect.size.x, 0)) / tsize,
-		(final_src_rect.pos + final_src_rect.size) / tsize,
-		(final_src_rect.pos + Vector2(0, final_src_rect.size.y)) / tsize,
+		final_uv_rect.pos,
+		final_uv_rect.pos + Vector2(final_uv_rect.size.x, 0),
+		final_uv_rect.pos + final_uv_rect.size,
+		final_uv_rect.pos + Vector2(0, final_uv_rect.size.y),
 	};
 
 	if (is_flipped_h()) {

+ 14 - 4
scene/resources/texture.cpp

@@ -49,10 +49,15 @@ void Texture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rec
 	VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, p_rect, get_rid(), p_src_rect, p_modulate, p_transpose);
 }
 
-bool Texture::get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const {
+bool Texture::get_rect_region_uv_rect(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_uv_rect) const {
+
+	Size2 size = get_size();
+
+	if (size.width == 0 || size.height == 0)
+		return false;
 
 	r_rect = p_rect;
-	r_src_rect = p_src_rect;
+	r_uv_rect = Rect2(p_src_rect.get_pos() / size, p_src_rect.get_size() / size);
 
 	return true;
 }
@@ -598,13 +603,18 @@ void AtlasTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, cons
 	VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, dr, atlas->get_rid(), src_c, p_modulate, p_transpose);
 }
 
-bool AtlasTexture::get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const {
+bool AtlasTexture::get_rect_region_uv_rect(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_uv_rect) const {
 
 	Rect2 rc = region;
 
 	if (!atlas.is_valid())
 		return false;
 
+	Size2 atlas_size = atlas->get_size();
+
+	if (atlas_size.width == 0 || atlas_size.height == 0)
+		return false;
+
 	Rect2 src = p_src_rect;
 	src.pos += (rc.pos - margin.pos);
 	Rect2 src_c = rc.clip(src);
@@ -626,7 +636,7 @@ bool AtlasTexture::get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect,
 	Rect2 dr(p_rect.pos + ofs * scale, src_c.size * scale);
 
 	r_rect = dr;
-	r_src_rect = src_c;
+	r_uv_rect = Rect2(src_c.get_pos() / atlas_size, src_c.get_size() / atlas_size);
 	return true;
 }
 

+ 2 - 2
scene/resources/texture.h

@@ -70,7 +70,7 @@ public:
 	virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false) const;
 	virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false) const;
 	virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false) const;
-	virtual bool get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const;
+	virtual bool get_rect_region_uv_rect(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_uv_rect) const;
 
 	Texture();
 };
@@ -186,7 +186,7 @@ public:
 	virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false) const;
 	virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false) const;
 	virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false) const;
-	virtual bool get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const;
+	virtual bool get_rect_region_uv_rect(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_uv_rect) const;
 
 	AtlasTexture();
 };