1 /*************************************************************************/
2 /* physics_body.cpp */
3 /*************************************************************************/
4 /* This file is part of: */
5 /* GODOT ENGINE */
6 /* https://godotengine.org */
7 /*************************************************************************/
8 /* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
9 /* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
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 "physics_body.h"
32
33 #include "core/core_string_names.h"
34 #include "core/engine.h"
35 #include "core/list.h"
36 #include "core/method_bind_ext.gen.inc"
37 #include "core/object.h"
38 #include "core/rid.h"
39 #include "scene/scene_string_names.h"
40
41 #ifdef TOOLS_ENABLED
42 #include "editor/plugins/spatial_editor_plugin.h"
43 #endif
44
_notification(int p_what)45 void PhysicsBody::_notification(int p_what) {
46 }
47
get_linear_velocity() const48 Vector3 PhysicsBody::get_linear_velocity() const {
49
50 return Vector3();
51 }
get_angular_velocity() const52 Vector3 PhysicsBody::get_angular_velocity() const {
53
54 return Vector3();
55 }
56
get_inverse_mass() const57 float PhysicsBody::get_inverse_mass() const {
58
59 return 0;
60 }
61
set_collision_layer(uint32_t p_layer)62 void PhysicsBody::set_collision_layer(uint32_t p_layer) {
63
64 collision_layer = p_layer;
65 PhysicsServer::get_singleton()->body_set_collision_layer(get_rid(), p_layer);
66 }
67
get_collision_layer() const68 uint32_t PhysicsBody::get_collision_layer() const {
69
70 return collision_layer;
71 }
72
set_collision_mask(uint32_t p_mask)73 void PhysicsBody::set_collision_mask(uint32_t p_mask) {
74
75 collision_mask = p_mask;
76 PhysicsServer::get_singleton()->body_set_collision_mask(get_rid(), p_mask);
77 }
78
get_collision_mask() const79 uint32_t PhysicsBody::get_collision_mask() const {
80
81 return collision_mask;
82 }
83
set_collision_mask_bit(int p_bit,bool p_value)84 void PhysicsBody::set_collision_mask_bit(int p_bit, bool p_value) {
85
86 uint32_t mask = get_collision_mask();
87 if (p_value)
88 mask |= 1 << p_bit;
89 else
90 mask &= ~(1 << p_bit);
91 set_collision_mask(mask);
92 }
93
get_collision_mask_bit(int p_bit) const94 bool PhysicsBody::get_collision_mask_bit(int p_bit) const {
95
96 return get_collision_mask() & (1 << p_bit);
97 }
98
set_collision_layer_bit(int p_bit,bool p_value)99 void PhysicsBody::set_collision_layer_bit(int p_bit, bool p_value) {
100
101 uint32_t mask = get_collision_layer();
102 if (p_value)
103 mask |= 1 << p_bit;
104 else
105 mask &= ~(1 << p_bit);
106 set_collision_layer(mask);
107 }
108
get_collision_layer_bit(int p_bit) const109 bool PhysicsBody::get_collision_layer_bit(int p_bit) const {
110
111 return get_collision_layer() & (1 << p_bit);
112 }
113
get_collision_exceptions()114 Array PhysicsBody::get_collision_exceptions() {
115 List<RID> exceptions;
116 PhysicsServer::get_singleton()->body_get_collision_exceptions(get_rid(), &exceptions);
117 Array ret;
118 for (List<RID>::Element *E = exceptions.front(); E; E = E->next()) {
119 RID body = E->get();
120 ObjectID instance_id = PhysicsServer::get_singleton()->body_get_object_instance_id(body);
121 Object *obj = ObjectDB::get_instance(instance_id);
122 PhysicsBody *physics_body = Object::cast_to<PhysicsBody>(obj);
123 ret.append(physics_body);
124 }
125 return ret;
126 }
127
add_collision_exception_with(Node * p_node)128 void PhysicsBody::add_collision_exception_with(Node *p_node) {
129
130 ERR_FAIL_NULL(p_node);
131 CollisionObject *collision_object = Object::cast_to<CollisionObject>(p_node);
132 ERR_FAIL_COND_MSG(!collision_object, "Collision exception only works between two CollisionObject.");
133 PhysicsServer::get_singleton()->body_add_collision_exception(get_rid(), collision_object->get_rid());
134 }
135
remove_collision_exception_with(Node * p_node)136 void PhysicsBody::remove_collision_exception_with(Node *p_node) {
137
138 ERR_FAIL_NULL(p_node);
139 CollisionObject *collision_object = Object::cast_to<CollisionObject>(p_node);
140 ERR_FAIL_COND_MSG(!collision_object, "Collision exception only works between two CollisionObject.");
141 PhysicsServer::get_singleton()->body_remove_collision_exception(get_rid(), collision_object->get_rid());
142 }
143
_set_layers(uint32_t p_mask)144 void PhysicsBody::_set_layers(uint32_t p_mask) {
145 set_collision_layer(p_mask);
146 set_collision_mask(p_mask);
147 }
148
_get_layers() const149 uint32_t PhysicsBody::_get_layers() const {
150
151 return get_collision_layer();
152 }
153
_bind_methods()154 void PhysicsBody::_bind_methods() {
155 ClassDB::bind_method(D_METHOD("set_collision_layer", "layer"), &PhysicsBody::set_collision_layer);
156 ClassDB::bind_method(D_METHOD("get_collision_layer"), &PhysicsBody::get_collision_layer);
157
158 ClassDB::bind_method(D_METHOD("set_collision_mask", "mask"), &PhysicsBody::set_collision_mask);
159 ClassDB::bind_method(D_METHOD("get_collision_mask"), &PhysicsBody::get_collision_mask);
160
161 ClassDB::bind_method(D_METHOD("set_collision_mask_bit", "bit", "value"), &PhysicsBody::set_collision_mask_bit);
162 ClassDB::bind_method(D_METHOD("get_collision_mask_bit", "bit"), &PhysicsBody::get_collision_mask_bit);
163
164 ClassDB::bind_method(D_METHOD("set_collision_layer_bit", "bit", "value"), &PhysicsBody::set_collision_layer_bit);
165 ClassDB::bind_method(D_METHOD("get_collision_layer_bit", "bit"), &PhysicsBody::get_collision_layer_bit);
166
167 ClassDB::bind_method(D_METHOD("_set_layers", "mask"), &PhysicsBody::_set_layers);
168 ClassDB::bind_method(D_METHOD("_get_layers"), &PhysicsBody::_get_layers);
169
170 ADD_GROUP("Collision", "collision_");
171 ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_layer", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_layer", "get_collision_layer");
172 ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_mask", "get_collision_mask");
173 }
174
PhysicsBody(PhysicsServer::BodyMode p_mode)175 PhysicsBody::PhysicsBody(PhysicsServer::BodyMode p_mode) :
176 CollisionObject(PhysicsServer::get_singleton()->body_create(p_mode), false) {
177
178 collision_layer = 1;
179 collision_mask = 1;
180 }
181
182 #ifndef DISABLE_DEPRECATED
set_friction(real_t p_friction)183 void StaticBody::set_friction(real_t p_friction) {
184
185 if (p_friction == 1.0 && physics_material_override.is_null()) { // default value, don't create an override for that
186 return;
187 }
188
189 WARN_DEPRECATED_MSG("The method set_friction has been deprecated and will be removed in the future, use physics material instead.");
190
191 ERR_FAIL_COND_MSG(p_friction < 0 || p_friction > 1, "Friction must be between 0 and 1.");
192
193 if (physics_material_override.is_null()) {
194 physics_material_override.instance();
195 set_physics_material_override(physics_material_override);
196 }
197 physics_material_override->set_friction(p_friction);
198 }
199
get_friction() const200 real_t StaticBody::get_friction() const {
201
202 WARN_DEPRECATED_MSG("The method get_friction has been deprecated and will be removed in the future, use physics material instead.");
203
204 if (physics_material_override.is_null()) {
205 return 1;
206 }
207
208 return physics_material_override->get_friction();
209 }
210
set_bounce(real_t p_bounce)211 void StaticBody::set_bounce(real_t p_bounce) {
212
213 if (p_bounce == 0.0 && physics_material_override.is_null()) { // default value, don't create an override for that
214 return;
215 }
216
217 WARN_DEPRECATED_MSG("The method set_bounce has been deprecated and will be removed in the future, use physics material instead.");
218
219 ERR_FAIL_COND_MSG(p_bounce < 0 || p_bounce > 1, "Bounce must be between 0 and 1.");
220
221 if (physics_material_override.is_null()) {
222 physics_material_override.instance();
223 set_physics_material_override(physics_material_override);
224 }
225 physics_material_override->set_bounce(p_bounce);
226 }
227
get_bounce() const228 real_t StaticBody::get_bounce() const {
229
230 WARN_DEPRECATED_MSG("The method get_bounce has been deprecated and will be removed in the future, use physics material instead.");
231
232 if (physics_material_override.is_null()) {
233 return 0;
234 }
235
236 return physics_material_override->get_bounce();
237 }
238 #endif
239
set_physics_material_override(const Ref<PhysicsMaterial> & p_physics_material_override)240 void StaticBody::set_physics_material_override(const Ref<PhysicsMaterial> &p_physics_material_override) {
241 if (physics_material_override.is_valid()) {
242 if (physics_material_override->is_connected(CoreStringNames::get_singleton()->changed, this, "_reload_physics_characteristics"))
243 physics_material_override->disconnect(CoreStringNames::get_singleton()->changed, this, "_reload_physics_characteristics");
244 }
245
246 physics_material_override = p_physics_material_override;
247
248 if (physics_material_override.is_valid()) {
249 physics_material_override->connect(CoreStringNames::get_singleton()->changed, this, "_reload_physics_characteristics");
250 }
251 _reload_physics_characteristics();
252 }
253
get_physics_material_override() const254 Ref<PhysicsMaterial> StaticBody::get_physics_material_override() const {
255 return physics_material_override;
256 }
257
set_constant_linear_velocity(const Vector3 & p_vel)258 void StaticBody::set_constant_linear_velocity(const Vector3 &p_vel) {
259
260 constant_linear_velocity = p_vel;
261 PhysicsServer::get_singleton()->body_set_state(get_rid(), PhysicsServer::BODY_STATE_LINEAR_VELOCITY, constant_linear_velocity);
262 }
263
set_constant_angular_velocity(const Vector3 & p_vel)264 void StaticBody::set_constant_angular_velocity(const Vector3 &p_vel) {
265
266 constant_angular_velocity = p_vel;
267 PhysicsServer::get_singleton()->body_set_state(get_rid(), PhysicsServer::BODY_STATE_ANGULAR_VELOCITY, constant_angular_velocity);
268 }
269
get_constant_linear_velocity() const270 Vector3 StaticBody::get_constant_linear_velocity() const {
271
272 return constant_linear_velocity;
273 }
get_constant_angular_velocity() const274 Vector3 StaticBody::get_constant_angular_velocity() const {
275
276 return constant_angular_velocity;
277 }
278
_bind_methods()279 void StaticBody::_bind_methods() {
280
281 ClassDB::bind_method(D_METHOD("set_constant_linear_velocity", "vel"), &StaticBody::set_constant_linear_velocity);
282 ClassDB::bind_method(D_METHOD("set_constant_angular_velocity", "vel"), &StaticBody::set_constant_angular_velocity);
283 ClassDB::bind_method(D_METHOD("get_constant_linear_velocity"), &StaticBody::get_constant_linear_velocity);
284 ClassDB::bind_method(D_METHOD("get_constant_angular_velocity"), &StaticBody::get_constant_angular_velocity);
285
286 #ifndef DISABLE_DEPRECATED
287 ClassDB::bind_method(D_METHOD("set_friction", "friction"), &StaticBody::set_friction);
288 ClassDB::bind_method(D_METHOD("get_friction"), &StaticBody::get_friction);
289
290 ClassDB::bind_method(D_METHOD("set_bounce", "bounce"), &StaticBody::set_bounce);
291 ClassDB::bind_method(D_METHOD("get_bounce"), &StaticBody::get_bounce);
292 #endif // DISABLE_DEPRECATED
293
294 ClassDB::bind_method(D_METHOD("set_physics_material_override", "physics_material_override"), &StaticBody::set_physics_material_override);
295 ClassDB::bind_method(D_METHOD("get_physics_material_override"), &StaticBody::get_physics_material_override);
296
297 ClassDB::bind_method(D_METHOD("_reload_physics_characteristics"), &StaticBody::_reload_physics_characteristics);
298
299 ClassDB::bind_method(D_METHOD("get_collision_exceptions"), &PhysicsBody::get_collision_exceptions);
300 ClassDB::bind_method(D_METHOD("add_collision_exception_with", "body"), &PhysicsBody::add_collision_exception_with);
301 ClassDB::bind_method(D_METHOD("remove_collision_exception_with", "body"), &PhysicsBody::remove_collision_exception_with);
302
303 #ifndef DISABLE_DEPRECATED
304 ADD_PROPERTY(PropertyInfo(Variant::REAL, "friction", PROPERTY_HINT_RANGE, "0,1,0.01", 0), "set_friction", "get_friction");
305 ADD_PROPERTY(PropertyInfo(Variant::REAL, "bounce", PROPERTY_HINT_RANGE, "0,1,0.01", 0), "set_bounce", "get_bounce");
306 #endif // DISABLE_DEPRECATED
307 ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "physics_material_override", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsMaterial"), "set_physics_material_override", "get_physics_material_override");
308 ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "constant_linear_velocity"), "set_constant_linear_velocity", "get_constant_linear_velocity");
309 ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "constant_angular_velocity"), "set_constant_angular_velocity", "get_constant_angular_velocity");
310 }
311
StaticBody()312 StaticBody::StaticBody() :
313 PhysicsBody(PhysicsServer::BODY_MODE_STATIC) {
314 }
315
~StaticBody()316 StaticBody::~StaticBody() {}
317
_reload_physics_characteristics()318 void StaticBody::_reload_physics_characteristics() {
319 if (physics_material_override.is_null()) {
320 PhysicsServer::get_singleton()->body_set_param(get_rid(), PhysicsServer::BODY_PARAM_BOUNCE, 0);
321 PhysicsServer::get_singleton()->body_set_param(get_rid(), PhysicsServer::BODY_PARAM_FRICTION, 1);
322 } else {
323 PhysicsServer::get_singleton()->body_set_param(get_rid(), PhysicsServer::BODY_PARAM_BOUNCE, physics_material_override->computed_bounce());
324 PhysicsServer::get_singleton()->body_set_param(get_rid(), PhysicsServer::BODY_PARAM_FRICTION, physics_material_override->computed_friction());
325 }
326 }
327
_body_enter_tree(ObjectID p_id)328 void RigidBody::_body_enter_tree(ObjectID p_id) {
329
330 Object *obj = ObjectDB::get_instance(p_id);
331 Node *node = Object::cast_to<Node>(obj);
332 ERR_FAIL_COND(!node);
333
334 ERR_FAIL_COND(!contact_monitor);
335 Map<ObjectID, BodyState>::Element *E = contact_monitor->body_map.find(p_id);
336 ERR_FAIL_COND(!E);
337 ERR_FAIL_COND(E->get().in_tree);
338
339 E->get().in_tree = true;
340
341 contact_monitor->locked = true;
342
343 emit_signal(SceneStringNames::get_singleton()->body_entered, node);
344
345 for (int i = 0; i < E->get().shapes.size(); i++) {
346
347 emit_signal(SceneStringNames::get_singleton()->body_shape_entered, p_id, node, E->get().shapes[i].body_shape, E->get().shapes[i].local_shape);
348 }
349
350 contact_monitor->locked = false;
351 }
352
_body_exit_tree(ObjectID p_id)353 void RigidBody::_body_exit_tree(ObjectID p_id) {
354
355 Object *obj = ObjectDB::get_instance(p_id);
356 Node *node = Object::cast_to<Node>(obj);
357 ERR_FAIL_COND(!node);
358 ERR_FAIL_COND(!contact_monitor);
359 Map<ObjectID, BodyState>::Element *E = contact_monitor->body_map.find(p_id);
360 ERR_FAIL_COND(!E);
361 ERR_FAIL_COND(!E->get().in_tree);
362 E->get().in_tree = false;
363
364 contact_monitor->locked = true;
365
366 emit_signal(SceneStringNames::get_singleton()->body_exited, node);
367
368 for (int i = 0; i < E->get().shapes.size(); i++) {
369
370 emit_signal(SceneStringNames::get_singleton()->body_shape_exited, p_id, node, E->get().shapes[i].body_shape, E->get().shapes[i].local_shape);
371 }
372
373 contact_monitor->locked = false;
374 }
375
_body_inout(int p_status,ObjectID p_instance,int p_body_shape,int p_local_shape)376 void RigidBody::_body_inout(int p_status, ObjectID p_instance, int p_body_shape, int p_local_shape) {
377
378 bool body_in = p_status == 1;
379 ObjectID objid = p_instance;
380
381 Object *obj = ObjectDB::get_instance(objid);
382 Node *node = Object::cast_to<Node>(obj);
383
384 ERR_FAIL_COND(!contact_monitor);
385 Map<ObjectID, BodyState>::Element *E = contact_monitor->body_map.find(objid);
386
387 ERR_FAIL_COND(!body_in && !E);
388
389 if (body_in) {
390 if (!E) {
391
392 E = contact_monitor->body_map.insert(objid, BodyState());
393 //E->get().rc=0;
394 E->get().in_tree = node && node->is_inside_tree();
395 if (node) {
396 node->connect(SceneStringNames::get_singleton()->tree_entered, this, SceneStringNames::get_singleton()->_body_enter_tree, make_binds(objid));
397 node->connect(SceneStringNames::get_singleton()->tree_exiting, this, SceneStringNames::get_singleton()->_body_exit_tree, make_binds(objid));
398 if (E->get().in_tree) {
399 emit_signal(SceneStringNames::get_singleton()->body_entered, node);
400 }
401 }
402 }
403 //E->get().rc++;
404 if (node)
405 E->get().shapes.insert(ShapePair(p_body_shape, p_local_shape));
406
407 if (E->get().in_tree) {
408 emit_signal(SceneStringNames::get_singleton()->body_shape_entered, objid, node, p_body_shape, p_local_shape);
409 }
410
411 } else {
412
413 //E->get().rc--;
414
415 if (node)
416 E->get().shapes.erase(ShapePair(p_body_shape, p_local_shape));
417
418 bool in_tree = E->get().in_tree;
419
420 if (E->get().shapes.empty()) {
421
422 if (node) {
423 node->disconnect(SceneStringNames::get_singleton()->tree_entered, this, SceneStringNames::get_singleton()->_body_enter_tree);
424 node->disconnect(SceneStringNames::get_singleton()->tree_exiting, this, SceneStringNames::get_singleton()->_body_exit_tree);
425 if (in_tree)
426 emit_signal(SceneStringNames::get_singleton()->body_exited, node);
427 }
428
429 contact_monitor->body_map.erase(E);
430 }
431 if (node && in_tree) {
432 emit_signal(SceneStringNames::get_singleton()->body_shape_exited, objid, obj, p_body_shape, p_local_shape);
433 }
434 }
435 }
436
437 struct _RigidBodyInOut {
438
439 ObjectID id;
440 int shape;
441 int local_shape;
442 };
443
_direct_state_changed(Object * p_state)444 void RigidBody::_direct_state_changed(Object *p_state) {
445
446 #ifdef DEBUG_ENABLED
447 state = Object::cast_to<PhysicsDirectBodyState>(p_state);
448 #else
449 state = (PhysicsDirectBodyState *)p_state; //trust it
450 #endif
451
452 set_ignore_transform_notification(true);
453 set_global_transform(state->get_transform());
454 linear_velocity = state->get_linear_velocity();
455 angular_velocity = state->get_angular_velocity();
456 inverse_inertia_tensor = state->get_inverse_inertia_tensor();
457 if (sleeping != state->is_sleeping()) {
458 sleeping = state->is_sleeping();
459 emit_signal(SceneStringNames::get_singleton()->sleeping_state_changed);
460 }
461 if (get_script_instance())
462 get_script_instance()->call("_integrate_forces", state);
463 set_ignore_transform_notification(false);
464
465 if (contact_monitor) {
466
467 contact_monitor->locked = true;
468
469 //untag all
470 int rc = 0;
471 for (Map<ObjectID, BodyState>::Element *E = contact_monitor->body_map.front(); E; E = E->next()) {
472
473 for (int i = 0; i < E->get().shapes.size(); i++) {
474
475 E->get().shapes[i].tagged = false;
476 rc++;
477 }
478 }
479
480 _RigidBodyInOut *toadd = (_RigidBodyInOut *)alloca(state->get_contact_count() * sizeof(_RigidBodyInOut));
481 int toadd_count = 0; //state->get_contact_count();
482 RigidBody_RemoveAction *toremove = (RigidBody_RemoveAction *)alloca(rc * sizeof(RigidBody_RemoveAction));
483 int toremove_count = 0;
484
485 //put the ones to add
486
487 for (int i = 0; i < state->get_contact_count(); i++) {
488
489 ObjectID obj = state->get_contact_collider_id(i);
490 int local_shape = state->get_contact_local_shape(i);
491 int shape = state->get_contact_collider_shape(i);
492
493 //bool found=false;
494
495 Map<ObjectID, BodyState>::Element *E = contact_monitor->body_map.find(obj);
496 if (!E) {
497 toadd[toadd_count].local_shape = local_shape;
498 toadd[toadd_count].id = obj;
499 toadd[toadd_count].shape = shape;
500 toadd_count++;
501 continue;
502 }
503
504 ShapePair sp(shape, local_shape);
505 int idx = E->get().shapes.find(sp);
506 if (idx == -1) {
507
508 toadd[toadd_count].local_shape = local_shape;
509 toadd[toadd_count].id = obj;
510 toadd[toadd_count].shape = shape;
511 toadd_count++;
512 continue;
513 }
514
515 E->get().shapes[idx].tagged = true;
516 }
517
518 //put the ones to remove
519
520 for (Map<ObjectID, BodyState>::Element *E = contact_monitor->body_map.front(); E; E = E->next()) {
521
522 for (int i = 0; i < E->get().shapes.size(); i++) {
523
524 if (!E->get().shapes[i].tagged) {
525
526 toremove[toremove_count].body_id = E->key();
527 toremove[toremove_count].pair = E->get().shapes[i];
528 toremove_count++;
529 }
530 }
531 }
532
533 //process remotions
534
535 for (int i = 0; i < toremove_count; i++) {
536
537 _body_inout(0, toremove[i].body_id, toremove[i].pair.body_shape, toremove[i].pair.local_shape);
538 }
539
540 //process aditions
541
542 for (int i = 0; i < toadd_count; i++) {
543
544 _body_inout(1, toadd[i].id, toadd[i].shape, toadd[i].local_shape);
545 }
546
547 contact_monitor->locked = false;
548 }
549
550 state = NULL;
551 }
552
_notification(int p_what)553 void RigidBody::_notification(int p_what) {
554
555 #ifdef TOOLS_ENABLED
556 if (p_what == NOTIFICATION_ENTER_TREE) {
557 if (Engine::get_singleton()->is_editor_hint()) {
558 set_notify_local_transform(true); //used for warnings and only in editor
559 }
560 }
561
562 if (p_what == NOTIFICATION_LOCAL_TRANSFORM_CHANGED) {
563 if (Engine::get_singleton()->is_editor_hint()) {
564 update_configuration_warning();
565 }
566 }
567
568 #endif
569 }
570
set_mode(Mode p_mode)571 void RigidBody::set_mode(Mode p_mode) {
572
573 mode = p_mode;
574 switch (p_mode) {
575
576 case MODE_RIGID: {
577
578 PhysicsServer::get_singleton()->body_set_mode(get_rid(), PhysicsServer::BODY_MODE_RIGID);
579 } break;
580 case MODE_STATIC: {
581
582 PhysicsServer::get_singleton()->body_set_mode(get_rid(), PhysicsServer::BODY_MODE_STATIC);
583
584 } break;
585 case MODE_CHARACTER: {
586 PhysicsServer::get_singleton()->body_set_mode(get_rid(), PhysicsServer::BODY_MODE_CHARACTER);
587
588 } break;
589 case MODE_KINEMATIC: {
590
591 PhysicsServer::get_singleton()->body_set_mode(get_rid(), PhysicsServer::BODY_MODE_KINEMATIC);
592 } break;
593 }
594 update_configuration_warning();
595 }
596
get_mode() const597 RigidBody::Mode RigidBody::get_mode() const {
598
599 return mode;
600 }
601
set_mass(real_t p_mass)602 void RigidBody::set_mass(real_t p_mass) {
603
604 ERR_FAIL_COND(p_mass <= 0);
605 mass = p_mass;
606 _change_notify("mass");
607 _change_notify("weight");
608 PhysicsServer::get_singleton()->body_set_param(get_rid(), PhysicsServer::BODY_PARAM_MASS, mass);
609 }
get_mass() const610 real_t RigidBody::get_mass() const {
611
612 return mass;
613 }
614
set_weight(real_t p_weight)615 void RigidBody::set_weight(real_t p_weight) {
616
617 set_mass(p_weight / real_t(GLOBAL_DEF("physics/3d/default_gravity", 9.8)));
618 }
get_weight() const619 real_t RigidBody::get_weight() const {
620
621 return mass * real_t(GLOBAL_DEF("physics/3d/default_gravity", 9.8));
622 }
623
624 #ifndef DISABLE_DEPRECATED
set_friction(real_t p_friction)625 void RigidBody::set_friction(real_t p_friction) {
626
627 if (p_friction == 1.0 && physics_material_override.is_null()) { // default value, don't create an override for that
628 return;
629 }
630
631 WARN_DEPRECATED_MSG("The method set_friction has been deprecated and will be removed in the future, use physics material instead.");
632
633 ERR_FAIL_COND(p_friction < 0 || p_friction > 1);
634
635 if (physics_material_override.is_null()) {
636 physics_material_override.instance();
637 set_physics_material_override(physics_material_override);
638 }
639 physics_material_override->set_friction(p_friction);
640 }
get_friction() const641 real_t RigidBody::get_friction() const {
642
643 WARN_DEPRECATED_MSG("The method get_friction has been deprecated and will be removed in the future, use physics material instead.");
644
645 if (physics_material_override.is_null()) {
646 return 1;
647 }
648
649 return physics_material_override->get_friction();
650 }
651
set_bounce(real_t p_bounce)652 void RigidBody::set_bounce(real_t p_bounce) {
653
654 if (p_bounce == 0.0 && physics_material_override.is_null()) { // default value, don't create an override for that
655 return;
656 }
657
658 WARN_DEPRECATED_MSG("The method set_bounce has been deprecated and will be removed in the future, use physics material instead.");
659
660 ERR_FAIL_COND(p_bounce < 0 || p_bounce > 1);
661
662 if (physics_material_override.is_null()) {
663 physics_material_override.instance();
664 set_physics_material_override(physics_material_override);
665 }
666 physics_material_override->set_bounce(p_bounce);
667 }
get_bounce() const668 real_t RigidBody::get_bounce() const {
669 WARN_DEPRECATED_MSG("The method get_bounce has been deprecated and will be removed in the future, use physics material instead.");
670 if (physics_material_override.is_null()) {
671 return 0;
672 }
673
674 return physics_material_override->get_bounce();
675 }
676 #endif // DISABLE_DEPRECATED
677
set_physics_material_override(const Ref<PhysicsMaterial> & p_physics_material_override)678 void RigidBody::set_physics_material_override(const Ref<PhysicsMaterial> &p_physics_material_override) {
679 if (physics_material_override.is_valid()) {
680 if (physics_material_override->is_connected(CoreStringNames::get_singleton()->changed, this, "_reload_physics_characteristics"))
681 physics_material_override->disconnect(CoreStringNames::get_singleton()->changed, this, "_reload_physics_characteristics");
682 }
683
684 physics_material_override = p_physics_material_override;
685
686 if (physics_material_override.is_valid()) {
687 physics_material_override->connect(CoreStringNames::get_singleton()->changed, this, "_reload_physics_characteristics");
688 }
689 _reload_physics_characteristics();
690 }
691
get_physics_material_override() const692 Ref<PhysicsMaterial> RigidBody::get_physics_material_override() const {
693 return physics_material_override;
694 }
695
set_gravity_scale(real_t p_gravity_scale)696 void RigidBody::set_gravity_scale(real_t p_gravity_scale) {
697
698 gravity_scale = p_gravity_scale;
699 PhysicsServer::get_singleton()->body_set_param(get_rid(), PhysicsServer::BODY_PARAM_GRAVITY_SCALE, gravity_scale);
700 }
get_gravity_scale() const701 real_t RigidBody::get_gravity_scale() const {
702
703 return gravity_scale;
704 }
705
set_linear_damp(real_t p_linear_damp)706 void RigidBody::set_linear_damp(real_t p_linear_damp) {
707
708 ERR_FAIL_COND(p_linear_damp < -1);
709 linear_damp = p_linear_damp;
710 PhysicsServer::get_singleton()->body_set_param(get_rid(), PhysicsServer::BODY_PARAM_LINEAR_DAMP, linear_damp);
711 }
get_linear_damp() const712 real_t RigidBody::get_linear_damp() const {
713
714 return linear_damp;
715 }
716
set_angular_damp(real_t p_angular_damp)717 void RigidBody::set_angular_damp(real_t p_angular_damp) {
718
719 ERR_FAIL_COND(p_angular_damp < -1);
720 angular_damp = p_angular_damp;
721 PhysicsServer::get_singleton()->body_set_param(get_rid(), PhysicsServer::BODY_PARAM_ANGULAR_DAMP, angular_damp);
722 }
get_angular_damp() const723 real_t RigidBody::get_angular_damp() const {
724
725 return angular_damp;
726 }
727
set_axis_velocity(const Vector3 & p_axis)728 void RigidBody::set_axis_velocity(const Vector3 &p_axis) {
729
730 Vector3 v = state ? state->get_linear_velocity() : linear_velocity;
731 Vector3 axis = p_axis.normalized();
732 v -= axis * axis.dot(v);
733 v += p_axis;
734 if (state) {
735 set_linear_velocity(v);
736 } else {
737 PhysicsServer::get_singleton()->body_set_axis_velocity(get_rid(), p_axis);
738 linear_velocity = v;
739 }
740 }
741
set_linear_velocity(const Vector3 & p_velocity)742 void RigidBody::set_linear_velocity(const Vector3 &p_velocity) {
743
744 linear_velocity = p_velocity;
745 if (state)
746 state->set_linear_velocity(linear_velocity);
747 else
748 PhysicsServer::get_singleton()->body_set_state(get_rid(), PhysicsServer::BODY_STATE_LINEAR_VELOCITY, linear_velocity);
749 }
750
get_linear_velocity() const751 Vector3 RigidBody::get_linear_velocity() const {
752
753 return linear_velocity;
754 }
755
set_angular_velocity(const Vector3 & p_velocity)756 void RigidBody::set_angular_velocity(const Vector3 &p_velocity) {
757
758 angular_velocity = p_velocity;
759 if (state)
760 state->set_angular_velocity(angular_velocity);
761 else
762 PhysicsServer::get_singleton()->body_set_state(get_rid(), PhysicsServer::BODY_STATE_ANGULAR_VELOCITY, angular_velocity);
763 }
get_angular_velocity() const764 Vector3 RigidBody::get_angular_velocity() const {
765
766 return angular_velocity;
767 }
768
get_inverse_inertia_tensor()769 Basis RigidBody::get_inverse_inertia_tensor() {
770 return inverse_inertia_tensor;
771 }
772
set_use_custom_integrator(bool p_enable)773 void RigidBody::set_use_custom_integrator(bool p_enable) {
774
775 if (custom_integrator == p_enable)
776 return;
777
778 custom_integrator = p_enable;
779 PhysicsServer::get_singleton()->body_set_omit_force_integration(get_rid(), p_enable);
780 }
is_using_custom_integrator()781 bool RigidBody::is_using_custom_integrator() {
782
783 return custom_integrator;
784 }
785
set_sleeping(bool p_sleeping)786 void RigidBody::set_sleeping(bool p_sleeping) {
787
788 sleeping = p_sleeping;
789 PhysicsServer::get_singleton()->body_set_state(get_rid(), PhysicsServer::BODY_STATE_SLEEPING, sleeping);
790 }
791
set_can_sleep(bool p_active)792 void RigidBody::set_can_sleep(bool p_active) {
793
794 can_sleep = p_active;
795 PhysicsServer::get_singleton()->body_set_state(get_rid(), PhysicsServer::BODY_STATE_CAN_SLEEP, p_active);
796 }
797
is_able_to_sleep() const798 bool RigidBody::is_able_to_sleep() const {
799
800 return can_sleep;
801 }
802
is_sleeping() const803 bool RigidBody::is_sleeping() const {
804
805 return sleeping;
806 }
807
set_max_contacts_reported(int p_amount)808 void RigidBody::set_max_contacts_reported(int p_amount) {
809
810 max_contacts_reported = p_amount;
811 PhysicsServer::get_singleton()->body_set_max_contacts_reported(get_rid(), p_amount);
812 }
813
get_max_contacts_reported() const814 int RigidBody::get_max_contacts_reported() const {
815
816 return max_contacts_reported;
817 }
818
add_central_force(const Vector3 & p_force)819 void RigidBody::add_central_force(const Vector3 &p_force) {
820 PhysicsServer::get_singleton()->body_add_central_force(get_rid(), p_force);
821 }
822
add_force(const Vector3 & p_force,const Vector3 & p_pos)823 void RigidBody::add_force(const Vector3 &p_force, const Vector3 &p_pos) {
824 PhysicsServer::get_singleton()->body_add_force(get_rid(), p_force, p_pos);
825 }
826
add_torque(const Vector3 & p_torque)827 void RigidBody::add_torque(const Vector3 &p_torque) {
828 PhysicsServer::get_singleton()->body_add_torque(get_rid(), p_torque);
829 }
830
apply_central_impulse(const Vector3 & p_impulse)831 void RigidBody::apply_central_impulse(const Vector3 &p_impulse) {
832 PhysicsServer::get_singleton()->body_apply_central_impulse(get_rid(), p_impulse);
833 }
834
apply_impulse(const Vector3 & p_pos,const Vector3 & p_impulse)835 void RigidBody::apply_impulse(const Vector3 &p_pos, const Vector3 &p_impulse) {
836
837 PhysicsServer::get_singleton()->body_apply_impulse(get_rid(), p_pos, p_impulse);
838 }
839
apply_torque_impulse(const Vector3 & p_impulse)840 void RigidBody::apply_torque_impulse(const Vector3 &p_impulse) {
841 PhysicsServer::get_singleton()->body_apply_torque_impulse(get_rid(), p_impulse);
842 }
843
set_use_continuous_collision_detection(bool p_enable)844 void RigidBody::set_use_continuous_collision_detection(bool p_enable) {
845
846 ccd = p_enable;
847 PhysicsServer::get_singleton()->body_set_enable_continuous_collision_detection(get_rid(), p_enable);
848 }
849
is_using_continuous_collision_detection() const850 bool RigidBody::is_using_continuous_collision_detection() const {
851
852 return ccd;
853 }
854
set_contact_monitor(bool p_enabled)855 void RigidBody::set_contact_monitor(bool p_enabled) {
856
857 if (p_enabled == is_contact_monitor_enabled())
858 return;
859
860 if (!p_enabled) {
861
862 ERR_FAIL_COND_MSG(contact_monitor->locked, "Can't disable contact monitoring during in/out callback. Use call_deferred(\"set_contact_monitor\", false) instead.");
863
864 for (Map<ObjectID, BodyState>::Element *E = contact_monitor->body_map.front(); E; E = E->next()) {
865
866 //clean up mess
867 Object *obj = ObjectDB::get_instance(E->key());
868 Node *node = Object::cast_to<Node>(obj);
869
870 if (node) {
871
872 node->disconnect(SceneStringNames::get_singleton()->tree_entered, this, SceneStringNames::get_singleton()->_body_enter_tree);
873 node->disconnect(SceneStringNames::get_singleton()->tree_exiting, this, SceneStringNames::get_singleton()->_body_exit_tree);
874 }
875 }
876
877 memdelete(contact_monitor);
878 contact_monitor = NULL;
879 } else {
880
881 contact_monitor = memnew(ContactMonitor);
882 contact_monitor->locked = false;
883 }
884 }
885
is_contact_monitor_enabled() const886 bool RigidBody::is_contact_monitor_enabled() const {
887
888 return contact_monitor != NULL;
889 }
890
set_axis_lock(PhysicsServer::BodyAxis p_axis,bool p_lock)891 void RigidBody::set_axis_lock(PhysicsServer::BodyAxis p_axis, bool p_lock) {
892 PhysicsServer::get_singleton()->body_set_axis_lock(get_rid(), p_axis, p_lock);
893 }
894
get_axis_lock(PhysicsServer::BodyAxis p_axis) const895 bool RigidBody::get_axis_lock(PhysicsServer::BodyAxis p_axis) const {
896 return PhysicsServer::get_singleton()->body_is_axis_locked(get_rid(), p_axis);
897 }
898
get_colliding_bodies() const899 Array RigidBody::get_colliding_bodies() const {
900
901 ERR_FAIL_COND_V(!contact_monitor, Array());
902
903 Array ret;
904 ret.resize(contact_monitor->body_map.size());
905 int idx = 0;
906 for (const Map<ObjectID, BodyState>::Element *E = contact_monitor->body_map.front(); E; E = E->next()) {
907 Object *obj = ObjectDB::get_instance(E->key());
908 if (!obj) {
909 ret.resize(ret.size() - 1); //ops
910 } else {
911 ret[idx++] = obj;
912 }
913 }
914
915 return ret;
916 }
917
get_configuration_warning() const918 String RigidBody::get_configuration_warning() const {
919
920 Transform t = get_transform();
921
922 String warning = CollisionObject::get_configuration_warning();
923
924 if ((get_mode() == MODE_RIGID || get_mode() == MODE_CHARACTER) && (ABS(t.basis.get_axis(0).length() - 1.0) > 0.05 || ABS(t.basis.get_axis(1).length() - 1.0) > 0.05 || ABS(t.basis.get_axis(2).length() - 1.0) > 0.05)) {
925 if (warning != String()) {
926 warning += "\n\n";
927 }
928 warning += TTR("Size changes to RigidBody (in character or rigid modes) will be overridden by the physics engine when running.\nChange the size in children collision shapes instead.");
929 }
930
931 return warning;
932 }
933
_bind_methods()934 void RigidBody::_bind_methods() {
935
936 ClassDB::bind_method(D_METHOD("set_mode", "mode"), &RigidBody::set_mode);
937 ClassDB::bind_method(D_METHOD("get_mode"), &RigidBody::get_mode);
938
939 ClassDB::bind_method(D_METHOD("set_mass", "mass"), &RigidBody::set_mass);
940 ClassDB::bind_method(D_METHOD("get_mass"), &RigidBody::get_mass);
941
942 ClassDB::bind_method(D_METHOD("set_weight", "weight"), &RigidBody::set_weight);
943 ClassDB::bind_method(D_METHOD("get_weight"), &RigidBody::get_weight);
944
945 #ifndef DISABLE_DEPRECATED
946 ClassDB::bind_method(D_METHOD("set_friction", "friction"), &RigidBody::set_friction);
947 ClassDB::bind_method(D_METHOD("get_friction"), &RigidBody::get_friction);
948
949 ClassDB::bind_method(D_METHOD("set_bounce", "bounce"), &RigidBody::set_bounce);
950 ClassDB::bind_method(D_METHOD("get_bounce"), &RigidBody::get_bounce);
951 #endif // DISABLE_DEPRECATED
952
953 ClassDB::bind_method(D_METHOD("set_physics_material_override", "physics_material_override"), &RigidBody::set_physics_material_override);
954 ClassDB::bind_method(D_METHOD("get_physics_material_override"), &RigidBody::get_physics_material_override);
955
956 ClassDB::bind_method(D_METHOD("_reload_physics_characteristics"), &RigidBody::_reload_physics_characteristics);
957
958 ClassDB::bind_method(D_METHOD("set_linear_velocity", "linear_velocity"), &RigidBody::set_linear_velocity);
959 ClassDB::bind_method(D_METHOD("get_linear_velocity"), &RigidBody::get_linear_velocity);
960
961 ClassDB::bind_method(D_METHOD("set_angular_velocity", "angular_velocity"), &RigidBody::set_angular_velocity);
962 ClassDB::bind_method(D_METHOD("get_angular_velocity"), &RigidBody::get_angular_velocity);
963
964 ClassDB::bind_method(D_METHOD("get_inverse_inertia_tensor"), &RigidBody::get_inverse_inertia_tensor);
965
966 ClassDB::bind_method(D_METHOD("set_gravity_scale", "gravity_scale"), &RigidBody::set_gravity_scale);
967 ClassDB::bind_method(D_METHOD("get_gravity_scale"), &RigidBody::get_gravity_scale);
968
969 ClassDB::bind_method(D_METHOD("set_linear_damp", "linear_damp"), &RigidBody::set_linear_damp);
970 ClassDB::bind_method(D_METHOD("get_linear_damp"), &RigidBody::get_linear_damp);
971
972 ClassDB::bind_method(D_METHOD("set_angular_damp", "angular_damp"), &RigidBody::set_angular_damp);
973 ClassDB::bind_method(D_METHOD("get_angular_damp"), &RigidBody::get_angular_damp);
974
975 ClassDB::bind_method(D_METHOD("set_max_contacts_reported", "amount"), &RigidBody::set_max_contacts_reported);
976 ClassDB::bind_method(D_METHOD("get_max_contacts_reported"), &RigidBody::get_max_contacts_reported);
977
978 ClassDB::bind_method(D_METHOD("set_use_custom_integrator", "enable"), &RigidBody::set_use_custom_integrator);
979 ClassDB::bind_method(D_METHOD("is_using_custom_integrator"), &RigidBody::is_using_custom_integrator);
980
981 ClassDB::bind_method(D_METHOD("set_contact_monitor", "enabled"), &RigidBody::set_contact_monitor);
982 ClassDB::bind_method(D_METHOD("is_contact_monitor_enabled"), &RigidBody::is_contact_monitor_enabled);
983
984 ClassDB::bind_method(D_METHOD("set_use_continuous_collision_detection", "enable"), &RigidBody::set_use_continuous_collision_detection);
985 ClassDB::bind_method(D_METHOD("is_using_continuous_collision_detection"), &RigidBody::is_using_continuous_collision_detection);
986
987 ClassDB::bind_method(D_METHOD("set_axis_velocity", "axis_velocity"), &RigidBody::set_axis_velocity);
988
989 ClassDB::bind_method(D_METHOD("add_central_force", "force"), &RigidBody::add_central_force);
990 ClassDB::bind_method(D_METHOD("add_force", "force", "position"), &RigidBody::add_force);
991 ClassDB::bind_method(D_METHOD("add_torque", "torque"), &RigidBody::add_torque);
992
993 ClassDB::bind_method(D_METHOD("apply_central_impulse", "impulse"), &RigidBody::apply_central_impulse);
994 ClassDB::bind_method(D_METHOD("apply_impulse", "position", "impulse"), &RigidBody::apply_impulse);
995 ClassDB::bind_method(D_METHOD("apply_torque_impulse", "impulse"), &RigidBody::apply_torque_impulse);
996
997 ClassDB::bind_method(D_METHOD("set_sleeping", "sleeping"), &RigidBody::set_sleeping);
998 ClassDB::bind_method(D_METHOD("is_sleeping"), &RigidBody::is_sleeping);
999
1000 ClassDB::bind_method(D_METHOD("set_can_sleep", "able_to_sleep"), &RigidBody::set_can_sleep);
1001 ClassDB::bind_method(D_METHOD("is_able_to_sleep"), &RigidBody::is_able_to_sleep);
1002
1003 ClassDB::bind_method(D_METHOD("_direct_state_changed"), &RigidBody::_direct_state_changed);
1004 ClassDB::bind_method(D_METHOD("_body_enter_tree"), &RigidBody::_body_enter_tree);
1005 ClassDB::bind_method(D_METHOD("_body_exit_tree"), &RigidBody::_body_exit_tree);
1006
1007 ClassDB::bind_method(D_METHOD("set_axis_lock", "axis", "lock"), &RigidBody::set_axis_lock);
1008 ClassDB::bind_method(D_METHOD("get_axis_lock", "axis"), &RigidBody::get_axis_lock);
1009
1010 ClassDB::bind_method(D_METHOD("get_colliding_bodies"), &RigidBody::get_colliding_bodies);
1011
1012 BIND_VMETHOD(MethodInfo("_integrate_forces", PropertyInfo(Variant::OBJECT, "state", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsDirectBodyState")));
1013
1014 ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Rigid,Static,Character,Kinematic"), "set_mode", "get_mode");
1015 ADD_PROPERTY(PropertyInfo(Variant::REAL, "mass", PROPERTY_HINT_EXP_RANGE, "0.01,65535,0.01"), "set_mass", "get_mass");
1016 ADD_PROPERTY(PropertyInfo(Variant::REAL, "weight", PROPERTY_HINT_EXP_RANGE, "0.01,65535,0.01", PROPERTY_USAGE_EDITOR), "set_weight", "get_weight");
1017 #ifndef DISABLE_DEPRECATED
1018 ADD_PROPERTY(PropertyInfo(Variant::REAL, "friction", PROPERTY_HINT_RANGE, "0,1,0.01", 0), "set_friction", "get_friction");
1019 ADD_PROPERTY(PropertyInfo(Variant::REAL, "bounce", PROPERTY_HINT_RANGE, "0,1,0.01", 0), "set_bounce", "get_bounce");
1020 #endif // DISABLE_DEPRECATED
1021 ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "physics_material_override", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsMaterial"), "set_physics_material_override", "get_physics_material_override");
1022 ADD_PROPERTY(PropertyInfo(Variant::REAL, "gravity_scale", PROPERTY_HINT_RANGE, "-128,128,0.01"), "set_gravity_scale", "get_gravity_scale");
1023 ADD_PROPERTY(PropertyInfo(Variant::BOOL, "custom_integrator"), "set_use_custom_integrator", "is_using_custom_integrator");
1024 ADD_PROPERTY(PropertyInfo(Variant::BOOL, "continuous_cd"), "set_use_continuous_collision_detection", "is_using_continuous_collision_detection");
1025 ADD_PROPERTY(PropertyInfo(Variant::INT, "contacts_reported", PROPERTY_HINT_RANGE, "0,64,1,or_greater"), "set_max_contacts_reported", "get_max_contacts_reported");
1026 ADD_PROPERTY(PropertyInfo(Variant::BOOL, "contact_monitor"), "set_contact_monitor", "is_contact_monitor_enabled");
1027 ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sleeping"), "set_sleeping", "is_sleeping");
1028 ADD_PROPERTY(PropertyInfo(Variant::BOOL, "can_sleep"), "set_can_sleep", "is_able_to_sleep");
1029 ADD_GROUP("Axis Lock", "axis_lock_");
1030 ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_linear_x"), "set_axis_lock", "get_axis_lock", PhysicsServer::BODY_AXIS_LINEAR_X);
1031 ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_linear_y"), "set_axis_lock", "get_axis_lock", PhysicsServer::BODY_AXIS_LINEAR_Y);
1032 ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_linear_z"), "set_axis_lock", "get_axis_lock", PhysicsServer::BODY_AXIS_LINEAR_Z);
1033 ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_x"), "set_axis_lock", "get_axis_lock", PhysicsServer::BODY_AXIS_ANGULAR_X);
1034 ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_y"), "set_axis_lock", "get_axis_lock", PhysicsServer::BODY_AXIS_ANGULAR_Y);
1035 ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_z"), "set_axis_lock", "get_axis_lock", PhysicsServer::BODY_AXIS_ANGULAR_Z);
1036 ADD_GROUP("Linear", "linear_");
1037 ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "linear_velocity"), "set_linear_velocity", "get_linear_velocity");
1038 ADD_PROPERTY(PropertyInfo(Variant::REAL, "linear_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"), "set_linear_damp", "get_linear_damp");
1039 ADD_GROUP("Angular", "angular_");
1040 ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "angular_velocity"), "set_angular_velocity", "get_angular_velocity");
1041 ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"), "set_angular_damp", "get_angular_damp");
1042
1043 ADD_SIGNAL(MethodInfo("body_shape_entered", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_shape")));
1044 ADD_SIGNAL(MethodInfo("body_shape_exited", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_shape")));
1045 ADD_SIGNAL(MethodInfo("body_entered", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node")));
1046 ADD_SIGNAL(MethodInfo("body_exited", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node")));
1047 ADD_SIGNAL(MethodInfo("sleeping_state_changed"));
1048
1049 BIND_ENUM_CONSTANT(MODE_RIGID);
1050 BIND_ENUM_CONSTANT(MODE_STATIC);
1051 BIND_ENUM_CONSTANT(MODE_CHARACTER);
1052 BIND_ENUM_CONSTANT(MODE_KINEMATIC);
1053 }
1054
RigidBody()1055 RigidBody::RigidBody() :
1056 PhysicsBody(PhysicsServer::BODY_MODE_RIGID) {
1057
1058 mode = MODE_RIGID;
1059
1060 mass = 1;
1061 max_contacts_reported = 0;
1062 state = NULL;
1063
1064 gravity_scale = 1;
1065 linear_damp = -1;
1066 angular_damp = -1;
1067
1068 //angular_velocity=0;
1069 sleeping = false;
1070 ccd = false;
1071
1072 custom_integrator = false;
1073 contact_monitor = NULL;
1074 can_sleep = true;
1075
1076 PhysicsServer::get_singleton()->body_set_force_integration_callback(get_rid(), this, "_direct_state_changed");
1077 }
1078
~RigidBody()1079 RigidBody::~RigidBody() {
1080
1081 if (contact_monitor)
1082 memdelete(contact_monitor);
1083 }
1084
_reload_physics_characteristics()1085 void RigidBody::_reload_physics_characteristics() {
1086 if (physics_material_override.is_null()) {
1087 PhysicsServer::get_singleton()->body_set_param(get_rid(), PhysicsServer::BODY_PARAM_BOUNCE, 0);
1088 PhysicsServer::get_singleton()->body_set_param(get_rid(), PhysicsServer::BODY_PARAM_FRICTION, 1);
1089 } else {
1090 PhysicsServer::get_singleton()->body_set_param(get_rid(), PhysicsServer::BODY_PARAM_BOUNCE, physics_material_override->computed_bounce());
1091 PhysicsServer::get_singleton()->body_set_param(get_rid(), PhysicsServer::BODY_PARAM_FRICTION, physics_material_override->computed_friction());
1092 }
1093 }
1094
1095 //////////////////////////////////////////////////////
1096 //////////////////////////
1097
_move(const Vector3 & p_motion,bool p_infinite_inertia,bool p_exclude_raycast_shapes,bool p_test_only)1098 Ref<KinematicCollision> KinematicBody::_move(const Vector3 &p_motion, bool p_infinite_inertia, bool p_exclude_raycast_shapes, bool p_test_only) {
1099
1100 Collision col;
1101 if (move_and_collide(p_motion, p_infinite_inertia, col, p_exclude_raycast_shapes, p_test_only)) {
1102 if (motion_cache.is_null()) {
1103 motion_cache.instance();
1104 motion_cache->owner = this;
1105 }
1106
1107 motion_cache->collision = col;
1108
1109 return motion_cache;
1110 }
1111
1112 return Ref<KinematicCollision>();
1113 }
1114
move_and_collide(const Vector3 & p_motion,bool p_infinite_inertia,Collision & r_collision,bool p_exclude_raycast_shapes,bool p_test_only)1115 bool KinematicBody::move_and_collide(const Vector3 &p_motion, bool p_infinite_inertia, Collision &r_collision, bool p_exclude_raycast_shapes, bool p_test_only) {
1116
1117 Transform gt = get_global_transform();
1118 PhysicsServer::MotionResult result;
1119 bool colliding = PhysicsServer::get_singleton()->body_test_motion(get_rid(), gt, p_motion, p_infinite_inertia, &result, p_exclude_raycast_shapes);
1120
1121 if (colliding) {
1122 r_collision.collider_metadata = result.collider_metadata;
1123 r_collision.collider_shape = result.collider_shape;
1124 r_collision.collider_vel = result.collider_velocity;
1125 r_collision.collision = result.collision_point;
1126 r_collision.normal = result.collision_normal;
1127 r_collision.collider = result.collider_id;
1128 r_collision.collider_rid = result.collider;
1129 r_collision.travel = result.motion;
1130 r_collision.remainder = result.remainder;
1131 r_collision.local_shape = result.collision_local_shape;
1132 }
1133
1134 for (int i = 0; i < 3; i++) {
1135 if (locked_axis & (1 << i)) {
1136 result.motion[i] = 0;
1137 }
1138 }
1139
1140 if (!p_test_only) {
1141 gt.origin += result.motion;
1142 set_global_transform(gt);
1143 }
1144
1145 return colliding;
1146 }
1147
1148 //so, if you pass 45 as limit, avoid numerical precision errors when angle is 45.
1149 #define FLOOR_ANGLE_THRESHOLD 0.01
1150
move_and_slide(const Vector3 & p_linear_velocity,const Vector3 & p_up_direction,bool p_stop_on_slope,int p_max_slides,float p_floor_max_angle,bool p_infinite_inertia)1151 Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_up_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) {
1152
1153 Vector3 body_velocity = p_linear_velocity;
1154 Vector3 body_velocity_normal = body_velocity.normalized();
1155 Vector3 up_direction = p_up_direction.normalized();
1156
1157 for (int i = 0; i < 3; i++) {
1158 if (locked_axis & (1 << i)) {
1159 body_velocity[i] = 0;
1160 }
1161 }
1162
1163 // Hack in order to work with calling from _process as well as from _physics_process; calling from thread is risky
1164 Vector3 motion = (floor_velocity + body_velocity) * (Engine::get_singleton()->is_in_physics_frame() ? get_physics_process_delta_time() : get_process_delta_time());
1165
1166 on_floor = false;
1167 on_floor_body = RID();
1168 on_ceiling = false;
1169 on_wall = false;
1170 colliders.clear();
1171 floor_normal = Vector3();
1172 floor_velocity = Vector3();
1173
1174 while (p_max_slides) {
1175
1176 Collision collision;
1177 bool found_collision = false;
1178
1179 for (int i = 0; i < 2; ++i) {
1180 bool collided;
1181 if (i == 0) { //collide
1182 collided = move_and_collide(motion, p_infinite_inertia, collision);
1183 if (!collided) {
1184 motion = Vector3(); //clear because no collision happened and motion completed
1185 }
1186 } else { //separate raycasts (if any)
1187 collided = separate_raycast_shapes(p_infinite_inertia, collision);
1188 if (collided) {
1189 collision.remainder = motion; //keep
1190 collision.travel = Vector3();
1191 }
1192 }
1193
1194 if (collided) {
1195 found_collision = true;
1196
1197 colliders.push_back(collision);
1198 motion = collision.remainder;
1199
1200 if (up_direction == Vector3()) {
1201 //all is a wall
1202 on_wall = true;
1203 } else {
1204 if (Math::acos(collision.normal.dot(up_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //floor
1205
1206 on_floor = true;
1207 floor_normal = collision.normal;
1208 on_floor_body = collision.collider_rid;
1209 floor_velocity = collision.collider_vel;
1210
1211 if (p_stop_on_slope) {
1212 if ((body_velocity_normal + up_direction).length() < 0.01 && collision.travel.length() < 1) {
1213 Transform gt = get_global_transform();
1214 gt.origin -= collision.travel.slide(up_direction);
1215 set_global_transform(gt);
1216 return Vector3();
1217 }
1218 }
1219 } else if (Math::acos(collision.normal.dot(-up_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //ceiling
1220 on_ceiling = true;
1221 } else {
1222 on_wall = true;
1223 }
1224 }
1225
1226 motion = motion.slide(collision.normal);
1227 body_velocity = body_velocity.slide(collision.normal);
1228
1229 for (int j = 0; j < 3; j++) {
1230 if (locked_axis & (1 << j)) {
1231 body_velocity[j] = 0;
1232 }
1233 }
1234 }
1235 }
1236
1237 if (!found_collision || motion == Vector3())
1238 break;
1239
1240 --p_max_slides;
1241 }
1242
1243 return body_velocity;
1244 }
1245
move_and_slide_with_snap(const Vector3 & p_linear_velocity,const Vector3 & p_snap,const Vector3 & p_up_direction,bool p_stop_on_slope,int p_max_slides,float p_floor_max_angle,bool p_infinite_inertia)1246 Vector3 KinematicBody::move_and_slide_with_snap(const Vector3 &p_linear_velocity, const Vector3 &p_snap, const Vector3 &p_up_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) {
1247
1248 Vector3 up_direction = p_up_direction.normalized();
1249 bool was_on_floor = on_floor;
1250
1251 Vector3 ret = move_and_slide(p_linear_velocity, up_direction, p_stop_on_slope, p_max_slides, p_floor_max_angle, p_infinite_inertia);
1252 if (!was_on_floor || p_snap == Vector3()) {
1253 return ret;
1254 }
1255
1256 Collision col;
1257 Transform gt = get_global_transform();
1258
1259 if (move_and_collide(p_snap, p_infinite_inertia, col, false, true)) {
1260
1261 bool apply = true;
1262 if (up_direction != Vector3()) {
1263 if (Math::acos(col.normal.dot(up_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) {
1264 on_floor = true;
1265 floor_normal = col.normal;
1266 on_floor_body = col.collider_rid;
1267 floor_velocity = col.collider_vel;
1268 if (p_stop_on_slope) {
1269 // move and collide may stray the object a bit because of pre un-stucking,
1270 // so only ensure that motion happens on floor direction in this case.
1271 col.travel = col.travel.project(up_direction);
1272 }
1273 } else {
1274 apply = false; //snapped with floor direction, but did not snap to a floor, do not snap.
1275 }
1276 }
1277 if (apply) {
1278 gt.origin += col.travel;
1279 set_global_transform(gt);
1280 }
1281 }
1282
1283 return ret;
1284 }
1285
is_on_floor() const1286 bool KinematicBody::is_on_floor() const {
1287
1288 return on_floor;
1289 }
1290
is_on_wall() const1291 bool KinematicBody::is_on_wall() const {
1292
1293 return on_wall;
1294 }
is_on_ceiling() const1295 bool KinematicBody::is_on_ceiling() const {
1296
1297 return on_ceiling;
1298 }
1299
get_floor_normal() const1300 Vector3 KinematicBody::get_floor_normal() const {
1301
1302 return floor_normal;
1303 }
1304
get_floor_velocity() const1305 Vector3 KinematicBody::get_floor_velocity() const {
1306
1307 return floor_velocity;
1308 }
1309
test_move(const Transform & p_from,const Vector3 & p_motion,bool p_infinite_inertia)1310 bool KinematicBody::test_move(const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia) {
1311
1312 ERR_FAIL_COND_V(!is_inside_tree(), false);
1313
1314 return PhysicsServer::get_singleton()->body_test_motion(get_rid(), p_from, p_motion, p_infinite_inertia);
1315 }
1316
separate_raycast_shapes(bool p_infinite_inertia,Collision & r_collision)1317 bool KinematicBody::separate_raycast_shapes(bool p_infinite_inertia, Collision &r_collision) {
1318
1319 PhysicsServer::SeparationResult sep_res[8]; //max 8 rays
1320
1321 Transform gt = get_global_transform();
1322
1323 Vector3 recover;
1324 int hits = PhysicsServer::get_singleton()->body_test_ray_separation(get_rid(), gt, p_infinite_inertia, recover, sep_res, 8, margin);
1325 int deepest = -1;
1326 float deepest_depth;
1327 for (int i = 0; i < hits; i++) {
1328 if (deepest == -1 || sep_res[i].collision_depth > deepest_depth) {
1329 deepest = i;
1330 deepest_depth = sep_res[i].collision_depth;
1331 }
1332 }
1333
1334 gt.origin += recover;
1335 set_global_transform(gt);
1336
1337 if (deepest != -1) {
1338 r_collision.collider = sep_res[deepest].collider_id;
1339 r_collision.collider_metadata = sep_res[deepest].collider_metadata;
1340 r_collision.collider_shape = sep_res[deepest].collider_shape;
1341 r_collision.collider_vel = sep_res[deepest].collider_velocity;
1342 r_collision.collision = sep_res[deepest].collision_point;
1343 r_collision.normal = sep_res[deepest].collision_normal;
1344 r_collision.local_shape = sep_res[deepest].collision_local_shape;
1345 r_collision.travel = recover;
1346 r_collision.remainder = Vector3();
1347
1348 return true;
1349 } else {
1350 return false;
1351 }
1352 }
1353
set_axis_lock(PhysicsServer::BodyAxis p_axis,bool p_lock)1354 void KinematicBody::set_axis_lock(PhysicsServer::BodyAxis p_axis, bool p_lock) {
1355 PhysicsServer::get_singleton()->body_set_axis_lock(get_rid(), p_axis, p_lock);
1356 }
1357
get_axis_lock(PhysicsServer::BodyAxis p_axis) const1358 bool KinematicBody::get_axis_lock(PhysicsServer::BodyAxis p_axis) const {
1359 return PhysicsServer::get_singleton()->body_is_axis_locked(get_rid(), p_axis);
1360 }
1361
set_safe_margin(float p_margin)1362 void KinematicBody::set_safe_margin(float p_margin) {
1363
1364 margin = p_margin;
1365 PhysicsServer::get_singleton()->body_set_kinematic_safe_margin(get_rid(), margin);
1366 }
1367
get_safe_margin() const1368 float KinematicBody::get_safe_margin() const {
1369
1370 return margin;
1371 }
get_slide_count() const1372 int KinematicBody::get_slide_count() const {
1373
1374 return colliders.size();
1375 }
1376
get_slide_collision(int p_bounce) const1377 KinematicBody::Collision KinematicBody::get_slide_collision(int p_bounce) const {
1378 ERR_FAIL_INDEX_V(p_bounce, colliders.size(), Collision());
1379 return colliders[p_bounce];
1380 }
1381
_get_slide_collision(int p_bounce)1382 Ref<KinematicCollision> KinematicBody::_get_slide_collision(int p_bounce) {
1383
1384 ERR_FAIL_INDEX_V(p_bounce, colliders.size(), Ref<KinematicCollision>());
1385 if (p_bounce >= slide_colliders.size()) {
1386 slide_colliders.resize(p_bounce + 1);
1387 }
1388
1389 if (slide_colliders[p_bounce].is_null()) {
1390 slide_colliders.write[p_bounce].instance();
1391 slide_colliders.write[p_bounce]->owner = this;
1392 }
1393
1394 slide_colliders.write[p_bounce]->collision = colliders[p_bounce];
1395 return slide_colliders[p_bounce];
1396 }
1397
_notification(int p_what)1398 void KinematicBody::_notification(int p_what) {
1399 if (p_what == NOTIFICATION_ENTER_TREE) {
1400 // Reset move_and_slide() data.
1401 on_floor = false;
1402 on_floor_body = RID();
1403 on_ceiling = false;
1404 on_wall = false;
1405 colliders.clear();
1406 floor_velocity = Vector3();
1407 }
1408 }
1409
_bind_methods()1410 void KinematicBody::_bind_methods() {
1411
1412 ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec", "infinite_inertia", "exclude_raycast_shapes", "test_only"), &KinematicBody::_move, DEFVAL(true), DEFVAL(true), DEFVAL(false));
1413 ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "up_direction", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody::move_and_slide, DEFVAL(Vector3(0, 0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)), DEFVAL(true));
1414 ClassDB::bind_method(D_METHOD("move_and_slide_with_snap", "linear_velocity", "snap", "up_direction", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody::move_and_slide_with_snap, DEFVAL(Vector3(0, 0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)), DEFVAL(true));
1415
1416 ClassDB::bind_method(D_METHOD("test_move", "from", "rel_vec", "infinite_inertia"), &KinematicBody::test_move, DEFVAL(true));
1417
1418 ClassDB::bind_method(D_METHOD("is_on_floor"), &KinematicBody::is_on_floor);
1419 ClassDB::bind_method(D_METHOD("is_on_ceiling"), &KinematicBody::is_on_ceiling);
1420 ClassDB::bind_method(D_METHOD("is_on_wall"), &KinematicBody::is_on_wall);
1421 ClassDB::bind_method(D_METHOD("get_floor_normal"), &KinematicBody::get_floor_normal);
1422 ClassDB::bind_method(D_METHOD("get_floor_velocity"), &KinematicBody::get_floor_velocity);
1423
1424 ClassDB::bind_method(D_METHOD("set_axis_lock", "axis", "lock"), &KinematicBody::set_axis_lock);
1425 ClassDB::bind_method(D_METHOD("get_axis_lock", "axis"), &KinematicBody::get_axis_lock);
1426
1427 ClassDB::bind_method(D_METHOD("set_safe_margin", "pixels"), &KinematicBody::set_safe_margin);
1428 ClassDB::bind_method(D_METHOD("get_safe_margin"), &KinematicBody::get_safe_margin);
1429
1430 ClassDB::bind_method(D_METHOD("get_slide_count"), &KinematicBody::get_slide_count);
1431 ClassDB::bind_method(D_METHOD("get_slide_collision", "slide_idx"), &KinematicBody::_get_slide_collision);
1432
1433 ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "move_lock_x", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_axis_lock", "get_axis_lock", PhysicsServer::BODY_AXIS_LINEAR_X);
1434 ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "move_lock_y", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_axis_lock", "get_axis_lock", PhysicsServer::BODY_AXIS_LINEAR_Y);
1435 ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "move_lock_z", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_axis_lock", "get_axis_lock", PhysicsServer::BODY_AXIS_LINEAR_Z);
1436
1437 ADD_PROPERTY(PropertyInfo(Variant::REAL, "collision/safe_margin", PROPERTY_HINT_RANGE, "0.001,256,0.001"), "set_safe_margin", "get_safe_margin");
1438 }
1439
KinematicBody()1440 KinematicBody::KinematicBody() :
1441 PhysicsBody(PhysicsServer::BODY_MODE_KINEMATIC) {
1442 locked_axis = 0;
1443 on_floor = false;
1444 on_ceiling = false;
1445 on_wall = false;
1446
1447 set_safe_margin(0.001);
1448 }
1449
~KinematicBody()1450 KinematicBody::~KinematicBody() {
1451
1452 if (motion_cache.is_valid()) {
1453 motion_cache->owner = NULL;
1454 }
1455
1456 for (int i = 0; i < slide_colliders.size(); i++) {
1457 if (slide_colliders[i].is_valid()) {
1458 slide_colliders.write[i]->owner = NULL;
1459 }
1460 }
1461 }
1462 ///////////////////////////////////////
1463
get_position() const1464 Vector3 KinematicCollision::get_position() const {
1465
1466 return collision.collision;
1467 }
get_normal() const1468 Vector3 KinematicCollision::get_normal() const {
1469 return collision.normal;
1470 }
get_travel() const1471 Vector3 KinematicCollision::get_travel() const {
1472 return collision.travel;
1473 }
get_remainder() const1474 Vector3 KinematicCollision::get_remainder() const {
1475 return collision.remainder;
1476 }
get_local_shape() const1477 Object *KinematicCollision::get_local_shape() const {
1478 if (!owner) return NULL;
1479 uint32_t ownerid = owner->shape_find_owner(collision.local_shape);
1480 return owner->shape_owner_get_owner(ownerid);
1481 }
1482
get_collider() const1483 Object *KinematicCollision::get_collider() const {
1484
1485 if (collision.collider) {
1486 return ObjectDB::get_instance(collision.collider);
1487 }
1488
1489 return NULL;
1490 }
get_collider_id() const1491 ObjectID KinematicCollision::get_collider_id() const {
1492
1493 return collision.collider;
1494 }
get_collider_shape() const1495 Object *KinematicCollision::get_collider_shape() const {
1496
1497 Object *collider = get_collider();
1498 if (collider) {
1499 CollisionObject *obj2d = Object::cast_to<CollisionObject>(collider);
1500 if (obj2d) {
1501 uint32_t ownerid = obj2d->shape_find_owner(collision.collider_shape);
1502 return obj2d->shape_owner_get_owner(ownerid);
1503 }
1504 }
1505
1506 return NULL;
1507 }
get_collider_shape_index() const1508 int KinematicCollision::get_collider_shape_index() const {
1509
1510 return collision.collider_shape;
1511 }
get_collider_velocity() const1512 Vector3 KinematicCollision::get_collider_velocity() const {
1513
1514 return collision.collider_vel;
1515 }
get_collider_metadata() const1516 Variant KinematicCollision::get_collider_metadata() const {
1517
1518 return Variant();
1519 }
1520
_bind_methods()1521 void KinematicCollision::_bind_methods() {
1522
1523 ClassDB::bind_method(D_METHOD("get_position"), &KinematicCollision::get_position);
1524 ClassDB::bind_method(D_METHOD("get_normal"), &KinematicCollision::get_normal);
1525 ClassDB::bind_method(D_METHOD("get_travel"), &KinematicCollision::get_travel);
1526 ClassDB::bind_method(D_METHOD("get_remainder"), &KinematicCollision::get_remainder);
1527 ClassDB::bind_method(D_METHOD("get_local_shape"), &KinematicCollision::get_local_shape);
1528 ClassDB::bind_method(D_METHOD("get_collider"), &KinematicCollision::get_collider);
1529 ClassDB::bind_method(D_METHOD("get_collider_id"), &KinematicCollision::get_collider_id);
1530 ClassDB::bind_method(D_METHOD("get_collider_shape"), &KinematicCollision::get_collider_shape);
1531 ClassDB::bind_method(D_METHOD("get_collider_shape_index"), &KinematicCollision::get_collider_shape_index);
1532 ClassDB::bind_method(D_METHOD("get_collider_velocity"), &KinematicCollision::get_collider_velocity);
1533 ClassDB::bind_method(D_METHOD("get_collider_metadata"), &KinematicCollision::get_collider_metadata);
1534
1535 ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "position"), "", "get_position");
1536 ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "normal"), "", "get_normal");
1537 ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "travel"), "", "get_travel");
1538 ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "remainder"), "", "get_remainder");
1539 ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "local_shape"), "", "get_local_shape");
1540 ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "collider"), "", "get_collider");
1541 ADD_PROPERTY(PropertyInfo(Variant::INT, "collider_id"), "", "get_collider_id");
1542 ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "collider_shape"), "", "get_collider_shape");
1543 ADD_PROPERTY(PropertyInfo(Variant::INT, "collider_shape_index"), "", "get_collider_shape_index");
1544 ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "collider_velocity"), "", "get_collider_velocity");
1545 ADD_PROPERTY(PropertyInfo(Variant::NIL, "collider_metadata", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT), "", "get_collider_metadata");
1546 }
1547
KinematicCollision()1548 KinematicCollision::KinematicCollision() {
1549 collision.collider = 0;
1550 collision.collider_shape = 0;
1551 collision.local_shape = 0;
1552 owner = NULL;
1553 }
1554
1555 ///////////////////////////////////////
1556
_set(const StringName & p_name,const Variant & p_value,RID j)1557 bool PhysicalBone::JointData::_set(const StringName &p_name, const Variant &p_value, RID j) {
1558 return false;
1559 }
1560
_get(const StringName & p_name,Variant & r_ret) const1561 bool PhysicalBone::JointData::_get(const StringName &p_name, Variant &r_ret) const {
1562 return false;
1563 }
1564
_get_property_list(List<PropertyInfo> * p_list) const1565 void PhysicalBone::JointData::_get_property_list(List<PropertyInfo> *p_list) const {
1566 }
1567
apply_central_impulse(const Vector3 & p_impulse)1568 void PhysicalBone::apply_central_impulse(const Vector3 &p_impulse) {
1569 PhysicsServer::get_singleton()->body_apply_central_impulse(get_rid(), p_impulse);
1570 }
1571
apply_impulse(const Vector3 & p_pos,const Vector3 & p_impulse)1572 void PhysicalBone::apply_impulse(const Vector3 &p_pos, const Vector3 &p_impulse) {
1573 PhysicsServer::get_singleton()->body_apply_impulse(get_rid(), p_pos, p_impulse);
1574 }
1575
_set(const StringName & p_name,const Variant & p_value,RID j)1576 bool PhysicalBone::PinJointData::_set(const StringName &p_name, const Variant &p_value, RID j) {
1577 if (JointData::_set(p_name, p_value, j)) {
1578 return true;
1579 }
1580
1581 if ("joint_constraints/bias" == p_name) {
1582 bias = p_value;
1583 if (j.is_valid())
1584 PhysicsServer::get_singleton()->pin_joint_set_param(j, PhysicsServer::PIN_JOINT_BIAS, bias);
1585
1586 } else if ("joint_constraints/damping" == p_name) {
1587 damping = p_value;
1588 if (j.is_valid())
1589 PhysicsServer::get_singleton()->pin_joint_set_param(j, PhysicsServer::PIN_JOINT_DAMPING, damping);
1590
1591 } else if ("joint_constraints/impulse_clamp" == p_name) {
1592 impulse_clamp = p_value;
1593 if (j.is_valid())
1594 PhysicsServer::get_singleton()->pin_joint_set_param(j, PhysicsServer::PIN_JOINT_IMPULSE_CLAMP, impulse_clamp);
1595
1596 } else {
1597 return false;
1598 }
1599
1600 return true;
1601 }
1602
_get(const StringName & p_name,Variant & r_ret) const1603 bool PhysicalBone::PinJointData::_get(const StringName &p_name, Variant &r_ret) const {
1604 if (JointData::_get(p_name, r_ret)) {
1605 return true;
1606 }
1607
1608 if ("joint_constraints/bias" == p_name) {
1609 r_ret = bias;
1610 } else if ("joint_constraints/damping" == p_name) {
1611 r_ret = damping;
1612 } else if ("joint_constraints/impulse_clamp" == p_name) {
1613 r_ret = impulse_clamp;
1614 } else {
1615 return false;
1616 }
1617
1618 return true;
1619 }
1620
_get_property_list(List<PropertyInfo> * p_list) const1621 void PhysicalBone::PinJointData::_get_property_list(List<PropertyInfo> *p_list) const {
1622 JointData::_get_property_list(p_list);
1623
1624 p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/bias", PROPERTY_HINT_RANGE, "0.01,0.99,0.01"));
1625 p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/damping", PROPERTY_HINT_RANGE, "0.01,8.0,0.01"));
1626 p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/impulse_clamp", PROPERTY_HINT_RANGE, "0.0,64.0,0.01"));
1627 }
1628
_set(const StringName & p_name,const Variant & p_value,RID j)1629 bool PhysicalBone::ConeJointData::_set(const StringName &p_name, const Variant &p_value, RID j) {
1630 if (JointData::_set(p_name, p_value, j)) {
1631 return true;
1632 }
1633
1634 if ("joint_constraints/swing_span" == p_name) {
1635 swing_span = Math::deg2rad(real_t(p_value));
1636 if (j.is_valid())
1637 PhysicsServer::get_singleton()->cone_twist_joint_set_param(j, PhysicsServer::CONE_TWIST_JOINT_SWING_SPAN, swing_span);
1638
1639 } else if ("joint_constraints/twist_span" == p_name) {
1640 twist_span = Math::deg2rad(real_t(p_value));
1641 if (j.is_valid())
1642 PhysicsServer::get_singleton()->cone_twist_joint_set_param(j, PhysicsServer::CONE_TWIST_JOINT_TWIST_SPAN, twist_span);
1643
1644 } else if ("joint_constraints/bias" == p_name) {
1645 bias = p_value;
1646 if (j.is_valid())
1647 PhysicsServer::get_singleton()->cone_twist_joint_set_param(j, PhysicsServer::CONE_TWIST_JOINT_BIAS, bias);
1648
1649 } else if ("joint_constraints/softness" == p_name) {
1650 softness = p_value;
1651 if (j.is_valid())
1652 PhysicsServer::get_singleton()->cone_twist_joint_set_param(j, PhysicsServer::CONE_TWIST_JOINT_SOFTNESS, softness);
1653
1654 } else if ("joint_constraints/relaxation" == p_name) {
1655 relaxation = p_value;
1656 if (j.is_valid())
1657 PhysicsServer::get_singleton()->cone_twist_joint_set_param(j, PhysicsServer::CONE_TWIST_JOINT_RELAXATION, relaxation);
1658
1659 } else {
1660 return false;
1661 }
1662
1663 return true;
1664 }
1665
_get(const StringName & p_name,Variant & r_ret) const1666 bool PhysicalBone::ConeJointData::_get(const StringName &p_name, Variant &r_ret) const {
1667 if (JointData::_get(p_name, r_ret)) {
1668 return true;
1669 }
1670
1671 if ("joint_constraints/swing_span" == p_name) {
1672 r_ret = Math::rad2deg(swing_span);
1673 } else if ("joint_constraints/twist_span" == p_name) {
1674 r_ret = Math::rad2deg(twist_span);
1675 } else if ("joint_constraints/bias" == p_name) {
1676 r_ret = bias;
1677 } else if ("joint_constraints/softness" == p_name) {
1678 r_ret = softness;
1679 } else if ("joint_constraints/relaxation" == p_name) {
1680 r_ret = relaxation;
1681 } else {
1682 return false;
1683 }
1684
1685 return true;
1686 }
1687
_get_property_list(List<PropertyInfo> * p_list) const1688 void PhysicalBone::ConeJointData::_get_property_list(List<PropertyInfo> *p_list) const {
1689 JointData::_get_property_list(p_list);
1690
1691 p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/swing_span", PROPERTY_HINT_RANGE, "-180,180,0.01"));
1692 p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/twist_span", PROPERTY_HINT_RANGE, "-40000,40000,0.1,or_lesser,or_greater"));
1693 p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/bias", PROPERTY_HINT_RANGE, "0.01,16.0,0.01"));
1694 p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/softness", PROPERTY_HINT_RANGE, "0.01,16.0,0.01"));
1695 p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/relaxation", PROPERTY_HINT_RANGE, "0.01,16.0,0.01"));
1696 }
1697
_set(const StringName & p_name,const Variant & p_value,RID j)1698 bool PhysicalBone::HingeJointData::_set(const StringName &p_name, const Variant &p_value, RID j) {
1699 if (JointData::_set(p_name, p_value, j)) {
1700 return true;
1701 }
1702
1703 if ("joint_constraints/angular_limit_enabled" == p_name) {
1704 angular_limit_enabled = p_value;
1705 if (j.is_valid())
1706 PhysicsServer::get_singleton()->hinge_joint_set_flag(j, PhysicsServer::HINGE_JOINT_FLAG_USE_LIMIT, angular_limit_enabled);
1707
1708 } else if ("joint_constraints/angular_limit_upper" == p_name) {
1709 angular_limit_upper = Math::deg2rad(real_t(p_value));
1710 if (j.is_valid())
1711 PhysicsServer::get_singleton()->hinge_joint_set_param(j, PhysicsServer::HINGE_JOINT_LIMIT_UPPER, angular_limit_upper);
1712
1713 } else if ("joint_constraints/angular_limit_lower" == p_name) {
1714 angular_limit_lower = Math::deg2rad(real_t(p_value));
1715 if (j.is_valid())
1716 PhysicsServer::get_singleton()->hinge_joint_set_param(j, PhysicsServer::HINGE_JOINT_LIMIT_LOWER, angular_limit_lower);
1717
1718 } else if ("joint_constraints/angular_limit_bias" == p_name) {
1719 angular_limit_bias = p_value;
1720 if (j.is_valid())
1721 PhysicsServer::get_singleton()->hinge_joint_set_param(j, PhysicsServer::HINGE_JOINT_LIMIT_BIAS, angular_limit_bias);
1722
1723 } else if ("joint_constraints/angular_limit_softness" == p_name) {
1724 angular_limit_softness = p_value;
1725 if (j.is_valid())
1726 PhysicsServer::get_singleton()->hinge_joint_set_param(j, PhysicsServer::HINGE_JOINT_LIMIT_SOFTNESS, angular_limit_softness);
1727
1728 } else if ("joint_constraints/angular_limit_relaxation" == p_name) {
1729 angular_limit_relaxation = p_value;
1730 if (j.is_valid())
1731 PhysicsServer::get_singleton()->hinge_joint_set_param(j, PhysicsServer::HINGE_JOINT_LIMIT_RELAXATION, angular_limit_relaxation);
1732
1733 } else {
1734 return false;
1735 }
1736
1737 return true;
1738 }
1739
_get(const StringName & p_name,Variant & r_ret) const1740 bool PhysicalBone::HingeJointData::_get(const StringName &p_name, Variant &r_ret) const {
1741 if (JointData::_get(p_name, r_ret)) {
1742 return true;
1743 }
1744
1745 if ("joint_constraints/angular_limit_enabled" == p_name) {
1746 r_ret = angular_limit_enabled;
1747 } else if ("joint_constraints/angular_limit_upper" == p_name) {
1748 r_ret = Math::rad2deg(angular_limit_upper);
1749 } else if ("joint_constraints/angular_limit_lower" == p_name) {
1750 r_ret = Math::rad2deg(angular_limit_lower);
1751 } else if ("joint_constraints/angular_limit_bias" == p_name) {
1752 r_ret = angular_limit_bias;
1753 } else if ("joint_constraints/angular_limit_softness" == p_name) {
1754 r_ret = angular_limit_softness;
1755 } else if ("joint_constraints/angular_limit_relaxation" == p_name) {
1756 r_ret = angular_limit_relaxation;
1757 } else {
1758 return false;
1759 }
1760
1761 return true;
1762 }
1763
_get_property_list(List<PropertyInfo> * p_list) const1764 void PhysicalBone::HingeJointData::_get_property_list(List<PropertyInfo> *p_list) const {
1765 JointData::_get_property_list(p_list);
1766
1767 p_list->push_back(PropertyInfo(Variant::BOOL, "joint_constraints/angular_limit_enabled"));
1768 p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/angular_limit_upper", PROPERTY_HINT_RANGE, "-180,180,0.01"));
1769 p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/angular_limit_lower", PROPERTY_HINT_RANGE, "-180,180,0.01"));
1770 p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/angular_limit_bias", PROPERTY_HINT_RANGE, "0.01,0.99,0.01"));
1771 p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/angular_limit_softness", PROPERTY_HINT_RANGE, "0.01,16,0.01"));
1772 p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/angular_limit_relaxation", PROPERTY_HINT_RANGE, "0.01,16,0.01"));
1773 }
1774
_set(const StringName & p_name,const Variant & p_value,RID j)1775 bool PhysicalBone::SliderJointData::_set(const StringName &p_name, const Variant &p_value, RID j) {
1776 if (JointData::_set(p_name, p_value, j)) {
1777 return true;
1778 }
1779
1780 if ("joint_constraints/linear_limit_upper" == p_name) {
1781 linear_limit_upper = p_value;
1782 if (j.is_valid())
1783 PhysicsServer::get_singleton()->slider_joint_set_param(j, PhysicsServer::SLIDER_JOINT_LINEAR_LIMIT_UPPER, linear_limit_upper);
1784
1785 } else if ("joint_constraints/linear_limit_lower" == p_name) {
1786 linear_limit_lower = p_value;
1787 if (j.is_valid())
1788 PhysicsServer::get_singleton()->slider_joint_set_param(j, PhysicsServer::SLIDER_JOINT_LINEAR_LIMIT_LOWER, linear_limit_lower);
1789
1790 } else if ("joint_constraints/linear_limit_softness" == p_name) {
1791 linear_limit_softness = p_value;
1792 if (j.is_valid())
1793 PhysicsServer::get_singleton()->slider_joint_set_param(j, PhysicsServer::SLIDER_JOINT_LINEAR_LIMIT_SOFTNESS, linear_limit_softness);
1794
1795 } else if ("joint_constraints/linear_limit_restitution" == p_name) {
1796 linear_limit_restitution = p_value;
1797 if (j.is_valid())
1798 PhysicsServer::get_singleton()->slider_joint_set_param(j, PhysicsServer::SLIDER_JOINT_LINEAR_LIMIT_RESTITUTION, linear_limit_restitution);
1799
1800 } else if ("joint_constraints/linear_limit_damping" == p_name) {
1801 linear_limit_damping = p_value;
1802 if (j.is_valid())
1803 PhysicsServer::get_singleton()->slider_joint_set_param(j, PhysicsServer::SLIDER_JOINT_LINEAR_LIMIT_DAMPING, linear_limit_restitution);
1804
1805 } else if ("joint_constraints/angular_limit_upper" == p_name) {
1806 angular_limit_upper = Math::deg2rad(real_t(p_value));
1807 if (j.is_valid())
1808 PhysicsServer::get_singleton()->slider_joint_set_param(j, PhysicsServer::SLIDER_JOINT_ANGULAR_LIMIT_UPPER, angular_limit_upper);
1809
1810 } else if ("joint_constraints/angular_limit_lower" == p_name) {
1811 angular_limit_lower = Math::deg2rad(real_t(p_value));
1812 if (j.is_valid())
1813 PhysicsServer::get_singleton()->slider_joint_set_param(j, PhysicsServer::SLIDER_JOINT_ANGULAR_LIMIT_LOWER, angular_limit_lower);
1814
1815 } else if ("joint_constraints/angular_limit_softness" == p_name) {
1816 angular_limit_softness = p_value;
1817 if (j.is_valid())
1818 PhysicsServer::get_singleton()->slider_joint_set_param(j, PhysicsServer::SLIDER_JOINT_ANGULAR_LIMIT_SOFTNESS, angular_limit_softness);
1819
1820 } else if ("joint_constraints/angular_limit_restitution" == p_name) {
1821 angular_limit_restitution = p_value;
1822 if (j.is_valid())
1823 PhysicsServer::get_singleton()->slider_joint_set_param(j, PhysicsServer::SLIDER_JOINT_ANGULAR_LIMIT_SOFTNESS, angular_limit_softness);
1824
1825 } else if ("joint_constraints/angular_limit_damping" == p_name) {
1826 angular_limit_damping = p_value;
1827 if (j.is_valid())
1828 PhysicsServer::get_singleton()->slider_joint_set_param(j, PhysicsServer::SLIDER_JOINT_ANGULAR_LIMIT_DAMPING, angular_limit_damping);
1829
1830 } else {
1831 return false;
1832 }
1833
1834 return true;
1835 }
1836
_get(const StringName & p_name,Variant & r_ret) const1837 bool PhysicalBone::SliderJointData::_get(const StringName &p_name, Variant &r_ret) const {
1838 if (JointData::_get(p_name, r_ret)) {
1839 return true;
1840 }
1841
1842 if ("joint_constraints/linear_limit_upper" == p_name) {
1843 r_ret = linear_limit_upper;
1844 } else if ("joint_constraints/linear_limit_lower" == p_name) {
1845 r_ret = linear_limit_lower;
1846 } else if ("joint_constraints/linear_limit_softness" == p_name) {
1847 r_ret = linear_limit_softness;
1848 } else if ("joint_constraints/linear_limit_restitution" == p_name) {
1849 r_ret = linear_limit_restitution;
1850 } else if ("joint_constraints/linear_limit_damping" == p_name) {
1851 r_ret = linear_limit_damping;
1852 } else if ("joint_constraints/angular_limit_upper" == p_name) {
1853 r_ret = Math::rad2deg(angular_limit_upper);
1854 } else if ("joint_constraints/angular_limit_lower" == p_name) {
1855 r_ret = Math::rad2deg(angular_limit_lower);
1856 } else if ("joint_constraints/angular_limit_softness" == p_name) {
1857 r_ret = angular_limit_softness;
1858 } else if ("joint_constraints/angular_limit_restitution" == p_name) {
1859 r_ret = angular_limit_restitution;
1860 } else if ("joint_constraints/angular_limit_damping" == p_name) {
1861 r_ret = angular_limit_damping;
1862 } else {
1863 return false;
1864 }
1865
1866 return true;
1867 }
1868
_get_property_list(List<PropertyInfo> * p_list) const1869 void PhysicalBone::SliderJointData::_get_property_list(List<PropertyInfo> *p_list) const {
1870 JointData::_get_property_list(p_list);
1871
1872 p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/linear_limit_upper"));
1873 p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/linear_limit_lower"));
1874 p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/linear_limit_softness", PROPERTY_HINT_RANGE, "0.01,16.0,0.01"));
1875 p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/linear_limit_restitution", PROPERTY_HINT_RANGE, "0.01,16.0,0.01"));
1876 p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/linear_limit_damping", PROPERTY_HINT_RANGE, "0,16.0,0.01"));
1877
1878 p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/angular_limit_upper", PROPERTY_HINT_RANGE, "-180,180,0.01"));
1879 p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/angular_limit_lower", PROPERTY_HINT_RANGE, "-180,180,0.01"));
1880 p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/angular_limit_softness", PROPERTY_HINT_RANGE, "0.01,16.0,0.01"));
1881 p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/angular_limit_restitution", PROPERTY_HINT_RANGE, "0.01,16.0,0.01"));
1882 p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/angular_limit_damping", PROPERTY_HINT_RANGE, "0,16.0,0.01"));
1883 }
1884
_set(const StringName & p_name,const Variant & p_value,RID j)1885 bool PhysicalBone::SixDOFJointData::_set(const StringName &p_name, const Variant &p_value, RID j) {
1886 if (JointData::_set(p_name, p_value, j)) {
1887 return true;
1888 }
1889
1890 String path = p_name;
1891
1892 Vector3::Axis axis;
1893 {
1894 const String axis_s = path.get_slicec('/', 1);
1895 if ("x" == axis_s) {
1896 axis = Vector3::AXIS_X;
1897 } else if ("y" == axis_s) {
1898 axis = Vector3::AXIS_Y;
1899 } else if ("z" == axis_s) {
1900 axis = Vector3::AXIS_Z;
1901 } else {
1902 return false;
1903 }
1904 }
1905
1906 String var_name = path.get_slicec('/', 2);
1907
1908 if ("linear_limit_enabled" == var_name) {
1909 axis_data[axis].linear_limit_enabled = p_value;
1910 if (j.is_valid())
1911 PhysicsServer::get_singleton()->generic_6dof_joint_set_flag(j, axis, PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_LINEAR_LIMIT, axis_data[axis].linear_limit_enabled);
1912
1913 } else if ("linear_limit_upper" == var_name) {
1914 axis_data[axis].linear_limit_upper = p_value;
1915 if (j.is_valid())
1916 PhysicsServer::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer::G6DOF_JOINT_LINEAR_UPPER_LIMIT, axis_data[axis].linear_limit_upper);
1917
1918 } else if ("linear_limit_lower" == var_name) {
1919 axis_data[axis].linear_limit_lower = p_value;
1920 if (j.is_valid())
1921 PhysicsServer::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer::G6DOF_JOINT_LINEAR_LOWER_LIMIT, axis_data[axis].linear_limit_lower);
1922
1923 } else if ("linear_limit_softness" == var_name) {
1924 axis_data[axis].linear_limit_softness = p_value;
1925 if (j.is_valid())
1926 PhysicsServer::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer::G6DOF_JOINT_LINEAR_LIMIT_SOFTNESS, axis_data[axis].linear_limit_softness);
1927
1928 } else if ("linear_spring_enabled" == var_name) {
1929 axis_data[axis].linear_spring_enabled = p_value;
1930 if (j.is_valid())
1931 PhysicsServer::get_singleton()->generic_6dof_joint_set_flag(j, axis, PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_LINEAR_SPRING, axis_data[axis].linear_spring_enabled);
1932
1933 } else if ("linear_spring_stiffness" == var_name) {
1934 axis_data[axis].linear_spring_stiffness = p_value;
1935 if (j.is_valid())
1936 PhysicsServer::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer::G6DOF_JOINT_LINEAR_SPRING_STIFFNESS, axis_data[axis].linear_spring_stiffness);
1937
1938 } else if ("linear_spring_damping" == var_name) {
1939 axis_data[axis].linear_spring_damping = p_value;
1940 if (j.is_valid())
1941 PhysicsServer::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer::G6DOF_JOINT_LINEAR_SPRING_DAMPING, axis_data[axis].linear_spring_damping);
1942
1943 } else if ("linear_equilibrium_point" == var_name) {
1944 axis_data[axis].linear_equilibrium_point = p_value;
1945 if (j.is_valid())
1946 PhysicsServer::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer::G6DOF_JOINT_LINEAR_SPRING_EQUILIBRIUM_POINT, axis_data[axis].linear_equilibrium_point);
1947
1948 } else if ("linear_restitution" == var_name) {
1949 axis_data[axis].linear_restitution = p_value;
1950 if (j.is_valid())
1951 PhysicsServer::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer::G6DOF_JOINT_LINEAR_RESTITUTION, axis_data[axis].linear_restitution);
1952
1953 } else if ("linear_damping" == var_name) {
1954 axis_data[axis].linear_damping = p_value;
1955 if (j.is_valid())
1956 PhysicsServer::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer::G6DOF_JOINT_LINEAR_DAMPING, axis_data[axis].linear_damping);
1957
1958 } else if ("angular_limit_enabled" == var_name) {
1959 axis_data[axis].angular_limit_enabled = p_value;
1960 if (j.is_valid())
1961 PhysicsServer::get_singleton()->generic_6dof_joint_set_flag(j, axis, PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_ANGULAR_LIMIT, axis_data[axis].angular_limit_enabled);
1962
1963 } else if ("angular_limit_upper" == var_name) {
1964 axis_data[axis].angular_limit_upper = Math::deg2rad(real_t(p_value));
1965 if (j.is_valid())
1966 PhysicsServer::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer::G6DOF_JOINT_ANGULAR_UPPER_LIMIT, axis_data[axis].angular_limit_upper);
1967
1968 } else if ("angular_limit_lower" == var_name) {
1969 axis_data[axis].angular_limit_lower = Math::deg2rad(real_t(p_value));
1970 if (j.is_valid())
1971 PhysicsServer::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer::G6DOF_JOINT_ANGULAR_LOWER_LIMIT, axis_data[axis].angular_limit_lower);
1972
1973 } else if ("angular_limit_softness" == var_name) {
1974 axis_data[axis].angular_limit_softness = p_value;
1975 if (j.is_valid())
1976 PhysicsServer::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer::G6DOF_JOINT_ANGULAR_LIMIT_SOFTNESS, axis_data[axis].angular_limit_softness);
1977
1978 } else if ("angular_restitution" == var_name) {
1979 axis_data[axis].angular_restitution = p_value;
1980 if (j.is_valid())
1981 PhysicsServer::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer::G6DOF_JOINT_ANGULAR_RESTITUTION, axis_data[axis].angular_restitution);
1982
1983 } else if ("angular_damping" == var_name) {
1984 axis_data[axis].angular_damping = p_value;
1985 if (j.is_valid())
1986 PhysicsServer::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer::G6DOF_JOINT_ANGULAR_DAMPING, axis_data[axis].angular_damping);
1987
1988 } else if ("erp" == var_name) {
1989 axis_data[axis].erp = p_value;
1990 if (j.is_valid())
1991 PhysicsServer::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer::G6DOF_JOINT_ANGULAR_ERP, axis_data[axis].erp);
1992
1993 } else if ("angular_spring_enabled" == var_name) {
1994 axis_data[axis].angular_spring_enabled = p_value;
1995 if (j.is_valid())
1996 PhysicsServer::get_singleton()->generic_6dof_joint_set_flag(j, axis, PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_ANGULAR_SPRING, axis_data[axis].angular_spring_enabled);
1997
1998 } else if ("angular_spring_stiffness" == var_name) {
1999 axis_data[axis].angular_spring_stiffness = p_value;
2000 if (j.is_valid())
2001 PhysicsServer::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer::G6DOF_JOINT_ANGULAR_SPRING_STIFFNESS, axis_data[axis].angular_spring_stiffness);
2002
2003 } else if ("angular_spring_damping" == var_name) {
2004 axis_data[axis].angular_spring_damping = p_value;
2005 if (j.is_valid())
2006 PhysicsServer::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer::G6DOF_JOINT_ANGULAR_SPRING_DAMPING, axis_data[axis].angular_spring_damping);
2007
2008 } else if ("angular_equilibrium_point" == var_name) {
2009 axis_data[axis].angular_equilibrium_point = p_value;
2010 if (j.is_valid())
2011 PhysicsServer::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer::G6DOF_JOINT_ANGULAR_SPRING_EQUILIBRIUM_POINT, axis_data[axis].angular_equilibrium_point);
2012
2013 } else {
2014 return false;
2015 }
2016
2017 return true;
2018 }
2019
_get(const StringName & p_name,Variant & r_ret) const2020 bool PhysicalBone::SixDOFJointData::_get(const StringName &p_name, Variant &r_ret) const {
2021 if (JointData::_get(p_name, r_ret)) {
2022 return true;
2023 }
2024
2025 String path = p_name;
2026
2027 int axis;
2028 {
2029 const String axis_s = path.get_slicec('/', 1);
2030 if ("x" == axis_s) {
2031 axis = 0;
2032 } else if ("y" == axis_s) {
2033 axis = 1;
2034 } else if ("z" == axis_s) {
2035 axis = 2;
2036 } else {
2037 return false;
2038 }
2039 }
2040
2041 String var_name = path.get_slicec('/', 2);
2042
2043 if ("linear_limit_enabled" == var_name) {
2044 r_ret = axis_data[axis].linear_limit_enabled;
2045 } else if ("linear_limit_upper" == var_name) {
2046 r_ret = axis_data[axis].linear_limit_upper;
2047 } else if ("linear_limit_lower" == var_name) {
2048 r_ret = axis_data[axis].linear_limit_lower;
2049 } else if ("linear_limit_softness" == var_name) {
2050 r_ret = axis_data[axis].linear_limit_softness;
2051 } else if ("linear_spring_enabled" == var_name) {
2052 r_ret = axis_data[axis].linear_spring_enabled;
2053 } else if ("linear_spring_stiffness" == var_name) {
2054 r_ret = axis_data[axis].linear_spring_stiffness;
2055 } else if ("linear_spring_damping" == var_name) {
2056 r_ret = axis_data[axis].linear_spring_damping;
2057 } else if ("linear_equilibrium_point" == var_name) {
2058 r_ret = axis_data[axis].linear_equilibrium_point;
2059 } else if ("linear_restitution" == var_name) {
2060 r_ret = axis_data[axis].linear_restitution;
2061 } else if ("linear_damping" == var_name) {
2062 r_ret = axis_data[axis].linear_damping;
2063 } else if ("angular_limit_enabled" == var_name) {
2064 r_ret = axis_data[axis].angular_limit_enabled;
2065 } else if ("angular_limit_upper" == var_name) {
2066 r_ret = Math::rad2deg(axis_data[axis].angular_limit_upper);
2067 } else if ("angular_limit_lower" == var_name) {
2068 r_ret = Math::rad2deg(axis_data[axis].angular_limit_lower);
2069 } else if ("angular_limit_softness" == var_name) {
2070 r_ret = axis_data[axis].angular_limit_softness;
2071 } else if ("angular_restitution" == var_name) {
2072 r_ret = axis_data[axis].angular_restitution;
2073 } else if ("angular_damping" == var_name) {
2074 r_ret = axis_data[axis].angular_damping;
2075 } else if ("erp" == var_name) {
2076 r_ret = axis_data[axis].erp;
2077 } else if ("angular_spring_enabled" == var_name) {
2078 r_ret = axis_data[axis].angular_spring_enabled;
2079 } else if ("angular_spring_stiffness" == var_name) {
2080 r_ret = axis_data[axis].angular_spring_stiffness;
2081 } else if ("angular_spring_damping" == var_name) {
2082 r_ret = axis_data[axis].angular_spring_damping;
2083 } else if ("angular_equilibrium_point" == var_name) {
2084 r_ret = axis_data[axis].angular_equilibrium_point;
2085 } else {
2086 return false;
2087 }
2088
2089 return true;
2090 }
2091
_get_property_list(List<PropertyInfo> * p_list) const2092 void PhysicalBone::SixDOFJointData::_get_property_list(List<PropertyInfo> *p_list) const {
2093 const StringName axis_names[] = { "x", "y", "z" };
2094 for (int i = 0; i < 3; ++i) {
2095 p_list->push_back(PropertyInfo(Variant::BOOL, "joint_constraints/" + axis_names[i] + "/linear_limit_enabled"));
2096 p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/" + axis_names[i] + "/linear_limit_upper"));
2097 p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/" + axis_names[i] + "/linear_limit_lower"));
2098 p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/" + axis_names[i] + "/linear_limit_softness", PROPERTY_HINT_RANGE, "0.01,16,0.01"));
2099 p_list->push_back(PropertyInfo(Variant::BOOL, "joint_constraints/" + axis_names[i] + "/linear_spring_enabled"));
2100 p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/" + axis_names[i] + "/linear_spring_stiffness"));
2101 p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/" + axis_names[i] + "/linear_spring_damping"));
2102 p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/" + axis_names[i] + "/linear_equilibrium_point"));
2103 p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/" + axis_names[i] + "/linear_restitution", PROPERTY_HINT_RANGE, "0.01,16,0.01"));
2104 p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/" + axis_names[i] + "/linear_damping", PROPERTY_HINT_RANGE, "0.01,16,0.01"));
2105 p_list->push_back(PropertyInfo(Variant::BOOL, "joint_constraints/" + axis_names[i] + "/angular_limit_enabled"));
2106 p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/" + axis_names[i] + "/angular_limit_upper", PROPERTY_HINT_RANGE, "-180,180,0.01"));
2107 p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/" + axis_names[i] + "/angular_limit_lower", PROPERTY_HINT_RANGE, "-180,180,0.01"));
2108 p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/" + axis_names[i] + "/angular_limit_softness", PROPERTY_HINT_RANGE, "0.01,16,0.01"));
2109 p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/" + axis_names[i] + "/angular_restitution", PROPERTY_HINT_RANGE, "0.01,16,0.01"));
2110 p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/" + axis_names[i] + "/angular_damping", PROPERTY_HINT_RANGE, "0.01,16,0.01"));
2111 p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/" + axis_names[i] + "/erp"));
2112 p_list->push_back(PropertyInfo(Variant::BOOL, "joint_constraints/" + axis_names[i] + "/angular_spring_enabled"));
2113 p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/" + axis_names[i] + "/angular_spring_stiffness"));
2114 p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/" + axis_names[i] + "/angular_spring_damping"));
2115 p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/" + axis_names[i] + "/angular_equilibrium_point"));
2116 }
2117 }
2118
_set(const StringName & p_name,const Variant & p_value)2119 bool PhysicalBone::_set(const StringName &p_name, const Variant &p_value) {
2120 if (p_name == "bone_name") {
2121 set_bone_name(p_value);
2122 return true;
2123 }
2124
2125 if (joint_data) {
2126 if (joint_data->_set(p_name, p_value)) {
2127 #ifdef TOOLS_ENABLED
2128 if (get_gizmo().is_valid())
2129 get_gizmo()->redraw();
2130 #endif
2131 return true;
2132 }
2133 }
2134
2135 return false;
2136 }
2137
_get(const StringName & p_name,Variant & r_ret) const2138 bool PhysicalBone::_get(const StringName &p_name, Variant &r_ret) const {
2139 if (p_name == "bone_name") {
2140 r_ret = get_bone_name();
2141 return true;
2142 }
2143
2144 if (joint_data) {
2145 return joint_data->_get(p_name, r_ret);
2146 }
2147
2148 return false;
2149 }
2150
_get_property_list(List<PropertyInfo> * p_list) const2151 void PhysicalBone::_get_property_list(List<PropertyInfo> *p_list) const {
2152
2153 Skeleton *parent = find_skeleton_parent(get_parent());
2154
2155 if (parent) {
2156
2157 String names;
2158 for (int i = 0; i < parent->get_bone_count(); i++) {
2159 if (i > 0)
2160 names += ",";
2161 names += parent->get_bone_name(i);
2162 }
2163
2164 p_list->push_back(PropertyInfo(Variant::STRING, "bone_name", PROPERTY_HINT_ENUM, names));
2165 } else {
2166
2167 p_list->push_back(PropertyInfo(Variant::STRING, "bone_name"));
2168 }
2169
2170 if (joint_data) {
2171 joint_data->_get_property_list(p_list);
2172 }
2173 }
2174
_notification(int p_what)2175 void PhysicalBone::_notification(int p_what) {
2176 switch (p_what) {
2177 case NOTIFICATION_ENTER_TREE:
2178 parent_skeleton = find_skeleton_parent(get_parent());
2179 update_bone_id();
2180 reset_to_rest_position();
2181 _reset_physics_simulation_state();
2182 if (!joint.is_valid() && joint_data) {
2183 _reload_joint();
2184 }
2185 break;
2186 case NOTIFICATION_EXIT_TREE:
2187 if (parent_skeleton) {
2188 if (-1 != bone_id) {
2189 parent_skeleton->unbind_physical_bone_from_bone(bone_id);
2190 }
2191 }
2192 parent_skeleton = NULL;
2193 if (joint.is_valid()) {
2194 PhysicsServer::get_singleton()->free(joint);
2195 joint = RID();
2196 }
2197 break;
2198 case NOTIFICATION_TRANSFORM_CHANGED:
2199 if (Engine::get_singleton()->is_editor_hint()) {
2200
2201 update_offset();
2202 }
2203 break;
2204 }
2205 }
2206
_direct_state_changed(Object * p_state)2207 void PhysicalBone::_direct_state_changed(Object *p_state) {
2208
2209 if (!simulate_physics || !_internal_simulate_physics) {
2210 return;
2211 }
2212
2213 /// Update bone transform
2214
2215 PhysicsDirectBodyState *state;
2216
2217 #ifdef DEBUG_ENABLED
2218 state = Object::cast_to<PhysicsDirectBodyState>(p_state);
2219 #else
2220 state = (PhysicsDirectBodyState *)p_state; //trust it
2221 #endif
2222
2223 Transform global_transform(state->get_transform());
2224
2225 set_ignore_transform_notification(true);
2226 set_global_transform(global_transform);
2227 set_ignore_transform_notification(false);
2228
2229 // Update skeleton
2230 if (parent_skeleton) {
2231 if (-1 != bone_id) {
2232 parent_skeleton->set_bone_global_pose_override(bone_id, parent_skeleton->get_global_transform().affine_inverse() * (global_transform * body_offset_inverse), 1.0, true);
2233 }
2234 }
2235 }
2236
_bind_methods()2237 void PhysicalBone::_bind_methods() {
2238 ClassDB::bind_method(D_METHOD("apply_central_impulse", "impulse"), &PhysicalBone::apply_central_impulse);
2239 ClassDB::bind_method(D_METHOD("apply_impulse", "position", "impulse"), &PhysicalBone::apply_impulse);
2240
2241 ClassDB::bind_method(D_METHOD("_direct_state_changed"), &PhysicalBone::_direct_state_changed);
2242
2243 ClassDB::bind_method(D_METHOD("set_joint_type", "joint_type"), &PhysicalBone::set_joint_type);
2244 ClassDB::bind_method(D_METHOD("get_joint_type"), &PhysicalBone::get_joint_type);
2245
2246 ClassDB::bind_method(D_METHOD("set_joint_offset", "offset"), &PhysicalBone::set_joint_offset);
2247 ClassDB::bind_method(D_METHOD("get_joint_offset"), &PhysicalBone::get_joint_offset);
2248
2249 ClassDB::bind_method(D_METHOD("set_body_offset", "offset"), &PhysicalBone::set_body_offset);
2250 ClassDB::bind_method(D_METHOD("get_body_offset"), &PhysicalBone::get_body_offset);
2251
2252 ClassDB::bind_method(D_METHOD("is_static_body"), &PhysicalBone::is_static_body);
2253
2254 ClassDB::bind_method(D_METHOD("get_simulate_physics"), &PhysicalBone::get_simulate_physics);
2255
2256 ClassDB::bind_method(D_METHOD("is_simulating_physics"), &PhysicalBone::is_simulating_physics);
2257
2258 ClassDB::bind_method(D_METHOD("get_bone_id"), &PhysicalBone::get_bone_id);
2259
2260 ClassDB::bind_method(D_METHOD("set_mass", "mass"), &PhysicalBone::set_mass);
2261 ClassDB::bind_method(D_METHOD("get_mass"), &PhysicalBone::get_mass);
2262
2263 ClassDB::bind_method(D_METHOD("set_weight", "weight"), &PhysicalBone::set_weight);
2264 ClassDB::bind_method(D_METHOD("get_weight"), &PhysicalBone::get_weight);
2265
2266 ClassDB::bind_method(D_METHOD("set_friction", "friction"), &PhysicalBone::set_friction);
2267 ClassDB::bind_method(D_METHOD("get_friction"), &PhysicalBone::get_friction);
2268
2269 ClassDB::bind_method(D_METHOD("set_bounce", "bounce"), &PhysicalBone::set_bounce);
2270 ClassDB::bind_method(D_METHOD("get_bounce"), &PhysicalBone::get_bounce);
2271
2272 ClassDB::bind_method(D_METHOD("set_gravity_scale", "gravity_scale"), &PhysicalBone::set_gravity_scale);
2273 ClassDB::bind_method(D_METHOD("get_gravity_scale"), &PhysicalBone::get_gravity_scale);
2274
2275 ADD_GROUP("Joint", "joint_");
2276 ADD_PROPERTY(PropertyInfo(Variant::INT, "joint_type", PROPERTY_HINT_ENUM, "None,PinJoint,ConeJoint,HingeJoint,SliderJoint,6DOFJoint"), "set_joint_type", "get_joint_type");
2277 ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "joint_offset"), "set_joint_offset", "get_joint_offset");
2278
2279 ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "body_offset"), "set_body_offset", "get_body_offset");
2280
2281 ADD_PROPERTY(PropertyInfo(Variant::REAL, "mass", PROPERTY_HINT_EXP_RANGE, "0.01,65535,0.01"), "set_mass", "get_mass");
2282 ADD_PROPERTY(PropertyInfo(Variant::REAL, "weight", PROPERTY_HINT_EXP_RANGE, "0.01,65535,0.01"), "set_weight", "get_weight");
2283 ADD_PROPERTY(PropertyInfo(Variant::REAL, "friction", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_friction", "get_friction");
2284 ADD_PROPERTY(PropertyInfo(Variant::REAL, "bounce", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_bounce", "get_bounce");
2285 ADD_PROPERTY(PropertyInfo(Variant::REAL, "gravity_scale", PROPERTY_HINT_RANGE, "-10,10,0.01"), "set_gravity_scale", "get_gravity_scale");
2286
2287 BIND_ENUM_CONSTANT(JOINT_TYPE_NONE);
2288 BIND_ENUM_CONSTANT(JOINT_TYPE_PIN);
2289 BIND_ENUM_CONSTANT(JOINT_TYPE_CONE);
2290 BIND_ENUM_CONSTANT(JOINT_TYPE_HINGE);
2291 BIND_ENUM_CONSTANT(JOINT_TYPE_SLIDER);
2292 BIND_ENUM_CONSTANT(JOINT_TYPE_6DOF);
2293 }
2294
find_skeleton_parent(Node * p_parent)2295 Skeleton *PhysicalBone::find_skeleton_parent(Node *p_parent) {
2296 if (!p_parent) {
2297 return NULL;
2298 }
2299 Skeleton *s = Object::cast_to<Skeleton>(p_parent);
2300 return s ? s : find_skeleton_parent(p_parent->get_parent());
2301 }
2302
_fix_joint_offset()2303 void PhysicalBone::_fix_joint_offset() {
2304 // Clamp joint origin to bone origin
2305 if (parent_skeleton) {
2306 joint_offset.origin = body_offset.affine_inverse().origin;
2307 }
2308 }
2309
_reload_joint()2310 void PhysicalBone::_reload_joint() {
2311
2312 if (joint.is_valid()) {
2313 PhysicsServer::get_singleton()->free(joint);
2314 joint = RID();
2315 }
2316
2317 if (!parent_skeleton) {
2318 return;
2319 }
2320
2321 PhysicalBone *body_a = parent_skeleton->get_physical_bone_parent(bone_id);
2322 if (!body_a) {
2323 return;
2324 }
2325
2326 Transform joint_transf = get_global_transform() * joint_offset;
2327 Transform local_a = body_a->get_global_transform().affine_inverse() * joint_transf;
2328 local_a.orthonormalize();
2329
2330 switch (get_joint_type()) {
2331 case JOINT_TYPE_PIN: {
2332
2333 joint = PhysicsServer::get_singleton()->joint_create_pin(body_a->get_rid(), local_a.origin, get_rid(), joint_offset.origin);
2334 const PinJointData *pjd(static_cast<const PinJointData *>(joint_data));
2335 PhysicsServer::get_singleton()->pin_joint_set_param(joint, PhysicsServer::PIN_JOINT_BIAS, pjd->bias);
2336 PhysicsServer::get_singleton()->pin_joint_set_param(joint, PhysicsServer::PIN_JOINT_DAMPING, pjd->damping);
2337 PhysicsServer::get_singleton()->pin_joint_set_param(joint, PhysicsServer::PIN_JOINT_IMPULSE_CLAMP, pjd->impulse_clamp);
2338
2339 } break;
2340 case JOINT_TYPE_CONE: {
2341
2342 joint = PhysicsServer::get_singleton()->joint_create_cone_twist(body_a->get_rid(), local_a, get_rid(), joint_offset);
2343 const ConeJointData *cjd(static_cast<const ConeJointData *>(joint_data));
2344 PhysicsServer::get_singleton()->cone_twist_joint_set_param(joint, PhysicsServer::CONE_TWIST_JOINT_SWING_SPAN, cjd->swing_span);
2345 PhysicsServer::get_singleton()->cone_twist_joint_set_param(joint, PhysicsServer::CONE_TWIST_JOINT_TWIST_SPAN, cjd->twist_span);
2346 PhysicsServer::get_singleton()->cone_twist_joint_set_param(joint, PhysicsServer::CONE_TWIST_JOINT_BIAS, cjd->bias);
2347 PhysicsServer::get_singleton()->cone_twist_joint_set_param(joint, PhysicsServer::CONE_TWIST_JOINT_SOFTNESS, cjd->softness);
2348 PhysicsServer::get_singleton()->cone_twist_joint_set_param(joint, PhysicsServer::CONE_TWIST_JOINT_RELAXATION, cjd->relaxation);
2349
2350 } break;
2351 case JOINT_TYPE_HINGE: {
2352
2353 joint = PhysicsServer::get_singleton()->joint_create_hinge(body_a->get_rid(), local_a, get_rid(), joint_offset);
2354 const HingeJointData *hjd(static_cast<const HingeJointData *>(joint_data));
2355 PhysicsServer::get_singleton()->hinge_joint_set_flag(joint, PhysicsServer::HINGE_JOINT_FLAG_USE_LIMIT, hjd->angular_limit_enabled);
2356 PhysicsServer::get_singleton()->hinge_joint_set_param(joint, PhysicsServer::HINGE_JOINT_LIMIT_UPPER, hjd->angular_limit_upper);
2357 PhysicsServer::get_singleton()->hinge_joint_set_param(joint, PhysicsServer::HINGE_JOINT_LIMIT_LOWER, hjd->angular_limit_lower);
2358 PhysicsServer::get_singleton()->hinge_joint_set_param(joint, PhysicsServer::HINGE_JOINT_LIMIT_BIAS, hjd->angular_limit_bias);
2359 PhysicsServer::get_singleton()->hinge_joint_set_param(joint, PhysicsServer::HINGE_JOINT_LIMIT_SOFTNESS, hjd->angular_limit_softness);
2360 PhysicsServer::get_singleton()->hinge_joint_set_param(joint, PhysicsServer::HINGE_JOINT_LIMIT_RELAXATION, hjd->angular_limit_relaxation);
2361
2362 } break;
2363 case JOINT_TYPE_SLIDER: {
2364
2365 joint = PhysicsServer::get_singleton()->joint_create_slider(body_a->get_rid(), local_a, get_rid(), joint_offset);
2366 const SliderJointData *sjd(static_cast<const SliderJointData *>(joint_data));
2367 PhysicsServer::get_singleton()->slider_joint_set_param(joint, PhysicsServer::SLIDER_JOINT_LINEAR_LIMIT_UPPER, sjd->linear_limit_upper);
2368 PhysicsServer::get_singleton()->slider_joint_set_param(joint, PhysicsServer::SLIDER_JOINT_LINEAR_LIMIT_LOWER, sjd->linear_limit_lower);
2369 PhysicsServer::get_singleton()->slider_joint_set_param(joint, PhysicsServer::SLIDER_JOINT_LINEAR_LIMIT_SOFTNESS, sjd->linear_limit_softness);
2370 PhysicsServer::get_singleton()->slider_joint_set_param(joint, PhysicsServer::SLIDER_JOINT_LINEAR_LIMIT_RESTITUTION, sjd->linear_limit_restitution);
2371 PhysicsServer::get_singleton()->slider_joint_set_param(joint, PhysicsServer::SLIDER_JOINT_LINEAR_LIMIT_DAMPING, sjd->linear_limit_restitution);
2372 PhysicsServer::get_singleton()->slider_joint_set_param(joint, PhysicsServer::SLIDER_JOINT_ANGULAR_LIMIT_UPPER, sjd->angular_limit_upper);
2373 PhysicsServer::get_singleton()->slider_joint_set_param(joint, PhysicsServer::SLIDER_JOINT_ANGULAR_LIMIT_LOWER, sjd->angular_limit_lower);
2374 PhysicsServer::get_singleton()->slider_joint_set_param(joint, PhysicsServer::SLIDER_JOINT_ANGULAR_LIMIT_SOFTNESS, sjd->angular_limit_softness);
2375 PhysicsServer::get_singleton()->slider_joint_set_param(joint, PhysicsServer::SLIDER_JOINT_ANGULAR_LIMIT_SOFTNESS, sjd->angular_limit_softness);
2376 PhysicsServer::get_singleton()->slider_joint_set_param(joint, PhysicsServer::SLIDER_JOINT_ANGULAR_LIMIT_DAMPING, sjd->angular_limit_damping);
2377
2378 } break;
2379 case JOINT_TYPE_6DOF: {
2380
2381 joint = PhysicsServer::get_singleton()->joint_create_generic_6dof(body_a->get_rid(), local_a, get_rid(), joint_offset);
2382 const SixDOFJointData *g6dofjd(static_cast<const SixDOFJointData *>(joint_data));
2383 for (int axis = 0; axis < 3; ++axis) {
2384 PhysicsServer::get_singleton()->generic_6dof_joint_set_flag(joint, static_cast<Vector3::Axis>(axis), PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_LINEAR_LIMIT, g6dofjd->axis_data[axis].linear_limit_enabled);
2385 PhysicsServer::get_singleton()->generic_6dof_joint_set_param(joint, static_cast<Vector3::Axis>(axis), PhysicsServer::G6DOF_JOINT_LINEAR_UPPER_LIMIT, g6dofjd->axis_data[axis].linear_limit_upper);
2386 PhysicsServer::get_singleton()->generic_6dof_joint_set_param(joint, static_cast<Vector3::Axis>(axis), PhysicsServer::G6DOF_JOINT_LINEAR_LOWER_LIMIT, g6dofjd->axis_data[axis].linear_limit_lower);
2387 PhysicsServer::get_singleton()->generic_6dof_joint_set_param(joint, static_cast<Vector3::Axis>(axis), PhysicsServer::G6DOF_JOINT_LINEAR_LIMIT_SOFTNESS, g6dofjd->axis_data[axis].linear_limit_softness);
2388 PhysicsServer::get_singleton()->generic_6dof_joint_set_flag(joint, static_cast<Vector3::Axis>(axis), PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_LINEAR_SPRING, g6dofjd->axis_data[axis].linear_spring_enabled);
2389 PhysicsServer::get_singleton()->generic_6dof_joint_set_param(joint, static_cast<Vector3::Axis>(axis), PhysicsServer::G6DOF_JOINT_LINEAR_SPRING_STIFFNESS, g6dofjd->axis_data[axis].linear_spring_stiffness);
2390 PhysicsServer::get_singleton()->generic_6dof_joint_set_param(joint, static_cast<Vector3::Axis>(axis), PhysicsServer::G6DOF_JOINT_LINEAR_SPRING_DAMPING, g6dofjd->axis_data[axis].linear_spring_damping);
2391 PhysicsServer::get_singleton()->generic_6dof_joint_set_param(joint, static_cast<Vector3::Axis>(axis), PhysicsServer::G6DOF_JOINT_LINEAR_SPRING_EQUILIBRIUM_POINT, g6dofjd->axis_data[axis].linear_equilibrium_point);
2392 PhysicsServer::get_singleton()->generic_6dof_joint_set_param(joint, static_cast<Vector3::Axis>(axis), PhysicsServer::G6DOF_JOINT_LINEAR_RESTITUTION, g6dofjd->axis_data[axis].linear_restitution);
2393 PhysicsServer::get_singleton()->generic_6dof_joint_set_param(joint, static_cast<Vector3::Axis>(axis), PhysicsServer::G6DOF_JOINT_LINEAR_DAMPING, g6dofjd->axis_data[axis].linear_damping);
2394 PhysicsServer::get_singleton()->generic_6dof_joint_set_flag(joint, static_cast<Vector3::Axis>(axis), PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_ANGULAR_LIMIT, g6dofjd->axis_data[axis].angular_limit_enabled);
2395 PhysicsServer::get_singleton()->generic_6dof_joint_set_param(joint, static_cast<Vector3::Axis>(axis), PhysicsServer::G6DOF_JOINT_ANGULAR_UPPER_LIMIT, g6dofjd->axis_data[axis].angular_limit_upper);
2396 PhysicsServer::get_singleton()->generic_6dof_joint_set_param(joint, static_cast<Vector3::Axis>(axis), PhysicsServer::G6DOF_JOINT_ANGULAR_LOWER_LIMIT, g6dofjd->axis_data[axis].angular_limit_lower);
2397 PhysicsServer::get_singleton()->generic_6dof_joint_set_param(joint, static_cast<Vector3::Axis>(axis), PhysicsServer::G6DOF_JOINT_ANGULAR_LIMIT_SOFTNESS, g6dofjd->axis_data[axis].angular_limit_softness);
2398 PhysicsServer::get_singleton()->generic_6dof_joint_set_param(joint, static_cast<Vector3::Axis>(axis), PhysicsServer::G6DOF_JOINT_ANGULAR_RESTITUTION, g6dofjd->axis_data[axis].angular_restitution);
2399 PhysicsServer::get_singleton()->generic_6dof_joint_set_param(joint, static_cast<Vector3::Axis>(axis), PhysicsServer::G6DOF_JOINT_ANGULAR_DAMPING, g6dofjd->axis_data[axis].angular_damping);
2400 PhysicsServer::get_singleton()->generic_6dof_joint_set_param(joint, static_cast<Vector3::Axis>(axis), PhysicsServer::G6DOF_JOINT_ANGULAR_ERP, g6dofjd->axis_data[axis].erp);
2401 PhysicsServer::get_singleton()->generic_6dof_joint_set_flag(joint, static_cast<Vector3::Axis>(axis), PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_ANGULAR_SPRING, g6dofjd->axis_data[axis].angular_spring_enabled);
2402 PhysicsServer::get_singleton()->generic_6dof_joint_set_param(joint, static_cast<Vector3::Axis>(axis), PhysicsServer::G6DOF_JOINT_ANGULAR_SPRING_STIFFNESS, g6dofjd->axis_data[axis].angular_spring_stiffness);
2403 PhysicsServer::get_singleton()->generic_6dof_joint_set_param(joint, static_cast<Vector3::Axis>(axis), PhysicsServer::G6DOF_JOINT_ANGULAR_SPRING_DAMPING, g6dofjd->axis_data[axis].angular_spring_damping);
2404 PhysicsServer::get_singleton()->generic_6dof_joint_set_param(joint, static_cast<Vector3::Axis>(axis), PhysicsServer::G6DOF_JOINT_ANGULAR_SPRING_EQUILIBRIUM_POINT, g6dofjd->axis_data[axis].angular_equilibrium_point);
2405 }
2406
2407 } break;
2408 case JOINT_TYPE_NONE: {
2409 } break;
2410 }
2411 }
2412
_on_bone_parent_changed()2413 void PhysicalBone::_on_bone_parent_changed() {
2414 _reload_joint();
2415 }
2416
_set_gizmo_move_joint(bool p_move_joint)2417 void PhysicalBone::_set_gizmo_move_joint(bool p_move_joint) {
2418 #ifdef TOOLS_ENABLED
2419 gizmo_move_joint = p_move_joint;
2420 SpatialEditor::get_singleton()->update_transform_gizmo();
2421 #endif
2422 }
2423
2424 #ifdef TOOLS_ENABLED
get_global_gizmo_transform() const2425 Transform PhysicalBone::get_global_gizmo_transform() const {
2426 return gizmo_move_joint ? get_global_transform() * joint_offset : get_global_transform();
2427 }
2428
get_local_gizmo_transform() const2429 Transform PhysicalBone::get_local_gizmo_transform() const {
2430 return gizmo_move_joint ? get_transform() * joint_offset : get_transform();
2431 }
2432 #endif
2433
get_joint_data() const2434 const PhysicalBone::JointData *PhysicalBone::get_joint_data() const {
2435 return joint_data;
2436 }
2437
find_skeleton_parent()2438 Skeleton *PhysicalBone::find_skeleton_parent() {
2439 return find_skeleton_parent(this);
2440 }
2441
set_joint_type(JointType p_joint_type)2442 void PhysicalBone::set_joint_type(JointType p_joint_type) {
2443
2444 if (p_joint_type == get_joint_type())
2445 return;
2446
2447 if (joint_data)
2448 memdelete(joint_data);
2449 joint_data = NULL;
2450 switch (p_joint_type) {
2451 case JOINT_TYPE_PIN:
2452 joint_data = memnew(PinJointData);
2453 break;
2454 case JOINT_TYPE_CONE:
2455 joint_data = memnew(ConeJointData);
2456 break;
2457 case JOINT_TYPE_HINGE:
2458 joint_data = memnew(HingeJointData);
2459 break;
2460 case JOINT_TYPE_SLIDER:
2461 joint_data = memnew(SliderJointData);
2462 break;
2463 case JOINT_TYPE_6DOF:
2464 joint_data = memnew(SixDOFJointData);
2465 break;
2466 case JOINT_TYPE_NONE:
2467 break;
2468 }
2469
2470 _reload_joint();
2471
2472 #ifdef TOOLS_ENABLED
2473 _change_notify();
2474 if (get_gizmo().is_valid())
2475 get_gizmo()->redraw();
2476 #endif
2477 }
2478
get_joint_type() const2479 PhysicalBone::JointType PhysicalBone::get_joint_type() const {
2480 return joint_data ? joint_data->get_joint_type() : JOINT_TYPE_NONE;
2481 }
2482
set_joint_offset(const Transform & p_offset)2483 void PhysicalBone::set_joint_offset(const Transform &p_offset) {
2484 joint_offset = p_offset;
2485
2486 _fix_joint_offset();
2487
2488 set_ignore_transform_notification(true);
2489 reset_to_rest_position();
2490 set_ignore_transform_notification(false);
2491
2492 #ifdef TOOLS_ENABLED
2493 if (get_gizmo().is_valid())
2494 get_gizmo()->redraw();
2495 #endif
2496 }
2497
get_body_offset() const2498 const Transform &PhysicalBone::get_body_offset() const {
2499 return body_offset;
2500 }
2501
set_body_offset(const Transform & p_offset)2502 void PhysicalBone::set_body_offset(const Transform &p_offset) {
2503 body_offset = p_offset;
2504 body_offset_inverse = body_offset.affine_inverse();
2505
2506 _fix_joint_offset();
2507
2508 set_ignore_transform_notification(true);
2509 reset_to_rest_position();
2510 set_ignore_transform_notification(false);
2511
2512 #ifdef TOOLS_ENABLED
2513 if (get_gizmo().is_valid())
2514 get_gizmo()->redraw();
2515 #endif
2516 }
2517
get_joint_offset() const2518 const Transform &PhysicalBone::get_joint_offset() const {
2519 return joint_offset;
2520 }
2521
set_static_body(bool p_static)2522 void PhysicalBone::set_static_body(bool p_static) {
2523
2524 static_body = p_static;
2525
2526 set_as_toplevel(!static_body);
2527
2528 _reset_physics_simulation_state();
2529 }
2530
is_static_body()2531 bool PhysicalBone::is_static_body() {
2532 return static_body;
2533 }
2534
set_simulate_physics(bool p_simulate)2535 void PhysicalBone::set_simulate_physics(bool p_simulate) {
2536 if (simulate_physics == p_simulate) {
2537 return;
2538 }
2539
2540 simulate_physics = p_simulate;
2541 _reset_physics_simulation_state();
2542 }
2543
get_simulate_physics()2544 bool PhysicalBone::get_simulate_physics() {
2545 return simulate_physics;
2546 }
2547
is_simulating_physics()2548 bool PhysicalBone::is_simulating_physics() {
2549 return _internal_simulate_physics && !_internal_static_body;
2550 }
2551
set_bone_name(const String & p_name)2552 void PhysicalBone::set_bone_name(const String &p_name) {
2553
2554 bone_name = p_name;
2555 bone_id = -1;
2556
2557 update_bone_id();
2558 reset_to_rest_position();
2559 }
2560
get_bone_name() const2561 const String &PhysicalBone::get_bone_name() const {
2562
2563 return bone_name;
2564 }
2565
set_mass(real_t p_mass)2566 void PhysicalBone::set_mass(real_t p_mass) {
2567
2568 ERR_FAIL_COND(p_mass <= 0);
2569 mass = p_mass;
2570 PhysicsServer::get_singleton()->body_set_param(get_rid(), PhysicsServer::BODY_PARAM_MASS, mass);
2571 }
2572
get_mass() const2573 real_t PhysicalBone::get_mass() const {
2574
2575 return mass;
2576 }
2577
set_weight(real_t p_weight)2578 void PhysicalBone::set_weight(real_t p_weight) {
2579
2580 set_mass(p_weight / real_t(GLOBAL_DEF("physics/3d/default_gravity", 9.8)));
2581 }
2582
get_weight() const2583 real_t PhysicalBone::get_weight() const {
2584
2585 return mass * real_t(GLOBAL_DEF("physics/3d/default_gravity", 9.8));
2586 }
2587
set_friction(real_t p_friction)2588 void PhysicalBone::set_friction(real_t p_friction) {
2589
2590 ERR_FAIL_COND(p_friction < 0 || p_friction > 1);
2591
2592 friction = p_friction;
2593 PhysicsServer::get_singleton()->body_set_param(get_rid(), PhysicsServer::BODY_PARAM_FRICTION, friction);
2594 }
2595
get_friction() const2596 real_t PhysicalBone::get_friction() const {
2597
2598 return friction;
2599 }
2600
set_bounce(real_t p_bounce)2601 void PhysicalBone::set_bounce(real_t p_bounce) {
2602
2603 ERR_FAIL_COND(p_bounce < 0 || p_bounce > 1);
2604
2605 bounce = p_bounce;
2606 PhysicsServer::get_singleton()->body_set_param(get_rid(), PhysicsServer::BODY_PARAM_BOUNCE, bounce);
2607 }
2608
get_bounce() const2609 real_t PhysicalBone::get_bounce() const {
2610
2611 return bounce;
2612 }
2613
set_gravity_scale(real_t p_gravity_scale)2614 void PhysicalBone::set_gravity_scale(real_t p_gravity_scale) {
2615
2616 gravity_scale = p_gravity_scale;
2617 PhysicsServer::get_singleton()->body_set_param(get_rid(), PhysicsServer::BODY_PARAM_GRAVITY_SCALE, gravity_scale);
2618 }
2619
get_gravity_scale() const2620 real_t PhysicalBone::get_gravity_scale() const {
2621
2622 return gravity_scale;
2623 }
2624
PhysicalBone()2625 PhysicalBone::PhysicalBone() :
2626 PhysicsBody(PhysicsServer::BODY_MODE_STATIC),
2627 #ifdef TOOLS_ENABLED
2628 gizmo_move_joint(false),
2629 #endif
2630 joint_data(NULL),
2631 parent_skeleton(NULL),
2632 static_body(false),
2633 _internal_static_body(false),
2634 simulate_physics(false),
2635 _internal_simulate_physics(false),
2636 bone_id(-1),
2637 bone_name(""),
2638 bounce(0),
2639 mass(1),
2640 friction(1),
2641 gravity_scale(1) {
2642
2643 set_static_body(static_body);
2644 _reset_physics_simulation_state();
2645 }
2646
~PhysicalBone()2647 PhysicalBone::~PhysicalBone() {
2648 if (joint_data)
2649 memdelete(joint_data);
2650 }
2651
update_bone_id()2652 void PhysicalBone::update_bone_id() {
2653 if (!parent_skeleton) {
2654 return;
2655 }
2656
2657 const int new_bone_id = parent_skeleton->find_bone(bone_name);
2658
2659 if (new_bone_id != bone_id) {
2660 if (-1 != bone_id) {
2661 // Assert the unbind from old node
2662 parent_skeleton->unbind_physical_bone_from_bone(bone_id);
2663 parent_skeleton->unbind_child_node_from_bone(bone_id, this);
2664 }
2665
2666 bone_id = new_bone_id;
2667
2668 parent_skeleton->bind_physical_bone_to_bone(bone_id, this);
2669
2670 _fix_joint_offset();
2671 _internal_static_body = !static_body; // Force staticness reset
2672 _reset_staticness_state();
2673 }
2674 }
2675
update_offset()2676 void PhysicalBone::update_offset() {
2677 #ifdef TOOLS_ENABLED
2678 if (parent_skeleton) {
2679
2680 Transform bone_transform(parent_skeleton->get_global_transform());
2681 if (-1 != bone_id)
2682 bone_transform *= parent_skeleton->get_bone_global_pose(bone_id);
2683
2684 if (gizmo_move_joint) {
2685 bone_transform *= body_offset;
2686 set_joint_offset(bone_transform.affine_inverse() * get_global_transform());
2687 } else {
2688 set_body_offset(bone_transform.affine_inverse() * get_global_transform());
2689 }
2690 }
2691 #endif
2692 }
2693
reset_to_rest_position()2694 void PhysicalBone::reset_to_rest_position() {
2695 if (parent_skeleton) {
2696 if (-1 == bone_id) {
2697 set_global_transform(parent_skeleton->get_global_transform() * body_offset);
2698 } else {
2699 set_global_transform(parent_skeleton->get_global_transform() * parent_skeleton->get_bone_global_pose(bone_id) * body_offset);
2700 }
2701 }
2702 }
2703
_reset_physics_simulation_state()2704 void PhysicalBone::_reset_physics_simulation_state() {
2705 if (simulate_physics && !static_body) {
2706 _start_physics_simulation();
2707 } else {
2708 _stop_physics_simulation();
2709 }
2710
2711 _reset_staticness_state();
2712 }
2713
_reset_staticness_state()2714 void PhysicalBone::_reset_staticness_state() {
2715
2716 if (parent_skeleton && -1 != bone_id) {
2717 if (static_body && simulate_physics) { // With this check I'm sure the position of this body is updated only when it's necessary
2718
2719 if (_internal_static_body) {
2720 return;
2721 }
2722
2723 parent_skeleton->bind_child_node_to_bone(bone_id, this);
2724 _internal_static_body = true;
2725 } else {
2726
2727 if (!_internal_static_body) {
2728 return;
2729 }
2730
2731 parent_skeleton->unbind_child_node_from_bone(bone_id, this);
2732 _internal_static_body = false;
2733 }
2734 }
2735 }
2736
_start_physics_simulation()2737 void PhysicalBone::_start_physics_simulation() {
2738 if (_internal_simulate_physics || !parent_skeleton) {
2739 return;
2740 }
2741 reset_to_rest_position();
2742 PhysicsServer::get_singleton()->body_set_mode(get_rid(), PhysicsServer::BODY_MODE_RIGID);
2743 PhysicsServer::get_singleton()->body_set_collision_layer(get_rid(), get_collision_layer());
2744 PhysicsServer::get_singleton()->body_set_collision_mask(get_rid(), get_collision_mask());
2745 PhysicsServer::get_singleton()->body_set_force_integration_callback(get_rid(), this, "_direct_state_changed");
2746 _internal_simulate_physics = true;
2747 }
2748
_stop_physics_simulation()2749 void PhysicalBone::_stop_physics_simulation() {
2750 if (!_internal_simulate_physics || !parent_skeleton) {
2751 return;
2752 }
2753 PhysicsServer::get_singleton()->body_set_mode(get_rid(), PhysicsServer::BODY_MODE_STATIC);
2754 PhysicsServer::get_singleton()->body_set_collision_layer(get_rid(), 0);
2755 PhysicsServer::get_singleton()->body_set_collision_mask(get_rid(), 0);
2756 PhysicsServer::get_singleton()->body_set_force_integration_callback(get_rid(), NULL, "");
2757 parent_skeleton->set_bone_global_pose_override(bone_id, Transform(), 0.0, false);
2758 _internal_simulate_physics = false;
2759 }
2760