small racing game im working on
Diffstat (limited to 'ui/editor/port.gd')
| -rw-r--r-- | ui/editor/port.gd | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/ui/editor/port.gd b/ui/editor/port.gd new file mode 100644 index 0000000..24ae3ff --- /dev/null +++ b/ui/editor/port.gd @@ -0,0 +1,108 @@ +extends SubViewport +class_name EditorViewport + +@onready var editor: TrackEditor = owner + +const map = { + TrackEditor.Mode.Select: preload("res://addons/@bendn/gizmo3d/selection_marker.tscn"), + TrackEditor.Mode.Move: preload("res://addons/@bendn/gizmo3d/translate/translate.tscn"), + TrackEditor.Mode.Scale: preload("res://addons/@bendn/gizmo3d/scale/scale.tscn"), + TrackEditor.Mode.Rotate: preload("res://addons/@bendn/gizmo3d/rotation/rotation.tscn"), +} + +var current: Gizmo +var gizmo_holder := Node3D.new() + +var original_gh_p: Vector3 +var original_scales: PackedVector3Array = [] +var original_transforms: Array[Transform3D] = [] + +func _ready() -> void: + add_child(gizmo_holder) + +func _position_gizmo_holder() -> void: + var sum := Vector3.ZERO + for block in editor.selected: + sum += block.live_node.global_position + gizmo_holder.global_position = sum / len(editor.selected) + +func _setup_originals() -> void: + original_transforms.resize(len(editor.selected)) + original_scales.resize(len(editor.selected)) + for i in len(editor.selected): + var n := editor.selected[i].live_node + original_transforms[i] = n.global_transform + original_scales[i] = n.scale + original_gh_p = gizmo_holder.global_position + +func update_gizmo(mode: TrackEditor.Mode) -> void: + if current != null: + current.queue_free() + current = null + original_transforms.clear() + original_scales.clear() + match mode: + _: + if editor.selected.size() == 0: + return + current = map[mode].instantiate() + _position_gizmo_holder() + gizmo_holder.add_child(current) + _setup_originals() + current.finalize.connect(_gizmo_finalize) + current.displaced.connect(_gizmo_displace) + current.scaled.connect(_gizmo_scale) + current.rotated.connect(_gizmo_rotate) + current.clicked.connect(%mousecast.gizmo_clicked) + +func snap(v: Vector3, step: Vector3 = Globals.SNAP) -> Vector3: + return v.snapped(step) if editor.snapping else v + +func _gizmo_displace(offset: Vector3): + const prop := &"global_position" + editor.history.create_action("move %d nodes" % editor.selected.size(), UndoRedo.MERGE_ENDS) + for i in len(editor.selected): + var n := editor.selected[i].live_node + editor.history.add_do_property(n, prop, snap(original_transforms[i].origin + offset)) + editor.history.add_undo_property(n, prop, original_transforms[i].origin) + editor.history.add_do_property(gizmo_holder, prop, original_gh_p + snap(offset)) + editor.history.add_undo_property(gizmo_holder, prop, original_gh_p) + editor.history.commit_action() + +func _gizmo_scale(change: Vector3): + const prop := &"scale" + editor.history.create_action("scale %d nodes" % editor.selected.size(), UndoRedo.MERGE_ENDS) + for i in len(editor.selected): + var n := editor.selected[i].live_node + var scl := snap(original_scales[i] + change, Vector3.ONE) + if scl.x <= 0 || scl.y <= 0: # pls no flip + scl = Vector3.ONE + editor.history.add_do_property(n, prop, scl) + editor.history.add_undo_property(n, prop, original_scales[i]) + editor.history.commit_action() + +func _gizmo_rotate(change: Vector3): + const prop := &"global_transform" + editor.history.create_action("rotate %d nodes" % editor.selected.size(), UndoRedo.MERGE_ENDS) + for i in len(editor.selected): + var n := editor.selected[i].live_node + var rotation := Transform3D(Basis.from_euler(change), Vector3()) + editor.history.add_do_property( + n, + prop, + (rotation * original_transforms[i].translated(-original_gh_p)).translated(original_gh_p) + ) + editor.history.add_undo_property(n, prop, original_transforms[i]) + editor.history.commit_action() + +func _gizmo_finalize(): + for i in len(editor.selected): + var n := editor.selected[i].live_node + original_scales[i] = n.scale + original_transforms[i] = n.global_transform + original_gh_p = gizmo_holder.global_position + +func _on_remove_tobj() -> void: + if current != null: + current.queue_free() + current = null |