27class PhysicsUpdateContext;
44 void Init(
uint inMaxBodyPairs,
uint inMaxContactConstraints);
71 if (mContactListener ==
nullptr)
74 return mContactListener->OnContactValidate(inBody1, inBody2, inBaseOffset, inCollisionResult);
78 void PrepareConstraintBuffer(PhysicsUpdateContext *inContext);
99 void GetContactsFromCache(ContactAllocator &ioContactAllocator,
Body &inBody1,
Body &inBody2,
bool &outPairHandled);
165 void ConstraintIdxToConstraintOffset(
uint32 *ioConstraintIdxBegin,
const uint32 *inConstraintIdxEnd)
const;
168 void SortContacts(
uint32 *ioConstraintOffsetBegin,
uint32 *inConstraintOffsetEnd)
const;
173 const ContactConstraintBase &constraint = *
reinterpret_cast<const ContactConstraintBase *
>(mConstraints + inConstraintOffset);
174 outBody1 = constraint.mBody1;
175 outBody2 = constraint.mBody2;
179 template <
class MotionPropertiesCallback>
180 void WarmStartVelocityConstraints(
const uint32 *inConstraintOffsetBegin,
const uint32 *inConstraintOffsetEnd,
float inWarmStartImpulseRatio, MotionPropertiesCallback &ioCallback);
212 bool SolveVelocityConstraints(
const uint32 *inConstraintOffsetBegin,
const uint32 *inConstraintOffsetEnd);
215 void StoreAppliedImpulses(
const uint32 *inConstraintOffsetBegin,
const uint32 *inConstraintOffsetEnd)
const;
233 bool SolvePositionConstraints(
const uint32 *inConstraintOffsetBegin,
const uint32 *inConstraintOffsetEnd);
236 void RecycleConstraintBuffer();
239 void FinishConstraintBuffer();
249#ifdef JPH_DEBUG_RENDERER
265 class CachedContactPoint
278 float mNonPenetrationLambda;
281 static_assert(
sizeof(CachedContactPoint) == 28,
"Unexpected size");
282 static_assert(
alignof(CachedContactPoint) == 4,
"Assuming 4 byte aligned");
289 static constexpr int sGetRequiredExtraSize(
int inNumContactPoints) {
return max(0, inNumContactPoints - 1) *
sizeof(CachedContactPoint); }
292 static constexpr int sGetRequiredTotalSize(
int inNumContactPoints) {
return sizeof(CachedManifold) + sGetRequiredExtraSize(inNumContactPoints); }
295 void SaveState(StateRecorder &inStream)
const;
296 void RestoreState(StateRecorder &inStream);
299 uint32 mNextWithSameBodyPair;
303 Float3 mContactNormal;
306 Vector<2> mFrictionLambda;
307 float mAngularFrictionLambda;
310 enum class EFlags :
uint16
312 ContactPersisted = 1,
317 mutable atomic<uint16> mFlags { 0 };
323 CachedContactPoint mContactPoints[1];
326 static_assert(
sizeof(CachedManifold) == 60,
"This structure is expect to not contain any waste due to alignment");
327 static_assert(
alignof(CachedManifold) == 4,
"Assuming 4 byte aligned");
330 using ManifoldMap = LockFreeHashMap<SubShapeIDPair, CachedManifold>;
331 using MKeyValue = ManifoldMap::KeyValue;
332 using MKVAndCreated = std::pair<MKeyValue *, bool>;
339 void SaveState(StateRecorder &inStream)
const;
340 void RestoreState(StateRecorder &inStream);
344 Float3 mDeltaPosition;
348 Float3 mDeltaRotation;
351 uint32 mFirstCachedManifold;
354 static_assert(
sizeof(CachedBodyPair) == 28,
"Unexpected size");
355 static_assert(
alignof(CachedBodyPair) == 4,
"Assuming 4 byte aligned");
358 using BodyPairMap = LockFreeHashMap<BodyPair, CachedBodyPair>;
359 using BPKeyValue = BodyPairMap::KeyValue;
366 void Init(
uint inMaxBodyPairs,
uint inMaxContactConstraints,
uint inCachedManifoldsSize);
373 void Prepare(
uint inExpectedNumBodyPairs,
uint inExpectedNumManifolds);
376 ContactAllocator GetContactAllocator() {
return ContactAllocator(mAllocator, cAllocatorBlockSize); }
379 const MKeyValue * Find(
const SubShapeIDPair &inKey,
uint64 inKeyHash)
const;
380 MKeyValue * Create(ContactAllocator &ioContactAllocator,
const SubShapeIDPair &inKey,
uint64 inKeyHash,
int inNumContactPoints);
381 MKVAndCreated FindOrCreate(ContactAllocator &ioContactAllocator,
const SubShapeIDPair &inKey,
uint64 inKeyHash,
int inNumContactPoints);
382 uint32 ToHandle(
const MKeyValue *inKeyValue)
const;
383 const MKeyValue * FromHandle(
uint32 inHandle)
const;
384 MKeyValue * FromHandle(
uint32 inHandle);
387 const BPKeyValue * Find(
const BodyPair &inKey,
uint64 inKeyHash)
const;
388 BPKeyValue * Create(ContactAllocator &ioContactAllocator,
const BodyPair &inKey,
uint64 inKeyHash);
392 void ContactPointRemovedCallbacks(ContactListener *inListener);
394#ifdef JPH_ENABLE_ASSERTS
396 uint GetNumManifolds()
const {
return mCachedManifolds.GetNumKeyValues(); }
399 uint GetNumBodyPairs()
const {
return mCachedBodyPairs.GetNumKeyValues(); }
406 void SaveState(StateRecorder &inStream,
const StateRecorderFilter *inFilter)
const;
407 bool RestoreState(
const ManifoldCache &inReadCache, StateRecorder &inStream,
const StateRecorderFilter *inFilter);
411 static constexpr uint32 cAllocatorBlockSize = 4096;
414 LFHMAllocator mAllocator;
417 ManifoldMap mCachedManifolds { mAllocator };
420 BodyPairMap mCachedBodyPairs { mAllocator };
422#ifdef JPH_ENABLE_ASSERTS
423 bool mIsFinalized =
false;
427 ManifoldCache mCache[2];
428 int mCacheWriteIdx = 0;
429 ManifoldCache * mReadCache =
nullptr;
430 ManifoldCache * mWriteCache =
nullptr;
433 template <EMotionType Type1, EMotionType Type2>
434 class WorldContactPoint
437 using ConstraintPart = ContactConstraintPart<Type1, Type2>;
440 JPH_INLINE
void CalculateNonPenetrationConstraintProperties(
float inDeltaTime,
Vec3Arg inGravity,
const Body &inBody1,
const Body &inBody2,
float inInvM1,
float inInvM2,
Mat44Arg inInvI1,
Mat44Arg inInvI2,
RVec3Arg inWorldSpacePosition1,
RVec3Arg inWorldSpacePosition2,
Vec3Arg inWorldSpaceNormal,
const ContactSettings &inSettings,
float inMinVelocityForRestitution);
443 ConstraintPart mNonPenetrationConstraint;
447 float mDistanceToFrictionCenter;
450 class ContactConstraintBase
454 JPH_INLINE Vec3 GetWorldSpaceNormal()
const
460 JPH_INLINE
void GetTangents(Vec3 &outTangent1, Vec3 &outTangent2)
const
462 Vec3 ws_normal = GetWorldSpaceNormal();
464 outTangent2 = ws_normal.
Cross(outTangent1);
470 Float3 mWorldSpaceNormal;
471 float mCombinedFriction;
473 float mInvInertiaScale1;
475 float mInvInertiaScale2;
476 uint32 mCachedManifoldHandle;
481 template <EMotionType Type1, EMotionType Type2>
482 class ContactConstraint :
public ContactConstraintBase
486 JPH_INLINE
void CalculateFrictionConstraintProperties(
const Body &inBody1,
const Body &inBody2,
float inInvM1,
float inInvM2,
Mat44Arg inInvI1,
Mat44Arg inInvI2,
const RVec3 *inWorldSpaceContacts,
Vec3Arg inWorldSpaceNormal,
Vec3Arg inWorldSpaceTangent1,
Vec3Arg inWorldSpaceTangent2,
const ContactSettings &inSettings);
488 #ifdef JPH_DEBUG_RENDERER
490 void Draw(DebugRenderer *inRenderer,
const ManifoldCache &inManifoldCache,
ColorArg inManifoldColor)
const;
493 ContactConstraintPart<Type1, Type2> mFrictionConstraint1;
494 ContactConstraintPart<Type1, Type2> mFrictionConstraint2;
495 AngularFrictionConstraintPart<Type1, Type2> mAngularFrictionConstraint;
497 WorldContactPoint<Type1, Type2> mContactPoints[1];
502 static constexpr uint32 cMaxConstraintSize =
sizeof(ContactConstraint<EMotionType::Dynamic, EMotionType::Dynamic>) + (
MaxContactPoints - 1) *
sizeof(WorldContactPoint<EMotionType::Dynamic, EMotionType::Dynamic>);
512 template <EMotionType Type1, EMotionType Type2>
513 JPH_INLINE ContactConstraint<Type1, Type2> *CreateConstraint(
bool &ioActivateAndLinkBodies,
Body &inBody1,
Body &inBody2,
uint64 inSortKey,
uint32 inCachedManifoldHandle,
Vec3Arg inWorldSpaceNormal,
const ContactSettings &inSettings,
uint32 inNumContactPoints);
516 template <EMotionType Type1, EMotionType Type2>
517 void TemplatedGetContactsFromCache(
ContactAllocator &ioContactAllocator,
Body &inBody1,
Body &inBody2,
const CachedBodyPair &inCachedBodyPair, CachedBodyPair &outCachedBodyPair);
520 template <EMotionType Type1, EMotionType Type2>
524 template <EMotionType Type1, EMotionType Type2>
528 template <EMotionType Type1, EMotionType Type2>
532 template <EMotionType Type1, EMotionType Type2>
533 static void sWarmStartConstraint(ContactConstraintBase &ioConstraint,
MotionProperties *ioMotionProperties1,
MotionProperties *ioMotionProperties2,
float inWarmStartImpulseRatio);
536 template <EMotionType Type1, EMotionType Type2>
540 template <EMotionType Type1, EMotionType Type2>
541 static void sStoreAppliedImpulses(ContactConstraintBase &ioConstraint, ManifoldCache &inManifoldCache);
544 template <EMotionType Type1, EMotionType Type2>
545 static bool sSolvePositionConstraint(ContactConstraintBase &ioConstraint,
Body &ioBody1,
Body &ioBody2,
const PhysicsSettings &inSettings,
const ManifoldCache &inManifoldCache);
558 uint8 * mConstraints =
nullptr;
559 uint32 * mConstraintIdxToOffset =
nullptr;
560 uint32 mMaxConstraints = 0;
561 atomic<uint64> mNumConstraintsAndNextConstraintOffset { 0 };
564 PhysicsUpdateContext * mUpdateContext;
Color ColorArg
Type to use for passing arguments to a function.
Definition Color.h:12
std::uint8_t uint8
Definition Core.h:547
#define JPH_EXPORT
Definition Core.h:286
#define JPH_SUPPRESS_WARNINGS_STD_BEGIN
Definition Core.h:474
#define JPH_SUPPRESS_WARNINGS_STD_END
Definition Core.h:488
std::uint64_t uint64
Definition Core.h:551
unsigned int uint
Definition Core.h:546
#define JPH_NAMESPACE_END
Definition Core.h:469
std::uint32_t uint32
Definition Core.h:549
#define JPH_NAMESPACE_BEGIN
Definition Core.h:463
std::uint16_t uint16
Definition Core.h:548
EPhysicsUpdateError
Enum used by PhysicsSystem to report error conditions during the PhysicsSystem::Update call....
Definition EPhysicsUpdateError.h:11
@ None
No errors.
Definition EPhysicsUpdateError.h:12
JPH_INLINE float Sqrt(float inV)
Take the square root of a float value.
Definition Math.h:76
const Vec3 Vec3Arg
Definition MathTypes.h:19
const Mat44 & Mat44Arg
Definition MathTypes.h:29
#define JPH_OVERRIDE_NEW_DELETE
Macro to override the new and delete functions.
Definition Memory.h:50
Vec3Arg RVec3Arg
Definition Real.h:30
Vec3 RVec3
Definition Real.h:29
@ Array
Used in attribute declaration, indicates that this is an array of objects.
Definition SerializableAttribute.h:23
float GetRestitution() const
Restitution (dimensionless number, usually between 0 and 1, 0 = completely inelastic collision respon...
Definition Body.h:146
float GetFriction() const
Friction (dimensionless number, usually between 0 and 1, 0 = no friction, 1 = friction force equals f...
Definition Body.h:142
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 information of two colliding shapes.
Definition CollideShape.h:19
Class that holds 3 floats. Used as a storage class. Convert to Vec3 for calculations.
Definition Float3.h:13
LFHMAllocatorContext(LFHMAllocator &inAllocator, uint32 inBlockSize)
Construct a new allocator context.
Definition LockFreeHashMap.inl:88
The Body class only keeps track of state for static bodies, the MotionProperties class keeps the addi...
Definition MotionProperties.h:29
User callbacks that allow determining which parts of the simulation should be saved by a StateRecorde...
Definition StateRecorder.h:79
Definition StateRecorder.h:110
A sub shape id contains a path to an element (usually a triangle or other primitive type) of a compou...
Definition SubShapeID.h:23
JPH_INLINE Vec3 Cross(Vec3Arg inV2) const
Cross product.
Definition Vec3.inl:855
JPH_INLINE Vec3 GetNormalizedPerpendicular() const
Get normalized vector that is perpendicular to this vector.
Definition Vec3.inl:1119
static JPH_INLINE Vec3 sLoadFloat3Unsafe(const Float3 &inV)
Load 3 floats from memory (reads 32 bits extra which it doesn't use).
Definition Vec3.inl:167
Definition PhysicsSettings.h:31