36        inline                  NodeID() = 
default;
 
   39        static inline NodeID    sInvalid()                          { 
return NodeID(cInvalidNodeIndex); }
 
   41        static inline NodeID    sFromNodeIndex(
uint32 inIdx)        { NodeID node_id(inIdx | cIsNode); 
JPH_ASSERT(node_id.IsNode()); 
return node_id; }
 
   44        inline bool             IsValid()
 const                     { 
return mID != cInvalidNodeIndex; }
 
   45        inline bool             IsBody()
 const                      { 
return (mID & cIsNode) == 0; }
 
   46        inline bool             IsNode()
 const                      { 
return (mID & cIsNode) != 0; }
 
   50        inline uint32           GetNodeIndex()
 const                { 
JPH_ASSERT(IsNode()); 
return mID & ~cIsNode; }
 
   54        inline bool             operator == (
const NodeID &inRHS)
 const { 
return mID == inRHS.mID; }
 
   57        friend class AtomicNodeID;
 
   59        inline explicit         NodeID(
uint32 inID)                 : mID(inID) { }
 
   66    static_assert(
sizeof(NodeID) == 
sizeof(
BodyID), 
"Body id's should have the same size as NodeIDs");
 
   73                                AtomicNodeID() = 
default;
 
   74        explicit                AtomicNodeID(
const NodeID &inRHS)           : mID(inRHS.mID) { }
 
   77        inline void             operator = (
const NodeID &inRHS)            { mID = inRHS.mID; }
 
   80        inline                  operator NodeID ()
 const                    { 
return NodeID(mID); }
 
   83        inline bool             IsValid()
 const                             { 
return mID != cInvalidNodeIndex; }
 
   87        inline bool             operator == (
const NodeID &inRHS)
 const     { 
return mID == inRHS.mID; }
 
   90        inline bool             CompareExchange(NodeID inOld, NodeID inNew) { 
return mID.compare_exchange_strong(inOld.mID, inNew.mID); }
 
  101        explicit                Node(
bool inIsChanged);
 
  104        void                    GetNodeBounds(
AABox &outBounds) 
const;
 
  107        void                    GetChildBounds(
int inChildIndex, 
AABox &outBounds) 
const;
 
  110        void                    SetChildBounds(
int inChildIndex, 
const AABox &inBounds);
 
  113        void                    InvalidateChildBounds(
int inChildIndex);
 
  116        bool                    EncapsulateChildBounds(
int inChildIndex, 
const AABox &inBounds);
 
  119        atomic<float>           mBoundsMinX[4];
 
  120        atomic<float>           mBoundsMinY[4];
 
  121        atomic<float>           mBoundsMinZ[4];
 
  122        atomic<float>           mBoundsMaxX[4];
 
  123        atomic<float>           mBoundsMaxY[4];
 
  124        atomic<float>           mBoundsMaxZ[4];
 
  127        AtomicNodeID            mChildNodeID[4];
 
  131        atomic<uint32>          mParentNodeIndex = cInvalidNodeIndex;
 
  135        atomic<uint32>          mIsChanged;
 
  142    static constexpr int        cStackSize = 128;
 
  144    static_assert(
sizeof(atomic<float>) == 4, 
"Assuming that an atomic doesn't add any additional storage");
 
  145    static_assert(
sizeof(atomic<uint32>) == 4, 
"Assuming that an atomic doesn't add any additional storage");
 
  146    static_assert(is_trivially_destructible<Node>(), 
"Assuming that we don't have a destructor");
 
  174#if defined(JPH_EXTERNAL_PROFILE) || defined(JPH_PROFILE_ENABLED) 
  176    void                        SetName(
const char *inName)         { mName = inName; }
 
  177    inline const char *         
