BroadPhaseQuadTree.h 5.1 KB

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