| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*************************************************************************/ | 
					
						
							| 
									
										
										
										
											2021-10-18 12:24:30 -07:00
										 |  |  | /*  godot_body_3d.cpp                                                    */ | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | /*                       This file is part of:                           */ | 
					
						
							|  |  |  | /*                           GODOT ENGINE                                */ | 
					
						
							| 
									
										
										
										
											2017-08-27 14:16:55 +02:00
										 |  |  | /*                      https://godotengine.org                          */ | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*************************************************************************/ | 
					
						
							| 
									
										
										
										
											2022-01-03 21:27:34 +01:00
										 |  |  | /* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur.                 */ | 
					
						
							|  |  |  | /* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md).   */ | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* Permission is hereby granted, free of charge, to any person obtaining */ | 
					
						
							|  |  |  | /* a copy of this software and associated documentation files (the       */ | 
					
						
							|  |  |  | /* "Software"), to deal in the Software without restriction, including   */ | 
					
						
							|  |  |  | /* without limitation the rights to use, copy, modify, merge, publish,   */ | 
					
						
							|  |  |  | /* distribute, sublicense, and/or sell copies of the Software, and to    */ | 
					
						
							|  |  |  | /* permit persons to whom the Software is furnished to do so, subject to */ | 
					
						
							|  |  |  | /* the following conditions:                                             */ | 
					
						
							|  |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* The above copyright notice and this permission notice shall be        */ | 
					
						
							|  |  |  | /* included in all copies or substantial portions of the Software.       */ | 
					
						
							|  |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */ | 
					
						
							|  |  |  | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */ | 
					
						
							|  |  |  | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ | 
					
						
							|  |  |  | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */ | 
					
						
							|  |  |  | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */ | 
					
						
							|  |  |  | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */ | 
					
						
							|  |  |  | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */ | 
					
						
							|  |  |  | /*************************************************************************/ | 
					
						
							| 
									
										
										
										
											2018-01-05 00:50:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-18 12:24:30 -07:00
										 |  |  | #include "godot_body_3d.h"
 | 
					
						
							| 
									
										
										
										
											2021-06-04 16:09:41 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-18 12:24:30 -07:00
										 |  |  | #include "godot_area_3d.h"
 | 
					
						
							|  |  |  | #include "godot_body_direct_state_3d.h"
 | 
					
						
							|  |  |  | #include "godot_space_3d.h"
 | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-18 12:24:30 -07:00
										 |  |  | void GodotBody3D::_mass_properties_changed() { | 
					
						
							| 
									
										
										
										
											2021-06-10 17:37:19 -07:00
										 |  |  | 	if (get_space() && !mass_properties_update_list.in_list() && (calculate_inertia || calculate_center_of_mass)) { | 
					
						
							|  |  |  | 		get_space()->body_add_to_mass_properties_update_list(&mass_properties_update_list); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-19 16:16:00 -07:00
										 |  |  | void GodotBody3D::_update_transform_dependent() { | 
					
						
							| 
									
										
										
										
											2016-12-31 14:39:25 +00:00
										 |  |  | 	center_of_mass = get_transform().basis.xform(center_of_mass_local); | 
					
						
							|  |  |  | 	principal_inertia_axes = get_transform().basis * principal_inertia_axes_local; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-10 17:37:19 -07:00
										 |  |  | 	// Update inertia tensor.
 | 
					
						
							| 
									
										
										
										
											2017-01-11 00:52:51 -03:00
										 |  |  | 	Basis tb = principal_inertia_axes; | 
					
						
							|  |  |  | 	Basis tbt = tb.transposed(); | 
					
						
							| 
									
										
										
										
											2017-09-16 17:50:46 +01:00
										 |  |  | 	Basis diag; | 
					
						
							|  |  |  | 	diag.scale(_inv_inertia); | 
					
						
							|  |  |  | 	_inv_inertia_tensor = tb * diag * tbt; | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-18 12:24:30 -07:00
										 |  |  | void GodotBody3D::update_mass_properties() { | 
					
						
							| 
									
										
										
										
											2021-03-08 16:11:55 -05:00
										 |  |  | 	// Update shapes and motions.
 | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	switch (mode) { | 
					
						
							| 
									
										
										
										
											2022-08-25 19:35:52 +02:00
										 |  |  | 		case PhysicsServer3D::BODY_MODE_RIGID: { | 
					
						
							| 
									
										
										
										
											2017-02-13 17:25:05 -06:00
										 |  |  | 			real_t total_area = 0; | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 			for (int i = 0; i < get_shape_count(); i++) { | 
					
						
							| 
									
										
										
										
											2021-06-10 17:37:19 -07:00
										 |  |  | 				if (is_shape_disabled(i)) { | 
					
						
							|  |  |  | 					continue; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-31 14:39:25 +00:00
										 |  |  | 				total_area += get_shape_area(i); | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-10 17:37:19 -07:00
										 |  |  | 			if (calculate_center_of_mass) { | 
					
						
							|  |  |  | 				// We have to recompute the center of mass.
 | 
					
						
							|  |  |  | 				center_of_mass_local.zero(); | 
					
						
							| 
									
										
										
										
											2016-12-31 14:39:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-10 17:37:19 -07:00
										 |  |  | 				if (total_area != 0.0) { | 
					
						
							|  |  |  | 					for (int i = 0; i < get_shape_count(); i++) { | 
					
						
							|  |  |  | 						if (is_shape_disabled(i)) { | 
					
						
							|  |  |  | 							continue; | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2016-12-31 14:39:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-10 17:37:19 -07:00
										 |  |  | 						real_t area = get_shape_area(i); | 
					
						
							| 
									
										
										
										
											2016-12-31 14:39:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-29 12:53:28 +03:00
										 |  |  | 						real_t mass_new = area * mass / total_area; | 
					
						
							| 
									
										
										
										
											2021-06-10 17:37:19 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 						// NOTE: we assume that the shape origin is also its center of mass.
 | 
					
						
							| 
									
										
										
										
											2022-09-29 12:53:28 +03:00
										 |  |  | 						center_of_mass_local += mass_new * get_shape_transform(i).origin; | 
					
						
							| 
									
										
										
										
											2021-06-10 17:37:19 -07:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-10 17:37:19 -07:00
										 |  |  | 					center_of_mass_local /= mass; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2021-05-29 14:11:59 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2016-12-31 14:39:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-10 17:37:19 -07:00
										 |  |  | 			if (calculate_inertia) { | 
					
						
							|  |  |  | 				// Recompute the inertia tensor.
 | 
					
						
							|  |  |  | 				Basis inertia_tensor; | 
					
						
							|  |  |  | 				inertia_tensor.set_zero(); | 
					
						
							|  |  |  | 				bool inertia_set = false; | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-10 17:37:19 -07:00
										 |  |  | 				for (int i = 0; i < get_shape_count(); i++) { | 
					
						
							|  |  |  | 					if (is_shape_disabled(i)) { | 
					
						
							|  |  |  | 						continue; | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2018-12-08 00:09:39 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-10 17:37:19 -07:00
										 |  |  | 					real_t area = get_shape_area(i); | 
					
						
							|  |  |  | 					if (area == 0.0) { | 
					
						
							|  |  |  | 						continue; | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2021-05-29 14:11:59 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-10 17:37:19 -07:00
										 |  |  | 					inertia_set = true; | 
					
						
							| 
									
										
										
										
											2021-03-08 16:11:55 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-18 12:24:30 -07:00
										 |  |  | 					const GodotShape3D *shape = get_shape(i); | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-29 12:53:28 +03:00
										 |  |  | 					real_t mass_new = area * mass / total_area; | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-29 12:53:28 +03:00
										 |  |  | 					Basis shape_inertia_tensor = Basis::from_scale(shape->get_moment_of_inertia(mass_new)); | 
					
						
							| 
									
										
										
										
											2021-06-10 17:37:19 -07:00
										 |  |  | 					Transform3D shape_transform = get_shape_transform(i); | 
					
						
							|  |  |  | 					Basis shape_basis = shape_transform.basis.orthonormalized(); | 
					
						
							| 
									
										
										
										
											2016-12-31 14:39:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-10 17:37:19 -07:00
										 |  |  | 					// NOTE: we don't take the scale of collision shapes into account when computing the inertia tensor!
 | 
					
						
							|  |  |  | 					shape_inertia_tensor = shape_basis * shape_inertia_tensor * shape_basis.transposed(); | 
					
						
							| 
									
										
										
										
											2016-12-31 14:39:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-10 17:37:19 -07:00
										 |  |  | 					Vector3 shape_origin = shape_transform.origin - center_of_mass_local; | 
					
						
							| 
									
										
										
										
											2022-10-19 23:26:20 +02:00
										 |  |  | 					inertia_tensor += shape_inertia_tensor + (Basis() * shape_origin.dot(shape_origin) - shape_origin.outer(shape_origin)) * mass_new; | 
					
						
							| 
									
										
										
										
											2021-06-10 17:37:19 -07:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-10 17:37:19 -07:00
										 |  |  | 				// Set the inertia to a valid value when there are no valid shapes.
 | 
					
						
							|  |  |  | 				if (!inertia_set) { | 
					
						
							| 
									
										
										
										
											2021-09-06 15:39:01 -05:00
										 |  |  | 					inertia_tensor = Basis(); | 
					
						
							| 
									
										
										
										
											2021-06-10 17:37:19 -07:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2021-03-08 16:11:55 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-10 17:37:19 -07:00
										 |  |  | 				// Handle partial custom inertia.
 | 
					
						
							|  |  |  | 				if (inertia.x > 0.0) { | 
					
						
							|  |  |  | 					inertia_tensor[0][0] = inertia.x; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				if (inertia.y > 0.0) { | 
					
						
							|  |  |  | 					inertia_tensor[1][1] = inertia.y; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				if (inertia.z > 0.0) { | 
					
						
							|  |  |  | 					inertia_tensor[2][2] = inertia.z; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				// Compute the principal axes of inertia.
 | 
					
						
							|  |  |  | 				principal_inertia_axes_local = inertia_tensor.diagonalize().transposed(); | 
					
						
							|  |  |  | 				_inv_inertia = inertia_tensor.get_main_diagonal().inverse(); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			if (mass) { | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 				_inv_mass = 1.0 / mass; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 				_inv_mass = 0; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		} break; | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 		case PhysicsServer3D::BODY_MODE_KINEMATIC: | 
					
						
							|  |  |  | 		case PhysicsServer3D::BODY_MODE_STATIC: { | 
					
						
							| 
									
										
										
										
											2021-06-10 17:37:19 -07:00
										 |  |  | 			_inv_inertia = Vector3(); | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 			_inv_mass = 0; | 
					
						
							|  |  |  | 		} break; | 
					
						
							| 
									
										
										
										
											2022-08-25 19:35:52 +02:00
										 |  |  | 		case PhysicsServer3D::BODY_MODE_RIGID_LINEAR: { | 
					
						
							| 
									
										
										
										
											2016-12-31 14:39:25 +00:00
										 |  |  | 			_inv_inertia_tensor.set_zero(); | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 			_inv_mass = 1.0 / mass; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-12-31 14:39:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-19 16:16:00 -07:00
										 |  |  | 	_update_transform_dependent(); | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-18 12:24:30 -07:00
										 |  |  | void GodotBody3D::reset_mass_properties() { | 
					
						
							| 
									
										
										
										
											2021-06-10 17:37:19 -07:00
										 |  |  | 	calculate_inertia = true; | 
					
						
							|  |  |  | 	calculate_center_of_mass = true; | 
					
						
							|  |  |  | 	_mass_properties_changed(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-18 12:24:30 -07:00
										 |  |  | void GodotBody3D::set_active(bool p_active) { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (active == p_active) { | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	active = p_active; | 
					
						
							| 
									
										
										
										
											2021-04-19 18:38:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (active) { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		if (mode == PhysicsServer3D::BODY_MODE_STATIC) { | 
					
						
							| 
									
										
										
										
											2021-04-19 18:38:11 -07:00
										 |  |  | 			// Static bodies can't be active.
 | 
					
						
							|  |  |  | 			active = false; | 
					
						
							|  |  |  | 		} else if (get_space()) { | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 			get_space()->body_add_to_active_list(&active_list); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2021-04-19 18:38:11 -07:00
										 |  |  | 	} else if (get_space()) { | 
					
						
							|  |  |  | 		get_space()->body_remove_from_active_list(&active_list); | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-18 12:24:30 -07:00
										 |  |  | void GodotBody3D::set_param(PhysicsServer3D::BodyParameter p_param, const Variant &p_value) { | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 	switch (p_param) { | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 		case PhysicsServer3D::BODY_PARAM_BOUNCE: { | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 			bounce = p_value; | 
					
						
							|  |  |  | 		} break; | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 		case PhysicsServer3D::BODY_PARAM_FRICTION: { | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 			friction = p_value; | 
					
						
							|  |  |  | 		} break; | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 		case PhysicsServer3D::BODY_PARAM_MASS: { | 
					
						
							| 
									
										
										
										
											2021-06-10 17:37:19 -07:00
										 |  |  | 			real_t mass_value = p_value; | 
					
						
							|  |  |  | 			ERR_FAIL_COND(mass_value <= 0); | 
					
						
							|  |  |  | 			mass = mass_value; | 
					
						
							| 
									
										
										
										
											2022-08-25 19:35:52 +02:00
										 |  |  | 			if (mode >= PhysicsServer3D::BODY_MODE_RIGID) { | 
					
						
							| 
									
										
										
										
											2021-06-10 17:37:19 -07:00
										 |  |  | 				_mass_properties_changed(); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 		case PhysicsServer3D::BODY_PARAM_INERTIA: { | 
					
						
							|  |  |  | 			inertia = p_value; | 
					
						
							|  |  |  | 			if ((inertia.x <= 0.0) || (inertia.y <= 0.0) || (inertia.z <= 0.0)) { | 
					
						
							|  |  |  | 				calculate_inertia = true; | 
					
						
							| 
									
										
										
										
											2022-08-25 19:35:52 +02:00
										 |  |  | 				if (mode == PhysicsServer3D::BODY_MODE_RIGID) { | 
					
						
							| 
									
										
										
										
											2021-06-10 17:37:19 -07:00
										 |  |  | 					_mass_properties_changed(); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				calculate_inertia = false; | 
					
						
							| 
									
										
										
										
											2022-08-25 19:35:52 +02:00
										 |  |  | 				if (mode == PhysicsServer3D::BODY_MODE_RIGID) { | 
					
						
							| 
									
										
										
										
											2021-09-06 15:39:01 -05:00
										 |  |  | 					principal_inertia_axes_local = Basis(); | 
					
						
							| 
									
										
										
										
											2021-06-10 17:37:19 -07:00
										 |  |  | 					_inv_inertia = inertia.inverse(); | 
					
						
							| 
									
										
										
										
											2021-10-19 16:16:00 -07:00
										 |  |  | 					_update_transform_dependent(); | 
					
						
							| 
									
										
										
										
											2021-06-10 17:37:19 -07:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 		case PhysicsServer3D::BODY_PARAM_CENTER_OF_MASS: { | 
					
						
							|  |  |  | 			calculate_center_of_mass = false; | 
					
						
							|  |  |  | 			center_of_mass_local = p_value; | 
					
						
							| 
									
										
										
										
											2021-10-19 16:16:00 -07:00
										 |  |  | 			_update_transform_dependent(); | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 		} break; | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 		case PhysicsServer3D::BODY_PARAM_GRAVITY_SCALE: { | 
					
						
							| 
									
										
										
										
											2021-11-20 11:25:27 -05:00
										 |  |  | 			if (Math::is_zero_approx(gravity_scale)) { | 
					
						
							|  |  |  | 				wakeup(); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2015-08-30 18:57:17 -03:00
										 |  |  | 			gravity_scale = p_value; | 
					
						
							|  |  |  | 		} break; | 
					
						
							| 
									
										
										
										
											2020-04-14 19:59:53 +02:00
										 |  |  | 		case PhysicsServer3D::BODY_PARAM_LINEAR_DAMP_MODE: { | 
					
						
							|  |  |  | 			int mode_value = p_value; | 
					
						
							|  |  |  | 			linear_damp_mode = (PhysicsServer3D::BodyDampMode)mode_value; | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 		case PhysicsServer3D::BODY_PARAM_ANGULAR_DAMP_MODE: { | 
					
						
							|  |  |  | 			int mode_value = p_value; | 
					
						
							|  |  |  | 			angular_damp_mode = (PhysicsServer3D::BodyDampMode)mode_value; | 
					
						
							|  |  |  | 		} break; | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 		case PhysicsServer3D::BODY_PARAM_LINEAR_DAMP: { | 
					
						
							| 
									
										
										
										
											2015-08-30 18:57:17 -03:00
										 |  |  | 			linear_damp = p_value; | 
					
						
							|  |  |  | 		} break; | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 		case PhysicsServer3D::BODY_PARAM_ANGULAR_DAMP: { | 
					
						
							| 
									
										
										
										
											2015-08-30 18:57:17 -03:00
										 |  |  | 			angular_damp = p_value; | 
					
						
							|  |  |  | 		} break; | 
					
						
							| 
									
										
										
										
											2019-04-09 17:08:36 +02:00
										 |  |  | 		default: { | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-18 12:24:30 -07:00
										 |  |  | Variant GodotBody3D::get_param(PhysicsServer3D::BodyParameter p_param) const { | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 	switch (p_param) { | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 		case PhysicsServer3D::BODY_PARAM_BOUNCE: { | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 			return bounce; | 
					
						
							|  |  |  | 		} break; | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 		case PhysicsServer3D::BODY_PARAM_FRICTION: { | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 			return friction; | 
					
						
							|  |  |  | 		} break; | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 		case PhysicsServer3D::BODY_PARAM_MASS: { | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 			return mass; | 
					
						
							|  |  |  | 		} break; | 
					
						
							| 
									
										
										
										
											2021-06-10 17:37:19 -07:00
										 |  |  | 		case PhysicsServer3D::BODY_PARAM_INERTIA: { | 
					
						
							| 
									
										
										
										
											2022-08-25 19:35:52 +02:00
										 |  |  | 			if (mode == PhysicsServer3D::BODY_MODE_RIGID) { | 
					
						
							| 
									
										
										
										
											2021-06-10 17:37:19 -07:00
										 |  |  | 				return _inv_inertia.inverse(); | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				return Vector3(); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 		case PhysicsServer3D::BODY_PARAM_CENTER_OF_MASS: { | 
					
						
							| 
									
										
										
										
											2021-10-22 11:56:00 -07:00
										 |  |  | 			return center_of_mass_local; | 
					
						
							| 
									
										
										
										
											2021-06-10 17:37:19 -07:00
										 |  |  | 		} break; | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 		case PhysicsServer3D::BODY_PARAM_GRAVITY_SCALE: { | 
					
						
							| 
									
										
										
										
											2015-08-30 18:57:17 -03:00
										 |  |  | 			return gravity_scale; | 
					
						
							|  |  |  | 		} break; | 
					
						
							| 
									
										
										
										
											2020-04-14 19:59:53 +02:00
										 |  |  | 		case PhysicsServer3D::BODY_PARAM_LINEAR_DAMP_MODE: { | 
					
						
							|  |  |  | 			return linear_damp_mode; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		case PhysicsServer3D::BODY_PARAM_ANGULAR_DAMP_MODE: { | 
					
						
							|  |  |  | 			return angular_damp_mode; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 		case PhysicsServer3D::BODY_PARAM_LINEAR_DAMP: { | 
					
						
							| 
									
										
										
										
											2015-08-30 18:57:17 -03:00
										 |  |  | 			return linear_damp; | 
					
						
							|  |  |  | 		} break; | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 		case PhysicsServer3D::BODY_PARAM_ANGULAR_DAMP: { | 
					
						
							| 
									
										
										
										
											2015-08-30 18:57:17 -03:00
										 |  |  | 			return angular_damp; | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-09 17:08:36 +02:00
										 |  |  | 		default: { | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-18 12:24:30 -07:00
										 |  |  | void GodotBody3D::set_mode(PhysicsServer3D::BodyMode p_mode) { | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 	PhysicsServer3D::BodyMode prev = mode; | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 	mode = p_mode; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch (p_mode) { | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 		case PhysicsServer3D::BODY_MODE_STATIC: | 
					
						
							|  |  |  | 		case PhysicsServer3D::BODY_MODE_KINEMATIC: { | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 			_set_inv_transform(get_transform().affine_inverse()); | 
					
						
							|  |  |  | 			_inv_mass = 0; | 
					
						
							| 
									
										
										
										
											2021-06-10 17:37:19 -07:00
										 |  |  | 			_inv_inertia = Vector3(); | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 			_set_static(p_mode == PhysicsServer3D::BODY_MODE_STATIC); | 
					
						
							|  |  |  | 			set_active(p_mode == PhysicsServer3D::BODY_MODE_KINEMATIC && contacts.size()); | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 			linear_velocity = Vector3(); | 
					
						
							|  |  |  | 			angular_velocity = Vector3(); | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 			if (mode == PhysicsServer3D::BODY_MODE_KINEMATIC && prev != mode) { | 
					
						
							| 
									
										
										
										
											2014-10-14 01:01:25 -03:00
										 |  |  | 				first_time_kinematic = true; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2021-10-19 16:16:00 -07:00
										 |  |  | 			_update_transform_dependent(); | 
					
						
							| 
									
										
										
										
											2014-10-14 01:01:25 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 		} break; | 
					
						
							| 
									
										
										
										
											2022-08-25 19:35:52 +02:00
										 |  |  | 		case PhysicsServer3D::BODY_MODE_RIGID: { | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 			_inv_mass = mass > 0 ? (1.0 / mass) : 0; | 
					
						
							| 
									
										
										
										
											2021-06-10 17:37:19 -07:00
										 |  |  | 			if (!calculate_inertia) { | 
					
						
							| 
									
										
										
										
											2021-09-06 15:39:01 -05:00
										 |  |  | 				principal_inertia_axes_local = Basis(); | 
					
						
							| 
									
										
										
										
											2021-06-10 17:37:19 -07:00
										 |  |  | 				_inv_inertia = inertia.inverse(); | 
					
						
							| 
									
										
										
										
											2021-10-19 16:16:00 -07:00
										 |  |  | 				_update_transform_dependent(); | 
					
						
							| 
									
										
										
										
											2021-06-10 17:37:19 -07:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			_mass_properties_changed(); | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 			_set_static(false); | 
					
						
							| 
									
										
										
										
											2019-10-14 16:19:15 +02:00
										 |  |  | 			set_active(true); | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		} break; | 
					
						
							| 
									
										
										
										
											2022-08-25 19:35:52 +02:00
										 |  |  | 		case PhysicsServer3D::BODY_MODE_RIGID_LINEAR: { | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 			_inv_mass = mass > 0 ? (1.0 / mass) : 0; | 
					
						
							| 
									
										
										
										
											2021-06-10 17:37:19 -07:00
										 |  |  | 			_inv_inertia = Vector3(); | 
					
						
							|  |  |  | 			angular_velocity = Vector3(); | 
					
						
							| 
									
										
										
										
											2021-10-19 16:16:00 -07:00
										 |  |  | 			_update_transform_dependent(); | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 			_set_static(false); | 
					
						
							| 
									
										
										
										
											2019-10-14 16:19:15 +02:00
										 |  |  | 			set_active(true); | 
					
						
							| 
									
										
										
										
											2021-06-10 17:37:19 -07:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-05-14 14:29:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-18 12:24:30 -07:00
										 |  |  | PhysicsServer3D::BodyMode GodotBody3D::get_mode() const { | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 	return mode; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-18 12:24:30 -07:00
										 |  |  | void GodotBody3D::_shapes_changed() { | 
					
						
							| 
									
										
										
										
											2021-06-10 17:37:19 -07:00
										 |  |  | 	_mass_properties_changed(); | 
					
						
							| 
									
										
										
										
											2021-10-21 17:28:27 -07:00
										 |  |  | 	wakeup(); | 
					
						
							|  |  |  | 	wakeup_neighbours(); | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-18 12:24:30 -07:00
										 |  |  | void GodotBody3D::set_state(PhysicsServer3D::BodyState p_state, const Variant &p_variant) { | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 	switch (p_state) { | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 		case PhysicsServer3D::BODY_STATE_TRANSFORM: { | 
					
						
							|  |  |  | 			if (mode == PhysicsServer3D::BODY_MODE_KINEMATIC) { | 
					
						
							| 
									
										
										
										
											2014-09-02 23:13:40 -03:00
										 |  |  | 				new_transform = p_variant; | 
					
						
							|  |  |  | 				//wakeup_neighbours();
 | 
					
						
							|  |  |  | 				set_active(true); | 
					
						
							| 
									
										
										
										
											2014-10-14 01:01:25 -03:00
										 |  |  | 				if (first_time_kinematic) { | 
					
						
							|  |  |  | 					_set_transform(p_variant); | 
					
						
							|  |  |  | 					_set_inv_transform(get_transform().affine_inverse()); | 
					
						
							|  |  |  | 					first_time_kinematic = false; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2014-09-02 23:13:40 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 			} else if (mode == PhysicsServer3D::BODY_MODE_STATIC) { | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 				_set_transform(p_variant); | 
					
						
							|  |  |  | 				_set_inv_transform(get_transform().affine_inverse()); | 
					
						
							|  |  |  | 				wakeup_neighbours(); | 
					
						
							|  |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2020-10-17 01:08:21 -04:00
										 |  |  | 				Transform3D t = p_variant; | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 				t.orthonormalize(); | 
					
						
							| 
									
										
										
										
											2014-09-02 23:13:40 -03:00
										 |  |  | 				new_transform = get_transform(); //used as old to compute motion
 | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 				if (new_transform == t) { | 
					
						
							| 
									
										
										
										
											2015-05-16 17:54:36 -03:00
										 |  |  | 					break; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 				_set_transform(t); | 
					
						
							|  |  |  | 				_set_inv_transform(get_transform().inverse()); | 
					
						
							| 
									
										
										
										
											2021-10-19 16:16:00 -07:00
										 |  |  | 				_update_transform_dependent(); | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2015-04-26 16:20:00 -03:00
										 |  |  | 			wakeup(); | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		} break; | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 		case PhysicsServer3D::BODY_STATE_LINEAR_VELOCITY: { | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 			linear_velocity = p_variant; | 
					
						
							| 
									
										
										
										
											2021-08-30 11:48:43 -07:00
										 |  |  | 			constant_linear_velocity = linear_velocity; | 
					
						
							| 
									
										
										
										
											2015-04-26 16:20:00 -03:00
										 |  |  | 			wakeup(); | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 		} break; | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 		case PhysicsServer3D::BODY_STATE_ANGULAR_VELOCITY: { | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 			angular_velocity = p_variant; | 
					
						
							| 
									
										
										
										
											2021-08-30 11:48:43 -07:00
										 |  |  | 			constant_angular_velocity = angular_velocity; | 
					
						
							| 
									
										
										
										
											2015-04-26 16:20:00 -03:00
										 |  |  | 			wakeup(); | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		} break; | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 		case PhysicsServer3D::BODY_STATE_SLEEPING: { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			if (mode == PhysicsServer3D::BODY_MODE_STATIC || mode == PhysicsServer3D::BODY_MODE_KINEMATIC) { | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 				break; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 			bool do_sleep = p_variant; | 
					
						
							|  |  |  | 			if (do_sleep) { | 
					
						
							|  |  |  | 				linear_velocity = Vector3(); | 
					
						
							|  |  |  | 				//biased_linear_velocity=Vector3();
 | 
					
						
							|  |  |  | 				angular_velocity = Vector3(); | 
					
						
							|  |  |  | 				//biased_angular_velocity=Vector3();
 | 
					
						
							|  |  |  | 				set_active(false); | 
					
						
							|  |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2019-06-20 16:59:48 +02:00
										 |  |  | 				set_active(true); | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} break; | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 		case PhysicsServer3D::BODY_STATE_CAN_SLEEP: { | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 			can_sleep = p_variant; | 
					
						
							| 
									
										
										
										
											2022-08-25 19:35:52 +02:00
										 |  |  | 			if (mode >= PhysicsServer3D::BODY_MODE_RIGID && !active && !can_sleep) { | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 				set_active(true); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-05-14 14:29:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-18 12:24:30 -07:00
										 |  |  | Variant GodotBody3D::get_state(PhysicsServer3D::BodyState p_state) const { | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 	switch (p_state) { | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 		case PhysicsServer3D::BODY_STATE_TRANSFORM: { | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 			return get_transform(); | 
					
						
							|  |  |  | 		} break; | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 		case PhysicsServer3D::BODY_STATE_LINEAR_VELOCITY: { | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 			return linear_velocity; | 
					
						
							|  |  |  | 		} break; | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 		case PhysicsServer3D::BODY_STATE_ANGULAR_VELOCITY: { | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 			return angular_velocity; | 
					
						
							|  |  |  | 		} break; | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 		case PhysicsServer3D::BODY_STATE_SLEEPING: { | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 			return !is_active(); | 
					
						
							|  |  |  | 		} break; | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 		case PhysicsServer3D::BODY_STATE_CAN_SLEEP: { | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 			return can_sleep; | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return Variant(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-18 12:24:30 -07:00
										 |  |  | void GodotBody3D::set_space(GodotSpace3D *p_space) { | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 	if (get_space()) { | 
					
						
							| 
									
										
										
										
											2021-06-10 17:37:19 -07:00
										 |  |  | 		if (mass_properties_update_list.in_list()) { | 
					
						
							|  |  |  | 			get_space()->body_remove_from_mass_properties_update_list(&mass_properties_update_list); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		if (active_list.in_list()) { | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 			get_space()->body_remove_from_active_list(&active_list); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		if (direct_state_query_list.in_list()) { | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 			get_space()->body_remove_from_state_query_list(&direct_state_query_list); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	_set_space(p_space); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (get_space()) { | 
					
						
							| 
									
										
										
										
											2021-06-10 17:37:19 -07:00
										 |  |  | 		_mass_properties_changed(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		if (active) { | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 			get_space()->body_add_to_active_list(&active_list); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-18 12:24:30 -07:00
										 |  |  | void GodotBody3D::set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool lock) { | 
					
						
							| 
									
										
										
										
											2017-12-10 17:21:14 +01:00
										 |  |  | 	if (lock) { | 
					
						
							|  |  |  | 		locked_axis |= p_axis; | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		locked_axis &= ~p_axis; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-18 12:24:30 -07:00
										 |  |  | bool GodotBody3D::is_axis_locked(PhysicsServer3D::BodyAxis p_axis) const { | 
					
						
							| 
									
										
										
										
											2017-12-10 17:21:14 +01:00
										 |  |  | 	return locked_axis & p_axis; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-18 12:24:30 -07:00
										 |  |  | void GodotBody3D::integrate_forces(real_t p_step) { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (mode == PhysicsServer3D::BODY_MODE_STATIC) { | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-04 18:12:00 -07:00
										 |  |  | 	ERR_FAIL_COND(!get_space()); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 	int ac = areas.size(); | 
					
						
							| 
									
										
										
										
											2021-11-04 18:12:00 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	bool gravity_done = false; | 
					
						
							|  |  |  | 	bool linear_damp_done = false; | 
					
						
							|  |  |  | 	bool angular_damp_done = false; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-14 02:56:11 +01:00
										 |  |  | 	bool stopped = false; | 
					
						
							| 
									
										
										
										
											2021-11-04 18:12:00 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-08 18:44:29 +01:00
										 |  |  | 	gravity = Vector3(0, 0, 0); | 
					
						
							| 
									
										
										
										
											2020-04-14 19:59:53 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	total_linear_damp = 0.0; | 
					
						
							|  |  |  | 	total_angular_damp = 0.0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Combine gravity and damping from overlapping areas in priority order.
 | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 	if (ac) { | 
					
						
							| 
									
										
										
										
											2015-03-24 04:05:56 +00:00
										 |  |  | 		areas.sort(); | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 		const AreaCMP *aa = &areas[0]; | 
					
						
							| 
									
										
										
										
											2015-12-14 02:56:11 +01:00
										 |  |  | 		for (int i = ac - 1; i >= 0 && !stopped; i--) { | 
					
						
							| 
									
										
										
										
											2021-11-04 18:12:00 -07:00
										 |  |  | 			if (!gravity_done) { | 
					
						
							|  |  |  | 				PhysicsServer3D::AreaSpaceOverrideMode area_gravity_mode = (PhysicsServer3D::AreaSpaceOverrideMode)(int)aa[i].area->get_param(PhysicsServer3D::AREA_PARAM_GRAVITY_OVERRIDE_MODE); | 
					
						
							|  |  |  | 				if (area_gravity_mode != PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED) { | 
					
						
							|  |  |  | 					Vector3 area_gravity; | 
					
						
							|  |  |  | 					aa[i].area->compute_gravity(get_transform().get_origin(), area_gravity); | 
					
						
							|  |  |  | 					switch (area_gravity_mode) { | 
					
						
							|  |  |  | 						case PhysicsServer3D::AREA_SPACE_OVERRIDE_COMBINE: | 
					
						
							|  |  |  | 						case PhysicsServer3D::AREA_SPACE_OVERRIDE_COMBINE_REPLACE: { | 
					
						
							|  |  |  | 							gravity += area_gravity; | 
					
						
							|  |  |  | 							gravity_done = area_gravity_mode == PhysicsServer3D::AREA_SPACE_OVERRIDE_COMBINE_REPLACE; | 
					
						
							|  |  |  | 						} break; | 
					
						
							|  |  |  | 						case PhysicsServer3D::AREA_SPACE_OVERRIDE_REPLACE: | 
					
						
							|  |  |  | 						case PhysicsServer3D::AREA_SPACE_OVERRIDE_REPLACE_COMBINE: { | 
					
						
							|  |  |  | 							gravity = area_gravity; | 
					
						
							|  |  |  | 							gravity_done = area_gravity_mode == PhysicsServer3D::AREA_SPACE_OVERRIDE_REPLACE; | 
					
						
							|  |  |  | 						} break; | 
					
						
							|  |  |  | 						default: { | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if (!linear_damp_done) { | 
					
						
							|  |  |  | 				PhysicsServer3D::AreaSpaceOverrideMode area_linear_damp_mode = (PhysicsServer3D::AreaSpaceOverrideMode)(int)aa[i].area->get_param(PhysicsServer3D::AREA_PARAM_LINEAR_DAMP_OVERRIDE_MODE); | 
					
						
							|  |  |  | 				if (area_linear_damp_mode != PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED) { | 
					
						
							|  |  |  | 					real_t area_linear_damp = aa[i].area->get_linear_damp(); | 
					
						
							|  |  |  | 					switch (area_linear_damp_mode) { | 
					
						
							|  |  |  | 						case PhysicsServer3D::AREA_SPACE_OVERRIDE_COMBINE: | 
					
						
							|  |  |  | 						case PhysicsServer3D::AREA_SPACE_OVERRIDE_COMBINE_REPLACE: { | 
					
						
							|  |  |  | 							total_linear_damp += area_linear_damp; | 
					
						
							|  |  |  | 							linear_damp_done = area_linear_damp_mode == PhysicsServer3D::AREA_SPACE_OVERRIDE_COMBINE_REPLACE; | 
					
						
							|  |  |  | 						} break; | 
					
						
							|  |  |  | 						case PhysicsServer3D::AREA_SPACE_OVERRIDE_REPLACE: | 
					
						
							|  |  |  | 						case PhysicsServer3D::AREA_SPACE_OVERRIDE_REPLACE_COMBINE: { | 
					
						
							|  |  |  | 							total_linear_damp = area_linear_damp; | 
					
						
							|  |  |  | 							linear_damp_done = area_linear_damp_mode == PhysicsServer3D::AREA_SPACE_OVERRIDE_REPLACE; | 
					
						
							|  |  |  | 						} break; | 
					
						
							|  |  |  | 						default: { | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if (!angular_damp_done) { | 
					
						
							|  |  |  | 				PhysicsServer3D::AreaSpaceOverrideMode area_angular_damp_mode = (PhysicsServer3D::AreaSpaceOverrideMode)(int)aa[i].area->get_param(PhysicsServer3D::AREA_PARAM_ANGULAR_DAMP_OVERRIDE_MODE); | 
					
						
							|  |  |  | 				if (area_angular_damp_mode != PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED) { | 
					
						
							|  |  |  | 					real_t area_angular_damp = aa[i].area->get_angular_damp(); | 
					
						
							|  |  |  | 					switch (area_angular_damp_mode) { | 
					
						
							|  |  |  | 						case PhysicsServer3D::AREA_SPACE_OVERRIDE_COMBINE: | 
					
						
							|  |  |  | 						case PhysicsServer3D::AREA_SPACE_OVERRIDE_COMBINE_REPLACE: { | 
					
						
							|  |  |  | 							total_angular_damp += area_angular_damp; | 
					
						
							|  |  |  | 							angular_damp_done = area_angular_damp_mode == PhysicsServer3D::AREA_SPACE_OVERRIDE_COMBINE_REPLACE; | 
					
						
							|  |  |  | 						} break; | 
					
						
							|  |  |  | 						case PhysicsServer3D::AREA_SPACE_OVERRIDE_REPLACE: | 
					
						
							|  |  |  | 						case PhysicsServer3D::AREA_SPACE_OVERRIDE_REPLACE_COMBINE: { | 
					
						
							|  |  |  | 							total_angular_damp = area_angular_damp; | 
					
						
							|  |  |  | 							angular_damp_done = area_angular_damp_mode == PhysicsServer3D::AREA_SPACE_OVERRIDE_REPLACE; | 
					
						
							|  |  |  | 						} break; | 
					
						
							|  |  |  | 						default: { | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2019-04-09 17:08:36 +02:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2021-11-04 18:12:00 -07:00
										 |  |  | 			stopped = gravity_done && linear_damp_done && angular_damp_done; | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-03-20 03:38:12 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-08-30 18:57:17 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-14 19:59:53 +02:00
										 |  |  | 	// Add default gravity and damping from space area.
 | 
					
						
							| 
									
										
										
										
											2015-12-14 02:56:11 +01:00
										 |  |  | 	if (!stopped) { | 
					
						
							| 
									
										
										
										
											2021-11-04 18:12:00 -07:00
										 |  |  | 		GodotArea3D *default_area = get_space()->get_default_area(); | 
					
						
							|  |  |  | 		ERR_FAIL_COND(!default_area); | 
					
						
							| 
									
										
										
										
											2020-04-14 19:59:53 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-04 18:12:00 -07:00
										 |  |  | 		if (!gravity_done) { | 
					
						
							|  |  |  | 			Vector3 default_gravity; | 
					
						
							|  |  |  | 			default_area->compute_gravity(get_transform().get_origin(), default_gravity); | 
					
						
							|  |  |  | 			gravity += default_gravity; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (!linear_damp_done) { | 
					
						
							|  |  |  | 			total_linear_damp += default_area->get_linear_damp(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (!angular_damp_done) { | 
					
						
							|  |  |  | 			total_angular_damp += default_area->get_angular_damp(); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-14 19:59:53 +02:00
										 |  |  | 	// Override linear damping with body's value.
 | 
					
						
							|  |  |  | 	switch (linear_damp_mode) { | 
					
						
							|  |  |  | 		case PhysicsServer3D::BODY_DAMP_MODE_COMBINE: { | 
					
						
							|  |  |  | 			total_linear_damp += linear_damp; | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 		case PhysicsServer3D::BODY_DAMP_MODE_REPLACE: { | 
					
						
							|  |  |  | 			total_linear_damp = linear_damp; | 
					
						
							|  |  |  | 		} break; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-08-30 18:57:17 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-14 19:59:53 +02:00
										 |  |  | 	// Override angular damping with body's value.
 | 
					
						
							|  |  |  | 	switch (angular_damp_mode) { | 
					
						
							|  |  |  | 		case PhysicsServer3D::BODY_DAMP_MODE_COMBINE: { | 
					
						
							|  |  |  | 			total_angular_damp += angular_damp; | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 		case PhysicsServer3D::BODY_DAMP_MODE_REPLACE: { | 
					
						
							|  |  |  | 			total_angular_damp = angular_damp; | 
					
						
							|  |  |  | 		} break; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-04-14 19:59:53 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	gravity *= gravity_scale; | 
					
						
							| 
									
										
										
										
											2015-08-30 18:57:17 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-25 08:26:38 -07:00
										 |  |  | 	prev_linear_velocity = linear_velocity; | 
					
						
							|  |  |  | 	prev_angular_velocity = angular_velocity; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-02 23:13:40 -03:00
										 |  |  | 	Vector3 motion; | 
					
						
							|  |  |  | 	bool do_motion = false; | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 	if (mode == PhysicsServer3D::BODY_MODE_KINEMATIC) { | 
					
						
							| 
									
										
										
										
											2014-09-02 23:13:40 -03:00
										 |  |  | 		//compute motion, angular and etc. velocities from prev transform
 | 
					
						
							| 
									
										
										
										
											2021-03-18 23:14:19 +10:00
										 |  |  | 		motion = new_transform.origin - get_transform().origin; | 
					
						
							|  |  |  | 		do_motion = true; | 
					
						
							| 
									
										
										
										
											2021-08-30 11:48:43 -07:00
										 |  |  | 		linear_velocity = constant_linear_velocity + motion / p_step; | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-02 23:13:40 -03:00
										 |  |  | 		//compute a FAKE angular velocity, not so easy
 | 
					
						
							| 
									
										
										
										
											2021-03-18 23:14:19 +10:00
										 |  |  | 		Basis rot = new_transform.basis.orthonormalized() * get_transform().basis.orthonormalized().transposed(); | 
					
						
							| 
									
										
										
										
											2014-09-02 23:13:40 -03:00
										 |  |  | 		Vector3 axis; | 
					
						
							| 
									
										
										
										
											2017-02-13 17:25:05 -06:00
										 |  |  | 		real_t angle; | 
					
						
							| 
									
										
										
										
											2014-09-02 23:13:40 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-05 17:47:13 -05:00
										 |  |  | 		rot.get_axis_angle(axis, angle); | 
					
						
							| 
									
										
										
										
											2014-09-02 23:13:40 -03:00
										 |  |  | 		axis.normalize(); | 
					
						
							| 
									
										
										
										
											2021-08-30 11:48:43 -07:00
										 |  |  | 		angular_velocity = constant_angular_velocity + axis * (angle / p_step); | 
					
						
							| 
									
										
										
										
											2014-09-02 23:13:40 -03:00
										 |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2021-06-10 17:37:19 -07:00
										 |  |  | 		if (!omit_force_integration) { | 
					
						
							| 
									
										
										
										
											2017-03-24 21:45:31 +01:00
										 |  |  | 			//overridden by direct state query
 | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-07 18:09:54 -07:00
										 |  |  | 			Vector3 force = gravity * mass + applied_force + constant_force; | 
					
						
							|  |  |  | 			Vector3 torque = applied_torque + constant_torque; | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-14 19:59:53 +02:00
										 |  |  | 			real_t damp = 1.0 - p_step * total_linear_damp; | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			if (damp < 0) { // reached zero in the given time
 | 
					
						
							| 
									
										
										
										
											2014-09-02 23:13:40 -03:00
										 |  |  | 				damp = 0; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-09-02 23:13:40 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-29 12:53:28 +03:00
										 |  |  | 			real_t angular_damp_new = 1.0 - p_step * total_angular_damp; | 
					
						
							| 
									
										
										
										
											2014-09-02 23:13:40 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-29 12:53:28 +03:00
										 |  |  | 			if (angular_damp_new < 0) { // reached zero in the given time
 | 
					
						
							|  |  |  | 				angular_damp_new = 0; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-09-02 23:13:40 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			linear_velocity *= damp; | 
					
						
							| 
									
										
										
										
											2022-09-29 12:53:28 +03:00
										 |  |  | 			angular_velocity *= angular_damp_new; | 
					
						
							| 
									
										
										
										
											2014-09-02 23:13:40 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			linear_velocity += _inv_mass * force * p_step; | 
					
						
							|  |  |  | 			angular_velocity += _inv_inertia_tensor.xform(torque) * p_step; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (continuous_cd) { | 
					
						
							|  |  |  | 			motion = linear_velocity * p_step; | 
					
						
							|  |  |  | 			do_motion = true; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	applied_force = Vector3(); | 
					
						
							|  |  |  | 	applied_torque = Vector3(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	biased_angular_velocity = Vector3(); | 
					
						
							|  |  |  | 	biased_linear_velocity = Vector3(); | 
					
						
							| 
									
										
										
										
											2014-09-02 23:13:40 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (do_motion) { //shapes temporarily extend for raycast
 | 
					
						
							|  |  |  | 		_update_shapes_with_motion(motion); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 	contact_count = 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-18 12:24:30 -07:00
										 |  |  | void GodotBody3D::integrate_velocities(real_t p_step) { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (mode == PhysicsServer3D::BODY_MODE_STATIC) { | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-15 14:15:39 +02:00
										 |  |  | 	if (fi_callback_data || body_state_callback.get_object()) { | 
					
						
							| 
									
										
										
										
											2014-09-02 23:13:40 -03:00
										 |  |  | 		get_space()->body_add_to_state_query_list(&direct_state_query_list); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-09-02 23:13:40 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-10 17:21:14 +01:00
										 |  |  | 	//apply axis lock linear
 | 
					
						
							|  |  |  | 	for (int i = 0; i < 3; i++) { | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 		if (is_axis_locked((PhysicsServer3D::BodyAxis)(1 << i))) { | 
					
						
							| 
									
										
										
										
											2017-12-10 17:21:14 +01:00
										 |  |  | 			linear_velocity[i] = 0; | 
					
						
							|  |  |  | 			biased_linear_velocity[i] = 0; | 
					
						
							|  |  |  | 			new_transform.origin[i] = get_transform().origin[i]; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	//apply axis lock angular
 | 
					
						
							|  |  |  | 	for (int i = 0; i < 3; i++) { | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 		if (is_axis_locked((PhysicsServer3D::BodyAxis)(1 << (i + 3)))) { | 
					
						
							| 
									
										
										
										
											2017-12-10 17:21:14 +01:00
										 |  |  | 			angular_velocity[i] = 0; | 
					
						
							|  |  |  | 			biased_angular_velocity[i] = 0; | 
					
						
							| 
									
										
										
										
											2014-05-14 01:22:15 -03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 	if (mode == PhysicsServer3D::BODY_MODE_KINEMATIC) { | 
					
						
							| 
									
										
										
										
											2017-11-08 22:35:47 +01:00
										 |  |  | 		_set_transform(new_transform, false); | 
					
						
							|  |  |  | 		_set_inv_transform(new_transform.affine_inverse()); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		if (contacts.size() == 0 && linear_velocity == Vector3() && angular_velocity == Vector3()) { | 
					
						
							| 
									
										
										
										
											2017-11-08 22:35:47 +01:00
										 |  |  | 			set_active(false); //stopped moving, deactivate
 | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-11-08 22:35:47 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 	Vector3 total_angular_velocity = angular_velocity + biased_angular_velocity; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-13 17:25:05 -06:00
										 |  |  | 	real_t ang_vel = total_angular_velocity.length(); | 
					
						
							| 
									
										
										
										
											2022-09-29 12:53:28 +03:00
										 |  |  | 	Transform3D transform_new = get_transform(); | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-16 20:05:11 +02:00
										 |  |  | 	if (!Math::is_zero_approx(ang_vel)) { | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 		Vector3 ang_vel_axis = total_angular_velocity / ang_vel; | 
					
						
							| 
									
										
										
										
											2017-01-15 09:49:58 -03:00
										 |  |  | 		Basis rot(ang_vel_axis, ang_vel * p_step); | 
					
						
							| 
									
										
										
										
											2017-01-11 00:52:51 -03:00
										 |  |  | 		Basis identity3(1, 0, 0, 0, 1, 0, 0, 0, 1); | 
					
						
							| 
									
										
										
										
											2022-09-29 12:53:28 +03:00
										 |  |  | 		transform_new.origin += ((identity3 - rot) * transform_new.basis).xform(center_of_mass_local); | 
					
						
							|  |  |  | 		transform_new.basis = rot * transform_new.basis; | 
					
						
							|  |  |  | 		transform_new.orthonormalize(); | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Vector3 total_linear_velocity = linear_velocity + biased_linear_velocity; | 
					
						
							| 
									
										
										
										
											2014-05-14 01:22:15 -03:00
										 |  |  | 	/*for(int i=0;i<3;i++) {
 | 
					
						
							|  |  |  | 		if (axis_lock&(1<<i)) { | 
					
						
							| 
									
										
										
										
											2022-09-29 12:53:28 +03:00
										 |  |  | 			transform_new.origin[i]=0.0; | 
					
						
							| 
									
										
										
										
											2014-05-14 01:22:15 -03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	}*/ | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-29 12:53:28 +03:00
										 |  |  | 	transform_new.origin += total_linear_velocity * p_step; | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-29 12:53:28 +03:00
										 |  |  | 	_set_transform(transform_new); | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 	_set_inv_transform(get_transform().inverse()); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-19 16:16:00 -07:00
										 |  |  | 	_update_transform_dependent(); | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-18 12:24:30 -07:00
										 |  |  | void GodotBody3D::wakeup_neighbours() { | 
					
						
							|  |  |  | 	for (const KeyValue<GodotConstraint3D *, int> &E : constraint_map) { | 
					
						
							|  |  |  | 		const GodotConstraint3D *c = E.key; | 
					
						
							|  |  |  | 		GodotBody3D **n = c->get_body_ptr(); | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 		int bc = c->get_body_count(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for (int i = 0; i < bc; i++) { | 
					
						
							| 
									
										
										
										
											2021-08-09 14:13:42 -06:00
										 |  |  | 			if (i == E.value) { | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 				continue; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2021-10-18 12:24:30 -07:00
										 |  |  | 			GodotBody3D *b = n[i]; | 
					
						
							| 
									
										
										
										
											2022-08-25 19:35:52 +02:00
										 |  |  | 			if (b->mode < PhysicsServer3D::BODY_MODE_RIGID) { | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 				continue; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			if (!b->is_active()) { | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 				b->set_active(true); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-18 12:24:30 -07:00
										 |  |  | void GodotBody3D::call_queries() { | 
					
						
							| 
									
										
										
										
											2022-09-15 14:15:39 +02:00
										 |  |  | 	Variant direct_state_variant = get_direct_state(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-04 16:09:41 -07:00
										 |  |  | 	if (fi_callback_data) { | 
					
						
							|  |  |  | 		if (!fi_callback_data->callable.get_object()) { | 
					
						
							| 
									
										
										
										
											2021-03-30 00:22:23 -06:00
										 |  |  | 			set_force_integration_callback(Callable()); | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2021-06-04 16:09:41 -07:00
										 |  |  | 			const Variant *vp[2] = { &direct_state_variant, &fi_callback_data->udata }; | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-19 16:27:19 -03:00
										 |  |  | 			Callable::CallError ce; | 
					
						
							| 
									
										
										
										
											2021-06-04 16:09:41 -07:00
										 |  |  | 			int argc = (fi_callback_data->udata.get_type() == Variant::NIL) ? 1 : 2; | 
					
						
							| 
									
										
										
										
											2021-03-30 00:22:23 -06:00
										 |  |  | 			Variant rv; | 
					
						
							| 
									
										
										
										
											2022-07-28 22:56:41 +02:00
										 |  |  | 			fi_callback_data->callable.callp(vp, argc, rv, ce); | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-06-04 16:09:41 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-15 14:15:39 +02:00
										 |  |  | 	if (body_state_callback.get_object()) { | 
					
						
							|  |  |  | 		const Variant *vp[1] = { &direct_state_variant }; | 
					
						
							|  |  |  | 		Callable::CallError ce; | 
					
						
							|  |  |  | 		Variant rv; | 
					
						
							|  |  |  | 		body_state_callback.callp(vp, 1, rv, ce); | 
					
						
							| 
									
										
										
										
											2021-06-04 16:09:41 -07:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-18 12:24:30 -07:00
										 |  |  | bool GodotBody3D::sleep_test(real_t p_step) { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (mode == PhysicsServer3D::BODY_MODE_STATIC || mode == PhysicsServer3D::BODY_MODE_KINEMATIC) { | 
					
						
							| 
									
										
										
										
											2021-05-19 18:15:07 -07:00
										 |  |  | 		return true; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} else if (!can_sleep) { | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 		return false; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-08 22:12:18 +07:00
										 |  |  | 	if (Math::abs(angular_velocity.length()) < get_space()->get_body_angular_velocity_sleep_threshold() && Math::abs(linear_velocity.length_squared()) < get_space()->get_body_linear_velocity_sleep_threshold() * get_space()->get_body_linear_velocity_sleep_threshold()) { | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 		still_time += p_step; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return still_time > get_space()->get_body_time_to_sleep(); | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		still_time = 0; //maybe this should be set to 0 on set_active?
 | 
					
						
							|  |  |  | 		return false; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-15 14:15:39 +02:00
										 |  |  | void GodotBody3D::set_state_sync_callback(const Callable &p_callable) { | 
					
						
							|  |  |  | 	body_state_callback = p_callable; | 
					
						
							| 
									
										
										
										
											2021-06-04 16:09:41 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-18 12:24:30 -07:00
										 |  |  | void GodotBody3D::set_force_integration_callback(const Callable &p_callable, const Variant &p_udata) { | 
					
						
							| 
									
										
										
										
											2021-06-04 16:09:41 -07:00
										 |  |  | 	if (p_callable.get_object()) { | 
					
						
							|  |  |  | 		if (!fi_callback_data) { | 
					
						
							|  |  |  | 			fi_callback_data = memnew(ForceIntegrationCallbackData); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		fi_callback_data->callable = p_callable; | 
					
						
							|  |  |  | 		fi_callback_data->udata = p_udata; | 
					
						
							|  |  |  | 	} else if (fi_callback_data) { | 
					
						
							|  |  |  | 		memdelete(fi_callback_data); | 
					
						
							|  |  |  | 		fi_callback_data = nullptr; | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-06-04 16:09:41 -07:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-18 12:24:30 -07:00
										 |  |  | GodotPhysicsDirectBodyState3D *GodotBody3D::get_direct_state() { | 
					
						
							| 
									
										
										
										
											2021-06-04 16:09:41 -07:00
										 |  |  | 	if (!direct_state) { | 
					
						
							| 
									
										
										
										
											2021-10-18 12:24:30 -07:00
										 |  |  | 		direct_state = memnew(GodotPhysicsDirectBodyState3D); | 
					
						
							| 
									
										
										
										
											2021-06-04 16:09:41 -07:00
										 |  |  | 		direct_state->body = this; | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-06-04 16:09:41 -07:00
										 |  |  | 	return direct_state; | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-18 12:24:30 -07:00
										 |  |  | GodotBody3D::GodotBody3D() : | 
					
						
							|  |  |  | 		GodotCollisionObject3D(TYPE_BODY), | 
					
						
							| 
									
										
										
										
											2017-12-06 21:36:34 +01:00
										 |  |  | 		active_list(this), | 
					
						
							| 
									
										
										
										
											2021-06-10 17:37:19 -07:00
										 |  |  | 		mass_properties_update_list(this), | 
					
						
							| 
									
										
										
										
											2018-09-28 17:17:38 +02:00
										 |  |  | 		direct_state_query_list(this) { | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | 	_set_static(false); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-18 12:24:30 -07:00
										 |  |  | GodotBody3D::~GodotBody3D() { | 
					
						
							| 
									
										
										
										
											2021-06-04 16:09:41 -07:00
										 |  |  | 	if (fi_callback_data) { | 
					
						
							|  |  |  | 		memdelete(fi_callback_data); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (direct_state) { | 
					
						
							|  |  |  | 		memdelete(direct_state); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-19 11:57:14 -03:00
										 |  |  | } |