1/**************************************************************************/
2/* joint_3d.cpp */
3/**************************************************************************/
4/* This file is part of: */
5/* GODOT ENGINE */
6/* https://godotengine.org */
7/**************************************************************************/
8/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10/* */
11/* Permission is hereby granted, free of charge, to any person obtaining */
12/* a copy of this software and associated documentation files (the */
13/* "Software"), to deal in the Software without restriction, including */
14/* without limitation the rights to use, copy, modify, merge, publish, */
15/* distribute, sublicense, and/or sell copies of the Software, and to */
16/* permit persons to whom the Software is furnished to do so, subject to */
17/* the following conditions: */
18/* */
19/* The above copyright notice and this permission notice shall be */
20/* included in all copies or substantial portions of the Software. */
21/* */
22/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29/**************************************************************************/
30
31#include "joint_3d.h"
32
33#include "scene/scene_string_names.h"
34
35void Joint3D::_disconnect_signals() {
36 Node *node_a = get_node_or_null(a);
37 PhysicsBody3D *body_a = Object::cast_to<PhysicsBody3D>(node_a);
38 if (body_a) {
39 body_a->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Joint3D::_body_exit_tree));
40 }
41
42 Node *node_b = get_node_or_null(b);
43 PhysicsBody3D *body_b = Object::cast_to<PhysicsBody3D>(node_b);
44 if (body_b) {
45 body_b->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Joint3D::_body_exit_tree));
46 }
47}
48
49void Joint3D::_body_exit_tree() {
50 _disconnect_signals();
51 _update_joint(true);
52 update_configuration_warnings();
53}
54
55void Joint3D::_update_joint(bool p_only_free) {
56 if (ba.is_valid() && bb.is_valid()) {
57 PhysicsServer3D::get_singleton()->body_remove_collision_exception(ba, bb);
58 PhysicsServer3D::get_singleton()->body_remove_collision_exception(bb, ba);
59 }
60
61 ba = RID();
62 bb = RID();
63
64 configured = false;
65
66 if (p_only_free || !is_inside_tree()) {
67 PhysicsServer3D::get_singleton()->joint_clear(joint);
68 warning = String();
69 return;
70 }
71
72 Node *node_a = get_node_or_null(a);
73 Node *node_b = get_node_or_null(b);
74
75 PhysicsBody3D *body_a = Object::cast_to<PhysicsBody3D>(node_a);
76 PhysicsBody3D *body_b = Object::cast_to<PhysicsBody3D>(node_b);
77
78 if (node_a && !body_a && node_b && !body_b) {
79 warning = RTR("Node A and Node B must be PhysicsBody3Ds");
80 } else if (node_a && !body_a) {
81 warning = RTR("Node A must be a PhysicsBody3D");
82 } else if (node_b && !body_b) {
83 warning = RTR("Node B must be a PhysicsBody3D");
84 } else if (!body_a && !body_b) {
85 warning = RTR("Joint is not connected to any PhysicsBody3Ds");
86 } else if (body_a == body_b) {
87 warning = RTR("Node A and Node B must be different PhysicsBody3Ds");
88 } else {
89 warning = String();
90 }
91
92 update_configuration_warnings();
93
94 if (!warning.is_empty()) {
95 PhysicsServer3D::get_singleton()->joint_clear(joint);
96 return;
97 }
98
99 configured = true;
100
101 if (body_a) {
102 _configure_joint(joint, body_a, body_b);
103 } else if (body_b) {
104 _configure_joint(joint, body_b, nullptr);
105 }
106
107 PhysicsServer3D::get_singleton()->joint_set_solver_priority(joint, solver_priority);
108
109 if (body_a) {
110 ba = body_a->get_rid();
111 body_a->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Joint3D::_body_exit_tree));
112 }
113
114 if (body_b) {
115 bb = body_b->get_rid();
116 body_b->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Joint3D::_body_exit_tree));
117 }
118
119 PhysicsServer3D::get_singleton()->joint_disable_collisions_between_bodies(joint, exclude_from_collision);
120}
121
122void Joint3D::set_node_a(const NodePath &p_node_a) {
123 if (a == p_node_a) {
124 return;
125 }
126
127 if (is_configured()) {
128 _disconnect_signals();
129 }
130
131 a = p_node_a;
132 _update_joint();
133}
134
135NodePath Joint3D::get_node_a() const {
136 return a;
137}
138
139void Joint3D::set_node_b(const NodePath &p_node_b) {
140 if (b == p_node_b) {
141 return;
142 }
143
144 if (is_configured()) {
145 _disconnect_signals();
146 }
147
148 b = p_node_b;
149 _update_joint();
150}
151
152NodePath Joint3D::get_node_b() const {
153 return b;
154}
155
156void Joint3D::set_solver_priority(int p_priority) {
157 solver_priority = p_priority;
158 if (joint.is_valid()) {
159 PhysicsServer3D::get_singleton()->joint_set_solver_priority(joint, solver_priority);
160 }
161}
162
163int Joint3D::get_solver_priority() const {
164 return solver_priority;
165}
166
167void Joint3D::_notification(int p_what) {
168 switch (p_what) {
169 case NOTIFICATION_POST_ENTER_TREE: {
170 if (is_configured()) {
171 _disconnect_signals();
172 }
173 _update_joint();
174 } break;
175
176 case NOTIFICATION_EXIT_TREE: {
177 if (is_configured()) {
178 _disconnect_signals();
179 }
180 _update_joint(true);
181 } break;
182 }
183}
184
185void Joint3D::set_exclude_nodes_from_collision(bool p_enable) {
186 if (exclude_from_collision == p_enable) {
187 return;
188 }
189 if (is_configured()) {
190 _disconnect_signals();
191 }
192 _update_joint(true);
193 exclude_from_collision = p_enable;
194 _update_joint();
195}
196
197bool Joint3D::get_exclude_nodes_from_collision() const {
198 return exclude_from_collision;
199}
200
201PackedStringArray Joint3D::get_configuration_warnings() const {
202 PackedStringArray warnings = Node3D::get_configuration_warnings();
203
204 if (!warning.is_empty()) {
205 warnings.push_back(warning);
206 }
207
208 return warnings;
209}
210
211void Joint3D::_bind_methods() {
212 ClassDB::bind_method(D_METHOD("set_node_a", "node"), &Joint3D::set_node_a);
213 ClassDB::bind_method(D_METHOD("get_node_a"), &Joint3D::get_node_a);
214
215 ClassDB::bind_method(D_METHOD("set_node_b", "node"), &Joint3D::set_node_b);
216 ClassDB::bind_method(D_METHOD("get_node_b"), &Joint3D::get_node_b);
217
218 ClassDB::bind_method(D_METHOD("set_solver_priority", "priority"), &Joint3D::set_solver_priority);
219 ClassDB::bind_method(D_METHOD("get_solver_priority"), &Joint3D::get_solver_priority);
220
221 ClassDB::bind_method(D_METHOD("set_exclude_nodes_from_collision", "enable"), &Joint3D::set_exclude_nodes_from_collision);
222 ClassDB::bind_method(D_METHOD("get_exclude_nodes_from_collision"), &Joint3D::get_exclude_nodes_from_collision);
223
224 ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "node_a", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "PhysicsBody3D"), "set_node_a", "get_node_a");
225 ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "node_b", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "PhysicsBody3D"), "set_node_b", "get_node_b");
226 ADD_PROPERTY(PropertyInfo(Variant::INT, "solver_priority", PROPERTY_HINT_RANGE, "1,8,1"), "set_solver_priority", "get_solver_priority");
227
228 ADD_PROPERTY(PropertyInfo(Variant::BOOL, "exclude_nodes_from_collision"), "set_exclude_nodes_from_collision", "get_exclude_nodes_from_collision");
229}
230
231Joint3D::Joint3D() {
232 set_notify_transform(true);
233 joint = PhysicsServer3D::get_singleton()->joint_create();
234}
235
236Joint3D::~Joint3D() {
237 ERR_FAIL_NULL(PhysicsServer3D::get_singleton());
238 PhysicsServer3D::get_singleton()->free(joint);
239}
240
241///////////////////////////////////
242
243void PinJoint3D::_bind_methods() {
244 ClassDB::bind_method(D_METHOD("set_param", "param", "value"), &PinJoint3D::set_param);
245 ClassDB::bind_method(D_METHOD("get_param", "param"), &PinJoint3D::get_param);
246
247 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "params/bias", PROPERTY_HINT_RANGE, "0.01,0.99,0.01"), "set_param", "get_param", PARAM_BIAS);
248 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "params/damping", PROPERTY_HINT_RANGE, "0.01,8.0,0.01"), "set_param", "get_param", PARAM_DAMPING);
249 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "params/impulse_clamp", PROPERTY_HINT_RANGE, "0.0,64.0,0.01"), "set_param", "get_param", PARAM_IMPULSE_CLAMP);
250
251 BIND_ENUM_CONSTANT(PARAM_BIAS);
252 BIND_ENUM_CONSTANT(PARAM_DAMPING);
253 BIND_ENUM_CONSTANT(PARAM_IMPULSE_CLAMP);
254}
255
256void PinJoint3D::set_param(Param p_param, real_t p_value) {
257 ERR_FAIL_INDEX(p_param, 3);
258 params[p_param] = p_value;
259 if (is_configured()) {
260 PhysicsServer3D::get_singleton()->pin_joint_set_param(get_joint(), PhysicsServer3D::PinJointParam(p_param), p_value);
261 }
262}
263
264real_t PinJoint3D::get_param(Param p_param) const {
265 ERR_FAIL_INDEX_V(p_param, 3, 0);
266 return params[p_param];
267}
268
269void PinJoint3D::_configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) {
270 Vector3 pinpos = get_global_transform().origin;
271 Vector3 local_a = body_a->to_local(pinpos);
272 Vector3 local_b;
273
274 if (body_b) {
275 local_b = body_b->to_local(pinpos);
276 } else {
277 local_b = pinpos;
278 }
279
280 PhysicsServer3D::get_singleton()->joint_make_pin(p_joint, body_a->get_rid(), local_a, body_b ? body_b->get_rid() : RID(), local_b);
281 for (int i = 0; i < 3; i++) {
282 PhysicsServer3D::get_singleton()->pin_joint_set_param(p_joint, PhysicsServer3D::PinJointParam(i), params[i]);
283 }
284}
285
286PinJoint3D::PinJoint3D() {
287 params[PARAM_BIAS] = 0.3;
288 params[PARAM_DAMPING] = 1;
289 params[PARAM_IMPULSE_CLAMP] = 0;
290}
291
292/////////////////////////////////////////////////
293
294///////////////////////////////////
295
296void HingeJoint3D::_bind_methods() {
297 ClassDB::bind_method(D_METHOD("set_param", "param", "value"), &HingeJoint3D::set_param);
298 ClassDB::bind_method(D_METHOD("get_param", "param"), &HingeJoint3D::get_param);
299
300 ClassDB::bind_method(D_METHOD("set_flag", "flag", "enabled"), &HingeJoint3D::set_flag);
301 ClassDB::bind_method(D_METHOD("get_flag", "flag"), &HingeJoint3D::get_flag);
302
303 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "params/bias", PROPERTY_HINT_RANGE, "0.00,0.99,0.01"), "set_param", "get_param", PARAM_BIAS);
304
305 ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "angular_limit/enable"), "set_flag", "get_flag", FLAG_USE_LIMIT);
306 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit/upper", PROPERTY_HINT_RANGE, "-180,180,0.1,radians"), "set_param", "get_param", PARAM_LIMIT_UPPER);
307 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit/lower", PROPERTY_HINT_RANGE, "-180,180,0.1,radians"), "set_param", "get_param", PARAM_LIMIT_LOWER);
308 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit/bias", PROPERTY_HINT_RANGE, "0.01,0.99,0.01"), "set_param", "get_param", PARAM_LIMIT_BIAS);
309 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit/softness", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param", "get_param", PARAM_LIMIT_SOFTNESS);
310 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit/relaxation", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param", "get_param", PARAM_LIMIT_RELAXATION);
311
312 ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "motor/enable"), "set_flag", "get_flag", FLAG_ENABLE_MOTOR);
313 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "motor/target_velocity", PROPERTY_HINT_RANGE, "-200,200,0.01,or_greater,or_less,suffix:m/s"), "set_param", "get_param", PARAM_MOTOR_TARGET_VELOCITY);
314 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "motor/max_impulse", PROPERTY_HINT_RANGE, "0.01,1024,0.01"), "set_param", "get_param", PARAM_MOTOR_MAX_IMPULSE);
315
316 BIND_ENUM_CONSTANT(PARAM_BIAS);
317 BIND_ENUM_CONSTANT(PARAM_LIMIT_UPPER);
318 BIND_ENUM_CONSTANT(PARAM_LIMIT_LOWER);
319 BIND_ENUM_CONSTANT(PARAM_LIMIT_BIAS);
320 BIND_ENUM_CONSTANT(PARAM_LIMIT_SOFTNESS);
321 BIND_ENUM_CONSTANT(PARAM_LIMIT_RELAXATION);
322 BIND_ENUM_CONSTANT(PARAM_MOTOR_TARGET_VELOCITY);
323 BIND_ENUM_CONSTANT(PARAM_MOTOR_MAX_IMPULSE);
324 BIND_ENUM_CONSTANT(PARAM_MAX);
325
326 BIND_ENUM_CONSTANT(FLAG_USE_LIMIT);
327 BIND_ENUM_CONSTANT(FLAG_ENABLE_MOTOR);
328 BIND_ENUM_CONSTANT(FLAG_MAX);
329}
330
331void HingeJoint3D::set_param(Param p_param, real_t p_value) {
332 ERR_FAIL_INDEX(p_param, PARAM_MAX);
333 params[p_param] = p_value;
334 if (is_configured()) {
335 PhysicsServer3D::get_singleton()->hinge_joint_set_param(get_joint(), PhysicsServer3D::HingeJointParam(p_param), p_value);
336 }
337
338 update_gizmos();
339}
340
341real_t HingeJoint3D::get_param(Param p_param) const {
342 ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0);
343 return params[p_param];
344}
345
346void HingeJoint3D::set_flag(Flag p_flag, bool p_value) {
347 ERR_FAIL_INDEX(p_flag, FLAG_MAX);
348 flags[p_flag] = p_value;
349 if (is_configured()) {
350 PhysicsServer3D::get_singleton()->hinge_joint_set_flag(get_joint(), PhysicsServer3D::HingeJointFlag(p_flag), p_value);
351 }
352
353 update_gizmos();
354}
355
356bool HingeJoint3D::get_flag(Flag p_flag) const {
357 ERR_FAIL_INDEX_V(p_flag, FLAG_MAX, false);
358 return flags[p_flag];
359}
360
361void HingeJoint3D::_configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) {
362 Transform3D gt = get_global_transform();
363 Transform3D ainv = body_a->get_global_transform().affine_inverse();
364
365 Transform3D local_a = ainv * gt;
366 local_a.orthonormalize();
367 Transform3D local_b = gt;
368
369 if (body_b) {
370 Transform3D binv = body_b->get_global_transform().affine_inverse();
371 local_b = binv * gt;
372 }
373
374 local_b.orthonormalize();
375
376 PhysicsServer3D::get_singleton()->joint_make_hinge(p_joint, body_a->get_rid(), local_a, body_b ? body_b->get_rid() : RID(), local_b);
377 for (int i = 0; i < PARAM_MAX; i++) {
378 PhysicsServer3D::get_singleton()->hinge_joint_set_param(p_joint, PhysicsServer3D::HingeJointParam(i), params[i]);
379 }
380 for (int i = 0; i < FLAG_MAX; i++) {
381 set_flag(Flag(i), flags[i]);
382 PhysicsServer3D::get_singleton()->hinge_joint_set_flag(p_joint, PhysicsServer3D::HingeJointFlag(i), flags[i]);
383 }
384}
385
386HingeJoint3D::HingeJoint3D() {
387 params[PARAM_BIAS] = 0.3;
388 params[PARAM_LIMIT_UPPER] = Math_PI * 0.5;
389 params[PARAM_LIMIT_LOWER] = -Math_PI * 0.5;
390 params[PARAM_LIMIT_BIAS] = 0.3;
391 params[PARAM_LIMIT_SOFTNESS] = 0.9;
392 params[PARAM_LIMIT_RELAXATION] = 1.0;
393 params[PARAM_MOTOR_TARGET_VELOCITY] = 1;
394 params[PARAM_MOTOR_MAX_IMPULSE] = 1;
395
396 flags[FLAG_USE_LIMIT] = false;
397 flags[FLAG_ENABLE_MOTOR] = false;
398}
399
400/////////////////////////////////////////////////
401
402void SliderJoint3D::_bind_methods() {
403 ClassDB::bind_method(D_METHOD("set_param", "param", "value"), &SliderJoint3D::set_param);
404 ClassDB::bind_method(D_METHOD("get_param", "param"), &SliderJoint3D::get_param);
405
406 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit/upper_distance", PROPERTY_HINT_RANGE, "-1024,1024,0.01,suffix:m"), "set_param", "get_param", PARAM_LINEAR_LIMIT_UPPER);
407 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit/lower_distance", PROPERTY_HINT_RANGE, "-1024,1024,0.01,suffix:m"), "set_param", "get_param", PARAM_LINEAR_LIMIT_LOWER);
408 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit/softness", PROPERTY_HINT_RANGE, "0.01,16.0,0.01"), "set_param", "get_param", PARAM_LINEAR_LIMIT_SOFTNESS);
409 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit/restitution", PROPERTY_HINT_RANGE, "0.01,16.0,0.01"), "set_param", "get_param", PARAM_LINEAR_LIMIT_RESTITUTION);
410 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit/damping", PROPERTY_HINT_RANGE, "0,16.0,0.01"), "set_param", "get_param", PARAM_LINEAR_LIMIT_DAMPING);
411 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_motion/softness", PROPERTY_HINT_RANGE, "0.01,16.0,0.01"), "set_param", "get_param", PARAM_LINEAR_MOTION_SOFTNESS);
412 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_motion/restitution", PROPERTY_HINT_RANGE, "0.01,16.0,0.01"), "set_param", "get_param", PARAM_LINEAR_MOTION_RESTITUTION);
413 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_motion/damping", PROPERTY_HINT_RANGE, "0,16.0,0.01"), "set_param", "get_param", PARAM_LINEAR_MOTION_DAMPING);
414 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_ortho/softness", PROPERTY_HINT_RANGE, "0.01,16.0,0.01"), "set_param", "get_param", PARAM_LINEAR_ORTHOGONAL_SOFTNESS);
415 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_ortho/restitution", PROPERTY_HINT_RANGE, "0.01,16.0,0.01"), "set_param", "get_param", PARAM_LINEAR_ORTHOGONAL_RESTITUTION);
416 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_ortho/damping", PROPERTY_HINT_RANGE, "0,16.0,0.01"), "set_param", "get_param", PARAM_LINEAR_ORTHOGONAL_DAMPING);
417
418 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit/upper_angle", PROPERTY_HINT_RANGE, "-180,180,0.1,radians"), "set_param", "get_param", PARAM_ANGULAR_LIMIT_UPPER);
419 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit/lower_angle", PROPERTY_HINT_RANGE, "-180,180,0.1,radians"), "set_param", "get_param", PARAM_ANGULAR_LIMIT_LOWER);
420 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit/softness", PROPERTY_HINT_RANGE, "0.01,16.0,0.01"), "set_param", "get_param", PARAM_ANGULAR_LIMIT_SOFTNESS);
421 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit/restitution", PROPERTY_HINT_RANGE, "0.01,16.0,0.01"), "set_param", "get_param", PARAM_ANGULAR_LIMIT_RESTITUTION);
422 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit/damping", PROPERTY_HINT_RANGE, "0,16.0,0.01"), "set_param", "get_param", PARAM_ANGULAR_LIMIT_DAMPING);
423 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_motion/softness", PROPERTY_HINT_RANGE, "0.01,16.0,0.01"), "set_param", "get_param", PARAM_ANGULAR_MOTION_SOFTNESS);
424 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_motion/restitution", PROPERTY_HINT_RANGE, "0.01,16.0,0.01"), "set_param", "get_param", PARAM_ANGULAR_MOTION_RESTITUTION);
425 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_motion/damping", PROPERTY_HINT_RANGE, "0,16.0,0.01"), "set_param", "get_param", PARAM_ANGULAR_MOTION_DAMPING);
426 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_ortho/softness", PROPERTY_HINT_RANGE, "0.01,16.0,0.01"), "set_param", "get_param", PARAM_ANGULAR_ORTHOGONAL_SOFTNESS);
427 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_ortho/restitution", PROPERTY_HINT_RANGE, "0.01,16.0,0.01"), "set_param", "get_param", PARAM_ANGULAR_ORTHOGONAL_RESTITUTION);
428 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_ortho/damping", PROPERTY_HINT_RANGE, "0,16.0,0.01"), "set_param", "get_param", PARAM_ANGULAR_ORTHOGONAL_DAMPING);
429
430 BIND_ENUM_CONSTANT(PARAM_LINEAR_LIMIT_UPPER);
431 BIND_ENUM_CONSTANT(PARAM_LINEAR_LIMIT_LOWER);
432 BIND_ENUM_CONSTANT(PARAM_LINEAR_LIMIT_SOFTNESS);
433 BIND_ENUM_CONSTANT(PARAM_LINEAR_LIMIT_RESTITUTION);
434 BIND_ENUM_CONSTANT(PARAM_LINEAR_LIMIT_DAMPING);
435 BIND_ENUM_CONSTANT(PARAM_LINEAR_MOTION_SOFTNESS);
436 BIND_ENUM_CONSTANT(PARAM_LINEAR_MOTION_RESTITUTION);
437 BIND_ENUM_CONSTANT(PARAM_LINEAR_MOTION_DAMPING);
438 BIND_ENUM_CONSTANT(PARAM_LINEAR_ORTHOGONAL_SOFTNESS);
439 BIND_ENUM_CONSTANT(PARAM_LINEAR_ORTHOGONAL_RESTITUTION);
440 BIND_ENUM_CONSTANT(PARAM_LINEAR_ORTHOGONAL_DAMPING);
441
442 BIND_ENUM_CONSTANT(PARAM_ANGULAR_LIMIT_UPPER);
443 BIND_ENUM_CONSTANT(PARAM_ANGULAR_LIMIT_LOWER);
444 BIND_ENUM_CONSTANT(PARAM_ANGULAR_LIMIT_SOFTNESS);
445 BIND_ENUM_CONSTANT(PARAM_ANGULAR_LIMIT_RESTITUTION);
446 BIND_ENUM_CONSTANT(PARAM_ANGULAR_LIMIT_DAMPING);
447 BIND_ENUM_CONSTANT(PARAM_ANGULAR_MOTION_SOFTNESS);
448 BIND_ENUM_CONSTANT(PARAM_ANGULAR_MOTION_RESTITUTION);
449 BIND_ENUM_CONSTANT(PARAM_ANGULAR_MOTION_DAMPING);
450 BIND_ENUM_CONSTANT(PARAM_ANGULAR_ORTHOGONAL_SOFTNESS);
451 BIND_ENUM_CONSTANT(PARAM_ANGULAR_ORTHOGONAL_RESTITUTION);
452 BIND_ENUM_CONSTANT(PARAM_ANGULAR_ORTHOGONAL_DAMPING);
453
454 BIND_ENUM_CONSTANT(PARAM_MAX);
455}
456
457void SliderJoint3D::set_param(Param p_param, real_t p_value) {
458 ERR_FAIL_INDEX(p_param, PARAM_MAX);
459 params[p_param] = p_value;
460 if (is_configured()) {
461 PhysicsServer3D::get_singleton()->slider_joint_set_param(get_joint(), PhysicsServer3D::SliderJointParam(p_param), p_value);
462 }
463 update_gizmos();
464}
465
466real_t SliderJoint3D::get_param(Param p_param) const {
467 ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0);
468 return params[p_param];
469}
470
471void SliderJoint3D::_configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) {
472 Transform3D gt = get_global_transform();
473 Transform3D ainv = body_a->get_global_transform().affine_inverse();
474
475 Transform3D local_a = ainv * gt;
476 local_a.orthonormalize();
477 Transform3D local_b = gt;
478
479 if (body_b) {
480 Transform3D binv = body_b->get_global_transform().affine_inverse();
481 local_b = binv * gt;
482 }
483
484 local_b.orthonormalize();
485
486 PhysicsServer3D::get_singleton()->joint_make_slider(p_joint, body_a->get_rid(), local_a, body_b ? body_b->get_rid() : RID(), local_b);
487 for (int i = 0; i < PARAM_MAX; i++) {
488 PhysicsServer3D::get_singleton()->slider_joint_set_param(p_joint, PhysicsServer3D::SliderJointParam(i), params[i]);
489 }
490}
491
492SliderJoint3D::SliderJoint3D() {
493 params[PARAM_LINEAR_LIMIT_UPPER] = 1.0;
494 params[PARAM_LINEAR_LIMIT_LOWER] = -1.0;
495 params[PARAM_LINEAR_LIMIT_SOFTNESS] = 1.0;
496 params[PARAM_LINEAR_LIMIT_RESTITUTION] = 0.7;
497 params[PARAM_LINEAR_LIMIT_DAMPING] = 1.0;
498 params[PARAM_LINEAR_MOTION_SOFTNESS] = 1.0;
499 params[PARAM_LINEAR_MOTION_RESTITUTION] = 0.7;
500 params[PARAM_LINEAR_MOTION_DAMPING] = 0; //1.0;
501 params[PARAM_LINEAR_ORTHOGONAL_SOFTNESS] = 1.0;
502 params[PARAM_LINEAR_ORTHOGONAL_RESTITUTION] = 0.7;
503 params[PARAM_LINEAR_ORTHOGONAL_DAMPING] = 1.0;
504
505 params[PARAM_ANGULAR_LIMIT_UPPER] = 0;
506 params[PARAM_ANGULAR_LIMIT_LOWER] = 0;
507 params[PARAM_ANGULAR_LIMIT_SOFTNESS] = 1.0;
508 params[PARAM_ANGULAR_LIMIT_RESTITUTION] = 0.7;
509 params[PARAM_ANGULAR_LIMIT_DAMPING] = 0; //1.0;
510 params[PARAM_ANGULAR_MOTION_SOFTNESS] = 1.0;
511 params[PARAM_ANGULAR_MOTION_RESTITUTION] = 0.7;
512 params[PARAM_ANGULAR_MOTION_DAMPING] = 1.0;
513 params[PARAM_ANGULAR_ORTHOGONAL_SOFTNESS] = 1.0;
514 params[PARAM_ANGULAR_ORTHOGONAL_RESTITUTION] = 0.7;
515 params[PARAM_ANGULAR_ORTHOGONAL_DAMPING] = 1.0;
516}
517
518//////////////////////////////////
519
520void ConeTwistJoint3D::_bind_methods() {
521 ClassDB::bind_method(D_METHOD("set_param", "param", "value"), &ConeTwistJoint3D::set_param);
522 ClassDB::bind_method(D_METHOD("get_param", "param"), &ConeTwistJoint3D::get_param);
523
524 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "swing_span", PROPERTY_HINT_RANGE, "-180,180,0.1,radians"), "set_param", "get_param", PARAM_SWING_SPAN);
525 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "twist_span", PROPERTY_HINT_RANGE, "-40000,40000,0.1,radians"), "set_param", "get_param", PARAM_TWIST_SPAN);
526
527 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "bias", PROPERTY_HINT_RANGE, "0.01,16.0,0.01"), "set_param", "get_param", PARAM_BIAS);
528 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "softness", PROPERTY_HINT_RANGE, "0.01,16.0,0.01"), "set_param", "get_param", PARAM_SOFTNESS);
529 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "relaxation", PROPERTY_HINT_RANGE, "0.01,16.0,0.01"), "set_param", "get_param", PARAM_RELAXATION);
530
531 BIND_ENUM_CONSTANT(PARAM_SWING_SPAN);
532 BIND_ENUM_CONSTANT(PARAM_TWIST_SPAN);
533 BIND_ENUM_CONSTANT(PARAM_BIAS);
534 BIND_ENUM_CONSTANT(PARAM_SOFTNESS);
535 BIND_ENUM_CONSTANT(PARAM_RELAXATION);
536 BIND_ENUM_CONSTANT(PARAM_MAX);
537}
538
539void ConeTwistJoint3D::set_param(Param p_param, real_t p_value) {
540 ERR_FAIL_INDEX(p_param, PARAM_MAX);
541 params[p_param] = p_value;
542 if (is_configured()) {
543 PhysicsServer3D::get_singleton()->cone_twist_joint_set_param(get_joint(), PhysicsServer3D::ConeTwistJointParam(p_param), p_value);
544 }
545
546 update_gizmos();
547}
548
549real_t ConeTwistJoint3D::get_param(Param p_param) const {
550 ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0);
551 return params[p_param];
552}
553
554void ConeTwistJoint3D::_configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) {
555 Transform3D gt = get_global_transform();
556
557 Transform3D ainv = body_a->get_global_transform().affine_inverse();
558
559 Transform3D local_a = ainv * gt;
560 local_a.orthonormalize();
561 Transform3D local_b = gt;
562
563 if (body_b) {
564 Transform3D binv = body_b->get_global_transform().affine_inverse();
565 local_b = binv * gt;
566 }
567
568 local_b.orthonormalize();
569
570 PhysicsServer3D::get_singleton()->joint_make_cone_twist(p_joint, body_a->get_rid(), local_a, body_b ? body_b->get_rid() : RID(), local_b);
571 for (int i = 0; i < PARAM_MAX; i++) {
572 PhysicsServer3D::get_singleton()->cone_twist_joint_set_param(p_joint, PhysicsServer3D::ConeTwistJointParam(i), params[i]);
573 }
574}
575
576ConeTwistJoint3D::ConeTwistJoint3D() {
577 params[PARAM_SWING_SPAN] = Math_PI * 0.25;
578 params[PARAM_TWIST_SPAN] = Math_PI;
579 params[PARAM_BIAS] = 0.3;
580 params[PARAM_SOFTNESS] = 0.8;
581 params[PARAM_RELAXATION] = 1.0;
582}
583
584/////////////////////////////////////////////////////////////////////
585
586void Generic6DOFJoint3D::_bind_methods() {
587 ClassDB::bind_method(D_METHOD("set_param_x", "param", "value"), &Generic6DOFJoint3D::set_param_x);
588 ClassDB::bind_method(D_METHOD("get_param_x", "param"), &Generic6DOFJoint3D::get_param_x);
589
590 ClassDB::bind_method(D_METHOD("set_param_y", "param", "value"), &Generic6DOFJoint3D::set_param_y);
591 ClassDB::bind_method(D_METHOD("get_param_y", "param"), &Generic6DOFJoint3D::get_param_y);
592
593 ClassDB::bind_method(D_METHOD("set_param_z", "param", "value"), &Generic6DOFJoint3D::set_param_z);
594 ClassDB::bind_method(D_METHOD("get_param_z", "param"), &Generic6DOFJoint3D::get_param_z);
595
596 ClassDB::bind_method(D_METHOD("set_flag_x", "flag", "value"), &Generic6DOFJoint3D::set_flag_x);
597 ClassDB::bind_method(D_METHOD("get_flag_x", "flag"), &Generic6DOFJoint3D::get_flag_x);
598
599 ClassDB::bind_method(D_METHOD("set_flag_y", "flag", "value"), &Generic6DOFJoint3D::set_flag_y);
600 ClassDB::bind_method(D_METHOD("get_flag_y", "flag"), &Generic6DOFJoint3D::get_flag_y);
601
602 ClassDB::bind_method(D_METHOD("set_flag_z", "flag", "value"), &Generic6DOFJoint3D::set_flag_z);
603 ClassDB::bind_method(D_METHOD("get_flag_z", "flag"), &Generic6DOFJoint3D::get_flag_z);
604
605 ADD_GROUP("Linear Limit", "linear_limit_");
606
607 ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "linear_limit_x/enabled"), "set_flag_x", "get_flag_x", FLAG_ENABLE_LINEAR_LIMIT);
608 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_x/upper_distance", PROPERTY_HINT_NONE, "suffix:m"), "set_param_x", "get_param_x", PARAM_LINEAR_UPPER_LIMIT);
609 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_x/lower_distance", PROPERTY_HINT_NONE, "suffix:m"), "set_param_x", "get_param_x", PARAM_LINEAR_LOWER_LIMIT);
610 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_x/softness", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_x", "get_param_x", PARAM_LINEAR_LIMIT_SOFTNESS);
611 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_x/restitution", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_x", "get_param_x", PARAM_LINEAR_RESTITUTION);
612 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_x/damping", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_x", "get_param_x", PARAM_LINEAR_DAMPING);
613
614 ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "linear_limit_y/enabled"), "set_flag_y", "get_flag_y", FLAG_ENABLE_LINEAR_LIMIT);
615 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_y/upper_distance", PROPERTY_HINT_NONE, "suffix:m"), "set_param_y", "get_param_y", PARAM_LINEAR_UPPER_LIMIT);
616 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_y/lower_distance", PROPERTY_HINT_NONE, "suffix:m"), "set_param_y", "get_param_y", PARAM_LINEAR_LOWER_LIMIT);
617 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_y/softness", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_y", "get_param_y", PARAM_LINEAR_LIMIT_SOFTNESS);
618 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_y/restitution", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_y", "get_param_y", PARAM_LINEAR_RESTITUTION);
619 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_y/damping", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_y", "get_param_y", PARAM_LINEAR_DAMPING);
620
621 ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "linear_limit_z/enabled"), "set_flag_z", "get_flag_z", FLAG_ENABLE_LINEAR_LIMIT);
622 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_z/upper_distance", PROPERTY_HINT_NONE, "suffix:m"), "set_param_z", "get_param_z", PARAM_LINEAR_UPPER_LIMIT);
623 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_z/lower_distance", PROPERTY_HINT_NONE, "suffix:m"), "set_param_z", "get_param_z", PARAM_LINEAR_LOWER_LIMIT);
624 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_z/softness", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_z", "get_param_z", PARAM_LINEAR_LIMIT_SOFTNESS);
625 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_z/restitution", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_z", "get_param_z", PARAM_LINEAR_RESTITUTION);
626 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_z/damping", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_z", "get_param_z", PARAM_LINEAR_DAMPING);
627
628 ADD_GROUP("Linear Motor", "linear_motor_");
629
630 ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "linear_motor_x/enabled"), "set_flag_x", "get_flag_x", FLAG_ENABLE_LINEAR_MOTOR);
631 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_motor_x/target_velocity", PROPERTY_HINT_NONE, "suffix:m/s"), "set_param_x", "get_param_x", PARAM_LINEAR_MOTOR_TARGET_VELOCITY);
632 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_motor_x/force_limit"), "set_param_x", "get_param_x", PARAM_LINEAR_MOTOR_FORCE_LIMIT);
633
634 ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "linear_motor_y/enabled"), "set_flag_y", "get_flag_y", FLAG_ENABLE_LINEAR_MOTOR);
635 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_motor_y/target_velocity", PROPERTY_HINT_NONE, "suffix:m/s"), "set_param_y", "get_param_y", PARAM_LINEAR_MOTOR_TARGET_VELOCITY);
636 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_motor_y/force_limit"), "set_param_y", "get_param_y", PARAM_LINEAR_MOTOR_FORCE_LIMIT);
637
638 ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "linear_motor_z/enabled"), "set_flag_z", "get_flag_z", FLAG_ENABLE_LINEAR_MOTOR);
639 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_motor_z/target_velocity", PROPERTY_HINT_NONE, "suffix:m/s"), "set_param_z", "get_param_z", PARAM_LINEAR_MOTOR_TARGET_VELOCITY);
640 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_motor_z/force_limit"), "set_param_z", "get_param_z", PARAM_LINEAR_MOTOR_FORCE_LIMIT);
641
642 ADD_GROUP("Linear Spring", "linear_spring_");
643
644 ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "linear_spring_x/enabled"), "set_flag_x", "get_flag_x", FLAG_ENABLE_LINEAR_SPRING);
645 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_spring_x/stiffness"), "set_param_x", "get_param_x", PARAM_LINEAR_SPRING_STIFFNESS);
646 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_spring_x/damping"), "set_param_x", "get_param_x", PARAM_LINEAR_SPRING_DAMPING);
647 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_spring_x/equilibrium_point"), "set_param_x", "get_param_x", PARAM_LINEAR_SPRING_EQUILIBRIUM_POINT);
648
649 ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "linear_spring_y/enabled"), "set_flag_y", "get_flag_y", FLAG_ENABLE_LINEAR_SPRING);
650 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_spring_y/stiffness"), "set_param_y", "get_param_y", PARAM_LINEAR_SPRING_STIFFNESS);
651 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_spring_y/damping"), "set_param_y", "get_param_y", PARAM_LINEAR_SPRING_DAMPING);
652 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_spring_y/equilibrium_point"), "set_param_y", "get_param_y", PARAM_LINEAR_SPRING_EQUILIBRIUM_POINT);
653
654 ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "linear_spring_z/enabled"), "set_flag_z", "get_flag_z", FLAG_ENABLE_LINEAR_SPRING);
655 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_spring_z/stiffness"), "set_param_z", "get_param_z", PARAM_LINEAR_SPRING_STIFFNESS);
656 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_spring_z/damping"), "set_param_z", "get_param_z", PARAM_LINEAR_SPRING_DAMPING);
657 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_spring_z/equilibrium_point"), "set_param_z", "get_param_z", PARAM_LINEAR_SPRING_EQUILIBRIUM_POINT);
658
659 ADD_GROUP("Angular Limit", "angular_limit_");
660
661 ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "angular_limit_x/enabled"), "set_flag_x", "get_flag_x", FLAG_ENABLE_ANGULAR_LIMIT);
662 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit_x/upper_angle", PROPERTY_HINT_RANGE, "-180,180,0.01,radians"), "set_param_x", "get_param_x", PARAM_ANGULAR_UPPER_LIMIT);
663 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit_x/lower_angle", PROPERTY_HINT_RANGE, "-180,180,0.01,radians"), "set_param_x", "get_param_x", PARAM_ANGULAR_LOWER_LIMIT);
664 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit_x/softness", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_x", "get_param_x", PARAM_ANGULAR_LIMIT_SOFTNESS);
665 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit_x/restitution", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_x", "get_param_x", PARAM_ANGULAR_RESTITUTION);
666 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit_x/damping", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_x", "get_param_x", PARAM_ANGULAR_DAMPING);
667 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit_x/force_limit"), "set_param_x", "get_param_x", PARAM_ANGULAR_FORCE_LIMIT);
668 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit_x/erp"), "set_param_x", "get_param_x", PARAM_ANGULAR_ERP);
669
670 ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "angular_limit_y/enabled"), "set_flag_y", "get_flag_y", FLAG_ENABLE_ANGULAR_LIMIT);
671 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit_y/upper_angle", PROPERTY_HINT_RANGE, "-180,180,0.01,radians"), "set_param_y", "get_param_y", PARAM_ANGULAR_UPPER_LIMIT);
672 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit_y/lower_angle", PROPERTY_HINT_RANGE, "-180,180,0.01,radians"), "set_param_y", "get_param_y", PARAM_ANGULAR_LOWER_LIMIT);
673 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit_y/softness", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_y", "get_param_y", PARAM_ANGULAR_LIMIT_SOFTNESS);
674 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit_y/restitution", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_y", "get_param_y", PARAM_ANGULAR_RESTITUTION);
675 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit_y/damping", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_y", "get_param_y", PARAM_ANGULAR_DAMPING);
676 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit_y/force_limit"), "set_param_y", "get_param_y", PARAM_ANGULAR_FORCE_LIMIT);
677 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit_y/erp"), "set_param_y", "get_param_y", PARAM_ANGULAR_ERP);
678
679 ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "angular_limit_z/enabled"), "set_flag_z", "get_flag_z", FLAG_ENABLE_ANGULAR_LIMIT);
680 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit_z/upper_angle", PROPERTY_HINT_RANGE, "-180,180,0.01,radians"), "set_param_z", "get_param_z", PARAM_ANGULAR_UPPER_LIMIT);
681 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit_z/lower_angle", PROPERTY_HINT_RANGE, "-180,180,0.01,radians"), "set_param_z", "get_param_z", PARAM_ANGULAR_LOWER_LIMIT);
682 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit_z/softness", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_z", "get_param_z", PARAM_ANGULAR_LIMIT_SOFTNESS);
683 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit_z/restitution", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_z", "get_param_z", PARAM_ANGULAR_RESTITUTION);
684 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit_z/damping", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_z", "get_param_z", PARAM_ANGULAR_DAMPING);
685 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit_z/force_limit"), "set_param_z", "get_param_z", PARAM_ANGULAR_FORCE_LIMIT);
686 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit_z/erp"), "set_param_z", "get_param_z", PARAM_ANGULAR_ERP);
687
688 ADD_GROUP("Angular Motor", "angular_motor_");
689
690 ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "angular_motor_x/enabled"), "set_flag_x", "get_flag_x", FLAG_ENABLE_MOTOR);
691 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_motor_x/target_velocity"), "set_param_x", "get_param_x", PARAM_ANGULAR_MOTOR_TARGET_VELOCITY);
692 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_motor_x/force_limit"), "set_param_x", "get_param_x", PARAM_ANGULAR_MOTOR_FORCE_LIMIT);
693
694 ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "angular_motor_y/enabled"), "set_flag_y", "get_flag_y", FLAG_ENABLE_MOTOR);
695 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_motor_y/target_velocity"), "set_param_y", "get_param_y", PARAM_ANGULAR_MOTOR_TARGET_VELOCITY);
696 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_motor_y/force_limit"), "set_param_y", "get_param_y", PARAM_ANGULAR_MOTOR_FORCE_LIMIT);
697
698 ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "angular_motor_z/enabled"), "set_flag_z", "get_flag_z", FLAG_ENABLE_MOTOR);
699 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_motor_z/target_velocity"), "set_param_z", "get_param_z", PARAM_ANGULAR_MOTOR_TARGET_VELOCITY);
700 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_motor_z/force_limit"), "set_param_z", "get_param_z", PARAM_ANGULAR_MOTOR_FORCE_LIMIT);
701
702 ADD_GROUP("Angular Spring", "angular_spring_");
703
704 ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "angular_spring_x/enabled"), "set_flag_x", "get_flag_x", FLAG_ENABLE_ANGULAR_SPRING);
705 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_spring_x/stiffness"), "set_param_x", "get_param_x", PARAM_ANGULAR_SPRING_STIFFNESS);
706 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_spring_x/damping"), "set_param_x", "get_param_x", PARAM_ANGULAR_SPRING_DAMPING);
707 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_spring_x/equilibrium_point"), "set_param_x", "get_param_x", PARAM_ANGULAR_SPRING_EQUILIBRIUM_POINT);
708
709 ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "angular_spring_y/enabled"), "set_flag_y", "get_flag_y", FLAG_ENABLE_ANGULAR_SPRING);
710 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_spring_y/stiffness"), "set_param_y", "get_param_y", PARAM_ANGULAR_SPRING_STIFFNESS);
711 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_spring_y/damping"), "set_param_y", "get_param_y", PARAM_ANGULAR_SPRING_DAMPING);
712 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_spring_y/equilibrium_point"), "set_param_y", "get_param_y", PARAM_ANGULAR_SPRING_EQUILIBRIUM_POINT);
713
714 ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "angular_spring_z/enabled"), "set_flag_z", "get_flag_z", FLAG_ENABLE_ANGULAR_SPRING);
715 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_spring_z/stiffness"), "set_param_z", "get_param_z", PARAM_ANGULAR_SPRING_STIFFNESS);
716 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_spring_z/damping"), "set_param_z", "get_param_z", PARAM_ANGULAR_SPRING_DAMPING);
717 ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_spring_z/equilibrium_point"), "set_param_z", "get_param_z", PARAM_ANGULAR_SPRING_EQUILIBRIUM_POINT);
718
719 BIND_ENUM_CONSTANT(PARAM_LINEAR_LOWER_LIMIT);
720 BIND_ENUM_CONSTANT(PARAM_LINEAR_UPPER_LIMIT);
721 BIND_ENUM_CONSTANT(PARAM_LINEAR_LIMIT_SOFTNESS);
722 BIND_ENUM_CONSTANT(PARAM_LINEAR_RESTITUTION);
723 BIND_ENUM_CONSTANT(PARAM_LINEAR_DAMPING);
724 BIND_ENUM_CONSTANT(PARAM_LINEAR_MOTOR_TARGET_VELOCITY);
725 BIND_ENUM_CONSTANT(PARAM_LINEAR_MOTOR_FORCE_LIMIT);
726 BIND_ENUM_CONSTANT(PARAM_LINEAR_SPRING_STIFFNESS);
727 BIND_ENUM_CONSTANT(PARAM_LINEAR_SPRING_DAMPING);
728 BIND_ENUM_CONSTANT(PARAM_LINEAR_SPRING_EQUILIBRIUM_POINT);
729 BIND_ENUM_CONSTANT(PARAM_ANGULAR_LOWER_LIMIT);
730 BIND_ENUM_CONSTANT(PARAM_ANGULAR_UPPER_LIMIT);
731 BIND_ENUM_CONSTANT(PARAM_ANGULAR_LIMIT_SOFTNESS);
732 BIND_ENUM_CONSTANT(PARAM_ANGULAR_DAMPING);
733 BIND_ENUM_CONSTANT(PARAM_ANGULAR_RESTITUTION);
734 BIND_ENUM_CONSTANT(PARAM_ANGULAR_FORCE_LIMIT);
735 BIND_ENUM_CONSTANT(PARAM_ANGULAR_ERP);
736 BIND_ENUM_CONSTANT(PARAM_ANGULAR_MOTOR_TARGET_VELOCITY);
737 BIND_ENUM_CONSTANT(PARAM_ANGULAR_MOTOR_FORCE_LIMIT);
738 BIND_ENUM_CONSTANT(PARAM_ANGULAR_SPRING_STIFFNESS);
739 BIND_ENUM_CONSTANT(PARAM_ANGULAR_SPRING_DAMPING);
740 BIND_ENUM_CONSTANT(PARAM_ANGULAR_SPRING_EQUILIBRIUM_POINT);
741 BIND_ENUM_CONSTANT(PARAM_MAX);
742
743 BIND_ENUM_CONSTANT(FLAG_ENABLE_LINEAR_LIMIT);
744 BIND_ENUM_CONSTANT(FLAG_ENABLE_ANGULAR_LIMIT);
745 BIND_ENUM_CONSTANT(FLAG_ENABLE_LINEAR_SPRING);
746 BIND_ENUM_CONSTANT(FLAG_ENABLE_ANGULAR_SPRING);
747 BIND_ENUM_CONSTANT(FLAG_ENABLE_MOTOR);
748 BIND_ENUM_CONSTANT(FLAG_ENABLE_LINEAR_MOTOR);
749 BIND_ENUM_CONSTANT(FLAG_MAX);
750}
751
752void Generic6DOFJoint3D::set_param_x(Param p_param, real_t p_value) {
753 ERR_FAIL_INDEX(p_param, PARAM_MAX);
754 params_x[p_param] = p_value;
755 if (is_configured()) {
756 PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(get_joint(), Vector3::AXIS_X, PhysicsServer3D::G6DOFJointAxisParam(p_param), p_value);
757 }
758
759 update_gizmos();
760}
761
762real_t Generic6DOFJoint3D::get_param_x(Param p_param) const {
763 ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0);
764 return params_x[p_param];
765}
766
767void Generic6DOFJoint3D::set_param_y(Param p_param, real_t p_value) {
768 ERR_FAIL_INDEX(p_param, PARAM_MAX);
769 params_y[p_param] = p_value;
770 if (is_configured()) {
771 PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(get_joint(), Vector3::AXIS_Y, PhysicsServer3D::G6DOFJointAxisParam(p_param), p_value);
772 }
773 update_gizmos();
774}
775
776real_t Generic6DOFJoint3D::get_param_y(Param p_param) const {
777 ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0);
778 return params_y[p_param];
779}
780
781void Generic6DOFJoint3D::set_param_z(Param p_param, real_t p_value) {
782 ERR_FAIL_INDEX(p_param, PARAM_MAX);
783 params_z[p_param] = p_value;
784 if (is_configured()) {
785 PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(get_joint(), Vector3::AXIS_Z, PhysicsServer3D::G6DOFJointAxisParam(p_param), p_value);
786 }
787 update_gizmos();
788}
789
790real_t Generic6DOFJoint3D::get_param_z(Param p_param) const {
791 ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0);
792 return params_z[p_param];
793}
794
795void Generic6DOFJoint3D::set_flag_x(Flag p_flag, bool p_enabled) {
796 ERR_FAIL_INDEX(p_flag, FLAG_MAX);
797 flags_x[p_flag] = p_enabled;
798 if (is_configured()) {
799 PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(get_joint(), Vector3::AXIS_X, PhysicsServer3D::G6DOFJointAxisFlag(p_flag), p_enabled);
800 }
801 update_gizmos();
802}
803
804bool Generic6DOFJoint3D::get_flag_x(Flag p_flag) const {
805 ERR_FAIL_INDEX_V(p_flag, FLAG_MAX, false);
806 return flags_x[p_flag];
807}
808
809void Generic6DOFJoint3D::set_flag_y(Flag p_flag, bool p_enabled) {
810 ERR_FAIL_INDEX(p_flag, FLAG_MAX);
811 flags_y[p_flag] = p_enabled;
812 if (is_configured()) {
813 PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(get_joint(), Vector3::AXIS_Y, PhysicsServer3D::G6DOFJointAxisFlag(p_flag), p_enabled);
814 }
815 update_gizmos();
816}
817
818bool Generic6DOFJoint3D::get_flag_y(Flag p_flag) const {
819 ERR_FAIL_INDEX_V(p_flag, FLAG_MAX, false);
820 return flags_y[p_flag];
821}
822
823void Generic6DOFJoint3D::set_flag_z(Flag p_flag, bool p_enabled) {
824 ERR_FAIL_INDEX(p_flag, FLAG_MAX);
825 flags_z[p_flag] = p_enabled;
826 if (is_configured()) {
827 PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(get_joint(), Vector3::AXIS_Z, PhysicsServer3D::G6DOFJointAxisFlag(p_flag), p_enabled);
828 }
829 update_gizmos();
830}
831
832bool Generic6DOFJoint3D::get_flag_z(Flag p_flag) const {
833 ERR_FAIL_INDEX_V(p_flag, FLAG_MAX, false);
834 return flags_z[p_flag];
835}
836
837void Generic6DOFJoint3D::_configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) {
838 Transform3D gt = get_global_transform();
839 //Vector3 cone_twistpos = gt.origin;
840 //Vector3 cone_twistdir = gt.basis.get_axis(2);
841
842 Transform3D ainv = body_a->get_global_transform().affine_inverse();
843
844 Transform3D local_a = ainv * gt;
845 local_a.orthonormalize();
846 Transform3D local_b = gt;
847
848 if (body_b) {
849 Transform3D binv = body_b->get_global_transform().affine_inverse();
850 local_b = binv * gt;
851 }
852
853 local_b.orthonormalize();
854
855 PhysicsServer3D::get_singleton()->joint_make_generic_6dof(p_joint, body_a->get_rid(), local_a, body_b ? body_b->get_rid() : RID(), local_b);
856 for (int i = 0; i < PARAM_MAX; i++) {
857 PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(p_joint, Vector3::AXIS_X, PhysicsServer3D::G6DOFJointAxisParam(i), params_x[i]);
858 PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(p_joint, Vector3::AXIS_Y, PhysicsServer3D::G6DOFJointAxisParam(i), params_y[i]);
859 PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(p_joint, Vector3::AXIS_Z, PhysicsServer3D::G6DOFJointAxisParam(i), params_z[i]);
860 }
861 for (int i = 0; i < FLAG_MAX; i++) {
862 PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(p_joint, Vector3::AXIS_X, PhysicsServer3D::G6DOFJointAxisFlag(i), flags_x[i]);
863 PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(p_joint, Vector3::AXIS_Y, PhysicsServer3D::G6DOFJointAxisFlag(i), flags_y[i]);
864 PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(p_joint, Vector3::AXIS_Z, PhysicsServer3D::G6DOFJointAxisFlag(i), flags_z[i]);
865 }
866}
867
868Generic6DOFJoint3D::Generic6DOFJoint3D() {
869 set_param_x(PARAM_LINEAR_LOWER_LIMIT, 0);
870 set_param_x(PARAM_LINEAR_UPPER_LIMIT, 0);
871 set_param_x(PARAM_LINEAR_LIMIT_SOFTNESS, 0.7);
872 set_param_x(PARAM_LINEAR_RESTITUTION, 0.5);
873 set_param_x(PARAM_LINEAR_DAMPING, 1.0);
874 set_param_x(PARAM_LINEAR_MOTOR_TARGET_VELOCITY, 0);
875 set_param_x(PARAM_LINEAR_MOTOR_FORCE_LIMIT, 0);
876 set_param_x(PARAM_LINEAR_SPRING_STIFFNESS, 0.01);
877 set_param_x(PARAM_LINEAR_SPRING_DAMPING, 0.01);
878 set_param_x(PARAM_LINEAR_SPRING_EQUILIBRIUM_POINT, 0.0);
879 set_param_x(PARAM_ANGULAR_LOWER_LIMIT, 0);
880 set_param_x(PARAM_ANGULAR_UPPER_LIMIT, 0);
881 set_param_x(PARAM_ANGULAR_LIMIT_SOFTNESS, 0.5f);
882 set_param_x(PARAM_ANGULAR_DAMPING, 1.0f);
883 set_param_x(PARAM_ANGULAR_RESTITUTION, 0);
884 set_param_x(PARAM_ANGULAR_FORCE_LIMIT, 0);
885 set_param_x(PARAM_ANGULAR_ERP, 0.5);
886 set_param_x(PARAM_ANGULAR_MOTOR_TARGET_VELOCITY, 0);
887 set_param_x(PARAM_ANGULAR_MOTOR_FORCE_LIMIT, 300);
888 set_param_x(PARAM_ANGULAR_SPRING_STIFFNESS, 0);
889 set_param_x(PARAM_ANGULAR_SPRING_DAMPING, 0);
890 set_param_x(PARAM_ANGULAR_SPRING_EQUILIBRIUM_POINT, 0);
891
892 set_flag_x(FLAG_ENABLE_ANGULAR_LIMIT, true);
893 set_flag_x(FLAG_ENABLE_LINEAR_LIMIT, true);
894 set_flag_x(FLAG_ENABLE_ANGULAR_SPRING, false);
895 set_flag_x(FLAG_ENABLE_LINEAR_SPRING, false);
896 set_flag_x(FLAG_ENABLE_MOTOR, false);
897 set_flag_x(FLAG_ENABLE_LINEAR_MOTOR, false);
898
899 set_param_y(PARAM_LINEAR_LOWER_LIMIT, 0);
900 set_param_y(PARAM_LINEAR_UPPER_LIMIT, 0);
901 set_param_y(PARAM_LINEAR_LIMIT_SOFTNESS, 0.7);
902 set_param_y(PARAM_LINEAR_RESTITUTION, 0.5);
903 set_param_y(PARAM_LINEAR_DAMPING, 1.0);
904 set_param_y(PARAM_LINEAR_MOTOR_TARGET_VELOCITY, 0);
905 set_param_y(PARAM_LINEAR_MOTOR_FORCE_LIMIT, 0);
906 set_param_y(PARAM_LINEAR_SPRING_STIFFNESS, 0.01);
907 set_param_y(PARAM_LINEAR_SPRING_DAMPING, 0.01);
908 set_param_y(PARAM_LINEAR_SPRING_EQUILIBRIUM_POINT, 0.0);
909 set_param_y(PARAM_ANGULAR_LOWER_LIMIT, 0);
910 set_param_y(PARAM_ANGULAR_UPPER_LIMIT, 0);
911 set_param_y(PARAM_ANGULAR_LIMIT_SOFTNESS, 0.5f);
912 set_param_y(PARAM_ANGULAR_DAMPING, 1.0f);
913 set_param_y(PARAM_ANGULAR_RESTITUTION, 0);
914 set_param_y(PARAM_ANGULAR_FORCE_LIMIT, 0);
915 set_param_y(PARAM_ANGULAR_ERP, 0.5);
916 set_param_y(PARAM_ANGULAR_MOTOR_TARGET_VELOCITY, 0);
917 set_param_y(PARAM_ANGULAR_MOTOR_FORCE_LIMIT, 300);
918 set_param_y(PARAM_ANGULAR_SPRING_STIFFNESS, 0);
919 set_param_y(PARAM_ANGULAR_SPRING_DAMPING, 0);
920 set_param_y(PARAM_ANGULAR_SPRING_EQUILIBRIUM_POINT, 0);
921
922 set_flag_y(FLAG_ENABLE_ANGULAR_LIMIT, true);
923 set_flag_y(FLAG_ENABLE_LINEAR_LIMIT, true);
924 set_flag_y(FLAG_ENABLE_ANGULAR_SPRING, false);
925 set_flag_y(FLAG_ENABLE_LINEAR_SPRING, false);
926 set_flag_y(FLAG_ENABLE_MOTOR, false);
927 set_flag_y(FLAG_ENABLE_LINEAR_MOTOR, false);
928
929 set_param_z(PARAM_LINEAR_LOWER_LIMIT, 0);
930 set_param_z(PARAM_LINEAR_UPPER_LIMIT, 0);
931 set_param_z(PARAM_LINEAR_LIMIT_SOFTNESS, 0.7);
932 set_param_z(PARAM_LINEAR_RESTITUTION, 0.5);
933 set_param_z(PARAM_LINEAR_DAMPING, 1.0);
934 set_param_z(PARAM_LINEAR_MOTOR_TARGET_VELOCITY, 0);
935 set_param_z(PARAM_LINEAR_MOTOR_FORCE_LIMIT, 0);
936 set_param_z(PARAM_LINEAR_SPRING_STIFFNESS, 0.01);
937 set_param_z(PARAM_LINEAR_SPRING_DAMPING, 0.01);
938 set_param_z(PARAM_LINEAR_SPRING_EQUILIBRIUM_POINT, 0.0);
939 set_param_z(PARAM_ANGULAR_LOWER_LIMIT, 0);
940 set_param_z(PARAM_ANGULAR_UPPER_LIMIT, 0);
941 set_param_z(PARAM_ANGULAR_LIMIT_SOFTNESS, 0.5f);
942 set_param_z(PARAM_ANGULAR_DAMPING, 1.0f);
943 set_param_z(PARAM_ANGULAR_RESTITUTION, 0);
944 set_param_z(PARAM_ANGULAR_FORCE_LIMIT, 0);
945 set_param_z(PARAM_ANGULAR_ERP, 0.5);
946 set_param_z(PARAM_ANGULAR_MOTOR_TARGET_VELOCITY, 0);
947 set_param_z(PARAM_ANGULAR_MOTOR_FORCE_LIMIT, 300);
948 set_param_z(PARAM_ANGULAR_SPRING_STIFFNESS, 0);
949 set_param_z(PARAM_ANGULAR_SPRING_DAMPING, 0);
950 set_param_z(PARAM_ANGULAR_SPRING_EQUILIBRIUM_POINT, 0);
951
952 set_flag_z(FLAG_ENABLE_ANGULAR_LIMIT, true);
953 set_flag_z(FLAG_ENABLE_LINEAR_LIMIT, true);
954 set_flag_z(FLAG_ENABLE_ANGULAR_SPRING, false);
955 set_flag_z(FLAG_ENABLE_LINEAR_SPRING, false);
956 set_flag_z(FLAG_ENABLE_MOTOR, false);
957 set_flag_z(FLAG_ENABLE_LINEAR_MOTOR, false);
958}
959