Jolt Physics
A multi core friendly Game Physics Engine
Loading...
Searching...
No Matches
LargeIslandSplitter.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2023 Jorrit Rouwe
2// SPDX-License-Identifier: MIT
3
4#pragma once
5
7#include <Jolt/Core/Atomics.h>
8
10
11class Body;
12class BodyID;
13class IslandBuilder;
14class TempAllocator;
15class Constraint;
16class BodyManager;
18
24{
25private:
26 using SplitMask = uint32;
27
28public:
29 static constexpr uint cNumSplits = sizeof(SplitMask) * 8;
30 static constexpr uint cNonParallelSplitIdx = cNumSplits - 1;
31 static constexpr uint cLargeIslandTreshold = 128;
32
34 enum class EStatus
35 {
39 };
40
42 struct Split
43 {
46 inline uint GetNumItems() const { return GetNumContacts() + GetNumConstraints(); }
47
50
53 };
54
56 class Splits
57 {
58 public:
59 inline uint GetNumSplits() const
60 {
61 return mNumSplits;
62 }
63
64 inline void GetConstraintsInSplit(uint inSplitIndex, uint32 &outConstraintsBegin, uint32 &outConstraintsEnd) const
65 {
66 const Split &split = mSplits[inSplitIndex];
67 outConstraintsBegin = split.mConstraintBufferBegin;
68 outConstraintsEnd = split.mConstraintBufferEnd;
69 }
70
71 inline void GetContactsInSplit(uint inSplitIndex, uint32 &outContactsBegin, uint32 &outContactsEnd) const
72 {
73 const Split &split = mSplits[inSplitIndex];
74 outContactsBegin = split.mContactBufferBegin;
75 outContactsEnd = split.mContactBufferEnd;
76 }
77
79 inline void ResetStatus()
80 {
81 mStatus.store(StatusItemMask, memory_order_relaxed);
82 }
83
85 inline void StartFirstBatch()
86 {
87 uint split_index = mNumSplits > 0? 0 : cNonParallelSplitIdx;
88 mStatus.store(uint64(split_index) << StatusSplitShift, memory_order_release);
89 }
90
92 EStatus FetchNextBatch(uint32 &outConstraintsBegin, uint32 &outConstraintsEnd, uint32 &outContactsBegin, uint32 &outContactsEnd, bool &outFirstIteration);
93
95 void MarkBatchProcessed(uint inNumProcessed, bool &outLastIteration, bool &outFinalBatch);
96
98 {
99 StatusIterationMask = 0xffff000000000000,
101 StatusSplitMask = 0x0000ffff00000000,
103 StatusItemMask = 0x00000000ffffffff,
104 };
105
106 static inline int sGetIteration(uint64 inStatus)
107 {
108 return int((inStatus & StatusIterationMask) >> StatusIterationShift);
109 }
110
111 static inline uint sGetSplit(uint64 inStatus)
112 {
113 return uint((inStatus & StatusSplitMask) >> StatusSplitShift);
114 }
115
116 static inline uint sGetItem(uint64 inStatus)
117 {
118 return uint(inStatus & StatusItemMask);
119 }
120
127 atomic<uint64> mStatus;
128 atomic<uint> mItemsProcessed;
129 };
130
131public:
134
136 void Prepare(const IslandBuilder &inIslandBuilder, uint32 inNumActiveBodies, TempAllocator *inTempAllocator);
137
139 uint AssignSplit(const Body *inBody1, const Body *inBody2);
140
142 uint AssignToNonParallelSplit(const Body *inBody);
143
145 bool SplitIsland(uint32 inIslandIndex, const IslandBuilder &inIslandBuilder, const BodyManager &inBodyManager, const ContactConstraintManager &inContactManager, Constraint **inActiveConstraints, int inNumVelocitySteps, int inNumPositionSteps);
146
148 EStatus FetchNextBatch(uint &outSplitIslandIndex, uint32 *&outConstraintsBegin, uint32 *&outConstraintsEnd, uint32 *&outContactsBegin, uint32 *&outContactsEnd, bool &outFirstIteration);
149
151 void MarkBatchProcessed(uint inSplitIslandIndex, const uint32 *inConstraintsBegin, const uint32 *inConstraintsEnd, const uint32 *inContactsBegin, const uint32 *inContactsEnd, bool &outLastIteration, bool &outFinalBatch);
152
154 inline uint32 GetIslandIndex(uint inSplitIslandIndex) const
155 {
156 JPH_ASSERT(inSplitIslandIndex < mNumSplitIslands);
157 return mSplitIslands[inSplitIslandIndex].mIslandIndex;
158 }
159
162
164 void Reset(TempAllocator *inTempAllocator);
165
166private:
167 static constexpr uint cSplitCombineTreshold = 32;
168 static constexpr uint cBatchSize = 16;
169
170 uint32 mNumActiveBodies = 0;
171
172 SplitMask * mSplitMasks = nullptr;
173
174 uint32 * mContactAndConstaintsSplitIdx = nullptr;
175 uint32 * mContactAndConstraintIndices = nullptr;
176 uint mContactAndConstraintsSize = 0;
177 atomic<uint> mContactAndConstraintsNextFree { 0 };
178
179 uint mNumSplitIslands = 0;
180 Splits * mSplitIslands = nullptr;
181 atomic<uint> mNextSplitIsland = 0;
182};
183
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
Definition: Body.h:33
ID of a body. This is a way of reasoning about bodies in a multithreaded simulation while avoiding ra...
Definition: BodyID.h:13
Class that contains all bodies.
Definition: BodyManager.h:30
Base class for all physics constraints. A constraint removes one or more degrees of freedom for a rig...
Definition: Constraint.h:99
Definition: ContactConstraintManager.h:28
Keeps track of connected bodies and builds islands for multithreaded velocity/position update.
Definition: IslandBuilder.h:19
Structure that describes the resulting splits from the large island splitter.
Definition: LargeIslandSplitter.h:57
void ResetStatus()
Reset current status so that no work can be picked up from this split.
Definition: LargeIslandSplitter.h:79
EIterationStatus
Definition: LargeIslandSplitter.h:98
@ StatusSplitMask
Definition: LargeIslandSplitter.h:101
@ StatusItemMask
Definition: LargeIslandSplitter.h:103
@ StatusSplitShift
Definition: LargeIslandSplitter.h:102
@ StatusIterationMask
Definition: LargeIslandSplitter.h:99
@ StatusIterationShift
Definition: LargeIslandSplitter.h:100
static uint sGetItem(uint64 inStatus)
Definition: LargeIslandSplitter.h:116
atomic< uint > mItemsProcessed
Number of items that have been marked as processed.
Definition: LargeIslandSplitter.h:128
int mNumPositionSteps
Number of position steps to do.
Definition: LargeIslandSplitter.h:126
void StartFirstBatch()
Make the first batch available to other threads.
Definition: LargeIslandSplitter.h:85
void MarkBatchProcessed(uint inNumProcessed, bool &outLastIteration, bool &outFinalBatch)
Mark a batch as processed.
Definition: LargeIslandSplitter.cpp:119
int mNumIterations
Number of iterations to do.
Definition: LargeIslandSplitter.h:124
void GetConstraintsInSplit(uint inSplitIndex, uint32 &outConstraintsBegin, uint32 &outConstraintsEnd) const
Definition: LargeIslandSplitter.h:64
EStatus FetchNextBatch(uint32 &outConstraintsBegin, uint32 &outConstraintsEnd, uint32 &outContactsBegin, uint32 &outContactsEnd, bool &outFirstIteration)
Fetch the next batch to process.
Definition: LargeIslandSplitter.cpp:18
uint32 mIslandIndex
Index of the island that was split.
Definition: LargeIslandSplitter.h:122
static int sGetIteration(uint64 inStatus)
Definition: LargeIslandSplitter.h:106
uint GetNumSplits() const
Definition: LargeIslandSplitter.h:59
void GetContactsInSplit(uint inSplitIndex, uint32 &outContactsBegin, uint32 &outContactsEnd) const
Definition: LargeIslandSplitter.h:71
Split mSplits[cNumSplits]
Data per split.
Definition: LargeIslandSplitter.h:121
uint mNumSplits
Number of splits that were created (excluding the non-parallel split)
Definition: LargeIslandSplitter.h:123
atomic< uint64 > mStatus
Status of the split, see EIterationStatus.
Definition: LargeIslandSplitter.h:127
int mNumVelocitySteps
Number of velocity steps to do (cached for 2nd sub step)
Definition: LargeIslandSplitter.h:125
static uint sGetSplit(uint64 inStatus)
Definition: LargeIslandSplitter.h:111
Definition: LargeIslandSplitter.h:24
uint AssignToNonParallelSplit(const Body *inBody)
Force a body to be in a non parallel split. Returns the split index.
Definition: LargeIslandSplitter.cpp:270
bool SplitIsland(uint32 inIslandIndex, const IslandBuilder &inIslandBuilder, const BodyManager &inBodyManager, const ContactConstraintManager &inContactManager, Constraint **inActiveConstraints, int inNumVelocitySteps, int inNumPositionSteps)
Splits up an island, the created splits will be added to the list of batches and can be fetched with ...
Definition: LargeIslandSplitter.cpp:282
void MarkBatchProcessed(uint inSplitIslandIndex, const uint32 *inConstraintsBegin, const uint32 *inConstraintsEnd, const uint32 *inContactsBegin, const uint32 *inContactsEnd, bool &outLastIteration, bool &outFinalBatch)
Mark a batch as processed.
Definition: LargeIslandSplitter.cpp:509
EStatus FetchNextBatch(uint &outSplitIslandIndex, uint32 *&outConstraintsBegin, uint32 *&outConstraintsEnd, uint32 *&outContactsBegin, uint32 *&outContactsEnd, bool &outFirstIteration)
Fetch the next batch to process, returns a handle in outSplitIslandIndex that must be provided to Mar...
Definition: LargeIslandSplitter.cpp:479
static constexpr uint cNumSplits
Definition: LargeIslandSplitter.h:29
void Prepare(const IslandBuilder &inIslandBuilder, uint32 inNumActiveBodies, TempAllocator *inTempAllocator)
Prepare the island splitter by allocating memory.
Definition: LargeIslandSplitter.cpp:182
~LargeIslandSplitter()
Destructor.
Definition: LargeIslandSplitter.cpp:174
static constexpr uint cLargeIslandTreshold
If the number of constraints + contacts in an island is larger than this, we will try to split the is...
Definition: LargeIslandSplitter.h:31
uint32 GetIslandIndex(uint inSplitIslandIndex) const
Get the island index of the island that was split for a particular split island index.
Definition: LargeIslandSplitter.h:154
EStatus
Status code for retrieving a batch.
Definition: LargeIslandSplitter.h:35
@ WaitingForBatch
Work is expected to be available later.
@ BatchRetrieved
Work is being returned.
@ AllBatchesDone
No further work is expected from this.
uint AssignSplit(const Body *inBody1, const Body *inBody2)
Assign two bodies to a split. Returns the split index.
Definition: LargeIslandSplitter.cpp:231
void Reset(TempAllocator *inTempAllocator)
Reset the island splitter.
Definition: LargeIslandSplitter.cpp:530
void PrepareForSolvePositions()
Prepare the island splitter for iterating over the split islands again for position solving....
Definition: LargeIslandSplitter.cpp:518
static constexpr uint cNonParallelSplitIdx
Definition: LargeIslandSplitter.h:30
Class that makes another class non-copyable. Usage: Inherit from NonCopyable.
Definition: NonCopyable.h:11
Definition: TempAllocator.h:16
Describes a split of constraints and contacts.
Definition: LargeIslandSplitter.h:43
uint32 mConstraintBufferBegin
Begin of the constraint buffer (offset relative to mContactAndConstraintIndices)
Definition: LargeIslandSplitter.h:51
uint GetNumItems() const
Definition: LargeIslandSplitter.h:46
uint32 mContactBufferEnd
End of the contact buffer.
Definition: LargeIslandSplitter.h:49
uint GetNumConstraints() const
Definition: LargeIslandSplitter.h:45
uint GetNumContacts() const
Definition: LargeIslandSplitter.h:44
uint32 mContactBufferBegin
Begin of the contact buffer (offset relative to mContactAndConstraintIndices)
Definition: LargeIslandSplitter.h:48
uint32 mConstraintBufferEnd
End of the constraint buffer.
Definition: LargeIslandSplitter.h:52