-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathbounds_gizmo.gd
137 lines (93 loc) · 3.86 KB
/
bounds_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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
extends EditorSpatialGizmo
const immediate_shape_util_const = preload("immediate_shape_util.gd")
var plugin: EditorSpatialGizmoPlugin = null
var spatial: Node = null
var color: Color = Color()
func get_handle_name(p_idx: int) -> String:
if p_idx == 0:
return "X"
elif p_idx == 1:
return "Y"
elif p_idx == 2:
return "Z"
return ""
func get_handle_value(p_idx: int) -> Vector3:
return spatial.get_bounds().size * 2
func set_handle(p_idx: int, p_camera: Camera, p_point: Vector2) -> void:
var gt: Transform = spatial.get_global_transform()
gt = gt.orthonormalized()
var gi: Transform = gt.affine_inverse()
var aabb: AABB = spatial.get_bounds()
var ray_from: Vector3 = p_camera.project_ray_origin(p_point)
var ray_dir: Vector3 = p_camera.project_ray_normal(p_point)
var sg = [gi.xform(ray_from), gi.xform(ray_from + ray_dir * 4096)]
var ofs = aabb.position + aabb.size * 0.5
var axis: Vector3 = Vector3()
axis[p_idx] = 1.0
var result: PoolVector3Array = Geometry.get_closest_points_between_segments(
ofs, ofs + axis * 4096, sg[0], sg[1]
)
var ra: Vector3 = result[0]
var rb: Vector3 = result[1]
var d: float = ra[p_idx]
if d < 0.001:
d = 0.001
aabb.position[p_idx] = (aabb.position[p_idx] + aabb.size[p_idx] * 0.5) - d
aabb.size[p_idx] = d * 2
spatial.set_bounds(aabb)
func commit_handle(p_idx: int, p_restore: bool, p_cancel: bool = false) -> void:
if p_cancel:
spatial.set_bounds(p_restore) # !
return
var ur: UndoRedo = plugin.get_undo_redo()
ur.create_action(tr("Change Box Shape Bounds"))
ur.add_do_method(spatial, "set_bounds", spatial.get_bounds())
ur.add_undo_method(spatial, "set_bounds", p_restore) # !
ur.commit_action()
static func get_lines(p_bounds: AABB) -> PoolVector3Array:
var lines = PoolVector3Array()
var aabb_min: Vector3 = p_bounds.position
var aabb_max: Vector3 = p_bounds.end
lines.append(Vector3(aabb_min.x, aabb_min.y, aabb_min.z))
lines.append(Vector3(aabb_min.x, aabb_max.y, aabb_min.z))
lines.append(Vector3(aabb_min.x, aabb_min.y, aabb_min.z))
lines.append(Vector3(aabb_max.x, aabb_min.y, aabb_min.z))
lines.append(Vector3(aabb_min.x, aabb_max.y, aabb_min.z))
lines.append(Vector3(aabb_max.x, aabb_max.y, aabb_min.z))
lines.append(Vector3(aabb_max.x, aabb_min.y, aabb_min.z))
lines.append(Vector3(aabb_max.x, aabb_max.y, aabb_min.z))
lines.append(Vector3(aabb_max.x, aabb_min.y, aabb_min.z))
lines.append(Vector3(aabb_max.x, aabb_min.y, aabb_max.z))
lines.append(Vector3(aabb_max.x, aabb_max.y, aabb_min.z))
lines.append(Vector3(aabb_max.x, aabb_max.y, aabb_max.z))
lines.append(Vector3(aabb_max.x, aabb_min.y, aabb_max.z))
lines.append(Vector3(aabb_max.x, aabb_max.y, aabb_max.z))
lines.append(Vector3(aabb_max.x, aabb_min.y, aabb_max.z))
lines.append(Vector3(aabb_min.x, aabb_min.y, aabb_max.z))
lines.append(Vector3(aabb_max.x, aabb_max.y, aabb_max.z))
lines.append(Vector3(aabb_min.x, aabb_max.y, aabb_max.z))
lines.append(Vector3(aabb_min.x, aabb_min.y, aabb_max.z))
lines.append(Vector3(aabb_min.x, aabb_max.y, aabb_max.z))
lines.append(Vector3(aabb_min.x, aabb_min.y, aabb_max.z))
lines.append(Vector3(aabb_min.x, aabb_min.y, aabb_min.z))
lines.append(Vector3(aabb_min.x, aabb_max.y, aabb_max.z))
lines.append(Vector3(aabb_min.x, aabb_max.y, aabb_min.z))
return lines
func redraw() -> void:
clear()
var material: SpatialMaterial = immediate_shape_util_const.create_debug_material(color)
var bounds: AABB = spatial.get_bounds()
var lines = get_lines(bounds)
var handles: PoolVector3Array = PoolVector3Array()
for i in range(0, 3):
var ax: Vector3 = Vector3()
ax[i] = bounds.position[i] + bounds.size[i]
handles.push_back(ax)
add_lines(lines, material)
add_collision_segments(lines)
add_handles(handles, material)
func _init(p_spatial: Node, p_plugin: EditorSpatialGizmoPlugin, p_color: Color) -> void:
spatial = p_spatial
plugin = p_plugin
color = p_color
set_spatial_node(spatial)