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;
19
25{
26private:
27 using SplitMask = uint32;
28
29public:
30 static constexpr uint cNumSplits = sizeof(SplitMask) * 8;
31 static constexpr uint cNonParallelSplitIdx = cNumSplits - 1;
32 static constexpr uint cLargeIslandTreshold = 128;
33
35 enum class EStatus
36 {
40 };
41
43 struct Split
44 {
47 inline uint GetNumItems() const { return GetNumContacts() + GetNumConstraints(); }
48
51
54 };
55
57 class Splits
58 {
59 public:
60 inline uint GetNumSplits() const
61 {
62 return mNumSplits;
63 }
64
65 inline void GetConstraintsInSplit(uint inSplitIndex, uint32 &outConstraintsBegin, uint32 &outConstraintsEnd) const
66 {
67 const Split &split = mSplits[inSplitIndex];
68 outConstraintsBegin = split.mConstraintBufferBegin;
69 outConstraintsEnd = split.mConstraintBufferEnd;
70 }
71
72 inline void GetContactsInSplit(uint inSplitIndex, uint32 &outContactsBegin, uint32 &outContactsEnd) const
73 {
74 const Split &split = mSplits[inSplitIndex];
75 outContactsBegin = split.mContactBufferBegin;
76 outContactsEnd = split.mContactBufferEnd;
77 }
78
80 inline void ResetStatus()
81 {
82 mStatus.store(StatusItemMask, memory_order_relaxed);
83 }
84
86 inline void StartFirstBatch()
87 {
88 uint split_index = mNumSplits > 0? 0 : cNonParallelSplitIdx;
89 mStatus.store(uint64(split_index) << StatusSplitShift, memory_order_release);
90 }
91
93 EStatus FetchNextBatch(uint32 &outConstraintsBegin, uint32 &outConstraintsEnd, uint32 &outContactsBegin, uint32 &outContactsEnd, bool &outFirstIteration);
94
96 void MarkBatchProcessed(uint inNumProcessed, bool &outLastIteration, bool &outFinalBatch);
97
99 {
100 StatusIterationMask = 0xffff000000000000,
102 StatusSplitMask = 0x0000ffff00000000,
104 StatusItemMask = 0x00000000ffffffff,
105 };
106
107 static inline int sGetIteration(uint64 inStatus)
108 {
109 return int((inStatus & StatusIterationMask) >> StatusIterationShift);
110 }
111
112 static inline uint sGetSplit(uint64 inStatus)
113 {
114 return uint((inStatus & StatusSplitMask) >> StatusSplitShift);
115 }
116
117 static inline uint sGetItem(uint64 inStatus)
118 {
119 return uint(inStatus & StatusItemMask);
120 }
121
128 atomic<uint64> mStatus;
129 atomic<uint> mItemsProcessed;
130 };
131
132public:
135
137 void Prepare(const IslandBuilder &inIslandBuilder, uint32 inNumActiveBodies, TempAllocator *inTempAllocator);
138
140 uint AssignSplit(const Body *inBody1, const Body *inBody2);
141
143 uint AssignToNonParallelSplit(const Body *inBody);
144
146 bool SplitIsland(uint32 inIslandIndex, const IslandBuilder &inIslandBuilder, const BodyManager &inBodyManager, const ContactConstraintManager &inContactManager, Constraint **inActiveConstraints, CalculateSolverSteps &ioStepsCalculator);
147
149 EStatus FetchNextBatch(uint &outSplitIslandIndex, uint32 *&outConstraintsBegin, uint32 *&outConstraintsEnd, uint32 *&outContactsBegin, uint32 *&outContactsEnd, bool &outFirstIteration);
150
152 void MarkBatchProcessed(uint inSplitIslandIndex, const uint32 *inConstraintsBegin, const uint32 *inConstraintsEnd, const uint32 *inContactsBegin, const uint32 *inContactsEnd, bool &outLastIteration, bool &outFinalBatch);
153
155 inline uint32 GetIslandIndex(uint inSplitIslandIndex) const
156 {
157 JPH_ASSERT(inSplitIslandIndex < mNumSplitIslands);
158 return mSplitIslands[inSplitIslandIndex].mIslandIndex;
159 }
160
163
165 void Reset(TempAllocator *inTempAllocator);
166
167private:
168 static constexpr uint cSplitCombineTreshold = 32;
169 static constexpr uint cBatchSize = 16;
170
171 uint32 mNumActiveBodies = 0;
172
173 SplitMask * mSplitMasks = nullptr;
174
175 uint32 * mContactAndConstraintsSplitIdx = nullptr;
176 uint32 * mContactAndConstraintIndices = nullptr;
177 uint mContactAndConstraintsSize = 0;
178 atomic<uint> mContactAndConstraintsNextFree { 0 };
179
180 uint mNumSplitIslands = 0;
181 Splits * mSplitIslands = nullptr;
182 atomic<uint> mNextSplitIsland = 0;
183};
184
std::uint64_t uint64
Definition: Core.h:456
unsigned int uint
Definition: Core.h:452
#define JPH_NAMESPACE_END
Definition: Core.h:378
std::uint32_t uint32
Definition: Core.h:455
#define JPH_NAMESPACE_BEGIN
Definition: Core.h:372
#define JPH_ASSERT(...)
Definition: IssueReporting.h:33
Definition: Body.h:35
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:44
Class used to calculate the total number of velocity and position steps.
Definition: CalculateSolverSteps.h:13
Base class for all physics constraints. A constraint removes one or more degrees of freedom for a rig...
Definition: Constraint.h:103
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:58
void ResetStatus()
Reset current status so that no work can be picked up from this split.
Definition: LargeIslandSplitter.h:80
EIterationStatus
Definition: LargeIslandSplitter.h:99
@ StatusSplitMask
Definition: LargeIslandSplitter.h:102
@ StatusItemMask
Definition: LargeIslandSplitter.h:104
@ StatusSplitShift
Definition: LargeIslandSplitter.h:103
@ StatusIterationMask
Definition: LargeIslandSplitter.h:100
@ StatusIterationShift
Definition: LargeIslandSplitter.h:101
static uint sGetItem(uint64 inStatus)
Definition: LargeIslandSplitter.h:117
atomic< uint > mItemsProcessed
Number of items that have been marked as processed.
Definition: LargeIslandSplitter.h:129
int mNumPositionSteps
Number of position steps to do.
Definition: LargeIslandSplitter.h:127
void StartFirstBatch()
Make the first batch available to other threads.
Definition: LargeIslandSplitter.h:86
void MarkBatchProcessed(uint inNumProcessed, bool &outLastIteration, bool &outFinalBatch)
Mark a batch as processed.
Definition: LargeIslandSplitter.cpp:120
int mNumIterations
Number of iterations to do.
Definition: LargeIslandSplitter.h:125
void GetConstraintsInSplit(uint inSplitIndex, uint32 &outConstraintsBegin, uint32 &outConstraintsEnd) const
Definition: LargeIslandSplitter.h:65
EStatus FetchNextBatch(uint32 &outConstraintsBegin, uint32 &outConstraintsEnd, uint32 &outContactsBegin, uint32 &outContactsEnd, bool &outFirstIteration)
Fetch the next batch to process.
Definition: LargeIslandSplitter.cpp:19
uint32 mIslandIndex
Index of the island that was split.
Definition: LargeIslandSplitter.h:123
static int sGetIteration(uint64 inStatus)
Definition: LargeIslandSplitter.h:107
uint GetNumSplits() const
Definition: LargeIslandSplitter.h:60
void GetContactsInSplit(uint inSplitIndex, uint32 &outContactsBegin, uint32 &outContactsEnd) const
Definition: LargeIslandSplitter.h:72
Split mSplits[cNumSplits]
Data per split.
Definition: LargeIslandSplitter.h:122
uint mNumSplits
Number of splits that were created (excluding the non-parallel split)
Definition: LargeIslandSplitter.h:124
atomic< uint64 > mStatus
Status of the split, see EIterationStatus.
Definition: LargeIslandSplitter.h:128
int mNumVelocitySteps
Number of velocity steps to do (cached for 2nd sub step)
Definition: LargeIslandSplitter.h:126
static uint sGetSplit(uint64 inStatus)
Definition: LargeIslandSplitter.h:112
Definition: LargeIslandSplitter.h:25
bool SplitIsland(uint32 inIslandIndex, const IslandBuilder &inIslandBuilder, const BodyManager &inBodyManager, const ContactConstraintManager &inContactManager, Constraint **inActiveConstraints, CalculateSolverSteps &ioStepsCalculator)
Splits up an island, the created splits will be added to the list of batches and can be fetched with ...
Definition: LargeIslandSplitter.cpp:283
uint AssignToNonParallelSplit(const Body *inBody)
Force a body to be in a non parallel split. Returns the split index.
Definition: LargeIslandSplitter.cpp:271
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:517
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:487
static constexpr uint cNumSplits
Definition: LargeIslandSplitter.h:30
void Prepare(const IslandBuilder &inIslandBuilder, uint32 inNumActiveBodies, TempAllocator *inTempAllocator)
Prepare the island splitter by allocating memory.
Definition: LargeIslandSplitter.cpp:183
~LargeIslandSplitter()
Destructor.
Definition: LargeIslandSplitter.cpp:175
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:32
uint32 GetIslandIndex(uint inSplitIslandIndex) const
Get the island index of the island that was split for a particular split island index.
Definition: LargeIslandSplitter.h:155
EStatus
Status code for retrieving a batch.
Definition: LargeIslandSplitter.h:36
@ 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:232
void Reset(TempAllocator *inTempAllocator)
Reset the island splitter.
Definition: LargeIslandSplitter.cpp:538
void PrepareForSolvePositions()
Prepare the island splitter for iterating over the split islands again for position solving....
Definition: LargeIslandSplitter.cpp:526
static constexpr uint cNonParallelSplitIdx
Definition: LargeIslandSplitter.h:31
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:44
uint32 mConstraintBufferBegin
Begin of the constraint buffer (offset relative to mContactAndConstraintIndices)
Definition: LargeIslandSplitter.h:52
uint GetNumItems() const
Definition: LargeIslandSplitter.h:47
uint32 mContactBufferEnd
End of the contact buffer.
Definition: LargeIslandSplitter.h:50
uint GetNumConstraints() const
Definition: LargeIslandSplitter.h:46
uint GetNumContacts() const
Definition: LargeIslandSplitter.h:45
uint32 mContactBufferBegin
Begin of the contact buffer (offset relative to mContactAndConstraintIndices)
Definition: LargeIslandSplitter.h:49
uint32 mConstraintBufferEnd
End of the constraint buffer.
Definition: LargeIslandSplitter.h:53