Files
nodewars/addons/curved_lines_2d/svs_vertex_merge_2d.gd
2026-05-13 18:52:00 +02:00

82 lines
2.7 KiB
GDScript

@tool
extends Node2D
class_name SVSVertexMerge2D
@export var vertex_map : Dictionary[ScalableVectorShape2D, int] = {}:
set = _set_vertex_owners
var _vertex_counts : Dictionary[ScalableVectorShape2D, int] = {}
var _closed_shapes : Dictionary[ScalableVectorShape2D, bool] = {}
func _enter_tree() -> void:
set_meta("_edit_lock_", true)
_connect_signals()
func _exit_tree() -> void:
_disconnect_signals()
func _set_vertex_owners(new_lst : Dictionary[ScalableVectorShape2D, int]):
_disconnect_signals()
vertex_map = new_lst
_connect_signals()
func _disconnect_signals() -> void:
for svs : ScalableVectorShape2D in vertex_map.keys().filter(is_instance_valid):
if svs.polygons_updated.is_connected(_on_svs_curve_changed):
svs.polygons_updated.disconnect(_on_svs_curve_changed)
if svs.transform_changed.is_connected(_on_svs_transform_changed):
svs.transform_changed.disconnect(_on_svs_transform_changed)
func _connect_signals():
for svs : ScalableVectorShape2D in vertex_map.keys().filter(is_instance_valid):
_vertex_counts[svs] = svs.curve.point_count
_closed_shapes[svs] = svs.is_curve_closed()
if not svs.polygons_updated.is_connected(_on_svs_curve_changed):
svs.polygons_updated.connect(_on_svs_curve_changed)
if not svs.transform_changed.is_connected(_on_svs_transform_changed):
svs.set_notify_local_transform(true)
svs.transform_changed.connect(_on_svs_transform_changed)
if vertex_map.size() > 0 and is_instance_valid(vertex_map.keys()[0]):
_align_vertices(vertex_map.keys()[0])
func _on_svs_transform_changed(svs : ScalableVectorShape2D):
_align_vertices(svs)
func _on_svs_curve_changed(
_a : Array[PackedVector2Array],
_b : Array[PackedVector2Array],
svs : ScalableVectorShape2D):
_align_vertices(svs)
func _align_vertices(svs : ScalableVectorShape2D):
if _vertex_counts[svs] != svs.curve.point_count:
for i in svs.curve.point_count:
if svs.to_global(svs.curve.get_point_position(i)).is_equal_approx(global_position):
vertex_map[svs] = i
break
_vertex_counts[svs] = svs.curve.point_count
_closed_shapes[svs] = svs.is_curve_closed()
var global_vertex_pos := svs.to_global(svs.curve.get_point_position(vertex_map[svs]))
global_position = global_vertex_pos
for svs1 : ScalableVectorShape2D in vertex_map.keys().filter(is_instance_valid):
if svs1 != svs:
var idx := vertex_map[svs1]
var new_pos := svs1.to_local(global_vertex_pos)
var old_pos := svs1.curve.get_point_position(idx)
if not old_pos.is_equal_approx(new_pos):
if _closed_shapes[svs1] and idx == 0:
svs1.curve.set_point_position(svs1.curve.point_count - 1, new_pos)
elif _closed_shapes[svs1] and idx == svs1.curve.point_count - 1:
svs1.curve.set_point_position(0, new_pos)
svs1.curve.set_point_position(idx, new_pos)