small godot addon for gizmo creation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
extends Node3D

var current: Gizmo
var gizmo_holder := Node3D.new()

var original_gh_p: Vector3
var original_positions: PackedVector3Array = []
var original_rotations: PackedVector3Array = []
var original_scales: PackedVector3Array = []

@export var target: Node3D
@export var gizmo: PackedScene
@onready var targets: Array[Node3D] = [target]

func _ready() -> void:
	add_child(gizmo_holder)
	current = gizmo.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)

func _position_gizmo_holder() -> void:
	var sum := Vector3.ZERO
	for node in targets:
		sum += node.global_position
	gizmo_holder.global_position = sum / len(targets)

func _setup_originals() -> void:
	original_positions.resize(len(targets))
	original_rotations.resize(len(targets))
	original_scales.resize(len(targets))
	for i in len(targets):
		var n := targets[i]
		original_positions[i] = n.global_position
		original_rotations[i] = n.global_rotation
		original_scales[i] = n.scale
	original_gh_p = gizmo_holder.global_position

func _gizmo_displace(offset: Vector3):
	for i in len(targets):
		targets[i].global_position = original_positions[i] + offset
	gizmo_holder.global_position = original_gh_p + offset

func _gizmo_scale(change: Vector3):
	for i in len(targets):
		var n := targets[i]
		var scl := original_scales[i] + change
		if scl.x <= 0 || scl.y <= 0: # no flipping allowed
			scl = Vector3.ONE
		n.scale = scl

func _gizmo_rotate(change: Vector3):
	for i in len(targets):
		var n := targets[i]
		n.global_rotation = original_rotations[i] + change

func _gizmo_finalize():
	for i in len(targets):
		var n := targets[i]
		original_positions[i] = n.global_position
		original_scales[i] = n.scale
		original_rotations[i] = n.global_rotation
	original_gh_p = gizmo_holder.global_position