1
0
Fork 0
mirror of https://github.com/Orama-Interactive/Pixelorama.git synced 2025-01-18 17:19:50 +00:00

Implement perspective guide snapping

This commit is contained in:
Emmanouil Papadeas 2023-02-12 21:32:35 +02:00
parent 7f026aa371
commit 6f6ff98923
3 changed files with 42 additions and 13 deletions

View file

@ -143,6 +143,7 @@ var show_mouse_guides := false
var snapping_distance := 10.0
var snap_to_rectangular_grid := false
var snap_to_guides := false
var snap_to_perspective_guides := false
# Onion skinning options
var onion_skinning := false

View file

@ -132,24 +132,32 @@ func snap_position(position: Vector2) -> Vector2:
if closest_point_grid != Vector2.INF:
position = closest_point_grid.floor()
var snap_to := Vector2.INF
if Global.snap_to_guides:
var snap_to := Vector2.INF
for guide in Global.current_project.guides:
if guide is SymmetryGuide:
continue
var closest_point := _get_closest_point_to_segment(
position, snap_distance, guide.points[0], guide.points[1]
)
if closest_point == Vector2.INF: # Is not close to a guide
var s1: Vector2 = guide.points[0]
var s2: Vector2 = guide.points[1]
var snap := _snap_to_guide(snap_to, position, snap_distance, s1, s2)
if snap == Vector2.INF:
continue
# Snap to the closest guide
if (
snap_to == Vector2.INF
or (snap_to - position).length() > (closest_point - position).length()
):
snap_to = closest_point
if snap_to != Vector2.INF:
position = snap_to.floor()
snap_to = snap
if Global.snap_to_perspective_guides:
for point in Global.current_project.vanishing_points:
for i in point.angles.size():
var angle: float = -deg2rad(point.angles[i])
var length: float = point.lengths[i]
var s1 := Vector2(point.position_x, point.position_y)
var s2 := s1 + Vector2(length * cos(angle), length * sin(angle))
var snap := _snap_to_guide(snap_to, position, snap_distance, s1, s2)
if snap == Vector2.INF:
continue
snap_to = snap
if snap_to != Vector2.INF:
position = snap_to.floor()
return position
@ -198,6 +206,22 @@ func _get_closest_point_to_segment(
return closest_point
func _snap_to_guide(
snap_to: Vector2, position: Vector2, distance: Vector2, s1: Vector2, s2: Vector2
) -> Vector2:
var closest_point := _get_closest_point_to_segment(position, distance, s1, s2)
if closest_point == Vector2.INF: # Is not close to a guide
return Vector2.INF
# Snap to the closest guide
if (
snap_to == Vector2.INF
or (snap_to - position).length() > (closest_point - position).length()
):
snap_to = closest_point
return snap_to
func _get_draw_rect() -> Rect2:
if Global.current_project.has_selection:
return Global.current_project.selection_map.get_used_rect()

View file

@ -188,6 +188,7 @@ func _setup_snap_to_submenu(item: String) -> void:
snap_to_submenu.set_name("snap_to_submenu")
snap_to_submenu.add_check_item("Snap to Rectangular Grid")
snap_to_submenu.add_check_item("Snap to Guides")
snap_to_submenu.add_check_item("Snap to Perspective Guides")
snap_to_submenu.connect("id_pressed", self, "_snap_to_submenu_id_pressed")
view_menu.add_child(snap_to_submenu)
view_menu.add_submenu_item(item, snap_to_submenu.get_name())
@ -491,6 +492,9 @@ func _snap_to_submenu_id_pressed(id: int) -> void:
elif id == 1:
Global.snap_to_guides = !Global.snap_to_guides
snap_to_submenu.set_item_checked(id, Global.snap_to_guides)
elif id == 2:
Global.snap_to_perspective_guides = !Global.snap_to_perspective_guides
snap_to_submenu.set_item_checked(id, Global.snap_to_perspective_guides)
func window_menu_id_pressed(id: int) -> void: