rigid_body_bullet.cpp 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056
  1. /*************************************************************************/
  2. /* rigid_body_bullet.cpp */
  3. /*************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* https://godotengine.org */
  7. /*************************************************************************/
  8. /* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
  9. /* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
  10. /* */
  11. /* Permission is hereby granted, free of charge, to any person obtaining */
  12. /* a copy of this software and associated documentation files (the */
  13. /* "Software"), to deal in the Software without restriction, including */
  14. /* without limitation the rights to use, copy, modify, merge, publish, */
  15. /* distribute, sublicense, and/or sell copies of the Software, and to */
  16. /* permit persons to whom the Software is furnished to do so, subject to */
  17. /* the following conditions: */
  18. /* */
  19. /* The above copyright notice and this permission notice shall be */
  20. /* included in all copies or substantial portions of the Software. */
  21. /* */
  22. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
  23. /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
  24. /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
  25. /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
  26. /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
  27. /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
  28. /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  29. /*************************************************************************/
  30. #include "rigid_body_bullet.h"
  31. #include "btRayShape.h"
  32. #include "bullet_physics_server.h"
  33. #include "bullet_types_converter.h"
  34. #include "bullet_utilities.h"
  35. #include "godot_motion_state.h"
  36. #include "joint_bullet.h"
  37. #include <BulletCollision/CollisionDispatch/btGhostObject.h>
  38. #include <BulletCollision/CollisionShapes/btConvexPointCloudShape.h>
  39. #include <BulletDynamics/Dynamics/btRigidBody.h>
  40. #include <btBulletCollisionCommon.h>
  41. #include <assert.h>
  42. /**
  43. @author AndreaCatania
  44. */
  45. BulletPhysicsDirectBodyState3D *BulletPhysicsDirectBodyState3D::singleton = nullptr;
  46. Vector3 BulletPhysicsDirectBodyState3D::get_total_gravity() const {
  47. Vector3 gVec;
  48. B_TO_G(body->btBody->getGravity(), gVec);
  49. return gVec;
  50. }
  51. real_t BulletPhysicsDirectBodyState3D::get_total_angular_damp() const {
  52. return body->btBody->getAngularDamping();
  53. }
  54. real_t BulletPhysicsDirectBodyState3D::get_total_linear_damp() const {
  55. return body->btBody->getLinearDamping();
  56. }
  57. Vector3 BulletPhysicsDirectBodyState3D::get_center_of_mass() const {
  58. Vector3 gVec;
  59. B_TO_G(body->btBody->getCenterOfMassPosition(), gVec);
  60. return gVec;
  61. }
  62. Basis BulletPhysicsDirectBodyState3D::get_principal_inertia_axes() const {
  63. return Basis();
  64. }
  65. real_t BulletPhysicsDirectBodyState3D::get_inverse_mass() const {
  66. return body->btBody->getInvMass();
  67. }
  68. Vector3 BulletPhysicsDirectBodyState3D::get_inverse_inertia() const {
  69. Vector3 gVec;
  70. B_TO_G(body->btBody->getInvInertiaDiagLocal(), gVec);
  71. return gVec;
  72. }
  73. Basis BulletPhysicsDirectBodyState3D::get_inverse_inertia_tensor() const {
  74. Basis gInertia;
  75. B_TO_G(body->btBody->getInvInertiaTensorWorld(), gInertia);
  76. return gInertia;
  77. }
  78. void BulletPhysicsDirectBodyState3D::set_linear_velocity(const Vector3 &p_velocity) {
  79. body->set_linear_velocity(p_velocity);
  80. }
  81. Vector3 BulletPhysicsDirectBodyState3D::get_linear_velocity() const {
  82. return body->get_linear_velocity();
  83. }
  84. void BulletPhysicsDirectBodyState3D::set_angular_velocity(const Vector3 &p_velocity) {
  85. body->set_angular_velocity(p_velocity);
  86. }
  87. Vector3 BulletPhysicsDirectBodyState3D::get_angular_velocity() const {
  88. return body->get_angular_velocity();
  89. }
  90. void BulletPhysicsDirectBodyState3D::set_transform(const Transform3D &p_transform) {
  91. body->set_transform(p_transform);
  92. }
  93. Transform3D BulletPhysicsDirectBodyState3D::get_transform() const {
  94. return body->get_transform();
  95. }
  96. Vector3 BulletPhysicsDirectBodyState3D::get_velocity_at_local_position(const Vector3 &p_position) const {
  97. btVector3 local_position;
  98. G_TO_B(p_position, local_position);
  99. Vector3 velocity;
  100. B_TO_G(body->btBody->getVelocityInLocalPoint(local_position), velocity);
  101. return velocity;
  102. }
  103. void BulletPhysicsDirectBodyState3D::add_central_force(const Vector3 &p_force) {
  104. body->apply_central_force(p_force);
  105. }
  106. void BulletPhysicsDirectBodyState3D::add_force(const Vector3 &p_force, const Vector3 &p_position) {
  107. body->apply_force(p_force, p_position);
  108. }
  109. void BulletPhysicsDirectBodyState3D::add_torque(const Vector3 &p_torque) {
  110. body->apply_torque(p_torque);
  111. }
  112. void BulletPhysicsDirectBodyState3D::apply_central_impulse(const Vector3 &p_impulse) {
  113. body->apply_central_impulse(p_impulse);
  114. }
  115. void BulletPhysicsDirectBodyState3D::apply_impulse(const Vector3 &p_impulse, const Vector3 &p_position) {
  116. body->apply_impulse(p_impulse, p_position);
  117. }
  118. void BulletPhysicsDirectBodyState3D::apply_torque_impulse(const Vector3 &p_impulse) {
  119. body->apply_torque_impulse(p_impulse);
  120. }
  121. void BulletPhysicsDirectBodyState3D::set_sleep_state(bool p_sleep) {
  122. body->set_activation_state(!p_sleep);
  123. }
  124. bool BulletPhysicsDirectBodyState3D::is_sleeping() const {
  125. return !body->is_active();
  126. }
  127. int BulletPhysicsDirectBodyState3D::get_contact_count() const {
  128. return body->collisionsCount;
  129. }
  130. Vector3 BulletPhysicsDirectBodyState3D::get_contact_local_position(int p_contact_idx) const {
  131. return body->collisions[p_contact_idx].hitLocalLocation;
  132. }
  133. Vector3 BulletPhysicsDirectBodyState3D::get_contact_local_normal(int p_contact_idx) const {
  134. return body->collisions[p_contact_idx].hitNormal;
  135. }
  136. real_t BulletPhysicsDirectBodyState3D::get_contact_impulse(int p_contact_idx) const {
  137. return body->collisions[p_contact_idx].appliedImpulse;
  138. }
  139. int BulletPhysicsDirectBodyState3D::get_contact_local_shape(int p_contact_idx) const {
  140. return body->collisions[p_contact_idx].local_shape;
  141. }
  142. RID BulletPhysicsDirectBodyState3D::get_contact_collider(int p_contact_idx) const {
  143. return body->collisions[p_contact_idx].otherObject->get_self();
  144. }
  145. Vector3 BulletPhysicsDirectBodyState3D::get_contact_collider_position(int p_contact_idx) const {
  146. return body->collisions[p_contact_idx].hitWorldLocation;
  147. }
  148. ObjectID BulletPhysicsDirectBodyState3D::get_contact_collider_id(int p_contact_idx) const {
  149. return body->collisions[p_contact_idx].otherObject->get_instance_id();
  150. }
  151. int BulletPhysicsDirectBodyState3D::get_contact_collider_shape(int p_contact_idx) const {
  152. return body->collisions[p_contact_idx].other_object_shape;
  153. }
  154. Vector3 BulletPhysicsDirectBodyState3D::get_contact_collider_velocity_at_position(int p_contact_idx) const {
  155. RigidBodyBullet::CollisionData &colDat = body->collisions.write[p_contact_idx];
  156. btVector3 hitLocation;
  157. G_TO_B(colDat.hitLocalLocation, hitLocation);
  158. Vector3 velocityAtPoint;
  159. B_TO_G(colDat.otherObject->get_bt_rigid_body()->getVelocityInLocalPoint(hitLocation), velocityAtPoint);
  160. return velocityAtPoint;
  161. }
  162. PhysicsDirectSpaceState3D *BulletPhysicsDirectBodyState3D::get_space_state() {
  163. return body->get_space()->get_direct_state();
  164. }
  165. RigidBodyBullet::KinematicUtilities::KinematicUtilities(RigidBodyBullet *p_owner) :
  166. owner(p_owner),
  167. safe_margin(0.001) {
  168. }
  169. RigidBodyBullet::KinematicUtilities::~KinematicUtilities() {
  170. just_delete_shapes(shapes.size()); // don't need to resize
  171. }
  172. void RigidBodyBullet::KinematicUtilities::setSafeMargin(btScalar p_margin) {
  173. safe_margin = p_margin;
  174. copyAllOwnerShapes();
  175. }
  176. void RigidBodyBullet::KinematicUtilities::copyAllOwnerShapes() {
  177. const Vector<CollisionObjectBullet::ShapeWrapper> &shapes_wrappers(owner->get_shapes_wrappers());
  178. const int shapes_count = shapes_wrappers.size();
  179. just_delete_shapes(shapes_count);
  180. const CollisionObjectBullet::ShapeWrapper *shape_wrapper;
  181. btVector3 owner_scale(owner->get_bt_body_scale());
  182. for (int i = shapes_count - 1; 0 <= i; --i) {
  183. shape_wrapper = &shapes_wrappers[i];
  184. if (!shape_wrapper->active) {
  185. continue;
  186. }
  187. shapes.write[i].transform = shape_wrapper->transform;
  188. shapes.write[i].transform.getOrigin() *= owner_scale;
  189. switch (shape_wrapper->shape->get_type()) {
  190. case PhysicsServer3D::SHAPE_SPHERE:
  191. case PhysicsServer3D::SHAPE_BOX:
  192. case PhysicsServer3D::SHAPE_CAPSULE:
  193. case PhysicsServer3D::SHAPE_CYLINDER:
  194. case PhysicsServer3D::SHAPE_CONVEX_POLYGON:
  195. case PhysicsServer3D::SHAPE_RAY: {
  196. shapes.write[i].shape = static_cast<btConvexShape *>(shape_wrapper->shape->create_bt_shape(owner_scale * shape_wrapper->scale, safe_margin));
  197. } break;
  198. default:
  199. WARN_PRINT("This shape is not supported for kinematic collision.");
  200. shapes.write[i].shape = nullptr;
  201. }
  202. }
  203. }
  204. void RigidBodyBullet::KinematicUtilities::just_delete_shapes(int new_size) {
  205. for (int i = shapes.size() - 1; 0 <= i; --i) {
  206. if (shapes[i].shape) {
  207. bulletdelete(shapes.write[i].shape);
  208. }
  209. }
  210. shapes.resize(new_size);
  211. }
  212. RigidBodyBullet::RigidBodyBullet() :
  213. RigidCollisionObjectBullet(CollisionObjectBullet::TYPE_RIGID_BODY) {
  214. godotMotionState = bulletnew(GodotMotionState(this));
  215. // Initial properties
  216. const btVector3 localInertia(0, 0, 0);
  217. btRigidBody::btRigidBodyConstructionInfo cInfo(mass, godotMotionState, nullptr, localInertia);
  218. btBody = bulletnew(btRigidBody(cInfo));
  219. btBody->setFriction(1.0);
  220. reload_shapes();
  221. setupBulletCollisionObject(btBody);
  222. set_mode(PhysicsServer3D::BODY_MODE_DYNAMIC);
  223. reload_axis_lock();
  224. areasWhereIam.resize(maxAreasWhereIam);
  225. for (int i = areasWhereIam.size() - 1; 0 <= i; --i) {
  226. areasWhereIam.write[i] = nullptr;
  227. }
  228. btBody->setSleepingThresholds(0.2, 0.2);
  229. prev_collision_traces = &collision_traces_1;
  230. curr_collision_traces = &collision_traces_2;
  231. }
  232. RigidBodyBullet::~RigidBodyBullet() {
  233. bulletdelete(godotMotionState);
  234. if (force_integration_callback) {
  235. memdelete(force_integration_callback);
  236. }
  237. destroy_kinematic_utilities();
  238. }
  239. void RigidBodyBullet::init_kinematic_utilities() {
  240. kinematic_utilities = memnew(KinematicUtilities(this));
  241. reload_kinematic_shapes();
  242. }
  243. void RigidBodyBullet::destroy_kinematic_utilities() {
  244. if (kinematic_utilities) {
  245. memdelete(kinematic_utilities);
  246. kinematic_utilities = nullptr;
  247. }
  248. }
  249. void RigidBodyBullet::main_shape_changed() {
  250. CRASH_COND(!get_main_shape());
  251. btBody->setCollisionShape(get_main_shape());
  252. set_continuous_collision_detection(is_continuous_collision_detection_enabled()); // Reset
  253. }
  254. void RigidBodyBullet::reload_body() {
  255. if (space) {
  256. space->remove_rigid_body(this);
  257. if (get_main_shape()) {
  258. space->add_rigid_body(this);
  259. }
  260. }
  261. }
  262. void RigidBodyBullet::set_space(SpaceBullet *p_space) {
  263. // Clear the old space if there is one
  264. if (space) {
  265. can_integrate_forces = false;
  266. isScratchedSpaceOverrideModificator = false;
  267. // Remove any constraints
  268. space->remove_rigid_body_constraints(this);
  269. // Remove this object form the physics world
  270. space->remove_rigid_body(this);
  271. }
  272. space = p_space;
  273. if (space) {
  274. space->add_rigid_body(this);
  275. }
  276. }
  277. void RigidBodyBullet::dispatch_callbacks() {
  278. /// The check isFirstTransformChanged is necessary in order to call integrated forces only when the first transform is sent
  279. if ((btBody->isKinematicObject() || btBody->isActive() || previousActiveState != btBody->isActive()) && force_integration_callback && can_integrate_forces) {
  280. if (omit_forces_integration) {
  281. btBody->clearForces();
  282. }
  283. BulletPhysicsDirectBodyState3D *bodyDirect = BulletPhysicsDirectBodyState3D::get_singleton(this);
  284. Variant variantBodyDirect = bodyDirect;
  285. Object *obj = force_integration_callback->callable.get_object();
  286. if (!obj) {
  287. // Remove integration callback
  288. set_force_integration_callback(Callable());
  289. } else {
  290. const Variant *vp[2] = { &variantBodyDirect, &force_integration_callback->udata };
  291. Callable::CallError responseCallError;
  292. int argc = (force_integration_callback->udata.get_type() == Variant::NIL) ? 1 : 2;
  293. Variant rv;
  294. force_integration_callback->callable.call(vp, argc, rv, responseCallError);
  295. }
  296. }
  297. if (isScratchedSpaceOverrideModificator || 0 < countGravityPointSpaces) {
  298. isScratchedSpaceOverrideModificator = false;
  299. reload_space_override_modificator();
  300. }
  301. /// Lock axis
  302. btBody->setLinearVelocity(btBody->getLinearVelocity() * btBody->getLinearFactor());
  303. btBody->setAngularVelocity(btBody->getAngularVelocity() * btBody->getAngularFactor());
  304. previousActiveState = btBody->isActive();
  305. }
  306. void RigidBodyBullet::set_force_integration_callback(const Callable &p_callable, const Variant &p_udata) {
  307. if (force_integration_callback) {
  308. memdelete(force_integration_callback);
  309. force_integration_callback = nullptr;
  310. }
  311. if (p_callable.get_object()) {
  312. force_integration_callback = memnew(ForceIntegrationCallback);
  313. force_integration_callback->callable = p_callable;
  314. force_integration_callback->udata = p_udata;
  315. }
  316. }
  317. void RigidBodyBullet::scratch_space_override_modificator() {
  318. isScratchedSpaceOverrideModificator = true;
  319. }
  320. void RigidBodyBullet::on_collision_filters_change() {
  321. if (space) {
  322. space->reload_collision_filters(this);
  323. }
  324. set_activation_state(true);
  325. }
  326. void RigidBodyBullet::on_collision_checker_start() {
  327. prev_collision_count = collisionsCount;
  328. collisionsCount = 0;
  329. // Swap array
  330. Vector<RigidBodyBullet *> *s = prev_collision_traces;
  331. prev_collision_traces = curr_collision_traces;
  332. curr_collision_traces = s;
  333. }
  334. void RigidBodyBullet::on_collision_checker_end() {
  335. // Always true if active and not a static or kinematic body
  336. isTransformChanged = btBody->isActive() && !btBody->isStaticOrKinematicObject();
  337. }
  338. bool RigidBodyBullet::add_collision_object(RigidBodyBullet *p_otherObject, const Vector3 &p_hitWorldLocation, const Vector3 &p_hitLocalLocation, const Vector3 &p_hitNormal, const real_t &p_appliedImpulse, int p_other_shape_index, int p_local_shape_index) {
  339. if (collisionsCount >= maxCollisionsDetection) {
  340. return false;
  341. }
  342. CollisionData &cd = collisions.write[collisionsCount];
  343. cd.hitLocalLocation = p_hitLocalLocation;
  344. cd.otherObject = p_otherObject;
  345. cd.hitWorldLocation = p_hitWorldLocation;
  346. cd.hitNormal = p_hitNormal;
  347. cd.appliedImpulse = p_appliedImpulse;
  348. cd.other_object_shape = p_other_shape_index;
  349. cd.local_shape = p_local_shape_index;
  350. curr_collision_traces->write[collisionsCount] = p_otherObject;
  351. ++collisionsCount;
  352. return true;
  353. }
  354. bool RigidBodyBullet::was_colliding(RigidBodyBullet *p_other_object) {
  355. for (int i = prev_collision_count - 1; 0 <= i; --i) {
  356. if ((*prev_collision_traces)[i] == p_other_object) {
  357. return true;
  358. }
  359. }
  360. return false;
  361. }
  362. void RigidBodyBullet::set_activation_state(bool p_active) {
  363. if (p_active) {
  364. btBody->activate();
  365. } else {
  366. btBody->setActivationState(WANTS_DEACTIVATION);
  367. }
  368. }
  369. bool RigidBodyBullet::is_active() const {
  370. return btBody->isActive();
  371. }
  372. void RigidBodyBullet::set_omit_forces_integration(bool p_omit) {
  373. omit_forces_integration = p_omit;
  374. }
  375. void RigidBodyBullet::set_param(PhysicsServer3D::BodyParameter p_param, real_t p_value) {
  376. switch (p_param) {
  377. case PhysicsServer3D::BODY_PARAM_BOUNCE:
  378. btBody->setRestitution(p_value);
  379. break;
  380. case PhysicsServer3D::BODY_PARAM_FRICTION:
  381. btBody->setFriction(p_value);
  382. break;
  383. case PhysicsServer3D::BODY_PARAM_MASS: {
  384. ERR_FAIL_COND(p_value < 0);
  385. mass = p_value;
  386. _internal_set_mass(p_value);
  387. break;
  388. }
  389. case PhysicsServer3D::BODY_PARAM_LINEAR_DAMP:
  390. linearDamp = p_value;
  391. // Mark for updating total linear damping.
  392. scratch_space_override_modificator();
  393. break;
  394. case PhysicsServer3D::BODY_PARAM_ANGULAR_DAMP:
  395. angularDamp = p_value;
  396. // Mark for updating total angular damping.
  397. scratch_space_override_modificator();
  398. break;
  399. case PhysicsServer3D::BODY_PARAM_GRAVITY_SCALE:
  400. gravity_scale = p_value;
  401. // The Bullet gravity will be is set by reload_space_override_modificator.
  402. // Mark for updating total gravity scale.
  403. scratch_space_override_modificator();
  404. break;
  405. default:
  406. WARN_PRINT("Parameter " + itos(p_param) + " not supported by bullet. Value: " + itos(p_value));
  407. }
  408. }
  409. real_t RigidBodyBullet::get_param(PhysicsServer3D::BodyParameter p_param) const {
  410. switch (p_param) {
  411. case PhysicsServer3D::BODY_PARAM_BOUNCE:
  412. return btBody->getRestitution();
  413. case PhysicsServer3D::BODY_PARAM_FRICTION:
  414. return btBody->getFriction();
  415. case PhysicsServer3D::BODY_PARAM_MASS: {
  416. const btScalar invMass = btBody->getInvMass();
  417. return 0 == invMass ? 0 : 1 / invMass;
  418. }
  419. case PhysicsServer3D::BODY_PARAM_LINEAR_DAMP:
  420. return linearDamp;
  421. case PhysicsServer3D::BODY_PARAM_ANGULAR_DAMP:
  422. return angularDamp;
  423. case PhysicsServer3D::BODY_PARAM_GRAVITY_SCALE:
  424. return gravity_scale;
  425. default:
  426. WARN_PRINT("Parameter " + itos(p_param) + " not supported by bullet");
  427. return 0;
  428. }
  429. }
  430. void RigidBodyBullet::set_mode(PhysicsServer3D::BodyMode p_mode) {
  431. // This is necessary to block force_integration until next move
  432. can_integrate_forces = false;
  433. destroy_kinematic_utilities();
  434. // The mode change is relevant to its mass
  435. mode = p_mode;
  436. switch (p_mode) {
  437. case PhysicsServer3D::BODY_MODE_KINEMATIC:
  438. reload_axis_lock();
  439. _internal_set_mass(0);
  440. init_kinematic_utilities();
  441. break;
  442. case PhysicsServer3D::BODY_MODE_STATIC:
  443. reload_axis_lock();
  444. _internal_set_mass(0);
  445. break;
  446. case PhysicsServer3D::BODY_MODE_DYNAMIC:
  447. reload_axis_lock();
  448. _internal_set_mass(0 == mass ? 1 : mass);
  449. scratch_space_override_modificator();
  450. break;
  451. case PhysicsServer3D::MODE_DYNAMIC_LINEAR:
  452. reload_axis_lock();
  453. _internal_set_mass(0 == mass ? 1 : mass);
  454. scratch_space_override_modificator();
  455. break;
  456. }
  457. btBody->setAngularVelocity(btVector3(0, 0, 0));
  458. btBody->setLinearVelocity(btVector3(0, 0, 0));
  459. }
  460. PhysicsServer3D::BodyMode RigidBodyBullet::get_mode() const {
  461. return mode;
  462. }
  463. void RigidBodyBullet::set_state(PhysicsServer3D::BodyState p_state, const Variant &p_variant) {
  464. switch (p_state) {
  465. case PhysicsServer3D::BODY_STATE_TRANSFORM:
  466. set_transform(p_variant);
  467. break;
  468. case PhysicsServer3D::BODY_STATE_LINEAR_VELOCITY:
  469. set_linear_velocity(p_variant);
  470. break;
  471. case PhysicsServer3D::BODY_STATE_ANGULAR_VELOCITY:
  472. set_angular_velocity(p_variant);
  473. break;
  474. case PhysicsServer3D::BODY_STATE_SLEEPING:
  475. set_activation_state(!bool(p_variant));
  476. break;
  477. case PhysicsServer3D::BODY_STATE_CAN_SLEEP:
  478. can_sleep = bool(p_variant);
  479. if (!can_sleep) {
  480. // Can't sleep
  481. btBody->forceActivationState(DISABLE_DEACTIVATION);
  482. } else {
  483. btBody->forceActivationState(ACTIVE_TAG);
  484. }
  485. break;
  486. }
  487. }
  488. Variant RigidBodyBullet::get_state(PhysicsServer3D::BodyState p_state) const {
  489. switch (p_state) {
  490. case PhysicsServer3D::BODY_STATE_TRANSFORM:
  491. return get_transform();
  492. case PhysicsServer3D::BODY_STATE_LINEAR_VELOCITY:
  493. return get_linear_velocity();
  494. case PhysicsServer3D::BODY_STATE_ANGULAR_VELOCITY:
  495. return get_angular_velocity();
  496. case PhysicsServer3D::BODY_STATE_SLEEPING:
  497. return !is_active();
  498. case PhysicsServer3D::BODY_STATE_CAN_SLEEP:
  499. return can_sleep;
  500. default:
  501. WARN_PRINT("This state " + itos(p_state) + " is not supported by Bullet");
  502. return Variant();
  503. }
  504. }
  505. void RigidBodyBullet::apply_central_impulse(const Vector3 &p_impulse) {
  506. btVector3 btImpulse;
  507. G_TO_B(p_impulse, btImpulse);
  508. if (Vector3() != p_impulse) {
  509. btBody->activate();
  510. }
  511. btBody->applyCentralImpulse(btImpulse);
  512. }
  513. void RigidBodyBullet::apply_impulse(const Vector3 &p_impulse, const Vector3 &p_position) {
  514. btVector3 btImpulse;
  515. btVector3 btPosition;
  516. G_TO_B(p_impulse, btImpulse);
  517. G_TO_B(p_position, btPosition);
  518. if (Vector3() != p_impulse) {
  519. btBody->activate();
  520. }
  521. btBody->applyImpulse(btImpulse, btPosition);
  522. }
  523. void RigidBodyBullet::apply_torque_impulse(const Vector3 &p_impulse) {
  524. btVector3 btImp;
  525. G_TO_B(p_impulse, btImp);
  526. if (Vector3() != p_impulse) {
  527. btBody->activate();
  528. }
  529. btBody->applyTorqueImpulse(btImp);
  530. }
  531. void RigidBodyBullet::apply_force(const Vector3 &p_force, const Vector3 &p_position) {
  532. btVector3 btForce;
  533. btVector3 btPosition;
  534. G_TO_B(p_force, btForce);
  535. G_TO_B(p_position, btPosition);
  536. if (Vector3() != p_force) {
  537. btBody->activate();
  538. }
  539. btBody->applyForce(btForce, btPosition);
  540. }
  541. void RigidBodyBullet::apply_central_force(const Vector3 &p_force) {
  542. btVector3 btForce;
  543. G_TO_B(p_force, btForce);
  544. if (Vector3() != p_force) {
  545. btBody->activate();
  546. }
  547. btBody->applyCentralForce(btForce);
  548. }
  549. void RigidBodyBullet::apply_torque(const Vector3 &p_torque) {
  550. btVector3 btTorq;
  551. G_TO_B(p_torque, btTorq);
  552. if (Vector3() != p_torque) {
  553. btBody->activate();
  554. }
  555. btBody->applyTorque(btTorq);
  556. }
  557. void RigidBodyBullet::set_applied_force(const Vector3 &p_force) {
  558. btVector3 btVec = btBody->getTotalTorque();
  559. if (Vector3() != p_force) {
  560. btBody->activate();
  561. }
  562. btBody->clearForces();
  563. btBody->applyTorque(btVec);
  564. G_TO_B(p_force, btVec);
  565. btBody->applyCentralForce(btVec);
  566. }
  567. Vector3 RigidBodyBullet::get_applied_force() const {
  568. Vector3 gTotForc;
  569. B_TO_G(btBody->getTotalForce(), gTotForc);
  570. return gTotForc;
  571. }
  572. void RigidBodyBullet::set_applied_torque(const Vector3 &p_torque) {
  573. btVector3 btVec = btBody->getTotalForce();
  574. if (Vector3() != p_torque) {
  575. btBody->activate();
  576. }
  577. btBody->clearForces();
  578. btBody->applyCentralForce(btVec);
  579. G_TO_B(p_torque, btVec);
  580. btBody->applyTorque(btVec);
  581. }
  582. Vector3 RigidBodyBullet::get_applied_torque() const {
  583. Vector3 gTotTorq;
  584. B_TO_G(btBody->getTotalTorque(), gTotTorq);
  585. return gTotTorq;
  586. }
  587. void RigidBodyBullet::set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool lock) {
  588. if (lock) {
  589. locked_axis |= p_axis;
  590. } else {
  591. locked_axis &= ~p_axis;
  592. }
  593. reload_axis_lock();
  594. }
  595. bool RigidBodyBullet::is_axis_locked(PhysicsServer3D::BodyAxis p_axis) const {
  596. return locked_axis & p_axis;
  597. }
  598. void RigidBodyBullet::reload_axis_lock() {
  599. btBody->setLinearFactor(btVector3(btScalar(!is_axis_locked(PhysicsServer3D::BODY_AXIS_LINEAR_X)), btScalar(!is_axis_locked(PhysicsServer3D::BODY_AXIS_LINEAR_Y)), btScalar(!is_axis_locked(PhysicsServer3D::BODY_AXIS_LINEAR_Z))));
  600. if (PhysicsServer3D::MODE_DYNAMIC_LINEAR == mode) {
  601. /// When character angular is always locked
  602. btBody->setAngularFactor(btVector3(0., 0., 0.));
  603. } else {
  604. btBody->setAngularFactor(btVector3(btScalar(!is_axis_locked(PhysicsServer3D::BODY_AXIS_ANGULAR_X)), btScalar(!is_axis_locked(PhysicsServer3D::BODY_AXIS_ANGULAR_Y)), btScalar(!is_axis_locked(PhysicsServer3D::BODY_AXIS_ANGULAR_Z))));
  605. }
  606. }
  607. void RigidBodyBullet::set_continuous_collision_detection(bool p_enable) {
  608. if (p_enable) {
  609. // This threshold enable CCD if the object moves more than
  610. // 1 meter in one simulation frame
  611. btBody->setCcdMotionThreshold(1e-7);
  612. /// Calculate using the rule write below the CCD swept sphere radius
  613. /// CCD works on an embedded sphere of radius, make sure this radius
  614. /// is embedded inside the convex objects, preferably smaller:
  615. /// for an object of dimensions 1 meter, try 0.2
  616. btScalar radius(1.0);
  617. if (btBody->getCollisionShape()) {
  618. btVector3 center;
  619. btBody->getCollisionShape()->getBoundingSphere(center, radius);
  620. }
  621. btBody->setCcdSweptSphereRadius(radius * 0.2);
  622. } else {
  623. btBody->setCcdMotionThreshold(0.);
  624. btBody->setCcdSweptSphereRadius(0.);
  625. }
  626. }
  627. bool RigidBodyBullet::is_continuous_collision_detection_enabled() const {
  628. return 0. < btBody->getCcdMotionThreshold();
  629. }
  630. void RigidBodyBullet::set_linear_velocity(const Vector3 &p_velocity) {
  631. btVector3 btVec;
  632. G_TO_B(p_velocity, btVec);
  633. if (Vector3() != p_velocity) {
  634. btBody->activate();
  635. }
  636. btBody->setLinearVelocity(btVec);
  637. }
  638. Vector3 RigidBodyBullet::get_linear_velocity() const {
  639. Vector3 gVec;
  640. B_TO_G(btBody->getLinearVelocity(), gVec);
  641. return gVec;
  642. }
  643. void RigidBodyBullet::set_angular_velocity(const Vector3 &p_velocity) {
  644. btVector3 btVec;
  645. G_TO_B(p_velocity, btVec);
  646. if (Vector3() != p_velocity) {
  647. btBody->activate();
  648. }
  649. btBody->setAngularVelocity(btVec);
  650. }
  651. Vector3 RigidBodyBullet::get_angular_velocity() const {
  652. Vector3 gVec;
  653. B_TO_G(btBody->getAngularVelocity(), gVec);
  654. return gVec;
  655. }
  656. void RigidBodyBullet::set_transform__bullet(const btTransform &p_global_transform) {
  657. if (mode == PhysicsServer3D::BODY_MODE_KINEMATIC) {
  658. if (space && space->get_delta_time() != 0) {
  659. btBody->setLinearVelocity((p_global_transform.getOrigin() - btBody->getWorldTransform().getOrigin()) / space->get_delta_time());
  660. }
  661. // The kinematic use MotionState class
  662. godotMotionState->moveBody(p_global_transform);
  663. } else {
  664. // Is necessary to avoid wrong location on the rendering side on the next frame
  665. godotMotionState->setWorldTransform(p_global_transform);
  666. }
  667. CollisionObjectBullet::set_transform__bullet(p_global_transform);
  668. }
  669. const btTransform &RigidBodyBullet::get_transform__bullet() const {
  670. if (is_static()) {
  671. return RigidCollisionObjectBullet::get_transform__bullet();
  672. } else {
  673. return godotMotionState->getCurrentWorldTransform();
  674. }
  675. }
  676. void RigidBodyBullet::reload_shapes() {
  677. RigidCollisionObjectBullet::reload_shapes();
  678. const btScalar invMass = btBody->getInvMass();
  679. const btScalar mass = invMass == 0 ? 0 : 1 / invMass;
  680. if (mainShape) {
  681. // inertia initialised zero here because some of bullet's collision
  682. // shapes incorrectly do not set the vector in calculateLocalIntertia.
  683. // Arbitrary zero is preferable to undefined behaviour.
  684. btVector3 inertia(0, 0, 0);
  685. if (EMPTY_SHAPE_PROXYTYPE != mainShape->getShapeType()) { // Necessary to avoid assertion of the empty shape
  686. mainShape->calculateLocalInertia(mass, inertia);
  687. }
  688. btBody->setMassProps(mass, inertia);
  689. }
  690. btBody->updateInertiaTensor();
  691. reload_kinematic_shapes();
  692. set_continuous_collision_detection(is_continuous_collision_detection_enabled());
  693. reload_body();
  694. }
  695. void RigidBodyBullet::on_enter_area(AreaBullet *p_area) {
  696. /// Add this area to the array in an ordered way
  697. ++areaWhereIamCount;
  698. if (areaWhereIamCount >= maxAreasWhereIam) {
  699. --areaWhereIamCount;
  700. return;
  701. }
  702. for (int i = 0; i < areaWhereIamCount; ++i) {
  703. if (nullptr == areasWhereIam[i]) {
  704. // This area has the highest priority
  705. areasWhereIam.write[i] = p_area;
  706. break;
  707. } else {
  708. if (areasWhereIam[i]->get_spOv_priority() > p_area->get_spOv_priority()) {
  709. // The position was found, just shift all elements
  710. for (int j = areaWhereIamCount; j > i; j--) {
  711. areasWhereIam.write[j] = areasWhereIam[j - 1];
  712. }
  713. areasWhereIam.write[i] = p_area;
  714. break;
  715. }
  716. }
  717. }
  718. if (PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED != p_area->get_spOv_mode()) {
  719. scratch_space_override_modificator();
  720. }
  721. if (p_area->is_spOv_gravityPoint()) {
  722. ++countGravityPointSpaces;
  723. ERR_FAIL_COND(countGravityPointSpaces <= 0);
  724. }
  725. }
  726. void RigidBodyBullet::on_exit_area(AreaBullet *p_area) {
  727. RigidCollisionObjectBullet::on_exit_area(p_area);
  728. /// Remove this area and keep the order
  729. /// N.B. Since I don't want resize the array I can't use the "erase" function
  730. bool wasTheAreaFound = false;
  731. for (int i = 0; i < areaWhereIamCount; ++i) {
  732. if (p_area == areasWhereIam[i]) {
  733. // The area was found, just shift down all elements
  734. for (int j = i; j < areaWhereIamCount; ++j) {
  735. areasWhereIam.write[j] = areasWhereIam[j + 1];
  736. }
  737. wasTheAreaFound = true;
  738. break;
  739. }
  740. }
  741. if (wasTheAreaFound) {
  742. if (p_area->is_spOv_gravityPoint()) {
  743. --countGravityPointSpaces;
  744. ERR_FAIL_COND(countGravityPointSpaces < 0);
  745. }
  746. --areaWhereIamCount;
  747. areasWhereIam.write[areaWhereIamCount] = nullptr; // Even if this is not required, I clear the last element to be safe
  748. if (PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED != p_area->get_spOv_mode()) {
  749. scratch_space_override_modificator();
  750. }
  751. }
  752. }
  753. void RigidBodyBullet::reload_space_override_modificator() {
  754. if (mode == PhysicsServer3D::BODY_MODE_STATIC) {
  755. return;
  756. }
  757. Vector3 newGravity(0.0, 0.0, 0.0);
  758. real_t newLinearDamp = MAX(0.0, linearDamp);
  759. real_t newAngularDamp = MAX(0.0, angularDamp);
  760. AreaBullet *currentArea;
  761. // Variable used to calculate new gravity for gravity point areas, it is pointed by currentGravity pointer
  762. Vector3 support_gravity(0, 0, 0);
  763. bool stopped = false;
  764. for (int i = areaWhereIamCount - 1; (0 <= i) && !stopped; --i) {
  765. currentArea = areasWhereIam[i];
  766. if (!currentArea || PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED == currentArea->get_spOv_mode()) {
  767. continue;
  768. }
  769. /// Here is calculated the gravity
  770. if (currentArea->is_spOv_gravityPoint()) {
  771. /// It calculates the direction of new gravity
  772. support_gravity = currentArea->get_transform().xform(currentArea->get_spOv_gravityVec()) - get_transform().get_origin();
  773. real_t distanceMag = support_gravity.length();
  774. // Normalized in this way to avoid the double call of function "length()"
  775. if (distanceMag == 0) {
  776. support_gravity.x = 0;
  777. support_gravity.y = 0;
  778. support_gravity.z = 0;
  779. } else {
  780. support_gravity.x /= distanceMag;
  781. support_gravity.y /= distanceMag;
  782. support_gravity.z /= distanceMag;
  783. }
  784. /// Here is calculated the final gravity
  785. if (currentArea->get_spOv_gravityPointDistanceScale() > 0) {
  786. // Scaled gravity by distance
  787. support_gravity *= currentArea->get_spOv_gravityMag() / Math::pow(distanceMag * currentArea->get_spOv_gravityPointDistanceScale() + 1, 2);
  788. } else {
  789. // Unscaled gravity
  790. support_gravity *= currentArea->get_spOv_gravityMag();
  791. }
  792. } else {
  793. support_gravity = currentArea->get_spOv_gravityVec() * currentArea->get_spOv_gravityMag();
  794. }
  795. switch (currentArea->get_spOv_mode()) {
  796. case PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED:
  797. /// This area does not affect gravity/damp. These are generally areas
  798. /// that exist only to detect collisions, and objects entering or exiting them.
  799. break;
  800. case PhysicsServer3D::AREA_SPACE_OVERRIDE_COMBINE:
  801. /// This area adds its gravity/damp values to whatever has been
  802. /// calculated so far. This way, many overlapping areas can combine
  803. /// their physics to make interesting
  804. newGravity += support_gravity;
  805. newLinearDamp += currentArea->get_spOv_linearDamp();
  806. newAngularDamp += currentArea->get_spOv_angularDamp();
  807. break;
  808. case PhysicsServer3D::AREA_SPACE_OVERRIDE_COMBINE_REPLACE:
  809. /// This area adds its gravity/damp values to whatever has been calculated
  810. /// so far. Then stops taking into account the rest of the areas, even the
  811. /// default one.
  812. newGravity += support_gravity;
  813. newLinearDamp += currentArea->get_spOv_linearDamp();
  814. newAngularDamp += currentArea->get_spOv_angularDamp();
  815. stopped = true;
  816. break;
  817. case PhysicsServer3D::AREA_SPACE_OVERRIDE_REPLACE:
  818. /// This area replaces any gravity/damp, even the default one, and
  819. /// stops taking into account the rest of the areas.
  820. newGravity = support_gravity;
  821. newLinearDamp = currentArea->get_spOv_linearDamp();
  822. newAngularDamp = currentArea->get_spOv_angularDamp();
  823. stopped = true;
  824. break;
  825. case PhysicsServer3D::AREA_SPACE_OVERRIDE_REPLACE_COMBINE:
  826. /// This area replaces any gravity/damp calculated so far, but keeps
  827. /// calculating the rest of the areas, down to the default one.
  828. newGravity = support_gravity;
  829. newLinearDamp = currentArea->get_spOv_linearDamp();
  830. newAngularDamp = currentArea->get_spOv_angularDamp();
  831. break;
  832. }
  833. }
  834. // Add default gravity and damping from space.
  835. if (!stopped) {
  836. newGravity += space->get_gravity_direction() * space->get_gravity_magnitude();
  837. newLinearDamp += space->get_linear_damp();
  838. newAngularDamp += space->get_angular_damp();
  839. }
  840. btVector3 newBtGravity;
  841. G_TO_B(newGravity * gravity_scale, newBtGravity);
  842. btBody->setGravity(newBtGravity);
  843. btBody->setDamping(newLinearDamp, newAngularDamp);
  844. }
  845. void RigidBodyBullet::reload_kinematic_shapes() {
  846. if (!kinematic_utilities) {
  847. return;
  848. }
  849. kinematic_utilities->copyAllOwnerShapes();
  850. }
  851. void RigidBodyBullet::notify_transform_changed() {
  852. RigidCollisionObjectBullet::notify_transform_changed();
  853. can_integrate_forces = true;
  854. }
  855. void RigidBodyBullet::_internal_set_mass(real_t p_mass) {
  856. btVector3 localInertia(0, 0, 0);
  857. int clearedCurrentFlags = btBody->getCollisionFlags();
  858. clearedCurrentFlags &= ~(btCollisionObject::CF_KINEMATIC_OBJECT | btCollisionObject::CF_STATIC_OBJECT | btCollisionObject::CF_CHARACTER_OBJECT);
  859. // Rigidbody is dynamic if and only if mass is non Zero, otherwise static
  860. const bool isDynamic = p_mass != 0.f;
  861. if (isDynamic) {
  862. if (PhysicsServer3D::BODY_MODE_DYNAMIC != mode && PhysicsServer3D::MODE_DYNAMIC_LINEAR != mode) {
  863. return;
  864. }
  865. m_isStatic = false;
  866. if (mainShape) {
  867. mainShape->calculateLocalInertia(p_mass, localInertia);
  868. }
  869. if (PhysicsServer3D::BODY_MODE_DYNAMIC == mode) {
  870. btBody->setCollisionFlags(clearedCurrentFlags); // Just set the flags without Kin and Static
  871. } else {
  872. btBody->setCollisionFlags(clearedCurrentFlags | btCollisionObject::CF_CHARACTER_OBJECT);
  873. }
  874. if (can_sleep) {
  875. btBody->forceActivationState(ACTIVE_TAG); // ACTIVE_TAG 1
  876. } else {
  877. btBody->forceActivationState(DISABLE_DEACTIVATION); // DISABLE_DEACTIVATION 4
  878. }
  879. } else {
  880. if (PhysicsServer3D::BODY_MODE_STATIC != mode && PhysicsServer3D::BODY_MODE_KINEMATIC != mode) {
  881. return;
  882. }
  883. m_isStatic = true;
  884. if (PhysicsServer3D::BODY_MODE_STATIC == mode) {
  885. btBody->setCollisionFlags(clearedCurrentFlags | btCollisionObject::CF_STATIC_OBJECT);
  886. } else {
  887. btBody->setCollisionFlags(clearedCurrentFlags | btCollisionObject::CF_KINEMATIC_OBJECT);
  888. set_transform__bullet(btBody->getWorldTransform()); // Set current Transform using kinematic method
  889. }
  890. btBody->forceActivationState(DISABLE_SIMULATION); // DISABLE_SIMULATION 5
  891. }
  892. btBody->setMassProps(p_mass, localInertia);
  893. btBody->updateInertiaTensor();
  894. reload_body();
  895. }