Jolt Physics
A multi core friendly Game Physics Engine
Loading...
Searching...
No Matches
CharacterVirtual.h
Go to the documentation of this file.
1// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
2// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
3// SPDX-License-Identifier: MIT
4
5#pragma once
6
16
18
21
24{
25public:
27
32
35
37 float mMass = 70.0f;
38
40 float mMaxStrength = 100.0f;
41
43 Vec3 mShapeOffset = Vec3::sZero();
44
47 float mPredictiveContactDistance = 0.1f;
48 uint mMaxCollisionIterations = 5;
49 uint mMaxConstraintIterations = 15;
50 float mMinTimeRemaining = 1.0e-4f;
51 float mCollisionTolerance = 1.0e-3f;
52 float mCharacterPadding = 0.02f;
53 uint mMaxNumHits = 256;
54 float mHitReductionCosMaxAngle = 0.999f;
55 float mPenetrationRecoverySpeed = 1.0f;
56
62
66
68 ObjectLayer mInnerBodyLayer = 0;
69};
70
73{
74public:
76 bool mCanPushCharacter = true;
77
81 bool mCanReceiveImpulses = true;
82};
83
86{
87public:
90 CharacterContactKey(const CharacterContactKey &inContact) = default;
91 CharacterContactKey(const BodyID &inBodyB, const SubShapeID &inSubShapeID) : mBodyB(inBodyB), mSubShapeIDB(inSubShapeID) { }
92 CharacterContactKey(const CharacterID &inCharacterIDB, const SubShapeID &inSubShapeID) : mCharacterIDB(inCharacterIDB), mSubShapeIDB(inSubShapeID) { }
94
96 inline bool IsSameBody(const CharacterContactKey &inOther) const
97 {
98 return mBodyB == inOther.mBodyB && mCharacterIDB == inOther.mCharacterIDB;
99 }
100
102 inline bool operator == (const CharacterContactKey &inRHS) const
103 {
104 return mBodyB == inRHS.mBodyB && mCharacterIDB == inRHS.mCharacterIDB && mSubShapeIDB == inRHS.mSubShapeIDB;
105 }
106
107 inline bool operator != (const CharacterContactKey &inRHS) const
108 {
109 return !(*this == inRHS);
110 }
111
113 inline uint64 GetHash() const
114 {
115 static_assert(sizeof(BodyID) + sizeof(CharacterID) + sizeof(SubShapeID) == sizeof(CharacterContactKey), "No padding expected");
116 return HashBytes(this, sizeof(CharacterContactKey));
117 }
118
119 // Saving / restoring state for replay
120 void SaveState(StateRecorder &inStream) const;
121 void RestoreState(StateRecorder &inStream);
122
126};
127
130{
131public:
132 // Saving / restoring state for replay
133 void SaveState(StateRecorder &inStream) const;
134 void RestoreState(StateRecorder &inStream);
135
140 float mDistance;
141 float mFraction;
144 const CharacterVirtual * mCharacterB = nullptr;
147 bool mHadCollision = false;
148 bool mWasDiscarded = false;
149 bool mCanPushCharacter = true;
150 bool mIsBackFacingContact = false;
151};
152
156{
157public:
159 virtual ~CharacterContactListener() = default;
160
163 virtual void OnAdjustBodyVelocity(const CharacterVirtual *inCharacter, const Body &inBody2, Vec3 &ioLinearVelocity, Vec3 &ioAngularVelocity) { /* Do nothing, the linear and angular velocity are already filled in */ }
164
166 virtual bool OnContactValidate(const CharacterVirtual *inCharacter, const CharacterContact &inContact) { return true; }
167
172 virtual void OnContactAdded(const CharacterVirtual *inCharacter, const CharacterContact &inContact, CharacterContactSettings &ioSettings) { /* Default do nothing */ }
173
178 virtual void OnContactPersisted(const CharacterVirtual *inCharacter, const CharacterContact &inContact, CharacterContactSettings &ioSettings) { /* Default do nothing */ }
179
185 virtual void OnContactRemoved(const CharacterVirtual *inCharacter, const BodyID &inBodyID2, const SubShapeID &inSubShapeID2) { /* Default do nothing */ }
186
188 virtual bool OnCharacterContactValidate(const CharacterVirtual *inCharacter, const CharacterContact &inContact) { return true; }
189
191 virtual void OnCharacterContactAdded(const CharacterVirtual *inCharacter, const CharacterContact &inContact, CharacterContactSettings &ioSettings) { /* Default do nothing */ }
192
194 virtual void OnCharacterContactPersisted(const CharacterVirtual *inCharacter, const CharacterContact &inContact, CharacterContactSettings &ioSettings) { /* Default do nothing */ }
195
198 virtual void OnCharacterContactRemoved(const CharacterVirtual *inCharacter, const CharacterID &inOtherCharacterID, const SubShapeID &inSubShapeID2) { /* Default do nothing */ }
199
210 virtual void OnContactSolve(const CharacterVirtual *inCharacter, const BodyID &inBodyID2, const SubShapeID &inSubShapeID2, RVec3Arg inContactPosition, Vec3Arg inContactNormal, Vec3Arg inContactVelocity, const PhysicsMaterial *inContactMaterial, Vec3Arg inCharacterVelocity, Vec3 &ioNewCharacterVelocity) { /* Default do nothing */ }
211
213 virtual void OnCharacterContactSolve(const CharacterVirtual *inCharacter, const CharacterVirtual *inOtherCharacter, const SubShapeID &inSubShapeID2, RVec3Arg inContactPosition, Vec3Arg inContactNormal, Vec3Arg inContactVelocity, const PhysicsMaterial *inContactMaterial, Vec3Arg inCharacterVelocity, Vec3 &ioNewCharacterVelocity) { /* Default do nothing */ }
214};
215
220{
221public:
223
230 virtual void CollideCharacter(const CharacterVirtual *inCharacter, RMat44Arg inCenterOfMassTransform, const CollideShapeSettings &inCollideShapeSettings, RVec3Arg inBaseOffset, CollideShapeCollector &ioCollector) const = 0;
231
239 virtual void CastCharacter(const CharacterVirtual *inCharacter, RMat44Arg inCenterOfMassTransform, Vec3Arg inDirection, const ShapeCastSettings &inShapeCastSettings, RVec3Arg inBaseOffset, CastShapeCollector &ioCollector) const = 0;
240};
241
247{
248public:
250 void Add(CharacterVirtual *inCharacter) { mCharacters.push_back(inCharacter); }
251
253 void Remove(const CharacterVirtual *inCharacter);
254
255 // See: CharacterVsCharacterCollision
256 virtual void CollideCharacter(const CharacterVirtual *inCharacter, RMat44Arg inCenterOfMassTransform, const CollideShapeSettings &inCollideShapeSettings, RVec3Arg inBaseOffset, CollideShapeCollector &ioCollector) const override;
257 virtual void CastCharacter(const CharacterVirtual *inCharacter, RMat44Arg inCenterOfMassTransform, Vec3Arg inDirection, const ShapeCastSettings &inShapeCastSettings, RVec3Arg inBaseOffset, CastShapeCollector &ioCollector) const override;
258
260};
261
269{
270public:
272
279 CharacterVirtual(const CharacterVirtualSettings *inSettings, RVec3Arg inPosition, QuatArg inRotation, uint64 inUserData, PhysicsSystem *inSystem);
280
282 CharacterVirtual(const CharacterVirtualSettings *inSettings, RVec3Arg inPosition, QuatArg inRotation, PhysicsSystem *inSystem) : CharacterVirtual(inSettings, inPosition, inRotation, 0, inSystem) { }
283
285 virtual ~CharacterVirtual() override;
286
288 inline const CharacterID & GetID() const { return mID; }
289
291 void SetListener(CharacterContactListener *inListener) { mListener = inListener; }
292
294 CharacterContactListener * GetListener() const { return mListener; }
295
297 void SetCharacterVsCharacterCollision(CharacterVsCharacterCollision *inCharacterVsCharacterCollision) { mCharacterVsCharacterCollision = inCharacterVsCharacterCollision; }
298
300 Vec3 GetLinearVelocity() const { return mLinearVelocity; }
301
303 void SetLinearVelocity(Vec3Arg inLinearVelocity) { mLinearVelocity = inLinearVelocity; }
304
306 RVec3 GetPosition() const { return mPosition; }
307
309 void SetPosition(RVec3Arg inPosition) { mPosition = inPosition; UpdateInnerBodyTransform(); }
310
312 Quat GetRotation() const { return mRotation; }
313
315 void SetRotation(QuatArg inRotation) { mRotation = inRotation; UpdateInnerBodyTransform(); }
316
317 // Get the center of mass position of the shape
318 inline RVec3 GetCenterOfMassPosition() const { return mPosition + (mRotation * (mShapeOffset + mShape->GetCenterOfMass()) + mCharacterPadding * mUp); }
319
321 RMat44 GetWorldTransform() const { return RMat44::sRotationTranslation(mRotation, mPosition); }
322
324 RMat44 GetCenterOfMassTransform() const { return GetCenterOfMassTransform(mPosition, mRotation, mShape); }
325
327 float GetMass() const { return mMass; }
328 void SetMass(float inMass) { mMass = inMass; }
329
331 float GetMaxStrength() const { return mMaxStrength; }
332 void SetMaxStrength(float inMaxStrength) { mMaxStrength = inMaxStrength; }
333
335 float GetPenetrationRecoverySpeed() const { return mPenetrationRecoverySpeed; }
336 void SetPenetrationRecoverySpeed(float inSpeed) { mPenetrationRecoverySpeed = inSpeed; }
337
340 void SetEnhancedInternalEdgeRemoval(bool inApply) { mEnhancedInternalEdgeRemoval = inApply; }
341
343 float GetCharacterPadding() const { return mCharacterPadding; }
344
346 uint GetMaxNumHits() const { return mMaxNumHits; }
347 void SetMaxNumHits(uint inMaxHits) { mMaxNumHits = inMaxHits; }
348
350 float GetHitReductionCosMaxAngle() const { return mHitReductionCosMaxAngle; }
351 void SetHitReductionCosMaxAngle(float inCosMaxAngle) { mHitReductionCosMaxAngle = inCosMaxAngle; }
352
357 bool GetMaxHitsExceeded() const { return mMaxHitsExceeded; }
358
360 Vec3 GetShapeOffset() const { return mShapeOffset; }
361 void SetShapeOffset(Vec3Arg inShapeOffset) { mShapeOffset = inShapeOffset; UpdateInnerBodyTransform(); }
362
364 uint64 GetUserData() const { return mUserData; }
365 void SetUserData(uint64 inUserData);
366
368 BodyID GetInnerBodyID() const { return mInnerBodyID; }
369
374 Vec3 CancelVelocityTowardsSteepSlopes(Vec3Arg inDesiredVelocity) const;
375
380 void StartTrackingContactChanges();
381
383 void FinishTrackingContactChanges();
384
395 void Update(float inDeltaTime, Vec3Arg inGravity, const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter, const BodyFilter &inBodyFilter, const ShapeFilter &inShapeFilter, TempAllocator &inAllocator);
396
400 bool CanWalkStairs(Vec3Arg inLinearVelocity) const;
401
414 bool WalkStairs(float inDeltaTime, Vec3Arg inStepUp, Vec3Arg inStepForward, Vec3Arg inStepForwardTest, Vec3Arg inStepDownExtra, const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter, const BodyFilter &inBodyFilter, const ShapeFilter &inShapeFilter, TempAllocator &inAllocator);
415
426 bool StickToFloor(Vec3Arg inStepDown, const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter, const BodyFilter &inBodyFilter, const ShapeFilter &inShapeFilter, TempAllocator &inAllocator);
427
430 {
431 Vec3 mStickToFloorStepDown { 0, -0.5f, 0 };
432 Vec3 mWalkStairsStepUp { 0, 0.4f, 0 };
433 float mWalkStairsMinStepForward { 0.02f };
434 float mWalkStairsStepForwardTest { 0.15f };
435 float mWalkStairsCosAngleForwardContact { Cos(DegreesToRadians(75.0f)) };
436 Vec3 mWalkStairsStepDownExtra { Vec3::sZero() };
437 };
438
451 void ExtendedUpdate(float inDeltaTime, Vec3Arg inGravity, const ExtendedUpdateSettings &inSettings, const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter, const BodyFilter &inBodyFilter, const ShapeFilter &inShapeFilter, TempAllocator &inAllocator);
452
454 void RefreshContacts(const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter, const BodyFilter &inBodyFilter, const ShapeFilter &inShapeFilter, TempAllocator &inAllocator);
455
458 void UpdateGroundVelocity();
459
469 bool SetShape(const Shape *inShape, float inMaxPenetrationDepth, const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter, const BodyFilter &inBodyFilter, const ShapeFilter &inShapeFilter, TempAllocator &inAllocator);
470
472 void SetInnerBodyShape(const Shape *inShape);
473
475 TransformedShape GetTransformedShape() const { return TransformedShape(GetCenterOfMassPosition(), mRotation, mShape, mInnerBodyID); }
476
490 void CheckCollision(RVec3Arg inPosition, QuatArg inRotation, Vec3Arg inMovementDirection, float inMaxSeparationDistance, const Shape *inShape, RVec3Arg inBaseOffset, CollideShapeCollector &ioCollector, const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter, const BodyFilter &inBodyFilter, const ShapeFilter &inShapeFilter) const;
491
493 CharacterVirtualSettings GetCharacterVirtualSettings() const;
494
495 // Saving / restoring state for replay
496 virtual void SaveState(StateRecorder &inStream) const override;
497 virtual void RestoreState(StateRecorder &inStream) override;
498
499#ifdef JPH_DEBUG_RENDERER
500 static inline bool sDrawConstraints = false;
501 static inline bool sDrawWalkStairs = false;
502 static inline bool sDrawStickToFloor = false;
503 static inline bool sDrawSupportingVolume = false;
504#endif
505
508
511 const ContactList & GetActiveContacts() const { return mActiveContacts; }
512
514 bool HasCollidedWith(const BodyID &inBody) const
515 {
516 for (const CharacterContact &c : mActiveContacts)
517 if (c.mHadCollision && c.mBodyB == inBody)
518 return true;
519 return false;
520 }
521
523 bool HasCollidedWith(const CharacterID &inCharacterID) const
524 {
525 for (const CharacterContact &c : mActiveContacts)
526 if (c.mHadCollision && c.mCharacterIDB == inCharacterID)
527 return true;
528 return false;
529 }
530
532 bool HasCollidedWith(const CharacterVirtual *inCharacter) const
533 {
534 return HasCollidedWith(inCharacter->GetID());
535 }
536
537private:
538 // Sorting predicate for making contact order deterministic
539 struct ContactOrderingPredicate
540 {
541 inline bool operator () (const CharacterContact &inLHS, const CharacterContact &inRHS) const
542 {
543 if (inLHS.mBodyB != inRHS.mBodyB)
544 return inLHS.mBodyB < inRHS.mBodyB;
545
546 if (inLHS.mCharacterIDB != inRHS.mCharacterIDB)
547 return inLHS.mCharacterIDB < inRHS.mCharacterIDB;
548
549 return inLHS.mSubShapeIDB.GetValue() < inRHS.mSubShapeIDB.GetValue();
550 }
551 };
552
554
555 // A constraint that limits the movement of the character
556 struct Constraint
557 {
558 CharacterContact * mContact;
559 float mTOI;
560 float mProjectedVelocity;
561 Vec3 mLinearVelocity;
562 Plane mPlane;
563 bool mIsSteepSlope = false;
564 };
565
567
568 // Collision collector that collects hits for CollideShape
569 class ContactCollector : public CollideShapeCollector
570 {
571 public:
572 ContactCollector(PhysicsSystem *inSystem, const CharacterVirtual *inCharacter, uint inMaxHits, float inHitReductionCosMaxAngle, Vec3Arg inUp, RVec3Arg inBaseOffset, TempContactList &outContacts) : mBaseOffset(inBaseOffset), mUp(inUp), mSystem(inSystem), mCharacter(inCharacter), mContacts(outContacts), mMaxHits(inMaxHits), mHitReductionCosMaxAngle(inHitReductionCosMaxAngle) { }
573
574 virtual void SetUserData(uint64 inUserData) override { mOtherCharacter = reinterpret_cast<CharacterVirtual *>(inUserData); }
575
576 virtual void AddHit(const CollideShapeResult &inResult) override;
577
578 RVec3 mBaseOffset;
579 Vec3 mUp;
580 PhysicsSystem * mSystem;
581 const CharacterVirtual * mCharacter;
582 CharacterVirtual * mOtherCharacter = nullptr;
583 TempContactList & mContacts;
584 uint mMaxHits;
585 float mHitReductionCosMaxAngle;
586 bool mMaxHitsExceeded = false;
587 };
588
589 // A collision collector that collects hits for CastShape
590 class ContactCastCollector : public CastShapeCollector
591 {
592 public:
593 ContactCastCollector(PhysicsSystem *inSystem, const CharacterVirtual *inCharacter, Vec3Arg inDisplacement, Vec3Arg inUp, const IgnoredContactList &inIgnoredContacts, RVec3Arg inBaseOffset, CharacterContact &outContact) : mBaseOffset(inBaseOffset), mDisplacement(inDisplacement), mUp(inUp), mSystem(inSystem), mCharacter(inCharacter), mIgnoredContacts(inIgnoredContacts), mContact(outContact) { }
594
595 virtual void SetUserData(uint64 inUserData) override { mOtherCharacter = reinterpret_cast<CharacterVirtual *>(inUserData); }
596
597 virtual void AddHit(const ShapeCastResult &inResult) override;
598
599 RVec3 mBaseOffset;
600 Vec3 mDisplacement;
601 Vec3 mUp;
602 PhysicsSystem * mSystem;
603 const CharacterVirtual * mCharacter;
604 CharacterVirtual * mOtherCharacter = nullptr;
605 const IgnoredContactList & mIgnoredContacts;
606 CharacterContact & mContact;
607 };
608
609 // Helper function to convert a Jolt collision result into a contact
610 template <class taCollector>
611 inline static void sFillContactProperties(const CharacterVirtual *inCharacter, CharacterContact &outContact, const Body &inBody, Vec3Arg inUp, RVec3Arg inBaseOffset, const taCollector &inCollector, const CollideShapeResult &inResult);
612 inline static void sFillCharacterContactProperties(CharacterContact &outContact, const CharacterVirtual *inOtherCharacter, RVec3Arg inBaseOffset, const CollideShapeResult &inResult);
613
614 // Move the shape from ioPosition and try to displace it by inVelocity * inDeltaTime, this will try to slide the shape along the world geometry
615 void MoveShape(RVec3 &ioPosition, Vec3Arg inVelocity, float inDeltaTime, ContactList *outActiveContacts, const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter, const BodyFilter &inBodyFilter, const ShapeFilter &inShapeFilter, TempAllocator &inAllocator
616 #ifdef JPH_DEBUG_RENDERER
617 , bool inDrawConstraints = false
618 #endif // JPH_DEBUG_RENDERER
619 );
620
621 // Ask the callback if inContact is a valid contact point
622 bool ValidateContact(const CharacterContact &inContact) const;
623
624 // Trigger the contact callback for inContact and get the contact settings
625 void ContactAdded(const CharacterContact &inContact, CharacterContactSettings &ioSettings);
626
627 // Tests the shape for collision around inPosition
628 void GetContactsAtPosition(RVec3Arg inPosition, Vec3Arg inMovementDirection, const Shape *inShape, TempContactList &outContacts, const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter, const BodyFilter &inBodyFilter, const ShapeFilter &inShapeFilter) const;
629
630 // Remove penetrating contacts with the same body that have conflicting normals, leaving these will make the character mover get stuck
631 void RemoveConflictingContacts(TempContactList &ioContacts, IgnoredContactList &outIgnoredContacts) const;
632
633 // Convert contacts into constraints. The character is assumed to start at the origin and the constraints are planes around the origin that confine the movement of the character.
634 void DetermineConstraints(TempContactList &inContacts, float inDeltaTime, ConstraintList &outConstraints) const;
635
636 // Use the constraints to solve the displacement of the character. This will slide the character on the planes around the origin for as far as possible.
637 void SolveConstraints(Vec3Arg inVelocity, float inDeltaTime, float inTimeRemaining, ConstraintList &ioConstraints, IgnoredContactList &ioIgnoredContacts, float &outTimeSimulated, Vec3 &outDisplacement, TempAllocator &inAllocator
638 #ifdef JPH_DEBUG_RENDERER
639 , bool inDrawConstraints = false
640 #endif // JPH_DEBUG_RENDERER
641 );
642
643 // Get the velocity of a body adjusted by the contact listener
644 void GetAdjustedBodyVelocity(const Body& inBody, Vec3 &outLinearVelocity, Vec3 &outAngularVelocity) const;
645
646 // Calculate the ground velocity of the character assuming it's standing on an object with specified linear and angular velocity and with specified center of mass.
647 // Note that we don't just take the point velocity because a point on an object with angular velocity traces an arc,
648 // so if you just take point velocity * delta time you get an error that accumulates over time
649 Vec3 CalculateCharacterGroundVelocity(RVec3Arg inCenterOfMass, Vec3Arg inLinearVelocity, Vec3Arg inAngularVelocity, float inDeltaTime) const;
650
651 // Handle contact with physics object that we're colliding against
652 bool HandleContact(Vec3Arg inVelocity, Constraint &ioConstraint, float inDeltaTime);
653
654 // Does a swept test of the shape from inPosition with displacement inDisplacement, returns true if there was a collision
655 bool GetFirstContactForSweep(RVec3Arg inPosition, Vec3Arg inDisplacement, CharacterContact &outContact, const IgnoredContactList &inIgnoredContacts, const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter, const BodyFilter &inBodyFilter, const ShapeFilter &inShapeFilter) const;
656
657 // Store contacts so that we have proper ground information
658 void StoreActiveContacts(const TempContactList &inContacts, TempAllocator &inAllocator);
659
660 // This function will determine which contacts are touching the character and will calculate the one that is supporting us
661 void UpdateSupportingContact(bool inSkipContactVelocityCheck, TempAllocator &inAllocator);
662
664 void MoveToContact(RVec3Arg inPosition, const CharacterContact &inContact, const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter, const BodyFilter &inBodyFilter, const ShapeFilter &inShapeFilter, TempAllocator &inAllocator);
665
666 // This function returns the actual center of mass of the shape, not corrected for the character padding
667 inline RMat44 GetCenterOfMassTransform(RVec3Arg inPosition, QuatArg inRotation, const Shape *inShape) const
668 {
669 return RMat44::sRotationTranslation(inRotation, inPosition).PreTranslated(mShapeOffset + inShape->GetCenterOfMass()).PostTranslated(mCharacterPadding * mUp);
670 }
671
672 // This function returns the position of the inner rigid body
673 inline RVec3 GetInnerBodyPosition() const
674 {
675 return mPosition + (mRotation * mShapeOffset + mCharacterPadding * mUp);
676 }
677
678 // Move the inner rigid body to the current position
679 void UpdateInnerBodyTransform();
680
681 // ID
682 CharacterID mID;
683
684 // Our main listener for contacts
685 CharacterContactListener * mListener = nullptr;
686
687 // Interface to detect collision between characters
688 CharacterVsCharacterCollision * mCharacterVsCharacterCollision = nullptr;
689
690 // Movement settings
691 EBackFaceMode mBackFaceMode; // When colliding with back faces, the character will not be able to move through back facing triangles. Use this if you have triangles that need to collide on both sides.
692 float mPredictiveContactDistance; // How far to scan outside of the shape for predictive contacts. A value of 0 will most likely cause the character to get stuck as it cannot properly calculate a sliding direction anymore. A value that's too high will cause ghost collisions.
693 uint mMaxCollisionIterations; // Max amount of collision loops
694 uint mMaxConstraintIterations; // How often to try stepping in the constraint solving
695 float mMinTimeRemaining; // Early out condition: If this much time is left to simulate we are done
696 float mCollisionTolerance; // How far we're willing to penetrate geometry
697 float mCharacterPadding; // How far we try to stay away from the geometry, this ensures that the sweep will hit as little as possible lowering the collision cost and reducing the risk of getting stuck
698 uint mMaxNumHits; // Max num hits to collect in order to avoid excess of contact points collection
699 float mHitReductionCosMaxAngle; // Cos(angle) where angle is the maximum angle between two hits contact normals that are allowed to be merged during hit reduction. Default is around 2.5 degrees. Set to -1 to turn off.
700 float mPenetrationRecoverySpeed; // This value governs how fast a penetration will be resolved, 0 = nothing is resolved, 1 = everything in one update
701 bool mEnhancedInternalEdgeRemoval; // Set to indicate that extra effort should be made to try to remove ghost contacts (collisions with internal edges of a mesh). This is more expensive but makes bodies move smoother over a mesh with convex edges.
702
703 // Character mass (kg)
704 float mMass;
705
706 // Maximum force with which the character can push other bodies (N)
707 float mMaxStrength;
708
709 // An extra offset applied to the shape in local space. This allows applying an extra offset to the shape in local space.
710 Vec3 mShapeOffset = Vec3::sZero();
711
712 // Current position (of the base, not the center of mass)
713 RVec3 mPosition = RVec3::sZero();
714
715 // Current rotation (of the base, not of the center of mass)
716 Quat mRotation = Quat::sIdentity();
717
718 // Current linear velocity
719 Vec3 mLinearVelocity = Vec3::sZero();
720
721 // List of contacts that were active in the last frame
722 ContactList mActiveContacts;
723
724 // Remembers how often we called StartTrackingContactChanges
725 int mTrackingContactChanges = 0;
726
727 // View from a contact listener perspective on which contacts have been added/removed
728 struct ListenerContactValue
729 {
730 ListenerContactValue() = default;
731 explicit ListenerContactValue(const CharacterContactSettings &inSettings) : mSettings(inSettings) { }
732
733 CharacterContactSettings mSettings;
734 int mCount = 0;
735 };
736
738 ListenerContacts mListenerContacts;
739
740 // Remembers the delta time of the last update
741 float mLastDeltaTime = 1.0f / 60.0f;
742
743 // Remember if we exceeded the maximum number of hits and had to remove similar contacts
744 mutable bool mMaxHitsExceeded = false;
745
746 // User data, can be used for anything by the application
747 uint64 mUserData = 0;
748
749 // The inner rigid body that proxies the character in the world
750 BodyID mInnerBodyID;
751};
752
EBackFaceMode
How collision detection functions will treat back facing triangles.
Definition BackFaceMode.h:11
@ CollideWithBackFaces
Collide with back facing surfaces/triangles.
#define JPH_EXPORT
Definition Core.h:283
std::uint64_t uint64
Definition Core.h:514
unsigned int uint
Definition Core.h:509
#define JPH_NAMESPACE_END
Definition Core.h:433
#define JPH_NAMESPACE_BEGIN
Definition Core.h:427
JPH_NAMESPACE_BEGIN uint64 HashBytes(const void *inData, uint inSize, uint64 inSeed=0xcbf29ce484222325UL)
Definition HashCombine.h:15
JPH_INLINE constexpr float DegreesToRadians(float inV)
Convert a value from degrees to radians.
Definition Math.h:16
#define JPH_OVERRIDE_NEW_DELETE
Macro to override the new and delete functions.
Definition Memory.h:50
EMotionType
Motion type of a physics body.
Definition MotionType.h:11
uint16 ObjectLayer
Definition ObjectLayer.h:16
JPH_INLINE float Cos(float inX)
Cosine of x (input in radians)
Definition Trigonometry.h:20
Definition Array.h:36
Class function to filter out bodies, returns true if test should collide with body.
Definition BodyFilter.h:16
Definition Body.h:39
ID of a body. This is a way of reasoning about bodies in a multithreaded simulation while avoiding ra...
Definition BodyID.h:13
Filter class for broadphase layers.
Definition BroadPhaseLayer.h:94
Base class for character class.
Definition CharacterBase.h:54
Base class for configuration of a character.
Definition CharacterBase.h:21
bool mEnhancedInternalEdgeRemoval
Set to indicate that extra effort should be made to try to remove ghost contacts (collisions with int...
Definition CharacterBase.h:45
CharacterBaseSettings & operator=(const CharacterBaseSettings &)=default
Vec3 mUp
Vector indicating the up direction of the character.
Definition CharacterBase.h:34
Encapsulates a collision contact between a character and another rigid body / character.
Definition CharacterVirtual.h:130
bool mIsSensorB
If B is a sensor.
Definition CharacterVirtual.h:143
float mFraction
Fraction along the path where this contact takes place.
Definition CharacterVirtual.h:141
Vec3 mLinearVelocity
Velocity of the contact point.
Definition CharacterVirtual.h:137
EMotionType mMotionTypeB
Motion type of B, used to determine the priority of the contact.
Definition CharacterVirtual.h:142
uint64 mUserData
User data of B.
Definition CharacterVirtual.h:145
Vec3 mSurfaceNormal
Surface normal of the contact. Has been flipped if the contact is back facing (mIsBackFacingContact) ...
Definition CharacterVirtual.h:139
float mDistance
Distance to the contact <= 0 means that it is an actual contact, > 0 means predictive.
Definition CharacterVirtual.h:140
RVec3 mPosition
Position where the character makes contact.
Definition CharacterVirtual.h:136
const PhysicsMaterial * mMaterial
Material of B.
Definition CharacterVirtual.h:146
Vec3 mContactNormal
Contact normal, pointing towards the character.
Definition CharacterVirtual.h:138
Uniquely identifies a contact between a character and another body or character.
Definition CharacterVirtual.h:86
CharacterContactKey(const CharacterID &inCharacterIDB, const SubShapeID &inSubShapeID)
Definition CharacterVirtual.h:92
SubShapeID mSubShapeIDB
Sub shape ID of body or character we're colliding with.
Definition CharacterVirtual.h:125
CharacterContactKey(const BodyID &inBodyB, const SubShapeID &inSubShapeID)
Definition CharacterVirtual.h:91
BodyID mBodyB
ID of body we're colliding with (if not invalid)
Definition CharacterVirtual.h:123
bool IsSameBody(const CharacterContactKey &inOther) const
Checks if two contacts refer to the same body (or virtual character)
Definition CharacterVirtual.h:96
CharacterID mCharacterIDB
Character we're colliding with (if not invalid)
Definition CharacterVirtual.h:124
uint64 GetHash() const
Hash of this structure.
Definition CharacterVirtual.h:113
CharacterContactKey()=default
Constructor.
CharacterContactKey(const CharacterContactKey &inContact)=default
Definition CharacterVirtual.h:156
virtual ~CharacterContactListener()=default
Destructor.
virtual void OnContactRemoved(const CharacterVirtual *inCharacter, const BodyID &inBodyID2, const SubShapeID &inSubShapeID2)
Definition CharacterVirtual.h:185
virtual void OnContactSolve(const CharacterVirtual *inCharacter, const BodyID &inBodyID2, const SubShapeID &inSubShapeID2, RVec3Arg inContactPosition, Vec3Arg inContactNormal, Vec3Arg inContactVelocity, const PhysicsMaterial *inContactMaterial, Vec3Arg inCharacterVelocity, Vec3 &ioNewCharacterVelocity)
Definition CharacterVirtual.h:210
virtual bool OnContactValidate(const CharacterVirtual *inCharacter, const CharacterContact &inContact)
Checks if a character can collide with specified body. Return true if the contact is valid.
Definition CharacterVirtual.h:166
virtual void OnCharacterContactAdded(const CharacterVirtual *inCharacter, const CharacterContact &inContact, CharacterContactSettings &ioSettings)
Same as OnContactAdded but when colliding with a CharacterVirtual.
Definition CharacterVirtual.h:191
virtual void OnAdjustBodyVelocity(const CharacterVirtual *inCharacter, const Body &inBody2, Vec3 &ioLinearVelocity, Vec3 &ioAngularVelocity)
Definition CharacterVirtual.h:163
virtual void OnCharacterContactRemoved(const CharacterVirtual *inCharacter, const CharacterID &inOtherCharacterID, const SubShapeID &inSubShapeID2)
Definition CharacterVirtual.h:198
virtual void OnContactAdded(const CharacterVirtual *inCharacter, const CharacterContact &inContact, CharacterContactSettings &ioSettings)
Definition CharacterVirtual.h:172
virtual bool OnCharacterContactValidate(const CharacterVirtual *inCharacter, const CharacterContact &inContact)
Same as OnContactValidate but when colliding with a CharacterVirtual.
Definition CharacterVirtual.h:188
virtual void OnCharacterContactSolve(const CharacterVirtual *inCharacter, const CharacterVirtual *inOtherCharacter, const SubShapeID &inSubShapeID2, RVec3Arg inContactPosition, Vec3Arg inContactNormal, Vec3Arg inContactVelocity, const PhysicsMaterial *inContactMaterial, Vec3Arg inCharacterVelocity, Vec3 &ioNewCharacterVelocity)
Same as OnContactSolve but when colliding with a CharacterVirtual.
Definition CharacterVirtual.h:213
virtual void OnContactPersisted(const CharacterVirtual *inCharacter, const CharacterContact &inContact, CharacterContactSettings &ioSettings)
Definition CharacterVirtual.h:178
virtual void OnCharacterContactPersisted(const CharacterVirtual *inCharacter, const CharacterContact &inContact, CharacterContactSettings &ioSettings)
Same as OnContactPersisted but when colliding with a CharacterVirtual.
Definition CharacterVirtual.h:194
This class contains settings that allow you to override the behavior of a character's collision respo...
Definition CharacterVirtual.h:73
ID of a character. Used primarily to identify deleted characters and to sort deterministically.
Definition CharacterID.h:13
static CharacterID sNextCharacterID()
Generate the next available character ID.
Definition CharacterID.h:74
Definition CharacterVirtual.h:269
void SetEnhancedInternalEdgeRemoval(bool inApply)
Definition CharacterVirtual.h:340
TransformedShape GetTransformedShape() const
Get the transformed shape that represents the volume of the character, can be used for collision chec...
Definition CharacterVirtual.h:475
float GetMass() const
Character mass (kg)
Definition CharacterVirtual.h:327
float GetPenetrationRecoverySpeed() const
This value governs how fast a penetration will be resolved, 0 = nothing is resolved,...
Definition CharacterVirtual.h:335
RVec3 GetPosition() const
Get the position of the character.
Definition CharacterVirtual.h:306
void SetLinearVelocity(Vec3Arg inLinearVelocity)
Set the linear velocity of the character (m / s)
Definition CharacterVirtual.h:303
const ContactList & GetActiveContacts() const
Definition CharacterVirtual.h:511
RMat44 GetWorldTransform() const
Calculate the world transform of the character.
Definition CharacterVirtual.h:321
void SetCharacterVsCharacterCollision(CharacterVsCharacterCollision *inCharacterVsCharacterCollision)
Set the character vs character collision interface.
Definition CharacterVirtual.h:297
RVec3 GetCenterOfMassPosition() const
Definition CharacterVirtual.h:318
bool GetMaxHitsExceeded() const
Definition CharacterVirtual.h:357
bool HasCollidedWith(const BodyID &inBody) const
Check if the character is currently in contact with or has collided with another body in the last ope...
Definition CharacterVirtual.h:514
void SetMaxStrength(float inMaxStrength)
Definition CharacterVirtual.h:332
float GetCharacterPadding() const
Character padding.
Definition CharacterVirtual.h:343
void SetMaxNumHits(uint inMaxHits)
Definition CharacterVirtual.h:347
uint GetMaxNumHits() const
Max num hits to collect in order to avoid excess of contact points collection.
Definition CharacterVirtual.h:346
float GetMaxStrength() const
Maximum force with which the character can push other bodies (N)
Definition CharacterVirtual.h:331
void SetShapeOffset(Vec3Arg inShapeOffset)
Definition CharacterVirtual.h:361
BodyID GetInnerBodyID() const
Optional inner rigid body that proxies the character in the world. Can be used to update body propert...
Definition CharacterVirtual.h:368
void SetMass(float inMass)
Definition CharacterVirtual.h:328
bool GetEnhancedInternalEdgeRemoval() const
Set to indicate that extra effort should be made to try to remove ghost contacts (collisions with int...
Definition CharacterVirtual.h:339
bool HasCollidedWith(const CharacterID &inCharacterID) const
Check if the character is currently in contact with or has collided with another character in the las...
Definition CharacterVirtual.h:523
Vec3 GetLinearVelocity() const
Get the linear velocity of the character (m / s)
Definition CharacterVirtual.h:300
CharacterContactListener * GetListener() const
Get the current contact listener.
Definition CharacterVirtual.h:294
RMat44 GetCenterOfMassTransform() const
Calculates the transform for this character's center of mass.
Definition CharacterVirtual.h:324
CharacterVirtual(const CharacterVirtualSettings *inSettings, RVec3Arg inPosition, QuatArg inRotation, PhysicsSystem *inSystem)
Constructor without user data.
Definition CharacterVirtual.h:282
void SetRotation(QuatArg inRotation)
Set the rotation of the character.
Definition CharacterVirtual.h:315
void SetHitReductionCosMaxAngle(float inCosMaxAngle)
Definition CharacterVirtual.h:351
uint64 GetUserData() const
Access to the user data, can be used for anything by the application.
Definition CharacterVirtual.h:364
Vec3 GetShapeOffset() const
An extra offset applied to the shape in local space. This allows applying an extra offset to the shap...
Definition CharacterVirtual.h:360
void SetPenetrationRecoverySpeed(float inSpeed)
Definition CharacterVirtual.h:336
bool HasCollidedWith(const CharacterVirtual *inCharacter) const
Check if the character is currently in contact with or has collided with another character in the las...
Definition CharacterVirtual.h:532
float GetHitReductionCosMaxAngle() const
Cos(angle) where angle is the maximum angle between two hits contact normals that are allowed to be m...
Definition CharacterVirtual.h:350
void SetPosition(RVec3Arg inPosition)
Set the position of the character.
Definition CharacterVirtual.h:309
const CharacterID & GetID() const
The ID of this character.
Definition CharacterVirtual.h:288
void SetListener(CharacterContactListener *inListener)
Set the contact listener.
Definition CharacterVirtual.h:291
Quat GetRotation() const
Get the rotation of the character.
Definition CharacterVirtual.h:312
Contains the configuration of a character.
Definition CharacterVirtual.h:24
JPH_OVERRIDE_NEW_DELETE CharacterVirtualSettings()=default
Constructor.
RefConst< Shape > mInnerBodyShape
Definition CharacterVirtual.h:61
CharacterVirtualSettings(const CharacterVirtualSettings &)=default
BodyID mInnerBodyIDOverride
Definition CharacterVirtual.h:65
Definition CharacterVirtual.h:220
virtual void CollideCharacter(const CharacterVirtual *inCharacter, RMat44Arg inCenterOfMassTransform, const CollideShapeSettings &inCollideShapeSettings, RVec3Arg inBaseOffset, CollideShapeCollector &ioCollector) const =0
virtual ~CharacterVsCharacterCollision()=default
virtual void CastCharacter(const CharacterVirtual *inCharacter, RMat44Arg inCenterOfMassTransform, Vec3Arg inDirection, const ShapeCastSettings &inShapeCastSettings, RVec3Arg inBaseOffset, CastShapeCollector &ioCollector) const =0
Definition CharacterVirtual.h:247
void Add(CharacterVirtual *inCharacter)
Add a character to the list of characters to check collision against.
Definition CharacterVirtual.h:250
Array< CharacterVirtual * > mCharacters
The list of characters to check collision against.
Definition CharacterVirtual.h:259
Class that contains all information of two colliding shapes.
Definition CollideShape.h:19
Settings to be passed with a collision query.
Definition CollideShape.h:94
Virtual interface that allows collecting multiple collision results.
Definition CollisionCollector.h:45
Base class for all physics constraints. A constraint removes one or more degrees of freedom for a rig...
Definition Constraint.h:108
Holds a 4x4 matrix of floats, but supports also operations on the 3x3 upper left part of the matrix.
Definition Mat44.h:13
JPH_INLINE Mat44 PostTranslated(Vec3Arg inTranslation) const
Post multiply by translation matrix: result = Mat44::sTranslation(inTranslation) * this (i....
Definition Mat44.inl:1136
JPH_INLINE Mat44 PreTranslated(Vec3Arg inTranslation) const
Pre multiply by translation matrix: result = this * Mat44::sTranslation(inTranslation)
Definition Mat44.inl:1131
static JPH_INLINE Mat44 sRotationTranslation(QuatArg inR, Vec3Arg inT)
Get matrix that rotates and translates.
Definition Mat44.inl:149
Class that makes another class non-copyable. Usage: Inherit from NonCopyable.
Definition NonCopyable.h:11
Filter class for object layers.
Definition ObjectLayer.h:28
Definition PhysicsMaterial.h:23
Definition PhysicsSystem.h:30
An infinite plane described by the formula X . Normal + Constant = 0.
Definition Plane.h:11
Definition Quat.h:33
static JPH_INLINE Quat sIdentity()
Definition Quat.h:104
Definition Reference.h:166
Result of a shape cast test.
Definition ShapeCast.h:114
Settings to be passed with a shape cast.
Definition ShapeCast.h:92
Filter class.
Definition ShapeFilter.h:17
Base class for all shapes (collision volume of a body). Defines a virtual interface for collision det...
Definition Shape.h:185
virtual Vec3 GetCenterOfMass() const
All shapes are centered around their center of mass. This function returns the center of mass positio...
Definition Shape.h:210
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
Type GetValue() const
Get the value of the path to the sub shape ID.
Definition SubShapeID.h:52
Definition TempAllocator.h:16
Definition TransformedShape.h:26
Definition UnorderedMap.h:31
Definition Vec3.h:17
static JPH_INLINE Vec3 sZero()
Vector with all zeros.
Definition Vec3.inl:125
Settings struct with settings for ExtendedUpdate.
Definition CharacterVirtual.h:430