BroadPhaseLayerInterfaceMask.h 3.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  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/BroadPhase/BroadPhaseLayer.h>
  6. #include <Jolt/Physics/Collision/ObjectLayerPairFilterMask.h>
  7. JPH_NAMESPACE_BEGIN
  8. /// BroadPhaseLayerInterface implementation.
  9. /// This defines a mapping between object and broadphase layers.
  10. /// This implementation works together with ObjectLayerPairFilterMask and ObjectVsBroadPhaseLayerFilterMask.
  11. /// A broadphase layer is suitable for an object if its group & inGroupsToInclude is not zero and its group & inGroupsToExclude is zero.
  12. /// The broadphase layers are iterated from lowest to highest value and the first one that matches is taken. If none match then it takes the last layer.
  13. class BroadPhaseLayerInterfaceMask : public BroadPhaseLayerInterface
  14. {
  15. public:
  16. JPH_OVERRIDE_NEW_DELETE
  17. explicit BroadPhaseLayerInterfaceMask(uint inNumBroadPhaseLayers)
  18. {
  19. JPH_ASSERT(inNumBroadPhaseLayers > 0);
  20. mMapping.resize(inNumBroadPhaseLayers);
  21. #if defined(JPH_EXTERNAL_PROFILE) || defined(JPH_PROFILE_ENABLED)
  22. mBroadPhaseLayerNames.resize(inNumBroadPhaseLayers, "Undefined");
  23. #endif // JPH_EXTERNAL_PROFILE || JPH_PROFILE_ENABLED
  24. }
  25. // Configures a broadphase layer.
  26. void ConfigureLayer(BroadPhaseLayer inBroadPhaseLayer, uint32 inGroupsToInclude, uint32 inGroupsToExclude)
  27. {
  28. JPH_ASSERT((BroadPhaseLayer::Type)inBroadPhaseLayer < (uint)mMapping.size());
  29. Mapping &m = mMapping[(BroadPhaseLayer::Type)inBroadPhaseLayer];
  30. m.mGroupsToInclude = inGroupsToInclude;
  31. m.mGroupsToExclude = inGroupsToExclude;
  32. }
  33. virtual uint GetNumBroadPhaseLayers() const override
  34. {
  35. return (uint)mMapping.size();
  36. }
  37. virtual BroadPhaseLayer GetBroadPhaseLayer(ObjectLayer inLayer) const override
  38. {
  39. // Try to find the first broadphase layer that matches
  40. uint32 group = ObjectLayerPairFilterMask::sGetGroup(inLayer);
  41. for (const Mapping &m : mMapping)
  42. if ((group & m.mGroupsToInclude) != 0 && (group & m.mGroupsToExclude) == 0)
  43. return BroadPhaseLayer(BroadPhaseLayer::Type(&m - mMapping.data()));
  44. // Fall back to the last broadphase layer
  45. return BroadPhaseLayer(BroadPhaseLayer::Type(mMapping.size() - 1));
  46. }
  47. /// Returns true if an object layer should collide with a broadphase layer, this function is being called from ObjectVsBroadPhaseLayerFilterMask
  48. inline bool ShouldCollide(ObjectLayer inLayer1, BroadPhaseLayer inLayer2) const
  49. {
  50. uint32 mask = ObjectLayerPairFilterMask::sGetMask(inLayer1);
  51. const Mapping &m = mMapping[(BroadPhaseLayer::Type)inLayer2];
  52. return &m == &mMapping.back() // Last layer may collide with anything
  53. || (m.mGroupsToInclude & mask) != 0; // Mask allows it to collide with objects that could reside in this layer
  54. }
  55. #if defined(JPH_EXTERNAL_PROFILE) || defined(JPH_PROFILE_ENABLED)
  56. void SetBroadPhaseLayerName(BroadPhaseLayer inLayer, const char *inName)
  57. {
  58. mBroadPhaseLayerNames[(BroadPhaseLayer::Type)inLayer] = inName;
  59. }
  60. virtual const char * GetBroadPhaseLayerName(BroadPhaseLayer inLayer) const override
  61. {
  62. return mBroadPhaseLayerNames[(BroadPhaseLayer::Type)inLayer];
  63. }
  64. #endif // JPH_EXTERNAL_PROFILE || JPH_PROFILE_ENABLED
  65. private:
  66. struct Mapping
  67. {
  68. uint32 mGroupsToInclude = 0;
  69. uint32 mGroupsToExclude = ~uint32(0);
  70. };
  71. Array<Mapping> mMapping;
  72. #if defined(JPH_EXTERNAL_PROFILE) || defined(JPH_PROFILE_ENABLED)
  73. Array<const char *> mBroadPhaseLayerNames;
  74. #endif // JPH_EXTERNAL_PROFILE || JPH_PROFILE_ENABLED
  75. };
  76. JPH_NAMESPACE_END