diff --git a/Prefabs/Dialogs/RotateImage.gd b/Prefabs/Dialogs/RotateImage.gd index 7e4dfbba1..0ed90a867 100644 --- a/Prefabs/Dialogs/RotateImage.gd +++ b/Prefabs/Dialogs/RotateImage.gd @@ -9,7 +9,7 @@ func _ready(): texture.flags = 0 aux_img = Image.new() $VBoxContainer/HBoxContainer2/OptionButton.add_item("Rotxel") - pass + $VBoxContainer/HBoxContainer2/OptionButton.add_item("Nearest neighbour") func set_sprite(sprite : Image): aux_img.copy_from(sprite) @@ -19,10 +19,7 @@ func set_sprite(sprite : Image): func _on_HSlider_value_changed(value): - var sprite : Image = Image.new() - sprite.copy_from(aux_img) - Global.rotxel(sprite,value*PI/180) - texture.create_from_image(sprite, 0) + rotate() $VBoxContainer/HBoxContainer/SpinBox.value = $VBoxContainer/HBoxContainer/HSlider.value @@ -35,3 +32,17 @@ func _on_RotateImage_confirmed(): Global.rotxel(layer,$VBoxContainer/HBoxContainer/HSlider.value*PI/180) Global.canvas.handle_redo("Draw") $VBoxContainer/HBoxContainer/HSlider.value = 0 + +func rotate(): + var sprite : Image = Image.new() + sprite.copy_from(aux_img) + match $VBoxContainer/HBoxContainer2/OptionButton.text: + "Rotxel": + Global.rotxel(sprite,$VBoxContainer/HBoxContainer/HSlider.value*PI/180) + "Nearest neighbour": + Global.nn_rotate(sprite,$VBoxContainer/HBoxContainer/HSlider.value*PI/180) + texture.create_from_image(sprite, 0) + + +func _on_OptionButton_item_selected(id): + rotate() diff --git a/Prefabs/Dialogs/RotateImage.tscn b/Prefabs/Dialogs/RotateImage.tscn index 2396d205f..b9ab68f15 100644 --- a/Prefabs/Dialogs/RotateImage.tscn +++ b/Prefabs/Dialogs/RotateImage.tscn @@ -75,5 +75,6 @@ margin_right = 229.0 margin_bottom = 24.0 max_value = 359.0 [connection signal="confirmed" from="." to="." method="_on_RotateImage_confirmed"] +[connection signal="item_selected" from="VBoxContainer/HBoxContainer2/OptionButton" to="." method="_on_OptionButton_item_selected"] [connection signal="value_changed" from="VBoxContainer/HBoxContainer/HSlider" to="." method="_on_HSlider_value_changed"] [connection signal="value_changed" from="VBoxContainer/HBoxContainer/SpinBox" to="." method="_on_SpinBox_value_changed"] diff --git a/Scripts/Global.gd b/Scripts/Global.gd index 1993ce807..4366edd3e 100644 --- a/Scripts/Global.gd +++ b/Scripts/Global.gd @@ -670,6 +670,13 @@ func scale3X(sprite : Image, tol : float = 50) -> Image: return scaled func rotxel(sprite : Image, angle : float): + + # If angle is simple, then nn rotation is the best + + if angle == 0 || angle == PI/2 || angle == PI || angle == 2*PI: + nn_rotate(sprite, angle) + return + var aux : Image = Image.new() aux.copy_from(sprite) var center : Vector2 = Vector2(sprite.get_width()/2, sprite.get_height()/2) @@ -772,7 +779,26 @@ func rotxel(sprite : Image, angle : float): sprite.set_pixel(x, y, p) sprite.unlock() aux.unlock() - + +func nn_rotate(sprite : Image, angle : float): + var aux : Image = Image.new() + aux.copy_from(sprite) + sprite.lock() + aux.lock() + var ox: int + var oy: int + var center : Vector2 = Vector2(sprite.get_width()/2, sprite.get_height()/2) + for x in range(sprite.get_width()): + for y in range(sprite.get_height()): + ox = (x - center.x)*cos(angle) + (y - center.y)*sin(angle) + center.x + oy = -(x - center.x)*sin(angle) + (y - center.y)*cos(angle) + center.y + if ox >= 0 && ox < sprite.get_width() && oy >= 0 && oy < sprite.get_height(): + sprite.set_pixel(x, y, aux.get_pixel(ox, oy)) + else: + sprite.set_pixel(x, y, Color(0,0,0,0)) + sprite.unlock() + aux.unlock() + func similarColors(c1 : Color, c2 : Color, tol : float = 100) -> bool: var dist = colorDistance(c1, c2) return dist <= tol