collision_object_bullet.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. /*************************************************************************/
  2. /* collision_object_bullet.cpp */
  3. /* Author: AndreaCatania */
  4. /*************************************************************************/
  5. /* This file is part of: */
  6. /* GODOT ENGINE */
  7. /* http://www.godotengine.org */
  8. /*************************************************************************/
  9. /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
  10. /* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
  11. /* */
  12. /* Permission is hereby granted, free of charge, to any person obtaining */
  13. /* a copy of this software and associated documentation files (the */
  14. /* "Software"), to deal in the Software without restriction, including */
  15. /* without limitation the rights to use, copy, modify, merge, publish, */
  16. /* distribute, sublicense, and/or sell copies of the Software, and to */
  17. /* permit persons to whom the Software is furnished to do so, subject to */
  18. /* the following conditions: */
  19. /* */
  20. /* The above copyright notice and this permission notice shall be */
  21. /* included in all copies or substantial portions of the Software. */
  22. /* */
  23. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
  24. /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
  25. /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
  26. /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
  27. /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
  28. /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
  29. /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  30. /*************************************************************************/
  31. #include "collision_object_bullet.h"
  32. #include "area_bullet.h"
  33. #include "btBulletCollisionCommon.h"
  34. #include "bullet_physics_server.h"
  35. #include "bullet_types_converter.h"
  36. #include "bullet_utilities.h"
  37. #include "shape_bullet.h"
  38. #include "space_bullet.h"
  39. #define enableDynamicAabbTree true
  40. #define initialChildCapacity 1
  41. CollisionObjectBullet::ShapeWrapper::~ShapeWrapper() {}
  42. void CollisionObjectBullet::ShapeWrapper::set_transform(const Transform &p_transform) {
  43. G_TO_B(p_transform, transform);
  44. }
  45. void CollisionObjectBullet::ShapeWrapper::set_transform(const btTransform &p_transform) {
  46. transform = p_transform;
  47. }
  48. CollisionObjectBullet::CollisionObjectBullet(Type p_type)
  49. : RIDBullet(), space(NULL), type(p_type), collisionsEnabled(true), m_isStatic(false), bt_collision_object(NULL), body_scale(1., 1., 1.) {}
  50. CollisionObjectBullet::~CollisionObjectBullet() {
  51. // Remove all overlapping
  52. for (int i = areasOverlapped.size() - 1; 0 <= i; --i) {
  53. areasOverlapped[i]->remove_overlapping_instantly(this);
  54. }
  55. // not required
  56. // areasOverlapped.clear();
  57. destroyBulletCollisionObject();
  58. }
  59. bool equal(real_t first, real_t second) {
  60. return Math::abs(first - second) <= 0.001f;
  61. }
  62. void CollisionObjectBullet::set_body_scale(const Vector3 &p_new_scale) {
  63. if (!equal(p_new_scale[0], body_scale[0]) || !equal(p_new_scale[1], body_scale[1]) || !equal(p_new_scale[2], body_scale[2])) {
  64. G_TO_B(p_new_scale, body_scale);
  65. on_body_scale_changed();
  66. }
  67. }
  68. void CollisionObjectBullet::on_body_scale_changed() {
  69. }
  70. void CollisionObjectBullet::destroyBulletCollisionObject() {
  71. bulletdelete(bt_collision_object);
  72. }
  73. void CollisionObjectBullet::setupBulletCollisionObject(btCollisionObject *p_collisionObject) {
  74. bt_collision_object = p_collisionObject;
  75. bt_collision_object->setUserPointer(this);
  76. bt_collision_object->setUserIndex(type);
  77. // Force the enabling of collision and avoid problems
  78. set_collision_enabled(collisionsEnabled);
  79. }
  80. void CollisionObjectBullet::add_collision_exception(const CollisionObjectBullet *p_ignoreCollisionObject) {
  81. exceptions.insert(p_ignoreCollisionObject->get_self());
  82. bt_collision_object->setIgnoreCollisionCheck(p_ignoreCollisionObject->bt_collision_object, true);
  83. }
  84. void CollisionObjectBullet::remove_collision_exception(const CollisionObjectBullet *p_ignoreCollisionObject) {
  85. exceptions.erase(p_ignoreCollisionObject->get_self());
  86. bt_collision_object->setIgnoreCollisionCheck(p_ignoreCollisionObject->bt_collision_object, false);
  87. }
  88. bool CollisionObjectBullet::has_collision_exception(const CollisionObjectBullet *p_otherCollisionObject) const {
  89. return !bt_collision_object->checkCollideWithOverride(p_otherCollisionObject->bt_collision_object);
  90. }
  91. void CollisionObjectBullet::set_collision_enabled(bool p_enabled) {
  92. collisionsEnabled = p_enabled;
  93. if (collisionsEnabled) {
  94. bt_collision_object->setCollisionFlags(bt_collision_object->getCollisionFlags() & (~btCollisionObject::CF_NO_CONTACT_RESPONSE));
  95. } else {
  96. bt_collision_object->setCollisionFlags(bt_collision_object->getCollisionFlags() | btCollisionObject::CF_NO_CONTACT_RESPONSE);
  97. }
  98. }
  99. bool CollisionObjectBullet::is_collisions_response_enabled() {
  100. return collisionsEnabled;
  101. }
  102. void CollisionObjectBullet::notify_new_overlap(AreaBullet *p_area) {
  103. areasOverlapped.push_back(p_area);
  104. }
  105. void CollisionObjectBullet::on_exit_area(AreaBullet *p_area) {
  106. areasOverlapped.erase(p_area);
  107. }
  108. void CollisionObjectBullet::set_godot_object_flags(int flags) {
  109. bt_collision_object->setUserIndex2(flags);
  110. }
  111. int CollisionObjectBullet::get_godot_object_flags() const {
  112. return bt_collision_object->getUserIndex2();
  113. }
  114. void CollisionObjectBullet::set_transform(const Transform &p_global_transform) {
  115. btTransform btTrans;
  116. Basis decomposed_basis;
  117. Vector3 decomposed_scale = p_global_transform.get_basis().rotref_posscale_decomposition(decomposed_basis);
  118. G_TO_B(p_global_transform.get_origin(), btTrans.getOrigin());
  119. G_TO_B(decomposed_basis, btTrans.getBasis());
  120. set_body_scale(decomposed_scale);
  121. set_transform__bullet(btTrans);
  122. }
  123. Transform CollisionObjectBullet::get_transform() const {
  124. Transform t;
  125. B_TO_G(get_transform__bullet(), t);
  126. return t;
  127. }
  128. void CollisionObjectBullet::set_transform__bullet(const btTransform &p_global_transform) {
  129. bt_collision_object->setWorldTransform(p_global_transform);
  130. }
  131. const btTransform &CollisionObjectBullet::get_transform__bullet() const {
  132. return bt_collision_object->getWorldTransform();
  133. }
  134. RigidCollisionObjectBullet::RigidCollisionObjectBullet(Type p_type)
  135. : CollisionObjectBullet(p_type), compoundShape(bulletnew(btCompoundShape(enableDynamicAabbTree, initialChildCapacity))) {
  136. }
  137. RigidCollisionObjectBullet::~RigidCollisionObjectBullet() {
  138. remove_all_shapes(true);
  139. bt_collision_object->setCollisionShape(NULL);
  140. bulletdelete(compoundShape);
  141. }
  142. /* Not used
  143. void RigidCollisionObjectBullet::_internal_replaceShape(btCollisionShape *p_old_shape, btCollisionShape *p_new_shape) {
  144. bool at_least_one_was_changed = false;
  145. btTransform old_transf;
  146. // Inverse because I need remove the shapes
  147. // Fetch all shapes to be sure to remove all shapes
  148. for (int i = compoundShape->getNumChildShapes() - 1; 0 <= i; --i) {
  149. if (compoundShape->getChildShape(i) == p_old_shape) {
  150. old_transf = compoundShape->getChildTransform(i);
  151. compoundShape->removeChildShapeByIndex(i);
  152. compoundShape->addChildShape(old_transf, p_new_shape);
  153. at_least_one_was_changed = true;
  154. }
  155. }
  156. if (at_least_one_was_changed) {
  157. on_shapes_changed();
  158. }
  159. }*/
  160. void RigidCollisionObjectBullet::add_shape(ShapeBullet *p_shape, const Transform &p_transform) {
  161. shapes.push_back(ShapeWrapper(p_shape, p_transform, true));
  162. p_shape->add_owner(this);
  163. on_shapes_changed();
  164. }
  165. void RigidCollisionObjectBullet::set_shape(int p_index, ShapeBullet *p_shape) {
  166. ShapeWrapper &shp = shapes[p_index];
  167. shp.shape->remove_owner(this);
  168. p_shape->add_owner(this);
  169. shp.shape = p_shape;
  170. on_shapes_changed();
  171. }
  172. void RigidCollisionObjectBullet::set_shape_transform(int p_index, const Transform &p_transform) {
  173. ERR_FAIL_INDEX(p_index, get_shape_count());
  174. shapes[p_index].set_transform(p_transform);
  175. on_shapes_changed();
  176. }
  177. void RigidCollisionObjectBullet::remove_shape(ShapeBullet *p_shape) {
  178. // Remove the shape, all the times it appears
  179. // Reverse order required for delete.
  180. for (int i = shapes.size() - 1; 0 <= i; --i) {
  181. if (p_shape == shapes[i].shape) {
  182. internal_shape_destroy(i);
  183. shapes.remove(i);
  184. }
  185. }
  186. on_shapes_changed();
  187. }
  188. void RigidCollisionObjectBullet::remove_shape(int p_index) {
  189. ERR_FAIL_INDEX(p_index, get_shape_count());
  190. internal_shape_destroy(p_index);
  191. shapes.remove(p_index);
  192. on_shapes_changed();
  193. }
  194. void RigidCollisionObjectBullet::remove_all_shapes(bool p_permanentlyFromThisBody) {
  195. // Reverse order required for delete.
  196. for (int i = shapes.size() - 1; 0 <= i; --i) {
  197. internal_shape_destroy(i, p_permanentlyFromThisBody);
  198. }
  199. shapes.clear();
  200. on_shapes_changed();
  201. }
  202. int RigidCollisionObjectBullet::get_shape_count() const {
  203. return shapes.size();
  204. }
  205. ShapeBullet *RigidCollisionObjectBullet::get_shape(int p_index) const {
  206. return shapes[p_index].shape;
  207. }
  208. btCollisionShape *RigidCollisionObjectBullet::get_bt_shape(int p_index) const {
  209. return shapes[p_index].bt_shape;
  210. }
  211. Transform RigidCollisionObjectBullet::get_shape_transform(int p_index) const {
  212. Transform trs;
  213. B_TO_G(shapes[p_index].transform, trs);
  214. return trs;
  215. }
  216. void RigidCollisionObjectBullet::on_shape_changed(const ShapeBullet *const p_shape) {
  217. const int size = shapes.size();
  218. for (int i = 0; i < size; ++i) {
  219. if (shapes[i].shape == p_shape) {
  220. bulletdelete(shapes[i].bt_shape);
  221. }
  222. }
  223. on_shapes_changed();
  224. }
  225. void RigidCollisionObjectBullet::on_shapes_changed() {
  226. int i;
  227. // Remove all shapes, reverse order for performance reason (Array resize)
  228. for (i = compoundShape->getNumChildShapes() - 1; 0 <= i; --i) {
  229. compoundShape->removeChildShapeByIndex(i);
  230. }
  231. // Insert all shapes
  232. ShapeWrapper *shpWrapper;
  233. const int size = shapes.size();
  234. for (i = 0; i < size; ++i) {
  235. shpWrapper = &shapes[i];
  236. if (!shpWrapper->bt_shape) {
  237. shpWrapper->bt_shape = shpWrapper->shape->create_bt_shape();
  238. }
  239. if (shpWrapper->active) {
  240. compoundShape->addChildShape(shpWrapper->transform, shpWrapper->bt_shape);
  241. } else {
  242. compoundShape->addChildShape(shpWrapper->transform, BulletPhysicsServer::get_empty_shape());
  243. }
  244. }
  245. compoundShape->setLocalScaling(body_scale);
  246. compoundShape->recalculateLocalAabb();
  247. }
  248. void RigidCollisionObjectBullet::set_shape_disabled(int p_index, bool p_disabled) {
  249. shapes[p_index].active = !p_disabled;
  250. on_shapes_changed();
  251. }
  252. bool RigidCollisionObjectBullet::is_shape_disabled(int p_index) {
  253. return !shapes[p_index].active;
  254. }
  255. void RigidCollisionObjectBullet::on_body_scale_changed() {
  256. CollisionObjectBullet::on_body_scale_changed();
  257. on_shapes_changed();
  258. }
  259. void RigidCollisionObjectBullet::internal_shape_destroy(int p_index, bool p_permanentlyFromThisBody) {
  260. ShapeWrapper &shp = shapes[p_index];
  261. shp.shape->remove_owner(this, p_permanentlyFromThisBody);
  262. bulletdelete(shp.bt_shape);
  263. }