GetName()
 const                     { 
return mName; }
 
  181    inline bool                 HasBodies()
 const                   { 
return mNumBodies != 0; }
 
  184    inline bool                 IsDirty()
 const                     { 
return mIsDirty; }
 
  187    inline bool                 CanBeUpdated()
 const                { 
return mFreeNodeBatch.mNumObjects == 0; }
 
  251#ifdef JPH_TRACK_BROADPHASE_STATS 
  253    void                        ReportStats() 
const;
 
  258    static const uint32         cInvalidNodeIndex = 0xffffffff;     
 
  259    static const float          cLargeFloat;                        
 
  260    static const AABox          cInvalidBounds;                     
 
  266        inline NodeID           GetNodeID()
 const                   { 
return NodeID::sFromNodeIndex(mIndex); }
 
  269        atomic<uint32>          mIndex { cInvalidNodeIndex };
 
  278    JPH_INLINE 
const RootNode & GetCurrentRoot()
 const              { 
return mRootNode[mRootNodeIndex]; }
 
  279    JPH_INLINE RootNode &       GetCurrentRoot()                    { 
return mRootNode[mRootNodeIndex]; }
 
  282    inline AABox                GetNodeOrBodyBounds(
const BodyVector &inBodies, NodeID inNodeID) 
const;
 
  285    inline void                 MarkNodeAndParentsChanged(
uint32 inNodeIndex);
 
  288    inline void                 WidenAndMarkNodeAndParentsChanged(
uint32 inNodeIndex, 
const AABox &inNewBounds);
 
  291    inline uint32               AllocateNode(
bool inIsChanged);
 
  294    inline bool                 TryInsertLeaf(
TrackingVector &ioTracking, 
int inNodeIndex, NodeID inLeafID, 
const AABox &inLeafBounds, 
int inLeafNumBodies);
 
  297    inline bool                 TryCreateNewRoot(
TrackingVector &ioTracking, atomic<uint32> &ioRootNodeIndex, NodeID inLeafID, 
const AABox &inLeafBounds, 
int inLeafNumBodies);
 
  304    static void                 sPartition(NodeID *ioNodeIDs, 
Vec3 *ioNodeCenters, 
int inNumber, 
int &outMidPoint);
 
  309    static void                 sPartition4(NodeID *ioNodeIDs, 
Vec3 *ioNodeCenters, 
int inBegin, 
int inEnd, 
int *outSplit);
 
  317#ifdef JPH_DUMP_BROADPHASE_TREE 
  319    void                        DumpTree(
const NodeID &inRoot, 
const char *inFileNamePrefix) 
const;
 
  322#ifdef JPH_TRACK_BROADPHASE_STATS 
  324    mutable Mutex               mStatsMutex;
 
  330        uint64                  mBodiesVisited = 0;
 
  333        uint64                  mCollectorTicks = 0;
 
  339    void                        ReportStats(
const char *inName, 
const LayerToStats &inLayer) 
const;
 
  341    mutable LayerToStats        mCastRayStats;
 
  342    mutable LayerToStats        mCollideAABoxStats;
 
  343    mutable LayerToStats        mCollideSphereStats;
 
  344    mutable LayerToStats        mCollidePointStats;
 
  345    mutable LayerToStats        mCollideOrientedBoxStats;
 
  346    mutable LayerToStats        mCastAABoxStats;
 
  350    uint                        GetMaxTreeDepth(
const NodeID &inNodeID) 
const;
 
  353    template <
class Visitor>
 
  356#if defined(JPH_EXTERNAL_PROFILE) || defined(JPH_PROFILE_ENABLED) 
  358    const char *                mName = 
"Layer";
 
  362    atomic<uint32>              mNumBodies { 0 };
 
  366    RootNode                    mRootNode[2];
 
  367    atomic<uint32>              mRootNodeIndex { 0 };
 
  373    Allocator::Batch            mFreeNodeBatch;
 
  376    atomic<bool>                mIsDirty = 
false;
 
Array< Body * > BodyVector
Array of bodies.
Definition: BodyManager.h:23
 
#define JPH_IF_TRACK_BROADPHASE_STATS(...)
Definition: BroadPhase.h:16
 
