2
0

ObjectLayerPairFilterTable.h 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  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 + 1) / 2
  20. // (this is the amount of bits needed to store a table of inLayer2 entries)
  21. return (inLayer2 * (inLayer2 + 1)) / 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 nothing collides
  30. // For the first layer we only need to store 1 bit, for the second 2 bits, for the third 3 bits, etc.
  31. // We use the formula Sum_i=1^N i = N * (N + 1) / 2 to calculate the size of the table
  32. int table_size = (inNumObjectLayers * (inNumObjectLayers + 1) / 2 + 7) / 8;
  33. mTable.resize(table_size, 0);
  34. }
  35. /// Get the number of object layers
  36. uint GetNumObjectLayers() const
  37. {
  38. return mNumObjectLayers;
  39. }
  40. /// Disable collision between two object layers
  41. void DisableCollision(ObjectLayer inLayer1, ObjectLayer inLayer2)
  42. {
  43. uint bit = GetBit(inLayer1, inLayer2);
  44. mTable[bit >> 3] &= (0xff ^ (1 << (bit & 0b111)));
  45. }
  46. /// Enable collision between two object layers
  47. void EnableCollision(ObjectLayer inLayer1, ObjectLayer inLayer2)
  48. {
  49. uint bit = GetBit(inLayer1, inLayer2);
  50. mTable[bit >> 3] |= 1 << (bit & 0b111);
  51. }
  52. /// Returns true if two layers can collide
  53. virtual bool ShouldCollide(ObjectLayer inObject1, ObjectLayer inObject2) const override
  54. {
  55. // Test if the bit is set for this group pair
  56. uint bit = GetBit(inObject1, inObject2);
  57. return (mTable[bit >> 3] & (1 << (bit & 0b111))) != 0;
  58. }
  59. private:
  60. uint mNumObjectLayers; ///< The number of layers that this table supports
  61. Array<uint8> mTable; ///< The table of bits that indicates which layers collide
  62. };
  63. JPH_NAMESPACE_END