-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathruntime_gizmo.gd
67 lines (56 loc) · 2.17 KB
/
runtime_gizmo.gd
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
class_name RuntimeGizmo
# Placeholder handle mesh.
var handle_mesh: MeshInstance3D
var handle_collision: CollisionShape3D
# Node being manipulated.
var selected_node: Node3D
var is_dragging = false
var start_drag_pos = Vector2()
var start_gizmo_pos = Vector3()
func _ready():
handle_mesh = MeshInstance3D.new()
var sphere = SphereMesh.new()
sphere.radius = 0.2
sphere.height = 0.4
handle_mesh.mesh = sphere
handle_collision = CollisionShape3D.new()
var collision_shape = SphereShape3D.new()
collision_shape.radius = 0.2
handle_collision.shape = collision_shape
handle_mesh.add_child(handle_collision)
add_child(handle_mesh)
func _input(event):
if event is InputEventMouseButton:
if event.button_index == MOUSE_BUTTON_LEFT:
if event.pressed:
var camera = get_viewport().get_camera_3d()
var from = camera.project_ray_origin(event.position)
var to = from + camera.project_ray_normal(event.position) * 1000
var space_state = get_world_3d().direct_space_state
var query = PhysicsRayQueryParameters3D.new()
query.from = from
query.to = to
query.collision_mask = 1 # Check for collisions on layer 1
var result = space_state.intersect_ray(query)
if result and result.collider == handle_mesh:
print("Handle clicked!")
is_dragging = true
start_drag_pos = event.position
start_gizmo_pos = global_position
else:
is_dragging = false
elif event is InputEventMouseMotion and is_dragging:
var camera = get_viewport().get_camera_3d()
var from_start = camera.project_ray_origin(start_drag_pos)
var to_start = from_start + camera.project_ray_normal(start_drag_pos) * 1000
var from_current = camera.project_ray_origin(event.position)
var to_current = from_current + camera.project_ray_normal(event.position) * 1000
# Calculate the movement in world space.
var plane = Plane(camera.global_transform.basis.z, start_gizmo_pos)
var start_point = plane.intersects_ray(from_start, to_start)
var current_point = plane.intersects_ray(from_current, to_current)
if start_point and current_point:
global_position = start_gizmo_pos + (current_point - start_point)
func set_selected_node(node):
selected_node = node