uint32_t uint32
Definition: Core.h:312
 
unsigned int uint
Definition: Core.h:309
 
#define JPH_NAMESPACE_END
Definition: Core.h:240
 
uint64_t uint64
Definition: Core.h:313
 
#define JPH_NAMESPACE_BEGIN
Definition: Core.h:234
 
#define JPH_ASSERT(...)
Definition: IssueReporting.h:33
 
#define JPH_OVERRIDE_NEW_DELETE
Macro to override the new and delete functions.
Definition: Memory.h:29
 
std::vector< T, STLAllocator< T > > Array
Definition: STLAllocator.h:81
 
std::unordered_map< Key, T, Hash, KeyEqual, STLAllocator< pair< const Key, T > > > UnorderedMap
Definition: UnorderedMap.h:13
 
Axis aligned box.
Definition: AABox.h:16
 
ID of a body. This is a way of reasoning about bodies in a multithreaded simulation while avoiding ra...
Definition: BodyID.h:13
 
static constexpr uint32 cBroadPhaseBit
This bit is used by the broadphase.
Definition: BodyID.h:18
 
uint32 GetIndexAndSequenceNumber() const
Returns the index and sequence number combined in an uint32.
Definition: BodyID.h:58
 
uint8 Type
Definition: BroadPhaseLayer.h:20
 
Virtual interface that allows collecting multiple collision results.
Definition: CollisionCollector.h:45
 
static const int ObjectStorageSize
Size of an object + bookkeeping for the freelist.
Definition: FixedSizeFreeList.h:77
 
Class that makes another class non-copyable. Usage: Inherit from NonCopyable.
Definition: NonCopyable.h:11
 
Filter class for object layers.
Definition: ObjectLayer.h:28
 
Filter class to test if two objects can collide based on their object layer. Used while finding colli...
Definition: ObjectLayer.h:50
 
Oriented box.
Definition: OrientedBox.h:18
 
Definition: QuadTree.h:21
 
const char * GetName() const
Definition: QuadTree.h:177
 
bool HasBodies() const
Check if there is anything in the tree.
Definition: QuadTree.h:181
 
void CastRay(const RayCast &inRay, RayCastBodyCollector &ioCollector, const ObjectLayerFilter &inObjectLayerFilter, const TrackingVector &inTracking) const
Cast a ray and get the intersecting bodies in ioCollector.
Definition: QuadTree.cpp:1038
 
void FindCollidingPairs(const BodyVector &inBodies, const BodyID *inActiveBodies, int inNumActiveBodies, float inSpeculativeContactDistance, BodyPairCollector &ioPairCollector, const ObjectLayerPairFilter &inObjectLayerPairFilter) const
Find all colliding pairs between dynamic bodies, calls ioPairCollector for every pair found.
Definition: QuadTree.cpp:1351
 
~QuadTree()
Destructor.
Definition: QuadTree.cpp:143
 
void CollideOrientedBox(const OrientedBox &inBox, CollideShapeBodyCollector &ioCollector, const ObjectLayerFilter &inObjectLayerFilter, const TrackingVector &inTracking) const
Get bodies intersecting with an oriented box and any hits to ioCollector.
Definition: QuadTree.cpp:1243
 
void AddBodiesAbort(TrackingVector &ioTracking, const AddState &inState)
Definition: QuadTree.cpp:822
 
void Init(Allocator &inAllocator)
Initialization.
Definition: QuadTree.cpp:198
 
void DiscardOldTree()
Will throw away the previous frame's nodes so that we can start building a new tree in the background...
Definition: QuadTree.cpp:207
 
void AddBodiesPrepare(const BodyVector &inBodies, TrackingVector &ioTracking, BodyID *ioBodyIDs, int inNumber, AddState &outState)
Definition: QuadTree.cpp:777
 
