-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
/
Copy pathtest_joints.gd
138 lines (110 loc) · 4.21 KB
/
test_joints.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
138
extends Test
const OPTION_JOINT_TYPE = "Joint Type/%s Joint (%d)"
const OPTION_TEST_CASE_BODIES_COLLIDE = "Test case/Attached bodies collide"
const OPTION_TEST_CASE_WORLD_ATTACHMENT = "Test case/No parent body"
const OPTION_TEST_CASE_DYNAMIC_ATTACHMENT = "Test case/Parent body is dynamic (no gravity)"
const OPTION_TEST_CASE_DESTROY_BODY = "Test case/Destroy attached body"
const OPTION_TEST_CASE_CHANGE_POSITIONS = "Test case/Set body positions after added to scene"
const BOX_SIZE = Vector3(1.0, 1.0, 1.0)
var _update_joint := false
var _selected_joint: Joint3D
var _bodies_collide := false
var _world_attachement := false
var _dynamic_attachement := false
var _destroy_body := false
var _change_positions := false
var _joint_types := {}
func _ready() -> void:
var options: OptionMenu = $Options
var joints: Node3D = $Joints
for joint_index in joints.get_child_count():
var joint_node := joints.get_child(joint_index)
joint_node.visible = false
var joint_name := String(joint_node.name)
var joint_short := joint_name.substr(0, joint_name.length() - 5)
var option_name := OPTION_JOINT_TYPE % [joint_short, joint_index + 1]
options.add_menu_item(option_name)
_joint_types[option_name] = joint_node
options.add_menu_item(OPTION_TEST_CASE_BODIES_COLLIDE, true, false)
options.add_menu_item(OPTION_TEST_CASE_WORLD_ATTACHMENT, true, false)
options.add_menu_item(OPTION_TEST_CASE_DYNAMIC_ATTACHMENT, true, false)
options.add_menu_item(OPTION_TEST_CASE_DESTROY_BODY, true, false)
options.add_menu_item(OPTION_TEST_CASE_CHANGE_POSITIONS, true, false)
options.option_selected.connect(_on_option_selected)
options.option_changed.connect(_on_option_changed)
_selected_joint = _joint_types.values()[0]
_update_joint = true
func _process(_delta: float) -> void:
if _update_joint:
_update_joint = false
await _create_joint()
$LabelJointType.text = "Joint Type: " + String(_selected_joint.name)
func _input(event: InputEvent) -> void:
if event is InputEventKey and event.pressed:
var joint_index: int = event.keycode - KEY_1
if joint_index >= 0 and joint_index < _joint_types.size():
_selected_joint = _joint_types.values()[joint_index]
_update_joint = true
func _on_option_selected(option: String) -> void:
if _joint_types.has(option):
_selected_joint = _joint_types[option]
_update_joint = true
func _on_option_changed(option: String, checked: bool) -> void:
match option:
OPTION_TEST_CASE_BODIES_COLLIDE:
_bodies_collide = checked
_update_joint = true
OPTION_TEST_CASE_WORLD_ATTACHMENT:
_world_attachement = checked
_update_joint = true
OPTION_TEST_CASE_DYNAMIC_ATTACHMENT:
_dynamic_attachement = checked
_update_joint = true
OPTION_TEST_CASE_DESTROY_BODY:
_destroy_body = checked
_update_joint = true
OPTION_TEST_CASE_CHANGE_POSITIONS:
_change_positions = checked
_update_joint = true
func _create_joint() -> void:
cancel_timer()
var root: Node3D = $Objects
while root.get_child_count():
var last_child_index := root.get_child_count() - 1
var last_child := root.get_child(last_child_index)
root.remove_child(last_child)
last_child.queue_free()
var child_body := create_rigidbody_box(BOX_SIZE, true)
if _change_positions:
root.add_child(child_body)
child_body.transform.origin = Vector3(0.0, -1.5, 0.0)
else:
child_body.transform.origin = Vector3(0.0, -1.5, 0.0)
root.add_child(child_body)
var parent_body: RigidBody3D
if not _world_attachement:
parent_body = create_rigidbody_box(BOX_SIZE, true)
if _dynamic_attachement:
parent_body.gravity_scale = 0.0
child_body.gravity_scale = 0.0
else:
parent_body.freeze_mode = RigidBody3D.FREEZE_MODE_KINEMATIC
parent_body.freeze = true
if _change_positions:
root.add_child(parent_body)
parent_body.transform.origin = Vector3(0.0, 1.5, 0.0)
else:
parent_body.transform.origin = Vector3(0.0, 1.5, 0.0)
root.add_child(parent_body)
var joint := _selected_joint.duplicate()
joint.visible = true
joint.set_exclude_nodes_from_collision(not _bodies_collide)
root.add_child(joint)
if parent_body:
joint.set_node_a(joint.get_path_to(parent_body))
joint.set_node_b(joint.get_path_to(child_body))
if _destroy_body:
await start_timer(0.5).timeout
if is_timer_canceled():
return
child_body.queue_free()