jolt_layers.cpp 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. /**************************************************************************/
  2. /* jolt_layers.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_layers.h"
  31. #include "../jolt_project_settings.h"
  32. #include "jolt_broad_phase_layer.h"
  33. #include "core/error/error_macros.h"
  34. #include "core/variant/variant.h"
  35. static_assert(sizeof(JPH::ObjectLayer) == 2, "Size of Jolt's object layer has changed.");
  36. static_assert(sizeof(JPH::BroadPhaseLayer::Type) == 1, "Size of Jolt's broadphase layer has changed.");
  37. static_assert(JoltBroadPhaseLayer::COUNT <= 8, "Maximum number of broadphase layers exceeded.");
  38. namespace {
  39. template <uint8_t TSize = JoltBroadPhaseLayer::COUNT>
  40. class JoltBroadPhaseMatrix {
  41. typedef JPH::BroadPhaseLayer LayerType;
  42. typedef LayerType::Type UnderlyingType;
  43. public:
  44. JoltBroadPhaseMatrix() {
  45. using namespace JoltBroadPhaseLayer;
  46. allow_collision(BODY_STATIC, BODY_DYNAMIC);
  47. allow_collision(BODY_STATIC_BIG, BODY_DYNAMIC);
  48. allow_collision(BODY_DYNAMIC, BODY_STATIC);
  49. allow_collision(BODY_DYNAMIC, BODY_STATIC_BIG);
  50. allow_collision(BODY_DYNAMIC, BODY_DYNAMIC);
  51. allow_collision(BODY_DYNAMIC, AREA_DETECTABLE);
  52. allow_collision(BODY_DYNAMIC, AREA_UNDETECTABLE);
  53. allow_collision(AREA_DETECTABLE, BODY_DYNAMIC);
  54. allow_collision(AREA_DETECTABLE, AREA_DETECTABLE);
  55. allow_collision(AREA_DETECTABLE, AREA_UNDETECTABLE);
  56. allow_collision(AREA_UNDETECTABLE, BODY_DYNAMIC);
  57. allow_collision(AREA_UNDETECTABLE, AREA_DETECTABLE);
  58. if (JoltProjectSettings::areas_detect_static_bodies()) {
  59. allow_collision(BODY_STATIC, AREA_DETECTABLE);
  60. allow_collision(BODY_STATIC, AREA_UNDETECTABLE);
  61. allow_collision(BODY_STATIC_BIG, AREA_DETECTABLE);
  62. allow_collision(BODY_STATIC_BIG, AREA_UNDETECTABLE);
  63. allow_collision(AREA_DETECTABLE, BODY_STATIC);
  64. allow_collision(AREA_DETECTABLE, BODY_STATIC_BIG);
  65. allow_collision(AREA_UNDETECTABLE, BODY_STATIC);
  66. allow_collision(AREA_UNDETECTABLE, BODY_STATIC_BIG);
  67. }
  68. }
  69. void allow_collision(UnderlyingType p_layer1, UnderlyingType p_layer2) { masks[p_layer1] |= uint8_t(1U << p_layer2); }
  70. void allow_collision(LayerType p_layer1, LayerType p_layer2) { allow_collision((UnderlyingType)p_layer1, (UnderlyingType)p_layer2); }
  71. bool should_collide(UnderlyingType p_layer1, UnderlyingType p_layer2) const { return (masks[p_layer1] & uint8_t(1U << p_layer2)) != 0; }
  72. bool should_collide(LayerType p_layer1, LayerType p_layer2) const { return should_collide((UnderlyingType)p_layer1, (UnderlyingType)p_layer2); }
  73. private:
  74. uint8_t masks[TSize] = {};
  75. };
  76. constexpr JPH::ObjectLayer encode_layers(JPH::BroadPhaseLayer p_broad_phase_layer, JPH::ObjectLayer p_object_layer) {
  77. const uint16_t upper_bits = uint16_t((uint8_t)p_broad_phase_layer << 13U);
  78. const uint16_t lower_bits = uint16_t(p_object_layer);
  79. return JPH::ObjectLayer(upper_bits | lower_bits);
  80. }
  81. constexpr void decode_layers(JPH::ObjectLayer p_encoded_layers, JPH::BroadPhaseLayer &r_broad_phase_layer, JPH::ObjectLayer &r_object_layer) {
  82. r_broad_phase_layer = JPH::BroadPhaseLayer(uint8_t(p_encoded_layers >> 13U));
  83. r_object_layer = JPH::ObjectLayer(p_encoded_layers & 0b0001'1111'1111'1111U);
  84. }
  85. constexpr uint64_t encode_collision(uint32_t p_collision_layer, uint32_t p_collision_mask) {
  86. const uint64_t upper_bits = (uint64_t)p_collision_layer << 32U;
  87. const uint64_t lower_bits = (uint64_t)p_collision_mask;
  88. return upper_bits | lower_bits;
  89. }
  90. constexpr void decode_collision(uint64_t p_collision, uint32_t &r_collision_layer, uint32_t &r_collision_mask) {
  91. r_collision_layer = uint32_t(p_collision >> 32U);
  92. r_collision_mask = uint32_t(p_collision & 0xFFFFFFFFU);
  93. }
  94. } // namespace
  95. uint32_t JoltLayers::GetNumBroadPhaseLayers() const {
  96. return JoltBroadPhaseLayer::COUNT;
  97. }
  98. JPH::BroadPhaseLayer JoltLayers::GetBroadPhaseLayer(JPH::ObjectLayer p_layer) const {
  99. JPH::BroadPhaseLayer broad_phase_layer = JoltBroadPhaseLayer::BODY_STATIC;
  100. JPH::ObjectLayer object_layer = 0;
  101. decode_layers(p_layer, broad_phase_layer, object_layer);
  102. return broad_phase_layer;
  103. }
  104. #if defined(JPH_EXTERNAL_PROFILE) || defined(JPH_PROFILE_ENABLED)
  105. const char *JoltLayers::GetBroadPhaseLayerName(JPH::BroadPhaseLayer p_layer) const {
  106. switch ((JPH::BroadPhaseLayer::Type)p_layer) {
  107. case (JPH::BroadPhaseLayer::Type)JoltBroadPhaseLayer::BODY_STATIC: {
  108. return "BODY_STATIC";
  109. }
  110. case (JPH::BroadPhaseLayer::Type)JoltBroadPhaseLayer::BODY_STATIC_BIG: {
  111. return "BODY_STATIC_BIG";
  112. }
  113. case (JPH::BroadPhaseLayer::Type)JoltBroadPhaseLayer::BODY_DYNAMIC: {
  114. return "BODY_DYNAMIC";
  115. }
  116. case (JPH::BroadPhaseLayer::Type)JoltBroadPhaseLayer::AREA_DETECTABLE: {
  117. return "AREA_DETECTABLE";
  118. }
  119. case (JPH::BroadPhaseLayer::Type)JoltBroadPhaseLayer::AREA_UNDETECTABLE: {
  120. return "AREA_UNDETECTABLE";
  121. }
  122. default: {
  123. return "UNKNOWN";
  124. }
  125. }
  126. }
  127. #endif
  128. bool JoltLayers::ShouldCollide(JPH::ObjectLayer p_encoded_layer1, JPH::ObjectLayer p_encoded_layer2) const {
  129. JPH::BroadPhaseLayer broad_phase_layer1 = JoltBroadPhaseLayer::BODY_STATIC;
  130. uint32_t collision_layer1 = 0;
  131. uint32_t collision_mask1 = 0;
  132. from_object_layer(p_encoded_layer1, broad_phase_layer1, collision_layer1, collision_mask1);
  133. JPH::BroadPhaseLayer broad_phase_layer2 = JoltBroadPhaseLayer::BODY_STATIC;
  134. uint32_t collision_layer2 = 0;
  135. uint32_t collision_mask2 = 0;
  136. from_object_layer(p_encoded_layer2, broad_phase_layer2, collision_layer2, collision_mask2);
  137. const bool first_scans_second = (collision_mask1 & collision_layer2) != 0;
  138. const bool second_scans_first = (collision_mask2 & collision_layer1) != 0;
  139. return first_scans_second || second_scans_first;
  140. }
  141. bool JoltLayers::ShouldCollide(JPH::ObjectLayer p_encoded_layer1, JPH::BroadPhaseLayer p_broad_phase_layer2) const {
  142. static const JoltBroadPhaseMatrix matrix;
  143. JPH::BroadPhaseLayer broad_phase_layer1 = JoltBroadPhaseLayer::BODY_STATIC;
  144. JPH::ObjectLayer object_layer1 = 0;
  145. decode_layers(p_encoded_layer1, broad_phase_layer1, object_layer1);
  146. return matrix.should_collide(broad_phase_layer1, p_broad_phase_layer2);
  147. }
  148. JPH::ObjectLayer JoltLayers::_allocate_object_layer(uint64_t p_collision) {
  149. const JPH::ObjectLayer new_object_layer = next_object_layer++;
  150. collisions_by_layer.resize(new_object_layer + 1);
  151. collisions_by_layer[new_object_layer] = p_collision;
  152. layers_by_collision[p_collision] = new_object_layer;
  153. return new_object_layer;
  154. }
  155. JoltLayers::JoltLayers() {
  156. _allocate_object_layer(0);
  157. }
  158. // MinGW GCC using LTO will emit errors during linking if this is defined in the header file, implicitly or otherwise.
  159. // Likely caused by this GCC bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94156
  160. JoltLayers::~JoltLayers() = default;
  161. JPH::ObjectLayer JoltLayers::to_object_layer(JPH::BroadPhaseLayer p_broad_phase_layer, uint32_t p_collision_layer, uint32_t p_collision_mask) {
  162. const uint64_t collision = encode_collision(p_collision_layer, p_collision_mask);
  163. JPH::ObjectLayer object_layer = 0;
  164. HashMap<uint64_t, JPH::ObjectLayer>::Iterator iter = layers_by_collision.find(collision);
  165. if (iter != layers_by_collision.end()) {
  166. object_layer = iter->value;
  167. } else {
  168. constexpr uint16_t object_layer_count = 1U << 13U;
  169. ERR_FAIL_COND_V_MSG(next_object_layer == object_layer_count, 0,
  170. vformat("Maximum number of object layers (%d) reached. "
  171. "This means there are %d combinations of collision layers and masks."
  172. "This should not happen under normal circumstances. Consider reporting this.",
  173. object_layer_count, object_layer_count));
  174. object_layer = _allocate_object_layer(collision);
  175. }
  176. return encode_layers(p_broad_phase_layer, object_layer);
  177. }
  178. void JoltLayers::from_object_layer(JPH::ObjectLayer p_encoded_layer, JPH::BroadPhaseLayer &r_broad_phase_layer, uint32_t &r_collision_layer, uint32_t &r_collision_mask) const {
  179. JPH::ObjectLayer object_layer = 0;
  180. decode_layers(p_encoded_layer, r_broad_phase_layer, object_layer);
  181. const uint64_t collision = collisions_by_layer[object_layer];
  182. decode_collision(collision, r_collision_layer, r_collision_mask);
  183. }