ObjectLayerPairFilterTable.h 2.7 KB

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