void CollideAABox(const AABox &inBox, CollideShapeBodyCollector &ioCollector, const ObjectLayerFilter &inObjectLayerFilter, const TrackingVector &inTracking) const
Get bodies intersecting with inBox in ioCollector.
Definition: QuadTree.cpp:1093
 
void NotifyBodiesAABBChanged(const BodyVector &inBodies, const TrackingVector &inTracking, const BodyID *ioBodyIDs, int inNumber)
Call whenever the aabb of a body changes.
Definition: QuadTree.cpp:899
 
bool IsDirty() const
Check if the tree needs an UpdatePrepare/Finalize()
Definition: QuadTree.h:184
 
void UpdateFinalize(const BodyVector &inBodies, const TrackingVector &inTracking, const UpdateState &inUpdateState)
Definition: QuadTree.cpp:358
 
void CastAABox(const AABoxCast &inBox, CastShapeBodyCollector &ioCollector, const ObjectLayerFilter &inObjectLayerFilter, const TrackingVector &inTracking) const
Cast a box and get intersecting bodies in ioCollector.
Definition: QuadTree.cpp:1291
 
bool CanBeUpdated() const
Check if this tree can get an UpdatePrepare/Finalize() or if it needs a DiscardOldTree() first.
Definition: QuadTree.h:187
 
void AddBodiesFinalize(TrackingVector &ioTracking, int inNumberBodies, const AddState &inState)
Finalize adding bodies to the quadtree, supply the same number of bodies as in AddBodiesPrepare.
Definition: QuadTree.cpp:799
 
void CollidePoint(Vec3Arg inPoint, CollideShapeBodyCollector &ioCollector, const ObjectLayerFilter &inObjectLayerFilter, const TrackingVector &inTracking) const
Get bodies intersecting with a point and any hits to ioCollector.
Definition: QuadTree.cpp:1195
 
void CollideSphere(Vec3Arg inCenter, float inRadius, CollideShapeBodyCollector &ioCollector, const ObjectLayerFilter &inObjectLayerFilter, const TrackingVector &inTracking) const
Get bodies intersecting with a sphere in ioCollector.
Definition: QuadTree.cpp:1141
 
Array< Tracking > TrackingVector
Definition: QuadTree.h:169
 
void UpdatePrepare(const BodyVector &inBodies, TrackingVector &ioTracking, UpdateState &outUpdateState, bool inFullRebuild)
Definition: QuadTree.cpp:224
 
void SetName(const char *inName)
Name of the tree for debugging purposes.
Definition: QuadTree.h:176
 
void RemoveBodies(const BodyVector &inBodies, TrackingVector &ioTracking, const BodyID *ioBodyIDs, int inNumber)
Remove inNumber bodies in ioBodyIDs from the quadtree.
Definition: QuadTree.cpp:863
 
FixedSizeFreeList< Node > Allocator
Class that allocates tree nodes, can be shared between multiple trees.
Definition: QuadTree.h:150
 
Structure that holds AABox moving linearly through 3d space.
Definition: AABoxCast.h:13
 
Temporary data structure to pass information between AddBodiesPrepare and AddBodiesFinalize/Abort.
Definition: QuadTree.h:207
 
AABox mLeafBounds
Definition: QuadTree.h:209
 
NodeID mLeafID
Definition: QuadTree.h:208
 
Data to track location of a Body in the tree.
Definition: QuadTree.h:156
 
atomic< BroadPhaseLayer::Type > mBroadPhaseLayer
Definition: QuadTree.h:164
 
static const uint32 cInvalidBodyLocation
Invalid body location identifier.
Definition: QuadTree.h:162
 
Tracking(const Tracking &inRHS)
Definition: QuadTree.h:159
 
atomic< ObjectLayer > mObjectLayer
Definition: QuadTree.h:165
 
atomic< uint32 > mBodyLocation
Definition: QuadTree.h:166
 
Tracking()=default
Constructor to satisfy the vector class.
 
Definition: QuadTree.h:193
 
NodeID mRootNodeID
This will be the new root node id.
Definition: QuadTree.h:194