ObjectLayerPairFilterTable.h 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. // Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
  2. // SPDX-FileCopyrightText: 2023 Jorrit Rouwe
  3. // SPDX-License-Identifier: MIT
  4. #include <Jolt/Physics/Collision/ObjectLayer.h>
  5. JPH_NAMESPACE_BEGIN
  6. /// Filter class to test if two objects can collide based on their object layer. Used while finding collision pairs.
  7. /// This implementation uses a table to determine if two layers can collide.
  8. class ObjectLayerPairFilterTable : public ObjectLayerPairFilter
  9. {
  10. private:
  11. /// Get which bit corresponds to the pair (inLayer1, inLayer2)
  12. uint GetBit(ObjectLayer inLayer1, ObjectLayer inLayer2) const
  13. {
  14. // We store the lower left half only, so swap the inputs when trying to access the top right half
  15. if (inLayer1 > inLayer2)
  16. swap(inLayer1, inLayer2);
  17. JPH_ASSERT(inLayer2 < mNumObjectLayers);
  18. // Calculate at which bit the entry for this pair resides
  19. // We use the fact that a row always starts at inLayer2 * inLayer2 / 2
  20. // (this is the amount of bits needed to store a table of inLayer2 entries)
  21. return (inLayer2 * inLayer2) / 2 + inLayer1;
  22. }
  23. public:
  24. JPH_OVERRIDE_NEW_DELETE
  25. /// Constructs the table with inNumObjectLayers Layers, initially all layer pairs are disabled
  26. explicit ObjectLayerPairFilterTable(uint inNumObjectLayers) :
  27. mNumObjectLayers(inNumObjectLayers)
  28. {
  29. // By default everything collides
  30. int table_size = (inNumObjectLayers * inNumObjectLayers / 2 + 7) / 8;
  31. mTable.resize(table_size, 0);
  32. }
  33. /// Get the number of object layers
  34. uint GetNumObjectLayers() const
  35. {
  36. return mNumObjectLayers;
  37. }
  38. /// Disable collision between two object layers
  39. void DisableCollision(ObjectLayer inLayer1, ObjectLayer inLayer2)
  40. {
  41. uint bit = GetBit(inLayer1, inLayer2);
  42. mTable[bit >> 3] &= (0xff ^ (1 << (bit & 0b111)));
  43. }
  44. /// Enable collision between two object layers
  45. void EnableCollision(ObjectLayer inLayer1, ObjectLayer inLayer2)
  46. {
  47. uint bit = GetBit(inLayer1, inLayer2);
  48. mTable[bit >> 3] |= 1 << (bit & 0b111);
  49. }
  50. /// Returns true if two layers can collide
  51. virtual bool ShouldCollide(ObjectLayer inObject1, ObjectLayer inObject2) const override
  52. {
  53. // Test if the bit is set for this group pair
  54. uint bit = GetBit(inObject1, inObject2);
  55. return (mTable[bit >> 3] & (1 << (bit & 0b111))) != 0;
  56. }
  57. private:
  58. uint mNumObjectLayers; ///< The number of layers that this table supports
  59. Array<uint8> mTable; ///< The table of bits that indicates which layers collide
  60. };
  61. JPH_NAMESPACE_END