Son aktivite 4 days ago

evert's Avatar evert bu gisti düzenledi 4 days ago. Düzenlemeye git

1 file changed, 22 insertions, 20 deletions

gizmo.gd

@@ -2,6 +2,7 @@
2 2 extends EditorNode3DGizmoPlugin
3 3
4 4 const ONE_VEC = Vector3(1.0, 1.0, 1.0)
5 + const MAX_DEFLECTION = 4096.0
5 6
6 7 var undo_redo: EditorUndoRedoManager
7 8
@@ -19,24 +20,27 @@ var directions: Array[String] = [
19 20 "+Y", "+Z", "+X", "-Y", "-Z", "-X"
20 21 ]
21 22
23 + var visible = true
24 +
22 25 var first_pos: Variant
23 26 var first_scale: Vector3
24 27 var first_position: Vector3
25 - var first_transform: Transform3D
28 + var first_global: Vector3
26 29
27 30 func _has_gizmo(node):
28 31 return node is Node3D
29 32
30 33 func _get_gizmo_name() -> String:
31 - return "Rodot gizmo"
34 + return "Rodot Resize"
32 35
33 36 func _init(undo_redo: EditorUndoRedoManager):
34 37 self.undo_redo = undo_redo
35 38 create_handle_material("handles")
36 39
37 - func _redraw(gizmo):
40 + func _redraw(gizmo: EditorNode3DGizmo):
38 41 gizmo.clear()
39 - gizmo.add_handles(handles, get_material("handles", gizmo), [])
42 + if visible:
43 + gizmo.add_handles(handles, get_material("handles", gizmo), [])
40 44
41 45 func _get_handle_name(gizmo: EditorNode3DGizmo, handle_id: int, secondary: bool) -> String:
42 46 return "Resize " + directions[handle_id]
@@ -49,7 +53,7 @@ func _begin_handle_action(gizmo: EditorNode3DGizmo, handle_id: int, secondary: b
49 53 first_pos = null
50 54 first_scale = node.scale
51 55 first_position = node.position
52 - first_transform = Transform3D(node.transform)
56 + first_global = node.global_position
53 57
54 58 func _commit_handle(gizmo: EditorNode3DGizmo, handle_id: int, secondary: bool, restore: Variant, cancel: bool) -> void:
55 59 var node = gizmo.get_node_3d()
@@ -69,10 +73,12 @@ func _commit_handle(gizmo: EditorNode3DGizmo, handle_id: int, secondary: bool, r
69 73 undo_redo.commit_action()
70 74
71 75 func _update_node(node: Node3D, change: Vector3, axis: Vector3, minimum_deflection = 1.0) -> void:
76 + # Reset to default
77 + node.position = first_position
78 + node.scale = first_scale
79 +
72 80 if change.length() == 0:
73 - # Reset to default, no size change
74 - node.position = first_position
75 - node.scale = first_scale
81 + # No size change
76 82 return
77 83
78 84 var axis_direction = sign(change.dot(axis))
@@ -93,8 +99,6 @@ func _update_node(node: Node3D, change: Vector3, axis: Vector3, minimum_deflecti
93 99
94 100 var pos_factor = ((apply_scale - ONE_VEC) / 2) * axis
95 101
96 - node.position = first_position
97 - node.scale = first_scale
98 102 node.translate_object_local(pos_factor)
99 103 node.scale_object_local(apply_scale)
100 104
@@ -115,9 +119,12 @@ func _set_handle(gizmo: EditorNode3DGizmo, handle_id: int, secondary: bool, came
115 119
116 120 var offset := (m_pos - o_pos) * axis
117 121
118 - var scale_snap: float = EditorInterface.get_node_3d_translate_snap()
122 + var scale_snap: float = EditorInterface.get_node_3d_scale_snap() / 100.0
119 123
120 124 var handle_diff := offset.length()
125 + if is_nan(handle_diff) or is_inf(handle_diff) or handle_diff >= MAX_DEFLECTION:
126 + return
127 +
121 128 var snap_diff = handle_diff
122 129
123 130 if EditorInterface.is_node_3d_snap_enabled():
@@ -129,19 +136,14 @@ func _set_handle(gizmo: EditorNode3DGizmo, handle_id: int, secondary: bool, came
129 136 var handle_diff_vec = axis * snap_diff * handle_dir
130 137
131 138 _update_node(node, handle_diff_vec, axis, scale_snap)
132 -
139 +
133 140 node.update_gizmos()
134 141
135 142 func _get_projected_pos(gizmo: EditorNode3DGizmo, handle_id: int, camera: Camera3D, screen_pos: Vector2) -> Variant:
136 143 var node := gizmo.get_node_3d()
137 - var pos_vector = Vector3(0, node.global_position.y, 0)
138 - var plane = Plane(node.global_basis.y, pos_vector)
139 - if handle_id == 0 or handle_id == 3:
140 - pos_vector = Vector3(node.global_position.x, 0, node.global_position.z)
141 - plane = Plane(node.global_basis.z, pos_vector)
142 -
143 144 var from := camera.project_ray_origin(screen_pos)
144 - var pos = plane.intersects_ray(from, camera.project_ray_normal(screen_pos) * 4096.0)
145 145
146 - return pos
146 + var plane = Plane(from, first_global)
147 + var pos = plane.intersects_ray(from, camera.project_ray_normal(screen_pos) * MAX_DEFLECTION)
147 148
149 + return pos

evert's Avatar evert bu gisti düzenledi 5 days ago. Düzenlemeye git

1 file changed, 147 insertions

gizmo.gd(dosya oluşturuldu)

@@ -0,0 +1,147 @@
1 + @tool
2 + extends EditorNode3DGizmoPlugin
3 +
4 + const ONE_VEC = Vector3(1.0, 1.0, 1.0)
5 +
6 + var undo_redo: EditorUndoRedoManager
7 +
8 + var handles: PackedVector3Array = [
9 + Vector3.UP,
10 + -Vector3.FORWARD,
11 + Vector3.RIGHT,
12 +
13 + -Vector3.UP,
14 + Vector3.FORWARD,
15 + -Vector3.RIGHT
16 + ]
17 +
18 + var directions: Array[String] = [
19 + "+Y", "+Z", "+X", "-Y", "-Z", "-X"
20 + ]
21 +
22 + var first_pos: Variant
23 + var first_scale: Vector3
24 + var first_position: Vector3
25 + var first_transform: Transform3D
26 +
27 + func _has_gizmo(node):
28 + return node is Node3D
29 +
30 + func _get_gizmo_name() -> String:
31 + return "Rodot gizmo"
32 +
33 + func _init(undo_redo: EditorUndoRedoManager):
34 + self.undo_redo = undo_redo
35 + create_handle_material("handles")
36 +
37 + func _redraw(gizmo):
38 + gizmo.clear()
39 + gizmo.add_handles(handles, get_material("handles", gizmo), [])
40 +
41 + func _get_handle_name(gizmo: EditorNode3DGizmo, handle_id: int, secondary: bool) -> String:
42 + return "Resize " + directions[handle_id]
43 +
44 + func _get_handle_value(gizmo: EditorNode3DGizmo, handle_id: int, secondary: bool) -> Variant:
45 + return handles[handle_id]
46 +
47 + func _begin_handle_action(gizmo: EditorNode3DGizmo, handle_id: int, secondary: bool) -> void:
48 + var node = gizmo.get_node_3d()
49 + first_pos = null
50 + first_scale = node.scale
51 + first_position = node.position
52 + first_transform = Transform3D(node.transform)
53 +
54 + func _commit_handle(gizmo: EditorNode3DGizmo, handle_id: int, secondary: bool, restore: Variant, cancel: bool) -> void:
55 + var node = gizmo.get_node_3d()
56 + if cancel:
57 + node.scale = first_scale
58 + node.position = first_position
59 + return
60 +
61 + if node.scale.is_equal_approx(first_scale) and node.position.is_equal_approx(first_position):
62 + return
63 +
64 + undo_redo.create_action("Resize Node3D")
65 + undo_redo.add_do_property(node, "position", node.position)
66 + undo_redo.add_undo_property(node, "position", first_position)
67 + undo_redo.add_do_property(node, "scale", node.scale)
68 + undo_redo.add_undo_property(node, "scale", first_scale)
69 + undo_redo.commit_action()
70 +
71 + func _update_node(node: Node3D, change: Vector3, axis: Vector3, minimum_deflection = 1.0) -> void:
72 + if change.length() == 0:
73 + # Reset to default, no size change
74 + node.position = first_position
75 + node.scale = first_scale
76 + return
77 +
78 + var axis_direction = sign(change.dot(axis))
79 + var direction = axis_direction * sign(axis.dot(axis.abs()))
80 + var amount_to_add = change.length() * direction
81 + var current_scale = (first_scale * axis.abs()).length()
82 +
83 + # If user attempts to go negative or zero, force them back to the minimum amount
84 + var deflection = current_scale + amount_to_add
85 + if deflection < minimum_deflection:
86 + amount_to_add = amount_to_add - deflection + minimum_deflection
87 +
88 + var abs_axis: Vector3 = axis.abs()
89 + var scale_vec: Vector3 = ONE_VEC - abs_axis
90 + var factor: float = (current_scale + amount_to_add) / current_scale
91 + var axis_factor: Vector3 = abs_axis * factor
92 + var apply_scale: Vector3 = scale_vec + axis_factor
93 +
94 + var pos_factor = ((apply_scale - ONE_VEC) / 2) * axis
95 +
96 + node.position = first_position
97 + node.scale = first_scale
98 + node.translate_object_local(pos_factor)
99 + node.scale_object_local(apply_scale)
100 +
101 + func _set_handle(gizmo: EditorNode3DGizmo, handle_id: int, secondary: bool, camera: Camera3D, screen_pos: Vector2) -> void:
102 + var node := gizmo.get_node_3d()
103 + var pos = _get_projected_pos(gizmo, handle_id, camera, screen_pos)
104 +
105 + if not pos is Vector3:
106 + return
107 +
108 + if not first_pos:
109 + first_pos = pos
110 + return
111 +
112 + var o_pos := first_pos as Vector3
113 + var m_pos := pos as Vector3
114 + var axis := handles[handle_id]
115 +
116 + var offset := (m_pos - o_pos) * axis
117 +
118 + var scale_snap: float = EditorInterface.get_node_3d_translate_snap()
119 +
120 + var handle_diff := offset.length()
121 + var snap_diff = handle_diff
122 +
123 + if EditorInterface.is_node_3d_snap_enabled():
124 + snap_diff = roundf(handle_diff / scale_snap) * scale_snap
125 +
126 + var handle_dot := offset.normalized().dot(axis)
127 + var handle_dir = sign(handle_dot)
128 +
129 + var handle_diff_vec = axis * snap_diff * handle_dir
130 +
131 + _update_node(node, handle_diff_vec, axis, scale_snap)
132 +
133 + node.update_gizmos()
134 +
135 + func _get_projected_pos(gizmo: EditorNode3DGizmo, handle_id: int, camera: Camera3D, screen_pos: Vector2) -> Variant:
136 + var node := gizmo.get_node_3d()
137 + var pos_vector = Vector3(0, node.global_position.y, 0)
138 + var plane = Plane(node.global_basis.y, pos_vector)
139 + if handle_id == 0 or handle_id == 3:
140 + pos_vector = Vector3(node.global_position.x, 0, node.global_position.z)
141 + plane = Plane(node.global_basis.z, pos_vector)
142 +
143 + var from := camera.project_ray_origin(screen_pos)
144 + var pos = plane.intersects_ray(from, camera.project_ray_normal(screen_pos) * 4096.0)
145 +
146 + return pos
147 +
Daha yeni Daha eski