Layers.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. // SPDX-FileCopyrightText: 2021 Jorrit Rouwe
  2. // SPDX-License-Identifier: MIT
  3. #pragma once
  4. #include <Jolt/Physics/Collision/ObjectLayer.h>
  5. #include <Jolt/Physics/Collision/BroadPhase/BroadPhaseLayer.h>
  6. /// Layer that objects can be in, determines which other objects it can collide with
  7. namespace Layers
  8. {
  9. static constexpr uint8 UNUSED1 = 0; // 5 unused values so that broadphase layers values don't match with object layer values (for testing purposes)
  10. static constexpr uint8 UNUSED2 = 1;
  11. static constexpr uint8 UNUSED3 = 2;
  12. static constexpr uint8 UNUSED4 = 3;
  13. static constexpr uint8 UNUSED5 = 4;
  14. static constexpr uint8 NON_MOVING = 5;
  15. static constexpr uint8 MOVING = 6;
  16. static constexpr uint8 HQ_DEBRIS = 7; // High quality debris collides with MOVING and NON_MOVING but not with any debris
  17. static constexpr uint8 LQ_DEBRIS = 8; // Low quality debris only collides with NON_MOVING
  18. static constexpr uint8 NUM_LAYERS = 9;
  19. };
  20. /// Function that determines if two object layers can collide
  21. inline bool ObjectCanCollide(ObjectLayer inObject1, ObjectLayer inObject2)
  22. {
  23. switch (inObject1)
  24. {
  25. case Layers::UNUSED1:
  26. case Layers::UNUSED2:
  27. case Layers::UNUSED3:
  28. case Layers::UNUSED4:
  29. case Layers::UNUSED5:
  30. return false;
  31. case Layers::NON_MOVING:
  32. return inObject2 == Layers::MOVING || inObject2 == Layers::HQ_DEBRIS || inObject2 == Layers::LQ_DEBRIS;
  33. case Layers::MOVING:
  34. return inObject2 == Layers::NON_MOVING || inObject2 == Layers::MOVING || inObject2 == Layers::HQ_DEBRIS;
  35. case Layers::HQ_DEBRIS:
  36. return inObject2 == Layers::NON_MOVING || inObject2 == Layers::MOVING;
  37. case Layers::LQ_DEBRIS:
  38. return inObject2 == Layers::NON_MOVING;
  39. default:
  40. JPH_ASSERT(false);
  41. return false;
  42. }
  43. };
  44. /// Broadphase layers
  45. namespace BroadPhaseLayers
  46. {
  47. static constexpr BroadPhaseLayer NON_MOVING(0);
  48. static constexpr BroadPhaseLayer MOVING(1);
  49. static constexpr BroadPhaseLayer LQ_DEBRIS(2);
  50. static constexpr BroadPhaseLayer UNUSED(3);
  51. static constexpr uint NUM_LAYERS(4);
  52. };
  53. /// BroadPhaseLayerInterface implementation
  54. class BPLayerInterfaceImpl final : public BroadPhaseLayerInterface
  55. {
  56. public:
  57. BPLayerInterfaceImpl()
  58. {
  59. // Create a mapping table from object to broad phase layer
  60. mObjectToBroadPhase[Layers::UNUSED1] = BroadPhaseLayers::UNUSED;
  61. mObjectToBroadPhase[Layers::UNUSED2] = BroadPhaseLayers::UNUSED;
  62. mObjectToBroadPhase[Layers::UNUSED3] = BroadPhaseLayers::UNUSED;
  63. mObjectToBroadPhase[Layers::UNUSED4] = BroadPhaseLayers::UNUSED;
  64. mObjectToBroadPhase[Layers::UNUSED5] = BroadPhaseLayers::UNUSED;
  65. mObjectToBroadPhase[Layers::NON_MOVING] = BroadPhaseLayers::NON_MOVING;
  66. mObjectToBroadPhase[Layers::MOVING] = BroadPhaseLayers::MOVING;
  67. mObjectToBroadPhase[Layers::HQ_DEBRIS] = BroadPhaseLayers::MOVING; // HQ_DEBRIS is also in the MOVING layer as an example on how to map multiple layers onto the same broadphase layer
  68. mObjectToBroadPhase[Layers::LQ_DEBRIS] = BroadPhaseLayers::LQ_DEBRIS;
  69. }
  70. virtual uint GetNumBroadPhaseLayers() const override
  71. {
  72. return BroadPhaseLayers::NUM_LAYERS;
  73. }
  74. virtual BroadPhaseLayer GetBroadPhaseLayer(ObjectLayer inLayer) const override
  75. {
  76. JPH_ASSERT(inLayer < Layers::NUM_LAYERS);
  77. return mObjectToBroadPhase[inLayer];
  78. }
  79. #if defined(JPH_EXTERNAL_PROFILE) || defined(JPH_PROFILE_ENABLED)
  80. virtual const char * GetBroadPhaseLayerName(BroadPhaseLayer inLayer) const override
  81. {
  82. switch ((BroadPhaseLayer::Type)inLayer)
  83. {
  84. case (BroadPhaseLayer::Type)BroadPhaseLayers::NON_MOVING: return "NON_MOVING";
  85. case (BroadPhaseLayer::Type)BroadPhaseLayers::MOVING: return "MOVING";
  86. case (BroadPhaseLayer::Type)BroadPhaseLayers::LQ_DEBRIS: return "LQ_DEBRIS";
  87. case (BroadPhaseLayer::Type)BroadPhaseLayers::UNUSED: return "UNUSED";
  88. default: JPH_ASSERT(false); return "INVALID";
  89. }
  90. }
  91. #endif // JPH_EXTERNAL_PROFILE || JPH_PROFILE_ENABLED
  92. private:
  93. BroadPhaseLayer mObjectToBroadPhase[Layers::NUM_LAYERS];
  94. };
  95. /// Function that determines if two broadphase layers can collide
  96. inline bool BroadPhaseCanCollide(ObjectLayer inLayer1, BroadPhaseLayer inLayer2)
  97. {
  98. switch (inLayer1)
  99. {
  100. case Layers::NON_MOVING:
  101. return inLayer2 == BroadPhaseLayers::MOVING;
  102. case Layers::MOVING:
  103. case Layers::HQ_DEBRIS:
  104. return inLayer2 == BroadPhaseLayers::NON_MOVING || inLayer2 == BroadPhaseLayers::MOVING;
  105. case Layers::LQ_DEBRIS:
  106. return inLayer2 == BroadPhaseLayers::NON_MOVING;
  107. case Layers::UNUSED1:
  108. case Layers::UNUSED2:
  109. case Layers::UNUSED3:
  110. case Layers::UNUSED4:
  111. case Layers::UNUSED5:
  112. return false;
  113. default:
  114. JPH_ASSERT(false);
  115. return false;
  116. }
  117. }