BroadPhaseQuadTree.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. // SPDX-FileCopyrightText: 2021 Jorrit Rouwe
  2. // SPDX-License-Identifier: MIT
  3. #pragma once
  4. #include <Jolt/Physics/Collision/BroadPhase/QuadTree.h>
  5. #include <Jolt/Physics/Collision/BroadPhase/BroadPhase.h>
  6. JPH_NAMESPACE_BEGIN
  7. /// Fast SIMD based quad tree BroadPhase that is multithreading aware and tries to do a minimal amount of locking.
  8. class BroadPhaseQuadTree final : public BroadPhase
  9. {
  10. public:
  11. JPH_OVERRIDE_NEW_DELETE
  12. /// Destructor
  13. virtual ~BroadPhaseQuadTree() override;
  14. // Implementing interface of BroadPhase (see BroadPhase for documentation)
  15. virtual void Init(BodyManager *inBodyManager, const BroadPhaseLayerInterface &inLayerInterface) override;
  16. virtual void Optimize() override;
  17. virtual void FrameSync() override;
  18. virtual void LockModifications() override;
  19. virtual UpdateState UpdatePrepare() override;
  20. virtual void UpdateFinalize(const UpdateState &inUpdateState) override;
  21. virtual void UnlockModifications() override;
  22. virtual AddState AddBodiesPrepare(BodyID *ioBodies, int inNumber) override;
  23. virtual void AddBodiesFinalize(BodyID *ioBodies, int inNumber, AddState inAddState) override;
  24. virtual void AddBodiesAbort(BodyID *ioBodies, int inNumber, AddState inAddState) override;
  25. virtual void RemoveBodies(BodyID *ioBodies, int inNumber) override;
  26. virtual void NotifyBodiesAABBChanged(BodyID *ioBodies, int inNumber, bool inTakeLock) override;
  27. virtual void NotifyBodiesLayerChanged(BodyID *ioBodies, int inNumber) override;
  28. virtual void CastRay(const RayCast &inRay, RayCastBodyCollector &ioCollector, const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter) const override;
  29. virtual void CollideAABox(const AABox &inBox, CollideShapeBodyCollector &ioCollector, const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter) const override;
  30. virtual void CollideSphere(Vec3Arg inCenter, float inRadius, CollideShapeBodyCollector &ioCollector, const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter) const override;
  31. virtual void CollidePoint(Vec3Arg inPoint, CollideShapeBodyCollector &ioCollector, const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter) const override;
  32. virtual void CollideOrientedBox(const OrientedBox &inBox, CollideShapeBodyCollector &ioCollector, const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter) const override;
  33. virtual void CastAABoxNoLock(const AABoxCast &inBox, CastShapeBodyCollector &ioCollector, const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter) const override;
  34. virtual void CastAABox(const AABoxCast &inBox, CastShapeBodyCollector &ioCollector, const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter) const override;
  35. virtual void FindCollidingPairs(BodyID *ioActiveBodies, int inNumActiveBodies, float inSpeculativeContactDistance, ObjectVsBroadPhaseLayerFilter inObjectVsBroadPhaseLayerFilter, ObjectLayerPairFilter inObjectLayerPairFilter, BodyPairCollector &ioPairCollector) const override;
  36. #ifdef JPH_TRACK_BROADPHASE_STATS
  37. virtual void ReportStats() override;
  38. #endif // JPH_TRACK_BROADPHASE_STATS
  39. private:
  40. /// Helper struct for AddBodies handle
  41. struct LayerState
  42. {
  43. JPH_OVERRIDE_NEW_DELETE
  44. BodyID * mBodyStart = nullptr;
  45. BodyID * mBodyEnd;
  46. QuadTree::AddState mAddState;
  47. };
  48. using Tracking = QuadTree::Tracking;
  49. using TrackingVector = QuadTree::TrackingVector;
  50. /// Max amount of bodies we support
  51. size_t mMaxBodies = 0;
  52. /// Array that for each BodyID keeps track of where it is located in which tree
  53. TrackingVector mTracking;
  54. /// Node allocator for all trees
  55. QuadTree::Allocator mAllocator;
  56. /// Information about broad phase layers
  57. const BroadPhaseLayerInterface *mBroadPhaseLayerInterface = nullptr;
  58. /// One tree per object layer
  59. QuadTree * mLayers;
  60. uint mNumLayers;
  61. /// UpdateState implementation for this tree used during UpdatePrepare/Finalize()
  62. struct UpdateStateImpl
  63. {
  64. QuadTree * mTree;
  65. QuadTree::UpdateState mUpdateState;
  66. };
  67. static_assert(sizeof(UpdateStateImpl) <= sizeof(UpdateState));
  68. static_assert(alignof(UpdateStateImpl) <= alignof(UpdateState));
  69. /// Mutex that prevents object modification during UpdatePrepare/Finalize()
  70. SharedMutex mUpdateMutex;
  71. /// We double buffer all trees so that we can query while building the next one and we destroy the old tree the next physics update.
  72. /// This structure ensures that we wait for queries that are still using the old tree.
  73. mutable SharedMutex mQueryLocks[2];
  74. /// This index indicates which lock is currently active, it alternates between 0 and 1
  75. atomic<uint32> mQueryLockIdx { 0 };
  76. /// This is the next tree to update in UpdatePrepare()
  77. uint32 mNextLayerToUpdate = 0;
  78. };
  79. JPH_NAMESPACE_END