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