small racing game im working on
Diffstat (limited to 'ui/editor/port.gd')
-rw-r--r--ui/editor/port.gd108
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