BroadPhaseQuadTree.h 5.0 KB

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