jolt_body_3d.cpp 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452
  1. /**************************************************************************/
  2. /* jolt_body_3d.cpp */
  3. /**************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* https://godotengine.org */
  7. /**************************************************************************/
  8. /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
  9. /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
  10. /* */
  11. /* Permission is hereby granted, free of charge, to any person obtaining */
  12. /* a copy of this software and associated documentation files (the */
  13. /* "Software"), to deal in the Software without restriction, including */
  14. /* without limitation the rights to use, copy, modify, merge, publish, */
  15. /* distribute, sublicense, and/or sell copies of the Software, and to */
  16. /* permit persons to whom the Software is furnished to do so, subject to */
  17. /* the following conditions: */
  18. /* */
  19. /* The above copyright notice and this permission notice shall be */
  20. /* included in all copies or substantial portions of the Software. */
  21. /* */
  22. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
  23. /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
  24. /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
  25. /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
  26. /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
  27. /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
  28. /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  29. /**************************************************************************/
  30. #include "jolt_body_3d.h"
  31. #include "../joints/jolt_joint_3d.h"
  32. #include "../jolt_project_settings.h"
  33. #include "../misc/jolt_type_conversions.h"
  34. #include "../shapes/jolt_shape_3d.h"
  35. #include "../spaces/jolt_broad_phase_layer.h"
  36. #include "../spaces/jolt_space_3d.h"
  37. #include "jolt_area_3d.h"
  38. #include "jolt_group_filter.h"
  39. #include "jolt_physics_direct_body_state_3d.h"
  40. #include "jolt_soft_body_3d.h"
  41. namespace {
  42. template <typename TValue, typename TGetter>
  43. bool integrate(TValue &p_value, PhysicsServer3D::AreaSpaceOverrideMode p_mode, TGetter &&p_getter) {
  44. switch (p_mode) {
  45. case PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED: {
  46. return false;
  47. }
  48. case PhysicsServer3D::AREA_SPACE_OVERRIDE_COMBINE: {
  49. p_value += p_getter();
  50. return false;
  51. }
  52. case PhysicsServer3D::AREA_SPACE_OVERRIDE_COMBINE_REPLACE: {
  53. p_value += p_getter();
  54. return true;
  55. }
  56. case PhysicsServer3D::AREA_SPACE_OVERRIDE_REPLACE: {
  57. p_value = p_getter();
  58. return true;
  59. }
  60. case PhysicsServer3D::AREA_SPACE_OVERRIDE_REPLACE_COMBINE: {
  61. p_value = p_getter();
  62. return false;
  63. }
  64. default: {
  65. ERR_FAIL_V_MSG(false, vformat("Unhandled override mode: '%d'. This should not happen. Please report this.", p_mode));
  66. }
  67. }
  68. }
  69. } // namespace
  70. JPH::BroadPhaseLayer JoltBody3D::_get_broad_phase_layer() const {
  71. switch (mode) {
  72. case PhysicsServer3D::BODY_MODE_STATIC: {
  73. return _is_big() ? JoltBroadPhaseLayer::BODY_STATIC_BIG : JoltBroadPhaseLayer::BODY_STATIC;
  74. }
  75. case PhysicsServer3D::BODY_MODE_KINEMATIC:
  76. case PhysicsServer3D::BODY_MODE_RIGID:
  77. case PhysicsServer3D::BODY_MODE_RIGID_LINEAR: {
  78. return JoltBroadPhaseLayer::BODY_DYNAMIC;
  79. }
  80. default: {
  81. ERR_FAIL_V_MSG(JoltBroadPhaseLayer::BODY_STATIC, vformat("Unhandled body mode: '%d'. This should not happen. Please report this.", mode));
  82. }
  83. }
  84. }
  85. JPH::ObjectLayer JoltBody3D::_get_object_layer() const {
  86. ERR_FAIL_NULL_V(space, 0);
  87. return space->map_to_object_layer(_get_broad_phase_layer(), collision_layer, collision_mask);
  88. }
  89. JPH::EMotionType JoltBody3D::_get_motion_type() const {
  90. switch (mode) {
  91. case PhysicsServer3D::BODY_MODE_STATIC: {
  92. return JPH::EMotionType::Static;
  93. }
  94. case PhysicsServer3D::BODY_MODE_KINEMATIC: {
  95. return JPH::EMotionType::Kinematic;
  96. }
  97. case PhysicsServer3D::BODY_MODE_RIGID:
  98. case PhysicsServer3D::BODY_MODE_RIGID_LINEAR: {
  99. return JPH::EMotionType::Dynamic;
  100. }
  101. default: {
  102. ERR_FAIL_V_MSG(JPH::EMotionType::Static, vformat("Unhandled body mode: '%d'. This should not happen. Please report this.", mode));
  103. }
  104. }
  105. }
  106. void JoltBody3D::_add_to_space() {
  107. jolt_shape = build_shapes(true);
  108. JPH::CollisionGroup::GroupID group_id = 0;
  109. JPH::CollisionGroup::SubGroupID sub_group_id = 0;
  110. JoltGroupFilter::encode_object(this, group_id, sub_group_id);
  111. jolt_settings->mUserData = reinterpret_cast<JPH::uint64>(this);
  112. jolt_settings->mObjectLayer = _get_object_layer();
  113. jolt_settings->mCollisionGroup = JPH::CollisionGroup(nullptr, group_id, sub_group_id);
  114. jolt_settings->mMotionType = _get_motion_type();
  115. jolt_settings->mAllowedDOFs = _calculate_allowed_dofs();
  116. jolt_settings->mAllowDynamicOrKinematic = true;
  117. jolt_settings->mCollideKinematicVsNonDynamic = reports_all_kinematic_contacts();
  118. jolt_settings->mUseManifoldReduction = !reports_contacts();
  119. jolt_settings->mAllowSleeping = is_sleep_actually_allowed();
  120. jolt_settings->mLinearDamping = 0.0f;
  121. jolt_settings->mAngularDamping = 0.0f;
  122. jolt_settings->mMaxLinearVelocity = JoltProjectSettings::get_max_linear_velocity();
  123. jolt_settings->mMaxAngularVelocity = JoltProjectSettings::get_max_angular_velocity();
  124. if (JoltProjectSettings::use_enhanced_internal_edge_removal_for_bodies()) {
  125. jolt_settings->mEnhancedInternalEdgeRemoval = true;
  126. }
  127. jolt_settings->mOverrideMassProperties = JPH::EOverrideMassProperties::MassAndInertiaProvided;
  128. jolt_settings->mMassPropertiesOverride = _calculate_mass_properties();
  129. jolt_settings->SetShape(jolt_shape);
  130. const JPH::BodyID new_jolt_id = space->add_rigid_body(*this, *jolt_settings, sleep_initially);
  131. if (new_jolt_id.IsInvalid()) {
  132. return;
  133. }
  134. jolt_id = new_jolt_id;
  135. delete jolt_settings;
  136. jolt_settings = nullptr;
  137. }
  138. void JoltBody3D::_enqueue_call_queries() {
  139. if (space != nullptr) {
  140. space->enqueue_call_queries(&call_queries_element);
  141. }
  142. }
  143. void JoltBody3D::_dequeue_call_queries() {
  144. if (space != nullptr) {
  145. space->dequeue_call_queries(&call_queries_element);
  146. }
  147. }
  148. void JoltBody3D::_integrate_forces(float p_step, JPH::Body &p_jolt_body) {
  149. _update_gravity(p_jolt_body);
  150. if (!custom_integrator) {
  151. JPH::MotionProperties &motion_properties = *p_jolt_body.GetMotionPropertiesUnchecked();
  152. JPH::Vec3 linear_velocity = motion_properties.GetLinearVelocity();
  153. JPH::Vec3 angular_velocity = motion_properties.GetAngularVelocity();
  154. // Jolt applies damping differently from Godot Physics, where Godot Physics applies damping before integrating
  155. // forces whereas Jolt does it after integrating forces. The way Godot Physics does it seems to yield more
  156. // consistent results across different update frequencies when using high (>1) damping values, so we apply the
  157. // damping ourselves instead, before any force integration happens.
  158. linear_velocity *= MAX(1.0f - total_linear_damp * p_step, 0.0f);
  159. angular_velocity *= MAX(1.0f - total_angular_damp * p_step, 0.0f);
  160. linear_velocity += to_jolt(gravity) * p_step;
  161. motion_properties.SetLinearVelocityClamped(linear_velocity);
  162. motion_properties.SetAngularVelocityClamped(angular_velocity);
  163. p_jolt_body.AddForce(to_jolt(constant_force));
  164. p_jolt_body.AddTorque(to_jolt(constant_torque));
  165. }
  166. }
  167. void JoltBody3D::_move_kinematic(float p_step, JPH::Body &p_jolt_body) {
  168. p_jolt_body.SetLinearVelocity(JPH::Vec3::sZero());
  169. p_jolt_body.SetAngularVelocity(JPH::Vec3::sZero());
  170. const JPH::RVec3 current_position = p_jolt_body.GetPosition();
  171. const JPH::Quat current_rotation = p_jolt_body.GetRotation();
  172. const JPH::RVec3 new_position = to_jolt_r(kinematic_transform.origin);
  173. const JPH::Quat new_rotation = to_jolt(kinematic_transform.basis);
  174. if (new_position == current_position && new_rotation == current_rotation) {
  175. return;
  176. }
  177. p_jolt_body.MoveKinematic(new_position, new_rotation, p_step);
  178. }
  179. JPH::EAllowedDOFs JoltBody3D::_calculate_allowed_dofs() const {
  180. if (is_static()) {
  181. return JPH::EAllowedDOFs::All;
  182. }
  183. JPH::EAllowedDOFs allowed_dofs = JPH::EAllowedDOFs::All;
  184. if (is_axis_locked(PhysicsServer3D::BODY_AXIS_LINEAR_X)) {
  185. allowed_dofs &= ~JPH::EAllowedDOFs::TranslationX;
  186. }
  187. if (is_axis_locked(PhysicsServer3D::BODY_AXIS_LINEAR_Y)) {
  188. allowed_dofs &= ~JPH::EAllowedDOFs::TranslationY;
  189. }
  190. if (is_axis_locked(PhysicsServer3D::BODY_AXIS_LINEAR_Z)) {
  191. allowed_dofs &= ~JPH::EAllowedDOFs::TranslationZ;
  192. }
  193. if (is_axis_locked(PhysicsServer3D::BODY_AXIS_ANGULAR_X) || is_rigid_linear()) {
  194. allowed_dofs &= ~JPH::EAllowedDOFs::RotationX;
  195. }
  196. if (is_axis_locked(PhysicsServer3D::BODY_AXIS_ANGULAR_Y) || is_rigid_linear()) {
  197. allowed_dofs &= ~JPH::EAllowedDOFs::RotationY;
  198. }
  199. if (is_axis_locked(PhysicsServer3D::BODY_AXIS_ANGULAR_Z) || is_rigid_linear()) {
  200. allowed_dofs &= ~JPH::EAllowedDOFs::RotationZ;
  201. }
  202. ERR_FAIL_COND_V_MSG(allowed_dofs == JPH::EAllowedDOFs::None, JPH::EAllowedDOFs::All, vformat("Invalid axis locks for '%s'. Locking all axes is not supported when using Jolt Physics. All axes will be unlocked. Considering freezing the body instead.", to_string()));
  203. return allowed_dofs;
  204. }
  205. JPH::MassProperties JoltBody3D::_calculate_mass_properties(const JPH::Shape &p_shape) const {
  206. const bool calculate_mass = mass <= 0;
  207. const bool calculate_inertia = inertia.x <= 0 || inertia.y <= 0 || inertia.z <= 0;
  208. JPH::MassProperties mass_properties = p_shape.GetMassProperties();
  209. if (calculate_mass && calculate_inertia) {
  210. // Use the mass properties calculated by the shape
  211. } else if (calculate_inertia) {
  212. mass_properties.ScaleToMass(mass);
  213. } else {
  214. mass_properties.mMass = mass;
  215. }
  216. if (inertia.x > 0) {
  217. mass_properties.mInertia(0, 0) = (float)inertia.x;
  218. mass_properties.mInertia(0, 1) = 0;
  219. mass_properties.mInertia(0, 2) = 0;
  220. mass_properties.mInertia(1, 0) = 0;
  221. mass_properties.mInertia(2, 0) = 0;
  222. }
  223. if (inertia.y > 0) {
  224. mass_properties.mInertia(1, 1) = (float)inertia.y;
  225. mass_properties.mInertia(1, 0) = 0;
  226. mass_properties.mInertia(1, 2) = 0;
  227. mass_properties.mInertia(0, 1) = 0;
  228. mass_properties.mInertia(2, 1) = 0;
  229. }
  230. if (inertia.z > 0) {
  231. mass_properties.mInertia(2, 2) = (float)inertia.z;
  232. mass_properties.mInertia(2, 0) = 0;
  233. mass_properties.mInertia(2, 1) = 0;
  234. mass_properties.mInertia(0, 2) = 0;
  235. mass_properties.mInertia(1, 2) = 0;
  236. }
  237. mass_properties.mInertia(3, 3) = 1.0f;
  238. return mass_properties;
  239. }
  240. JPH::MassProperties JoltBody3D::_calculate_mass_properties() const {
  241. return _calculate_mass_properties(*jolt_shape);
  242. }
  243. void JoltBody3D::_update_mass_properties() {
  244. if (!in_space()) {
  245. return;
  246. }
  247. const JoltWritableBody3D body = space->write_body(jolt_id);
  248. ERR_FAIL_COND(body.is_invalid());
  249. body->GetMotionPropertiesUnchecked()->SetMassProperties(_calculate_allowed_dofs(), _calculate_mass_properties());
  250. }
  251. void JoltBody3D::_update_gravity(JPH::Body &p_jolt_body) {
  252. gravity = Vector3();
  253. const Vector3 position = to_godot(p_jolt_body.GetPosition());
  254. bool gravity_done = false;
  255. for (const JoltArea3D *area : areas) {
  256. gravity_done = integrate(gravity, area->get_gravity_mode(), [&]() {
  257. return area->compute_gravity(position);
  258. });
  259. if (gravity_done) {
  260. break;
  261. }
  262. }
  263. if (!gravity_done) {
  264. gravity += space->get_default_area()->compute_gravity(position);
  265. }
  266. gravity *= gravity_scale;
  267. }
  268. void JoltBody3D::_update_damp() {
  269. if (!in_space()) {
  270. return;
  271. }
  272. total_linear_damp = 0.0;
  273. total_angular_damp = 0.0;
  274. bool linear_damp_done = linear_damp_mode == PhysicsServer3D::BODY_DAMP_MODE_REPLACE;
  275. bool angular_damp_done = angular_damp_mode == PhysicsServer3D::BODY_DAMP_MODE_REPLACE;
  276. for (const JoltArea3D *area : areas) {
  277. if (!linear_damp_done) {
  278. linear_damp_done = integrate(total_linear_damp, area->get_linear_damp_mode(), [&]() {
  279. return area->get_linear_damp();
  280. });
  281. }
  282. if (!angular_damp_done) {
  283. angular_damp_done = integrate(total_angular_damp, area->get_angular_damp_mode(), [&]() {
  284. return area->get_angular_damp();
  285. });
  286. }
  287. if (linear_damp_done && angular_damp_done) {
  288. break;
  289. }
  290. }
  291. const JoltArea3D *default_area = space->get_default_area();
  292. if (!linear_damp_done) {
  293. total_linear_damp += default_area->get_linear_damp();
  294. }
  295. if (!angular_damp_done) {
  296. total_angular_damp += default_area->get_angular_damp();
  297. }
  298. switch (linear_damp_mode) {
  299. case PhysicsServer3D::BODY_DAMP_MODE_COMBINE: {
  300. total_linear_damp += linear_damp;
  301. } break;
  302. case PhysicsServer3D::BODY_DAMP_MODE_REPLACE: {
  303. total_linear_damp = linear_damp;
  304. } break;
  305. }
  306. switch (angular_damp_mode) {
  307. case PhysicsServer3D::BODY_DAMP_MODE_COMBINE: {
  308. total_angular_damp += angular_damp;
  309. } break;
  310. case PhysicsServer3D::BODY_DAMP_MODE_REPLACE: {
  311. total_angular_damp = angular_damp;
  312. } break;
  313. }
  314. _motion_changed();
  315. }
  316. void JoltBody3D::_update_kinematic_transform() {
  317. if (is_kinematic()) {
  318. kinematic_transform = get_transform_unscaled();
  319. }
  320. }
  321. void JoltBody3D::_update_joint_constraints() {
  322. for (JoltJoint3D *joint : joints) {
  323. joint->rebuild();
  324. }
  325. }
  326. void JoltBody3D::_update_possible_kinematic_contacts() {
  327. const bool value = reports_all_kinematic_contacts();
  328. if (!in_space()) {
  329. jolt_settings->mCollideKinematicVsNonDynamic = value;
  330. } else {
  331. const JoltWritableBody3D body = space->write_body(jolt_id);
  332. ERR_FAIL_COND(body.is_invalid());
  333. body->SetCollideKinematicVsNonDynamic(value);
  334. }
  335. }
  336. void JoltBody3D::_update_sleep_allowed() {
  337. const bool value = is_sleep_actually_allowed();
  338. if (!in_space()) {
  339. jolt_settings->mAllowSleeping = value;
  340. return;
  341. }
  342. const JoltWritableBody3D body = space->write_body(jolt_id);
  343. ERR_FAIL_COND(body.is_invalid());
  344. body->SetAllowSleeping(value);
  345. }
  346. void JoltBody3D::_destroy_joint_constraints() {
  347. for (JoltJoint3D *joint : joints) {
  348. joint->destroy();
  349. }
  350. }
  351. void JoltBody3D::_exit_all_areas() {
  352. for (JoltArea3D *area : areas) {
  353. area->body_exited(jolt_id, false);
  354. }
  355. areas.clear();
  356. }
  357. void JoltBody3D::_update_group_filter() {
  358. JPH::GroupFilter *group_filter = !exceptions.is_empty() ? JoltGroupFilter::instance : nullptr;
  359. if (!in_space()) {
  360. jolt_settings->mCollisionGroup.SetGroupFilter(group_filter);
  361. return;
  362. }
  363. const JoltWritableBody3D body = space->write_body(jolt_id);
  364. ERR_FAIL_COND(body.is_invalid());
  365. body->GetCollisionGroup().SetGroupFilter(group_filter);
  366. }
  367. void JoltBody3D::_mode_changed() {
  368. _update_object_layer();
  369. _update_kinematic_transform();
  370. _update_mass_properties();
  371. _update_sleep_allowed();
  372. wake_up();
  373. }
  374. void JoltBody3D::_shapes_committed() {
  375. JoltShapedObject3D::_shapes_committed();
  376. _update_mass_properties();
  377. _update_joint_constraints();
  378. wake_up();
  379. }
  380. void JoltBody3D::_space_changing() {
  381. JoltShapedObject3D::_space_changing();
  382. sleep_initially = is_sleeping();
  383. _destroy_joint_constraints();
  384. _exit_all_areas();
  385. _dequeue_call_queries();
  386. }
  387. void JoltBody3D::_space_changed() {
  388. JoltShapedObject3D::_space_changed();
  389. _update_kinematic_transform();
  390. _update_group_filter();
  391. _update_joint_constraints();
  392. _update_sleep_allowed();
  393. _areas_changed();
  394. }
  395. void JoltBody3D::_areas_changed() {
  396. _update_damp();
  397. wake_up();
  398. }
  399. void JoltBody3D::_joints_changed() {
  400. wake_up();
  401. }
  402. void JoltBody3D::_transform_changed() {
  403. wake_up();
  404. }
  405. void JoltBody3D::_motion_changed() {
  406. wake_up();
  407. }
  408. void JoltBody3D::_exceptions_changed() {
  409. _update_group_filter();
  410. }
  411. void JoltBody3D::_axis_lock_changed() {
  412. _update_mass_properties();
  413. wake_up();
  414. }
  415. void JoltBody3D::_contact_reporting_changed() {
  416. _update_possible_kinematic_contacts();
  417. _update_sleep_allowed();
  418. wake_up();
  419. }
  420. void JoltBody3D::_sleep_allowed_changed() {
  421. _update_sleep_allowed();
  422. wake_up();
  423. }
  424. JoltBody3D::JoltBody3D() :
  425. JoltShapedObject3D(OBJECT_TYPE_BODY),
  426. call_queries_element(this) {
  427. }
  428. JoltBody3D::~JoltBody3D() {
  429. if (direct_state != nullptr) {
  430. memdelete(direct_state);
  431. direct_state = nullptr;
  432. }
  433. }
  434. void JoltBody3D::set_transform(Transform3D p_transform) {
  435. JOLT_ENSURE_SCALE_NOT_ZERO(p_transform, vformat("An invalid transform was passed to physics body '%s'.", to_string()));
  436. const Vector3 new_scale = p_transform.basis.get_scale();
  437. // Ideally we would do an exact comparison here, but due to floating-point precision this would be invalidated very often.
  438. if (!scale.is_equal_approx(new_scale)) {
  439. scale = new_scale;
  440. _shapes_changed();
  441. }
  442. p_transform.basis.orthonormalize();
  443. if (!in_space()) {
  444. jolt_settings->mPosition = to_jolt_r(p_transform.origin);
  445. jolt_settings->mRotation = to_jolt(p_transform.basis);
  446. } else if (is_kinematic()) {
  447. kinematic_transform = p_transform;
  448. } else {
  449. space->get_body_iface().SetPositionAndRotation(jolt_id, to_jolt_r(p_transform.origin), to_jolt(p_transform.basis), JPH::EActivation::DontActivate);
  450. }
  451. _transform_changed();
  452. }
  453. Variant JoltBody3D::get_state(PhysicsServer3D::BodyState p_state) const {
  454. switch (p_state) {
  455. case PhysicsServer3D::BODY_STATE_TRANSFORM: {
  456. return get_transform_scaled();
  457. }
  458. case PhysicsServer3D::BODY_STATE_LINEAR_VELOCITY: {
  459. return get_linear_velocity();
  460. }
  461. case PhysicsServer3D::BODY_STATE_ANGULAR_VELOCITY: {
  462. return get_angular_velocity();
  463. }
  464. case PhysicsServer3D::BODY_STATE_SLEEPING: {
  465. return is_sleeping();
  466. }
  467. case PhysicsServer3D::BODY_STATE_CAN_SLEEP: {
  468. return is_sleep_allowed();
  469. }
  470. default: {
  471. ERR_FAIL_V_MSG(Variant(), vformat("Unhandled body state: '%d'. This should not happen. Please report this.", p_state));
  472. }
  473. }
  474. }
  475. void JoltBody3D::set_state(PhysicsServer3D::BodyState p_state, const Variant &p_value) {
  476. switch (p_state) {
  477. case PhysicsServer3D::BODY_STATE_TRANSFORM: {
  478. set_transform(p_value);
  479. } break;
  480. case PhysicsServer3D::BODY_STATE_LINEAR_VELOCITY: {
  481. set_linear_velocity(p_value);
  482. } break;
  483. case PhysicsServer3D::BODY_STATE_ANGULAR_VELOCITY: {
  484. set_angular_velocity(p_value);
  485. } break;
  486. case PhysicsServer3D::BODY_STATE_SLEEPING: {
  487. set_is_sleeping(p_value);
  488. } break;
  489. case PhysicsServer3D::BODY_STATE_CAN_SLEEP: {
  490. set_is_sleep_allowed(p_value);
  491. } break;
  492. default: {
  493. ERR_FAIL_MSG(vformat("Unhandled body state: '%d'. This should not happen. Please report this.", p_state));
  494. } break;
  495. }
  496. }
  497. Variant JoltBody3D::get_param(PhysicsServer3D::BodyParameter p_param) const {
  498. switch (p_param) {
  499. case PhysicsServer3D::BODY_PARAM_BOUNCE: {
  500. return get_bounce();
  501. }
  502. case PhysicsServer3D::BODY_PARAM_FRICTION: {
  503. return get_friction();
  504. }
  505. case PhysicsServer3D::BODY_PARAM_MASS: {
  506. return get_mass();
  507. }
  508. case PhysicsServer3D::BODY_PARAM_INERTIA: {
  509. return get_inertia();
  510. }
  511. case PhysicsServer3D::BODY_PARAM_CENTER_OF_MASS: {
  512. return get_center_of_mass_custom();
  513. }
  514. case PhysicsServer3D::BODY_PARAM_GRAVITY_SCALE: {
  515. return get_gravity_scale();
  516. }
  517. case PhysicsServer3D::BODY_PARAM_LINEAR_DAMP_MODE: {
  518. return get_linear_damp_mode();
  519. }
  520. case PhysicsServer3D::BODY_PARAM_ANGULAR_DAMP_MODE: {
  521. return get_angular_damp_mode();
  522. }
  523. case PhysicsServer3D::BODY_PARAM_LINEAR_DAMP: {
  524. return get_linear_damp();
  525. }
  526. case PhysicsServer3D::BODY_PARAM_ANGULAR_DAMP: {
  527. return get_angular_damp();
  528. }
  529. default: {
  530. ERR_FAIL_V_MSG(Variant(), vformat("Unhandled body parameter: '%d'. This should not happen. Please report this.", p_param));
  531. }
  532. }
  533. }
  534. void JoltBody3D::set_param(PhysicsServer3D::BodyParameter p_param, const Variant &p_value) {
  535. switch (p_param) {
  536. case PhysicsServer3D::BODY_PARAM_BOUNCE: {
  537. set_bounce(p_value);
  538. } break;
  539. case PhysicsServer3D::BODY_PARAM_FRICTION: {
  540. set_friction(p_value);
  541. } break;
  542. case PhysicsServer3D::BODY_PARAM_MASS: {
  543. set_mass(p_value);
  544. } break;
  545. case PhysicsServer3D::BODY_PARAM_INERTIA: {
  546. set_inertia(p_value);
  547. } break;
  548. case PhysicsServer3D::BODY_PARAM_CENTER_OF_MASS: {
  549. set_center_of_mass_custom(p_value);
  550. } break;
  551. case PhysicsServer3D::BODY_PARAM_GRAVITY_SCALE: {
  552. set_gravity_scale(p_value);
  553. } break;
  554. case PhysicsServer3D::BODY_PARAM_LINEAR_DAMP_MODE: {
  555. set_linear_damp_mode((DampMode)(int)p_value);
  556. } break;
  557. case PhysicsServer3D::BODY_PARAM_ANGULAR_DAMP_MODE: {
  558. set_angular_damp_mode((DampMode)(int)p_value);
  559. } break;
  560. case PhysicsServer3D::BODY_PARAM_LINEAR_DAMP: {
  561. set_linear_damp(p_value);
  562. } break;
  563. case PhysicsServer3D::BODY_PARAM_ANGULAR_DAMP: {
  564. set_angular_damp(p_value);
  565. } break;
  566. default: {
  567. ERR_FAIL_MSG(vformat("Unhandled body parameter: '%d'. This should not happen. Please report this.", p_param));
  568. } break;
  569. }
  570. }
  571. void JoltBody3D::set_custom_integrator(bool p_enabled) {
  572. if (custom_integrator == p_enabled) {
  573. return;
  574. }
  575. custom_integrator = p_enabled;
  576. if (!in_space()) {
  577. _motion_changed();
  578. return;
  579. }
  580. const JoltWritableBody3D body = space->write_body(jolt_id);
  581. ERR_FAIL_COND(body.is_invalid());
  582. body->ResetForce();
  583. body->ResetTorque();
  584. _motion_changed();
  585. }
  586. bool JoltBody3D::is_sleeping() const {
  587. if (!in_space()) {
  588. return sleep_initially;
  589. }
  590. const JoltReadableBody3D body = space->read_body(jolt_id);
  591. ERR_FAIL_COND_V(body.is_invalid(), false);
  592. return !body->IsActive();
  593. }
  594. bool JoltBody3D::is_sleep_actually_allowed() const {
  595. return sleep_allowed && !(is_kinematic() && reports_contacts());
  596. }
  597. void JoltBody3D::set_is_sleeping(bool p_enabled) {
  598. if (!in_space()) {
  599. sleep_initially = p_enabled;
  600. return;
  601. }
  602. JPH::BodyInterface &body_iface = space->get_body_iface();
  603. if (p_enabled) {
  604. body_iface.DeactivateBody(jolt_id);
  605. } else {
  606. body_iface.ActivateBody(jolt_id);
  607. }
  608. }
  609. void JoltBody3D::set_is_sleep_allowed(bool p_enabled) {
  610. if (sleep_allowed == p_enabled) {
  611. return;
  612. }
  613. sleep_allowed = p_enabled;
  614. _sleep_allowed_changed();
  615. }
  616. Basis JoltBody3D::get_principal_inertia_axes() const {
  617. ERR_FAIL_NULL_V_MSG(space, Basis(), vformat("Failed to retrieve principal inertia axes of '%s'. Doing so without a physics space is not supported when using Jolt Physics. If this relates to a node, try adding the node to a scene tree first.", to_string()));
  618. if (unlikely(is_static() || is_kinematic())) {
  619. return Basis();
  620. }
  621. const JoltReadableBody3D body = space->read_body(jolt_id);
  622. ERR_FAIL_COND_V(body.is_invalid(), Basis());
  623. return to_godot(body->GetRotation() * body->GetMotionProperties()->GetInertiaRotation());
  624. }
  625. Vector3 JoltBody3D::get_inverse_inertia() const {
  626. ERR_FAIL_NULL_V_MSG(space, Vector3(), vformat("Failed to retrieve inverse inertia of '%s'. Doing so without a physics space is not supported when using Jolt Physics. If this relates to a node, try adding the node to a scene tree first.", to_string()));
  627. if (unlikely(is_static() || is_kinematic())) {
  628. return Vector3();
  629. }
  630. const JoltReadableBody3D body = space->read_body(jolt_id);
  631. ERR_FAIL_COND_V(body.is_invalid(), Vector3());
  632. const JPH::MotionProperties &motion_properties = *body->GetMotionPropertiesUnchecked();
  633. return to_godot(motion_properties.GetLocalSpaceInverseInertia().GetDiagonal3());
  634. }
  635. Basis JoltBody3D::get_inverse_inertia_tensor() const {
  636. ERR_FAIL_NULL_V_MSG(space, Basis(), vformat("Failed to retrieve inverse inertia tensor of '%s'. Doing so without a physics space is not supported when using Jolt Physics. If this relates to a node, try adding the node to a scene tree first.", to_string()));
  637. if (unlikely(is_static() || is_kinematic())) {
  638. return Basis();
  639. }
  640. const JoltReadableBody3D body = space->read_body(jolt_id);
  641. ERR_FAIL_COND_V(body.is_invalid(), Basis());
  642. return to_godot(body->GetInverseInertia()).basis;
  643. }
  644. void JoltBody3D::set_linear_velocity(const Vector3 &p_velocity) {
  645. if (is_static() || is_kinematic()) {
  646. linear_surface_velocity = p_velocity;
  647. _motion_changed();
  648. return;
  649. }
  650. if (!in_space()) {
  651. jolt_settings->mLinearVelocity = to_jolt(p_velocity);
  652. _motion_changed();
  653. return;
  654. }
  655. const JoltWritableBody3D body = space->write_body(jolt_id);
  656. ERR_FAIL_COND(body.is_invalid());
  657. body->GetMotionPropertiesUnchecked()->SetLinearVelocityClamped(to_jolt(p_velocity));
  658. _motion_changed();
  659. }
  660. void JoltBody3D::set_angular_velocity(const Vector3 &p_velocity) {
  661. if (is_static() || is_kinematic()) {
  662. angular_surface_velocity = p_velocity;
  663. _motion_changed();
  664. return;
  665. }
  666. if (!in_space()) {
  667. jolt_settings->mAngularVelocity = to_jolt(p_velocity);
  668. _motion_changed();
  669. return;
  670. }
  671. const JoltWritableBody3D body = space->write_body(jolt_id);
  672. ERR_FAIL_COND(body.is_invalid());
  673. body->GetMotionPropertiesUnchecked()->SetAngularVelocityClamped(to_jolt(p_velocity));
  674. _motion_changed();
  675. }
  676. void JoltBody3D::set_axis_velocity(const Vector3 &p_axis_velocity) {
  677. const Vector3 axis = p_axis_velocity.normalized();
  678. if (!in_space()) {
  679. Vector3 linear_velocity = to_godot(jolt_settings->mLinearVelocity);
  680. linear_velocity -= axis * axis.dot(linear_velocity);
  681. linear_velocity += p_axis_velocity;
  682. jolt_settings->mLinearVelocity = to_jolt(linear_velocity);
  683. } else {
  684. const JoltWritableBody3D body = space->write_body(jolt_id);
  685. ERR_FAIL_COND(body.is_invalid());
  686. Vector3 linear_velocity = get_linear_velocity();
  687. linear_velocity -= axis * axis.dot(linear_velocity);
  688. linear_velocity += p_axis_velocity;
  689. set_linear_velocity(linear_velocity);
  690. }
  691. _motion_changed();
  692. }
  693. Vector3 JoltBody3D::get_velocity_at_position(const Vector3 &p_position) const {
  694. if (unlikely(!in_space())) {
  695. return Vector3();
  696. }
  697. const JoltReadableBody3D body = space->read_body(jolt_id);
  698. ERR_FAIL_COND_V(body.is_invalid(), Vector3());
  699. const JPH::MotionProperties &motion_properties = *body->GetMotionPropertiesUnchecked();
  700. const Vector3 total_linear_velocity = to_godot(motion_properties.GetLinearVelocity()) + linear_surface_velocity;
  701. const Vector3 total_angular_velocity = to_godot(motion_properties.GetAngularVelocity()) + angular_surface_velocity;
  702. const Vector3 com_to_pos = p_position - to_godot(body->GetCenterOfMassPosition());
  703. return total_linear_velocity + total_angular_velocity.cross(com_to_pos);
  704. }
  705. void JoltBody3D::set_center_of_mass_custom(const Vector3 &p_center_of_mass) {
  706. if (custom_center_of_mass && p_center_of_mass == center_of_mass_custom) {
  707. return;
  708. }
  709. custom_center_of_mass = true;
  710. center_of_mass_custom = p_center_of_mass;
  711. _shapes_changed();
  712. }
  713. void JoltBody3D::set_max_contacts_reported(int p_count) {
  714. ERR_FAIL_COND(p_count < 0);
  715. if (unlikely((int)contacts.size() == p_count)) {
  716. return;
  717. }
  718. contacts.resize(p_count);
  719. contact_count = MIN(contact_count, p_count);
  720. const bool use_manifold_reduction = !reports_contacts();
  721. if (!in_space()) {
  722. jolt_settings->mUseManifoldReduction = use_manifold_reduction;
  723. _contact_reporting_changed();
  724. return;
  725. }
  726. JPH::BodyInterface &body_iface = space->get_body_iface();
  727. body_iface.SetUseManifoldReduction(jolt_id, use_manifold_reduction);
  728. _contact_reporting_changed();
  729. }
  730. bool JoltBody3D::reports_all_kinematic_contacts() const {
  731. return reports_contacts() && JoltProjectSettings::should_generate_all_kinematic_contacts();
  732. }
  733. void JoltBody3D::add_contact(const JoltBody3D *p_collider, float p_depth, int p_shape_index, int p_collider_shape_index, const Vector3 &p_normal, const Vector3 &p_position, const Vector3 &p_collider_position, const Vector3 &p_velocity, const Vector3 &p_collider_velocity, const Vector3 &p_impulse) {
  734. const int max_contacts = get_max_contacts_reported();
  735. if (max_contacts == 0) {
  736. return;
  737. }
  738. Contact *contact = nullptr;
  739. if (contact_count < max_contacts) {
  740. contact = &contacts[contact_count++];
  741. } else {
  742. Contact *shallowest_contact = &contacts[0];
  743. for (int i = 1; i < (int)contacts.size(); i++) {
  744. Contact &other_contact = contacts[i];
  745. if (other_contact.depth < shallowest_contact->depth) {
  746. shallowest_contact = &other_contact;
  747. }
  748. }
  749. if (shallowest_contact->depth < p_depth) {
  750. contact = shallowest_contact;
  751. }
  752. }
  753. if (contact != nullptr) {
  754. contact->normal = p_normal;
  755. contact->position = p_position;
  756. contact->collider_position = p_collider_position;
  757. contact->velocity = p_velocity;
  758. contact->collider_velocity = p_collider_velocity;
  759. contact->impulse = p_impulse;
  760. contact->collider_id = p_collider->get_instance_id();
  761. contact->collider_rid = p_collider->get_rid();
  762. contact->shape_index = p_shape_index;
  763. contact->collider_shape_index = p_collider_shape_index;
  764. }
  765. }
  766. void JoltBody3D::reset_mass_properties() {
  767. if (custom_center_of_mass) {
  768. custom_center_of_mass = false;
  769. center_of_mass_custom.zero();
  770. _shapes_changed();
  771. }
  772. inertia.zero();
  773. _update_mass_properties();
  774. }
  775. void JoltBody3D::apply_force(const Vector3 &p_force, const Vector3 &p_position) {
  776. ERR_FAIL_NULL_MSG(space, vformat("Failed to apply force to '%s'. Doing so without a physics space is not supported when using Jolt Physics. If this relates to a node, try adding the node to a scene tree first.", to_string()));
  777. if (unlikely(!is_rigid())) {
  778. return;
  779. }
  780. if (custom_integrator || p_force == Vector3()) {
  781. return;
  782. }
  783. const JoltWritableBody3D body = space->write_body(jolt_id);
  784. ERR_FAIL_COND(body.is_invalid());
  785. body->AddForce(to_jolt(p_force), body->GetPosition() + to_jolt(p_position));
  786. _motion_changed();
  787. }
  788. void JoltBody3D::apply_central_force(const Vector3 &p_force) {
  789. ERR_FAIL_NULL_MSG(space, vformat("Failed to apply central force to '%s'. Doing so without a physics space is not supported when using Jolt Physics. If this relates to a node, try adding the node to a scene tree first.", to_string()));
  790. if (unlikely(!is_rigid())) {
  791. return;
  792. }
  793. if (custom_integrator || p_force == Vector3()) {
  794. return;
  795. }
  796. const JoltWritableBody3D body = space->write_body(jolt_id);
  797. ERR_FAIL_COND(body.is_invalid());
  798. body->AddForce(to_jolt(p_force));
  799. _motion_changed();
  800. }
  801. void JoltBody3D::apply_impulse(const Vector3 &p_impulse, const Vector3 &p_position) {
  802. ERR_FAIL_NULL_MSG(space, vformat("Failed to apply impulse to '%s'. Doing so without a physics space is not supported when using Jolt Physics. If this relates to a node, try adding the node to a scene tree first.", to_string()));
  803. if (unlikely(!is_rigid())) {
  804. return;
  805. }
  806. if (p_impulse == Vector3()) {
  807. return;
  808. }
  809. const JoltWritableBody3D body = space->write_body(jolt_id);
  810. ERR_FAIL_COND(body.is_invalid());
  811. body->AddImpulse(to_jolt(p_impulse), body->GetPosition() + to_jolt(p_position));
  812. _motion_changed();
  813. }
  814. void JoltBody3D::apply_central_impulse(const Vector3 &p_impulse) {
  815. ERR_FAIL_NULL_MSG(space, vformat("Failed to apply central impulse to '%s'. Doing so without a physics space is not supported when using Jolt Physics. If this relates to a node, try adding the node to a scene tree first.", to_string()));
  816. if (unlikely(!is_rigid())) {
  817. return;
  818. }
  819. if (p_impulse == Vector3()) {
  820. return;
  821. }
  822. const JoltWritableBody3D body = space->write_body(jolt_id);
  823. ERR_FAIL_COND(body.is_invalid());
  824. body->AddImpulse(to_jolt(p_impulse));
  825. _motion_changed();
  826. }
  827. void JoltBody3D::apply_torque(const Vector3 &p_torque) {
  828. ERR_FAIL_NULL_MSG(space, vformat("Failed to apply torque to '%s'. Doing so without a physics space is not supported when using Jolt Physics. If this relates to a node, try adding the node to a scene tree first.", to_string()));
  829. if (unlikely(!is_rigid())) {
  830. return;
  831. }
  832. if (custom_integrator || p_torque == Vector3()) {
  833. return;
  834. }
  835. const JoltWritableBody3D body = space->write_body(jolt_id);
  836. ERR_FAIL_COND(body.is_invalid());
  837. body->AddTorque(to_jolt(p_torque));
  838. _motion_changed();
  839. }
  840. void JoltBody3D::apply_torque_impulse(const Vector3 &p_impulse) {
  841. ERR_FAIL_NULL_MSG(space, vformat("Failed to apply torque impulse to '%s'. Doing so without a physics space is not supported when using Jolt Physics. If this relates to a node, try adding the node to a scene tree first.", to_string()));
  842. if (unlikely(!is_rigid())) {
  843. return;
  844. }
  845. if (p_impulse == Vector3()) {
  846. return;
  847. }
  848. const JoltWritableBody3D body = space->write_body(jolt_id);
  849. ERR_FAIL_COND(body.is_invalid());
  850. body->AddAngularImpulse(to_jolt(p_impulse));
  851. _motion_changed();
  852. }
  853. void JoltBody3D::add_constant_central_force(const Vector3 &p_force) {
  854. if (p_force == Vector3()) {
  855. return;
  856. }
  857. constant_force += p_force;
  858. _motion_changed();
  859. }
  860. void JoltBody3D::add_constant_force(const Vector3 &p_force, const Vector3 &p_position) {
  861. if (p_force == Vector3()) {
  862. return;
  863. }
  864. const JoltWritableBody3D body = space->write_body(jolt_id);
  865. ERR_FAIL_COND(body.is_invalid());
  866. constant_force += p_force;
  867. constant_torque += (p_position - get_center_of_mass_relative()).cross(p_force);
  868. _motion_changed();
  869. }
  870. void JoltBody3D::add_constant_torque(const Vector3 &p_torque) {
  871. if (p_torque == Vector3()) {
  872. return;
  873. }
  874. constant_torque += p_torque;
  875. _motion_changed();
  876. }
  877. Vector3 JoltBody3D::get_constant_force() const {
  878. return constant_force;
  879. }
  880. void JoltBody3D::set_constant_force(const Vector3 &p_force) {
  881. if (constant_force == p_force) {
  882. return;
  883. }
  884. constant_force = p_force;
  885. _motion_changed();
  886. }
  887. Vector3 JoltBody3D::get_constant_torque() const {
  888. return constant_torque;
  889. }
  890. void JoltBody3D::set_constant_torque(const Vector3 &p_torque) {
  891. if (constant_torque == p_torque) {
  892. return;
  893. }
  894. constant_torque = p_torque;
  895. _motion_changed();
  896. }
  897. void JoltBody3D::add_collision_exception(const RID &p_excepted_body) {
  898. exceptions.push_back(p_excepted_body);
  899. _exceptions_changed();
  900. }
  901. void JoltBody3D::remove_collision_exception(const RID &p_excepted_body) {
  902. exceptions.erase(p_excepted_body);
  903. _exceptions_changed();
  904. }
  905. bool JoltBody3D::has_collision_exception(const RID &p_excepted_body) const {
  906. return exceptions.find(p_excepted_body) >= 0;
  907. }
  908. void JoltBody3D::add_area(JoltArea3D *p_area) {
  909. int i = 0;
  910. for (; i < (int)areas.size(); i++) {
  911. if (p_area->get_priority() > areas[i]->get_priority()) {
  912. break;
  913. }
  914. }
  915. areas.insert(i, p_area);
  916. _areas_changed();
  917. }
  918. void JoltBody3D::remove_area(JoltArea3D *p_area) {
  919. areas.erase(p_area);
  920. _areas_changed();
  921. }
  922. void JoltBody3D::add_joint(JoltJoint3D *p_joint) {
  923. joints.push_back(p_joint);
  924. _joints_changed();
  925. }
  926. void JoltBody3D::remove_joint(JoltJoint3D *p_joint) {
  927. joints.erase(p_joint);
  928. _joints_changed();
  929. }
  930. void JoltBody3D::call_queries() {
  931. if (custom_integration_callback.is_valid()) {
  932. const Variant direct_state_variant = get_direct_state();
  933. const Variant *args[2] = { &direct_state_variant, &custom_integration_userdata };
  934. const int argc = custom_integration_userdata.get_type() != Variant::NIL ? 2 : 1;
  935. Callable::CallError ce;
  936. Variant ret;
  937. custom_integration_callback.callp(args, argc, ret, ce);
  938. if (unlikely(ce.error != Callable::CallError::CALL_OK)) {
  939. ERR_PRINT_ONCE(vformat("Failed to call force integration callback for '%s'. It returned the following error: '%s'.", to_string(), Variant::get_callable_error_text(custom_integration_callback, args, argc, ce)));
  940. }
  941. }
  942. if (state_sync_callback.is_valid()) {
  943. const Variant direct_state_variant = get_direct_state();
  944. const Variant *args[1] = { &direct_state_variant };
  945. Callable::CallError ce;
  946. Variant ret;
  947. state_sync_callback.callp(args, 1, ret, ce);
  948. if (unlikely(ce.error != Callable::CallError::CALL_OK)) {
  949. ERR_PRINT_ONCE(vformat("Failed to call state synchronization callback for '%s'. It returned the following error: '%s'.", to_string(), Variant::get_callable_error_text(state_sync_callback, args, 1, ce)));
  950. }
  951. }
  952. }
  953. void JoltBody3D::pre_step(float p_step, JPH::Body &p_jolt_body) {
  954. JoltObject3D::pre_step(p_step, p_jolt_body);
  955. switch (mode) {
  956. case PhysicsServer3D::BODY_MODE_STATIC: {
  957. // Will never happen.
  958. } break;
  959. case PhysicsServer3D::BODY_MODE_RIGID:
  960. case PhysicsServer3D::BODY_MODE_RIGID_LINEAR: {
  961. _integrate_forces(p_step, p_jolt_body);
  962. } break;
  963. case PhysicsServer3D::BODY_MODE_KINEMATIC: {
  964. _update_gravity(p_jolt_body);
  965. _move_kinematic(p_step, p_jolt_body);
  966. } break;
  967. }
  968. if (_should_call_queries()) {
  969. _enqueue_call_queries();
  970. }
  971. contact_count = 0;
  972. }
  973. JoltPhysicsDirectBodyState3D *JoltBody3D::get_direct_state() {
  974. if (direct_state == nullptr) {
  975. direct_state = memnew(JoltPhysicsDirectBodyState3D(this));
  976. }
  977. return direct_state;
  978. }
  979. void JoltBody3D::set_mode(PhysicsServer3D::BodyMode p_mode) {
  980. if (p_mode == mode) {
  981. return;
  982. }
  983. mode = p_mode;
  984. if (!in_space()) {
  985. _mode_changed();
  986. return;
  987. }
  988. const JPH::EMotionType motion_type = _get_motion_type();
  989. const JoltWritableBody3D body = space->write_body(jolt_id);
  990. ERR_FAIL_COND(body.is_invalid());
  991. if (motion_type == JPH::EMotionType::Static) {
  992. put_to_sleep();
  993. }
  994. body->SetMotionType(motion_type);
  995. if (motion_type != JPH::EMotionType::Static) {
  996. wake_up();
  997. }
  998. if (motion_type == JPH::EMotionType::Kinematic) {
  999. body->SetLinearVelocity(JPH::Vec3::sZero());
  1000. body->SetAngularVelocity(JPH::Vec3::sZero());
  1001. }
  1002. linear_surface_velocity = Vector3();
  1003. angular_surface_velocity = Vector3();
  1004. _mode_changed();
  1005. }
  1006. bool JoltBody3D::is_ccd_enabled() const {
  1007. if (!in_space()) {
  1008. return jolt_settings->mMotionQuality == JPH::EMotionQuality::LinearCast;
  1009. }
  1010. const JPH::BodyInterface &body_iface = space->get_body_iface();
  1011. return body_iface.GetMotionQuality(jolt_id) == JPH::EMotionQuality::LinearCast;
  1012. }
  1013. void JoltBody3D::set_ccd_enabled(bool p_enabled) {
  1014. const JPH::EMotionQuality motion_quality = p_enabled ? JPH::EMotionQuality::LinearCast : JPH::EMotionQuality::Discrete;
  1015. if (!in_space()) {
  1016. jolt_settings->mMotionQuality = motion_quality;
  1017. return;
  1018. }
  1019. JPH::BodyInterface &body_iface = space->get_body_iface();
  1020. body_iface.SetMotionQuality(jolt_id, motion_quality);
  1021. }
  1022. void JoltBody3D::set_mass(float p_mass) {
  1023. if (p_mass != mass) {
  1024. mass = p_mass;
  1025. _update_mass_properties();
  1026. }
  1027. }
  1028. void JoltBody3D::set_inertia(const Vector3 &p_inertia) {
  1029. if (p_inertia != inertia) {
  1030. inertia = p_inertia;
  1031. _update_mass_properties();
  1032. }
  1033. }
  1034. float JoltBody3D::get_bounce() const {
  1035. if (!in_space()) {
  1036. return jolt_settings->mRestitution;
  1037. }
  1038. const JoltReadableBody3D body = space->read_body(jolt_id);
  1039. ERR_FAIL_COND_V(body.is_invalid(), 0.0f);
  1040. return body->GetRestitution();
  1041. }
  1042. void JoltBody3D::set_bounce(float p_bounce) {
  1043. if (!in_space()) {
  1044. jolt_settings->mRestitution = p_bounce;
  1045. return;
  1046. }
  1047. const JoltWritableBody3D body = space->write_body(jolt_id);
  1048. ERR_FAIL_COND(body.is_invalid());
  1049. body->SetRestitution(p_bounce);
  1050. }
  1051. float JoltBody3D::get_friction() const {
  1052. if (!in_space()) {
  1053. return jolt_settings->mFriction;
  1054. }
  1055. const JoltReadableBody3D body = space->read_body(jolt_id);
  1056. ERR_FAIL_COND_V(body.is_invalid(), 0.0f);
  1057. return body->GetFriction();
  1058. }
  1059. void JoltBody3D::set_friction(float p_friction) {
  1060. if (!in_space()) {
  1061. jolt_settings->mFriction = p_friction;
  1062. return;
  1063. }
  1064. const JoltWritableBody3D body = space->write_body(jolt_id);
  1065. ERR_FAIL_COND(body.is_invalid());
  1066. body->SetFriction(p_friction);
  1067. }
  1068. void JoltBody3D::set_gravity_scale(float p_scale) {
  1069. if (gravity_scale == p_scale) {
  1070. return;
  1071. }
  1072. gravity_scale = p_scale;
  1073. _motion_changed();
  1074. }
  1075. void JoltBody3D::set_linear_damp(float p_damp) {
  1076. p_damp = MAX(0.0f, p_damp);
  1077. if (p_damp == linear_damp) {
  1078. return;
  1079. }
  1080. linear_damp = p_damp;
  1081. _update_damp();
  1082. }
  1083. void JoltBody3D::set_angular_damp(float p_damp) {
  1084. p_damp = MAX(0.0f, p_damp);
  1085. if (p_damp == angular_damp) {
  1086. return;
  1087. }
  1088. angular_damp = p_damp;
  1089. _update_damp();
  1090. }
  1091. void JoltBody3D::set_linear_damp_mode(DampMode p_mode) {
  1092. if (p_mode == linear_damp_mode) {
  1093. return;
  1094. }
  1095. linear_damp_mode = p_mode;
  1096. _update_damp();
  1097. }
  1098. void JoltBody3D::set_angular_damp_mode(DampMode p_mode) {
  1099. if (p_mode == angular_damp_mode) {
  1100. return;
  1101. }
  1102. angular_damp_mode = p_mode;
  1103. _update_damp();
  1104. }
  1105. bool JoltBody3D::is_axis_locked(PhysicsServer3D::BodyAxis p_axis) const {
  1106. return (locked_axes & (uint32_t)p_axis) != 0;
  1107. }
  1108. void JoltBody3D::set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool p_enabled) {
  1109. const uint32_t previous_locked_axes = locked_axes;
  1110. if (p_enabled) {
  1111. locked_axes |= (uint32_t)p_axis;
  1112. } else {
  1113. locked_axes &= ~(uint32_t)p_axis;
  1114. }
  1115. if (previous_locked_axes != locked_axes) {
  1116. _axis_lock_changed();
  1117. }
  1118. }
  1119. bool JoltBody3D::can_interact_with(const JoltBody3D &p_other) const {
  1120. return (can_collide_with(p_other) || p_other.can_collide_with(*this)) && !has_collision_exception(p_other.get_rid()) && !p_other.has_collision_exception(rid);
  1121. }
  1122. bool JoltBody3D::can_interact_with(const JoltSoftBody3D &p_other) const {
  1123. return p_other.can_interact_with(*this);
  1124. }
  1125. bool JoltBody3D::can_interact_with(const JoltArea3D &p_other) const {
  1126. return p_other.can_interact_with(*this);
  1127. }