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
15
17
20
23{
24public:
26
31
34
36 float mMass = 70.0f;
37
39 float mMaxStrength = 100.0f;
40
42 Vec3 mShapeOffset = Vec3::sZero();
43
46 float mPredictiveContactDistance = 0.1f;
47 uint mMaxCollisionIterations = 5;
48 uint mMaxConstraintIterations = 15;
49 float mMinTimeRemaining = 1.0e-4f;
50 float mCollisionTolerance = 1.0e-3f;
51 float mCharacterPadding = 0.02f;
52 uint mMaxNumHits = 256;
53 float mHitReductionCosMaxAngle = 0.999f;
54 float mPenetrationRecoverySpeed = 1.0f;
55
61
65
67 ObjectLayer mInnerBodyLayer = 0;
68};
69
72{
73public:
75 bool mCanPushCharacter = true;
76
81};
82
85{
86public:
88 virtual ~CharacterContactListener() = default;
89
92 virtual void OnAdjustBodyVelocity(const CharacterVirtual *inCharacter, const Body &inBody2, Vec3 &ioLinearVelocity, Vec3 &ioAngularVelocity) { /* Do nothing, the linear and angular velocity are already filled in */ }
93
95 virtual bool OnContactValidate(const CharacterVirtual *inCharacter, const BodyID &inBodyID2, const SubShapeID &inSubShapeID2) { return true; }
96
98 virtual bool OnCharacterContactValidate(const CharacterVirtual *inCharacter, const CharacterVirtual *inOtherCharacter, const SubShapeID &inSubShapeID2) { return true; }
99
107 virtual void OnContactAdded(const CharacterVirtual *inCharacter, const BodyID &inBodyID2, const SubShapeID &inSubShapeID2, RVec3Arg inContactPosition, Vec3Arg inContactNormal, CharacterContactSettings &ioSettings) { /* Default do nothing */ }
108
116 virtual void OnContactPersisted(const CharacterVirtual *inCharacter, const BodyID &inBodyID2, const SubShapeID &inSubShapeID2, RVec3Arg inContactPosition, Vec3Arg inContactNormal, CharacterContactSettings &ioSettings) { /* Default do nothing */ }
117
123 virtual void OnContactRemoved(const CharacterVirtual *inCharacter, const BodyID &inBodyID2, const SubShapeID &inSubShapeID2) { /* Default do nothing */ }
124
126 virtual void OnCharacterContactAdded(const CharacterVirtual *inCharacter, const CharacterVirtual *inOtherCharacter, const SubShapeID &inSubShapeID2, RVec3Arg inContactPosition, Vec3Arg inContactNormal, CharacterContactSettings &ioSettings) { /* Default do nothing */ }
127
129 virtual void OnCharacterContactPersisted(const CharacterVirtual *inCharacter, const CharacterVirtual *inOtherCharacter, const SubShapeID &inSubShapeID2, RVec3Arg inContactPosition, Vec3Arg inContactNormal, CharacterContactSettings &ioSettings) { /* Default do nothing */ }
130
133 virtual void OnCharacterContactRemoved(const CharacterVirtual *inCharacter, const CharacterID &inOtherCharacterID, const SubShapeID &inSubShapeID2) { /* Default do nothing */ }
134
145 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 */ }
146
148 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 */ }
149};
150
155{
156public:
158
165 virtual void CollideCharacter(const CharacterVirtual *inCharacter, RMat44Arg inCenterOfMassTransform, const CollideShapeSettings &inCollideShapeSettings, RVec3Arg inBaseOffset, CollideShapeCollector &ioCollector) const = 0;
166
174 virtual void CastCharacter(const CharacterVirtual *inCharacter, RMat44Arg inCenterOfMassTransform, Vec3Arg inDirection, const ShapeCastSettings &inShapeCastSettings, RVec3Arg inBaseOffset, CastShapeCollector &ioCollector) const = 0;
175};
176
182{
183public:
185 void Add(CharacterVirtual *inCharacter) { mCharacters.push_back(inCharacter); }
186
188 void Remove(const CharacterVirtual *inCharacter);
189
190 // See: CharacterVsCharacterCollision
191 virtual void CollideCharacter(const CharacterVirtual *inCharacter, RMat44Arg inCenterOfMassTransform, const CollideShapeSettings &inCollideShapeSettings, RVec3Arg inBaseOffset, CollideShapeCollector &ioCollector) const override;
192 virtual void CastCharacter(const CharacterVirtual *inCharacter, RMat44Arg inCenterOfMassTransform, Vec3Arg inDirection, const ShapeCastSettings &inShapeCastSettings, RVec3Arg inBaseOffset, CastShapeCollector &ioCollector) const override;
193
195};
196
204{
205public:
207
214 CharacterVirtual(const CharacterVirtualSettings *inSettings, RVec3Arg inPosition, QuatArg inRotation, uint64 inUserData, PhysicsSystem *inSystem);
215
217 CharacterVirtual(const CharacterVirtualSettings *inSettings, RVec3Arg inPosition, QuatArg inRotation, PhysicsSystem *inSystem) : CharacterVirtual(inSettings, inPosition, inRotation, 0, inSystem) { }
218
220 virtual ~CharacterVirtual() override;
221
223 inline const CharacterID & GetID() const { return mID; }
224
226 void SetListener(CharacterContactListener *inListener) { mListener = inListener; }
227
229 CharacterContactListener * GetListener() const { return mListener; }
230
232 void SetCharacterVsCharacterCollision(CharacterVsCharacterCollision *inCharacterVsCharacterCollision) { mCharacterVsCharacterCollision = inCharacterVsCharacterCollision; }
233
235 Vec3 GetLinearVelocity() const { return mLinearVelocity; }
236
238 void SetLinearVelocity(Vec3Arg inLinearVelocity) { mLinearVelocity = inLinearVelocity; }
239
241 RVec3 GetPosition() const { return mPosition; }
242
244 void SetPosition(RVec3Arg inPosition) { mPosition = inPosition; UpdateInnerBodyTransform(); }
245
247 Quat GetRotation() const { return mRotation; }
248
250 void SetRotation(QuatArg inRotation) { mRotation = inRotation; UpdateInnerBodyTransform(); }
251
252 // Get the center of mass position of the shape
253 inline RVec3 GetCenterOfMassPosition() const { return mPosition + (mRotation * (mShapeOffset + mShape->GetCenterOfMass()) + mCharacterPadding * mUp); }
254
256 RMat44 GetWorldTransform() const { return RMat44::sRotationTranslation(mRotation, mPosition); }
257
259 RMat44 GetCenterOfMassTransform() const { return GetCenterOfMassTransform(mPosition, mRotation, mShape); }
260
262 float GetMass() const { return mMass; }
263 void SetMass(float inMass) { mMass = inMass; }
264
266 float GetMaxStrength() const { return mMaxStrength; }
267 void SetMaxStrength(float inMaxStrength) { mMaxStrength = inMaxStrength; }
268
270 float GetPenetrationRecoverySpeed() const { return mPenetrationRecoverySpeed; }
271 void SetPenetrationRecoverySpeed(float inSpeed) { mPenetrationRecoverySpeed = inSpeed; }
272
275 void SetEnhancedInternalEdgeRemoval(bool inApply) { mEnhancedInternalEdgeRemoval = inApply; }
276
278 float GetCharacterPadding() const { return mCharacterPadding; }
279
281 uint GetMaxNumHits() const { return mMaxNumHits; }
282 void SetMaxNumHits(uint inMaxHits) { mMaxNumHits = inMaxHits; }
283
285 float GetHitReductionCosMaxAngle() const { return mHitReductionCosMaxAngle; }
286 void SetHitReductionCosMaxAngle(float inCosMaxAngle) { mHitReductionCosMaxAngle = inCosMaxAngle; }
287
292 bool GetMaxHitsExceeded() const { return mMaxHitsExceeded; }
293
295 Vec3 GetShapeOffset() const { return mShapeOffset; }
296 void SetShapeOffset(Vec3Arg inShapeOffset) { mShapeOffset = inShapeOffset; UpdateInnerBodyTransform(); }
297
299 uint64 GetUserData() const { return mUserData; }
300 void SetUserData(uint64 inUserData);
301
303 BodyID GetInnerBodyID() const { return mInnerBodyID; }
304
309 Vec3 CancelVelocityTowardsSteepSlopes(Vec3Arg inDesiredVelocity) const;
310
315 void StartTrackingContactChanges();
316
318 void FinishTrackingContactChanges();
319
330 void Update(float inDeltaTime, Vec3Arg inGravity, const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter, const BodyFilter &inBodyFilter, const ShapeFilter &inShapeFilter, TempAllocator &inAllocator);
331
335 bool CanWalkStairs(Vec3Arg inLinearVelocity) const;
336
349 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);
350
361 bool StickToFloor(Vec3Arg inStepDown, const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter, const BodyFilter &inBodyFilter, const ShapeFilter &inShapeFilter, TempAllocator &inAllocator);
362
365 {
366 Vec3 mStickToFloorStepDown { 0, -0.5f, 0 };
367 Vec3 mWalkStairsStepUp { 0, 0.4f, 0 };
368 float mWalkStairsMinStepForward { 0.02f };
369 float mWalkStairsStepForwardTest { 0.15f };
370 float mWalkStairsCosAngleForwardContact { Cos(DegreesToRadians(75.0f)) };
371 Vec3 mWalkStairsStepDownExtra { Vec3::sZero() };
372 };
373
386 void ExtendedUpdate(float inDeltaTime, Vec3Arg inGravity, const ExtendedUpdateSettings &inSettings, const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter, const BodyFilter &inBodyFilter, const ShapeFilter &inShapeFilter, TempAllocator &inAllocator);
387
389 void RefreshContacts(const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter, const BodyFilter &inBodyFilter, const ShapeFilter &inShapeFilter, TempAllocator &inAllocator);
390
393 void UpdateGroundVelocity();
394
404 bool SetShape(const Shape *inShape, float inMaxPenetrationDepth, const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter, const BodyFilter &inBodyFilter, const ShapeFilter &inShapeFilter, TempAllocator &inAllocator);
405
407 void SetInnerBodyShape(const Shape *inShape);
408
410 TransformedShape GetTransformedShape() const { return TransformedShape(GetCenterOfMassPosition(), mRotation, mShape, mInnerBodyID); }
411
425 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;
426
428 CharacterVirtualSettings GetCharacterVirtualSettings() const;
429
430 // Saving / restoring state for replay
431 virtual void SaveState(StateRecorder &inStream) const override;
432 virtual void RestoreState(StateRecorder &inStream) override;
433
434#ifdef JPH_DEBUG_RENDERER
435 static inline bool sDrawConstraints = false;
436 static inline bool sDrawWalkStairs = false;
437 static inline bool sDrawStickToFloor = false;
438#endif
439
442 {
443 public:
445 ContactKey() = default;
446 ContactKey(const ContactKey &inContact) = default;
447 ContactKey(const BodyID &inBodyB, const SubShapeID &inSubShapeID) : mBodyB(inBodyB), mSubShapeIDB(inSubShapeID) { }
448 ContactKey(const CharacterID &inCharacterIDB, const SubShapeID &inSubShapeID) : mCharacterIDB(inCharacterIDB), mSubShapeIDB(inSubShapeID) { }
449 ContactKey & operator = (const ContactKey &inContact) = default;
450
452 inline bool IsSameBody(const ContactKey &inOther) const { return mBodyB == inOther.mBodyB && mCharacterIDB == inOther.mCharacterIDB; }
453
455 bool operator == (const ContactKey &inRHS) const
456 {
457 return mBodyB == inRHS.mBodyB && mCharacterIDB == inRHS.mCharacterIDB && mSubShapeIDB == inRHS.mSubShapeIDB;
458 }
459
460 bool operator != (const ContactKey &inRHS) const
461 {
462 return !(*this == inRHS);
463 }
464
467 {
468 static_assert(sizeof(BodyID) + sizeof(CharacterID) + sizeof(SubShapeID) == sizeof(ContactKey), "No padding expected");
469 return HashBytes(this, sizeof(ContactKey));
470 }
471
472 // Saving / restoring state for replay
473 void SaveState(StateRecorder &inStream) const;
474 void RestoreState(StateRecorder &inStream);
475
479 };
480
482 struct Contact : public ContactKey
483 {
484 // Saving / restoring state for replay
485 void SaveState(StateRecorder &inStream) const;
486 void RestoreState(StateRecorder &inStream);
487
492 float mDistance;
493 float mFraction;
496 const CharacterVirtual * mCharacterB = nullptr;
499 bool mHadCollision = false;
500 bool mWasDiscarded = false;
501 bool mCanPushCharacter = true;
502 };
503
506
509 const ContactList & GetActiveContacts() const { return mActiveContacts; }
510
512 bool HasCollidedWith(const BodyID &inBody) const
513 {
514 for (const CharacterVirtual::Contact &c : mActiveContacts)
515 if (c.mHadCollision && c.mBodyB == inBody)
516 return true;
517 return false;
518 }
519
521 bool HasCollidedWith(const CharacterID &inCharacterID) const
522 {
523 for (const CharacterVirtual::Contact &c : mActiveContacts)
524 if (c.mHadCollision && c.mCharacterIDB == inCharacterID)
525 return true;
526 return false;
527 }
528
530 bool HasCollidedWith(const CharacterVirtual *inCharacter) const
531 {
532 return HasCollidedWith(inCharacter->GetID());
533 }
534
535private:
536 // Sorting predicate for making contact order deterministic
537 struct ContactOrderingPredicate
538 {
539 inline bool operator () (const Contact &inLHS, const Contact &inRHS) const
540 {
541 if (inLHS.mBodyB != inRHS.mBodyB)
542 return inLHS.mBodyB < inRHS.mBodyB;
543
544 if (inLHS.mCharacterIDB != inRHS.mCharacterIDB)
545 return inLHS.mCharacterIDB < inRHS.mCharacterIDB;
546
547 return inLHS.mSubShapeIDB.GetValue() < inRHS.mSubShapeIDB.GetValue();
548 }
549 };
550
551 using IgnoredContactList = Array<ContactKey, STLTempAllocator<ContactKey>>;
552
553 // A constraint that limits the movement of the character
554 struct Constraint
555 {
556 Contact * mContact;
557 float mTOI;
558 float mProjectedVelocity;
559 Vec3 mLinearVelocity;
560 Plane mPlane;
561 bool mIsSteepSlope = false;
562 };
563
565
566 // Collision collector that collects hits for CollideShape
567 class ContactCollector : public CollideShapeCollector
568 {
569 public:
570 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) { }
571
572 virtual void SetUserData(uint64 inUserData) override { mOtherCharacter = reinterpret_cast<CharacterVirtual *>(inUserData); }
573
574 virtual void AddHit(const CollideShapeResult &inResult) override;
575
576 RVec3 mBaseOffset;
577 Vec3 mUp;
578 PhysicsSystem * mSystem;
579 const CharacterVirtual * mCharacter;
580 CharacterVirtual * mOtherCharacter = nullptr;
581 TempContactList & mContacts;
582 uint mMaxHits;
583 float mHitReductionCosMaxAngle;
584 bool mMaxHitsExceeded = false;
585 };
586
587 // A collision collector that collects hits for CastShape
588 class ContactCastCollector : public CastShapeCollector
589 {
590 public:
591 ContactCastCollector(PhysicsSystem *inSystem, const CharacterVirtual *inCharacter, Vec3Arg inDisplacement, Vec3Arg inUp, const IgnoredContactList &inIgnoredContacts, RVec3Arg inBaseOffset, Contact &outContact) : mBaseOffset(inBaseOffset), mDisplacement(inDisplacement), mUp(inUp), mSystem(inSystem), mCharacter(inCharacter), mIgnoredContacts(inIgnoredContacts), mContact(outContact) { }
592
593 virtual void SetUserData(uint64 inUserData) override { mOtherCharacter = reinterpret_cast<CharacterVirtual *>(inUserData); }
594
595 virtual void AddHit(const ShapeCastResult &inResult) override;
596
597 RVec3 mBaseOffset;
598 Vec3 mDisplacement;
599 Vec3 mUp;
600 PhysicsSystem * mSystem;
601 const CharacterVirtual * mCharacter;
602 CharacterVirtual * mOtherCharacter = nullptr;
603 const IgnoredContactList & mIgnoredContacts;
604 Contact & mContact;
605 };
606
607 // Helper function to convert a Jolt collision result into a contact
608 template <class taCollector>
609 inline static void sFillContactProperties(const CharacterVirtual *inCharacter, Contact &outContact, const Body &inBody, Vec3Arg inUp, RVec3Arg inBaseOffset, const taCollector &inCollector, const CollideShapeResult &inResult);
610 inline static void sFillCharacterContactProperties(Contact &outContact, const CharacterVirtual *inOtherCharacter, RVec3Arg inBaseOffset, const CollideShapeResult &inResult);
611
612 // Move the shape from ioPosition and try to displace it by inVelocity * inDeltaTime, this will try to slide the shape along the world geometry
613 void MoveShape(RVec3 &ioPosition, Vec3Arg inVelocity, float inDeltaTime, ContactList *outActiveContacts, const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter, const BodyFilter &inBodyFilter, const ShapeFilter &inShapeFilter, TempAllocator &inAllocator
614 #ifdef JPH_DEBUG_RENDERER
615 , bool inDrawConstraints = false
616 #endif // JPH_DEBUG_RENDERER
617 );
618
619 // Ask the callback if inContact is a valid contact point
620 bool ValidateContact(const Contact &inContact) const;
621
622 // Trigger the contact callback for inContact and get the contact settings
623 void ContactAdded(const Contact &inContact, CharacterContactSettings &ioSettings);
624
625 // Tests the shape for collision around inPosition
626 void GetContactsAtPosition(RVec3Arg inPosition, Vec3Arg inMovementDirection, const Shape *inShape, TempContactList &outContacts, const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter, const BodyFilter &inBodyFilter, const ShapeFilter &inShapeFilter) const;
627
628 // Remove penetrating contacts with the same body that have conflicting normals, leaving these will make the character mover get stuck
629 void RemoveConflictingContacts(TempContactList &ioContacts, IgnoredContactList &outIgnoredContacts) const;
630
631 // 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.
632 void DetermineConstraints(TempContactList &inContacts, float inDeltaTime, ConstraintList &outConstraints) const;
633
634 // 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.
635 void SolveConstraints(Vec3Arg inVelocity, float inDeltaTime, float inTimeRemaining, ConstraintList &ioConstraints, IgnoredContactList &ioIgnoredContacts, float &outTimeSimulated, Vec3 &outDisplacement, TempAllocator &inAllocator
636 #ifdef JPH_DEBUG_RENDERER
637 , bool inDrawConstraints = false
638 #endif // JPH_DEBUG_RENDERER
639 );
640
641 // Get the velocity of a body adjusted by the contact listener
642 void GetAdjustedBodyVelocity(const Body& inBody, Vec3 &outLinearVelocity, Vec3 &outAngularVelocity) const;
643
644 // 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.
645 // Note that we don't just take the point velocity because a point on an object with angular velocity traces an arc,
646 // so if you just take point velocity * delta time you get an error that accumulates over time
647 Vec3 CalculateCharacterGroundVelocity(RVec3Arg inCenterOfMass, Vec3Arg inLinearVelocity, Vec3Arg inAngularVelocity, float inDeltaTime) const;
648
649 // Handle contact with physics object that we're colliding against
650 bool HandleContact(Vec3Arg inVelocity, Constraint &ioConstraint, float inDeltaTime);
651
652 // Does a swept test of the shape from inPosition with displacement inDisplacement, returns true if there was a collision
653 bool GetFirstContactForSweep(RVec3Arg inPosition, Vec3Arg inDisplacement, Contact &outContact, const IgnoredContactList &inIgnoredContacts, const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter, const BodyFilter &inBodyFilter, const ShapeFilter &inShapeFilter) const;
654
655 // Store contacts so that we have proper ground information
656 void StoreActiveContacts(const TempContactList &inContacts, TempAllocator &inAllocator);
657
658 // This function will determine which contacts are touching the character and will calculate the one that is supporting us
659 void UpdateSupportingContact(bool inSkipContactVelocityCheck, TempAllocator &inAllocator);
660
662 void MoveToContact(RVec3Arg inPosition, const Contact &inContact, const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter, const BodyFilter &inBodyFilter, const ShapeFilter &inShapeFilter, TempAllocator &inAllocator);
663
664 // This function returns the actual center of mass of the shape, not corrected for the character padding
665 inline RMat44 GetCenterOfMassTransform(RVec3Arg inPosition, QuatArg inRotation, const Shape *inShape) const
666 {
667 return RMat44::sRotationTranslation(inRotation, inPosition).PreTranslated(mShapeOffset + inShape->GetCenterOfMass()).PostTranslated(mCharacterPadding * mUp);
668 }
669
670 // This function returns the position of the inner rigid body
671 inline RVec3 GetInnerBodyPosition() const
672 {
673 return mPosition + (mRotation * mShapeOffset + mCharacterPadding * mUp);
674 }
675
676 // Move the inner rigid body to the current position
677 void UpdateInnerBodyTransform();
678
679 // ID
680 CharacterID mID;
681
682 // Our main listener for contacts
683 CharacterContactListener * mListener = nullptr;
684
685 // Interface to detect collision between characters
686 CharacterVsCharacterCollision * mCharacterVsCharacterCollision = nullptr;
687
688 // Movement settings
689 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.
690 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.
691 uint mMaxCollisionIterations; // Max amount of collision loops
692 uint mMaxConstraintIterations; // How often to try stepping in the constraint solving
693 float mMinTimeRemaining; // Early out condition: If this much time is left to simulate we are done
694 float mCollisionTolerance; // How far we're willing to penetrate geometry
695 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
696 uint mMaxNumHits; // Max num hits to collect in order to avoid excess of contact points collection
697 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.
698 float mPenetrationRecoverySpeed; // This value governs how fast a penetration will be resolved, 0 = nothing is resolved, 1 = everything in one update
699 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.
700
701 // Character mass (kg)
702 float mMass;
703
704 // Maximum force with which the character can push other bodies (N)
705 float mMaxStrength;
706
707 // An extra offset applied to the shape in local space. This allows applying an extra offset to the shape in local space.
708 Vec3 mShapeOffset = Vec3::sZero();
709
710 // Current position (of the base, not the center of mass)
711 RVec3 mPosition = RVec3::sZero();
712
713 // Current rotation (of the base, not of the center of mass)
714 Quat mRotation = Quat::sIdentity();
715
716 // Current linear velocity
717 Vec3 mLinearVelocity = Vec3::sZero();
718
719 // List of contacts that were active in the last frame
720 ContactList mActiveContacts;
721
722 // Remembers how often we called StartTrackingContactChanges
723 int mTrackingContactChanges = 0;
724
725 // View from a contact listener perspective on which contacts have been added/removed
726 struct ListenerContactValue
727 {
728 ListenerContactValue() = default;
729 explicit ListenerContactValue(const CharacterContactSettings &inSettings) : mSettings(inSettings) { }
730
731 CharacterContactSettings mSettings;
732 int mCount = 0;
733 };
734
735 using ListenerContacts = UnorderedMap<ContactKey, ListenerContactValue>;
736 ListenerContacts mListenerContacts;
737
738 // Remembers the delta time of the last update
739 float mLastDeltaTime = 1.0f / 60.0f;
740
741 // Remember if we exceeded the maximum number of hits and had to remove similar contacts
742 mutable bool mMaxHitsExceeded = false;
743
744 // User data, can be used for anything by the application
745 uint64 mUserData = 0;
746
747 // The inner rigid body that proxies the character in the world
748 BodyID mInnerBodyID;
749};
750
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:275
std::uint64_t uint64
Definition Core.h:496
unsigned int uint
Definition Core.h:492
#define JPH_NAMESPACE_END
Definition Core.h:419
#define JPH_NAMESPACE_BEGIN
Definition Core.h:413
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:43
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
This class receives callbacks when a virtual character hits something.
Definition CharacterVirtual.h:85
virtual void OnContactAdded(const CharacterVirtual *inCharacter, const BodyID &inBodyID2, const SubShapeID &inSubShapeID2, RVec3Arg inContactPosition, Vec3Arg inContactNormal, CharacterContactSettings &ioSettings)
Definition CharacterVirtual.h:107
virtual ~CharacterContactListener()=default
Destructor.
virtual void OnContactRemoved(const CharacterVirtual *inCharacter, const BodyID &inBodyID2, const SubShapeID &inSubShapeID2)
Definition CharacterVirtual.h:123
virtual bool OnContactValidate(const CharacterVirtual *inCharacter, const BodyID &inBodyID2, const SubShapeID &inSubShapeID2)
Checks if a character can collide with specified body. Return true if the contact is valid.
Definition CharacterVirtual.h:95
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:145
virtual bool OnCharacterContactValidate(const CharacterVirtual *inCharacter, const CharacterVirtual *inOtherCharacter, const SubShapeID &inSubShapeID2)
Same as OnContactValidate but when colliding with a CharacterVirtual.
Definition CharacterVirtual.h:98
virtual void OnCharacterContactAdded(const CharacterVirtual *inCharacter, const CharacterVirtual *inOtherCharacter, const SubShapeID &inSubShapeID2, RVec3Arg inContactPosition, Vec3Arg inContactNormal, CharacterContactSettings &ioSettings)
Same as OnContactAdded but when colliding with a CharacterVirtual.
Definition CharacterVirtual.h:126
virtual void OnAdjustBodyVelocity(const CharacterVirtual *inCharacter, const Body &inBody2, Vec3 &ioLinearVelocity, Vec3 &ioAngularVelocity)
Definition CharacterVirtual.h:92
virtual void OnCharacterContactRemoved(const CharacterVirtual *inCharacter, const CharacterID &inOtherCharacterID, const SubShapeID &inSubShapeID2)
Definition CharacterVirtual.h:133
virtual void OnContactPersisted(const CharacterVirtual *inCharacter, const BodyID &inBodyID2, const SubShapeID &inSubShapeID2, RVec3Arg inContactPosition, Vec3Arg inContactNormal, CharacterContactSettings &ioSettings)
Definition CharacterVirtual.h:116
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:148
virtual void OnCharacterContactPersisted(const CharacterVirtual *inCharacter, const CharacterVirtual *inOtherCharacter, const SubShapeID &inSubShapeID2, RVec3Arg inContactPosition, Vec3Arg inContactNormal, CharacterContactSettings &ioSettings)
Same as OnContactPersisted but when colliding with a CharacterVirtual.
Definition CharacterVirtual.h:129
This class contains settings that allow you to override the behavior of a character's collision respo...
Definition CharacterVirtual.h:72
bool mCanPushCharacter
True when the object can push the virtual character.
Definition CharacterVirtual.h:75
bool mCanReceiveImpulses
Definition CharacterVirtual.h:80
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
Uniquely identifies a contact between a character and another body or character.
Definition CharacterVirtual.h:442
BodyID mBodyB
ID of body we're colliding with (if not invalid)
Definition CharacterVirtual.h:476
ContactKey(const CharacterID &inCharacterIDB, const SubShapeID &inSubShapeID)
Definition CharacterVirtual.h:448
ContactKey()=default
Constructor.
ContactKey(const BodyID &inBodyB, const SubShapeID &inSubShapeID)
Definition CharacterVirtual.h:447
bool IsSameBody(const ContactKey &inOther) const
Checks if two contacts refer to the same body (or virtual character)
Definition CharacterVirtual.h:452
uint64 GetHash() const
Hash of this structure.
Definition CharacterVirtual.h:466
CharacterID mCharacterIDB
Character we're colliding with (if not invalid)
Definition CharacterVirtual.h:477
ContactKey(const ContactKey &inContact)=default
SubShapeID mSubShapeIDB
Sub shape ID of body or character we're colliding with.
Definition CharacterVirtual.h:478
Definition CharacterVirtual.h:204
void SetEnhancedInternalEdgeRemoval(bool inApply)
Definition CharacterVirtual.h:275
TransformedShape GetTransformedShape() const
Get the transformed shape that represents the volume of the character, can be used for collision chec...
Definition CharacterVirtual.h:410
float GetMass() const
Character mass (kg)
Definition CharacterVirtual.h:262
float GetPenetrationRecoverySpeed() const
This value governs how fast a penetration will be resolved, 0 = nothing is resolved,...
Definition CharacterVirtual.h:270
RVec3 GetPosition() const
Get the position of the character.
Definition CharacterVirtual.h:241
void SetLinearVelocity(Vec3Arg inLinearVelocity)
Set the linear velocity of the character (m / s)
Definition CharacterVirtual.h:238
const ContactList & GetActiveContacts() const
Definition CharacterVirtual.h:509
RMat44 GetWorldTransform() const
Calculate the world transform of the character.
Definition CharacterVirtual.h:256
void SetCharacterVsCharacterCollision(CharacterVsCharacterCollision *inCharacterVsCharacterCollision)
Set the character vs character collision interface.
Definition CharacterVirtual.h:232
RVec3 GetCenterOfMassPosition() const
Definition CharacterVirtual.h:253
bool GetMaxHitsExceeded() const
Definition CharacterVirtual.h:292
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:512
void SetMaxStrength(float inMaxStrength)
Definition CharacterVirtual.h:267
float GetCharacterPadding() const
Character padding.
Definition CharacterVirtual.h:278
void SetMaxNumHits(uint inMaxHits)
Definition CharacterVirtual.h:282
uint GetMaxNumHits() const
Max num hits to collect in order to avoid excess of contact points collection.
Definition CharacterVirtual.h:281
float GetMaxStrength() const
Maximum force with which the character can push other bodies (N)
Definition CharacterVirtual.h:266
void SetShapeOffset(Vec3Arg inShapeOffset)
Definition CharacterVirtual.h:296
BodyID GetInnerBodyID() const
Optional inner rigid body that proxies the character in the world. Can be used to update body propert...
Definition CharacterVirtual.h:303
void SetMass(float inMass)
Definition CharacterVirtual.h:263
bool GetEnhancedInternalEdgeRemoval() const
Set to indicate that extra effort should be made to try to remove ghost contacts (collisions with int...
Definition CharacterVirtual.h:274
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:521
Vec3 GetLinearVelocity() const
Get the linear velocity of the character (m / s)
Definition CharacterVirtual.h:235
CharacterContactListener * GetListener() const
Get the current contact listener.
Definition CharacterVirtual.h:229
RMat44 GetCenterOfMassTransform() const
Calculates the transform for this character's center of mass.
Definition CharacterVirtual.h:259
CharacterVirtual(const CharacterVirtualSettings *inSettings, RVec3Arg inPosition, QuatArg inRotation, PhysicsSystem *inSystem)
Constructor without user data.
Definition CharacterVirtual.h:217
void SetRotation(QuatArg inRotation)
Set the rotation of the character.
Definition CharacterVirtual.h:250
void SetHitReductionCosMaxAngle(float inCosMaxAngle)
Definition CharacterVirtual.h:286
uint64 GetUserData() const
Access to the user data, can be used for anything by the application.
Definition CharacterVirtual.h:299
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:295
void SetPenetrationRecoverySpeed(float inSpeed)
Definition CharacterVirtual.h:271
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:530
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:285
void SetPosition(RVec3Arg inPosition)
Set the position of the character.
Definition CharacterVirtual.h:244
const CharacterID & GetID() const
The ID of this character.
Definition CharacterVirtual.h:223
void SetListener(CharacterContactListener *inListener)
Set the contact listener.
Definition CharacterVirtual.h:226
Quat GetRotation() const
Get the rotation of the character.
Definition CharacterVirtual.h:247
Contains the configuration of a character.
Definition CharacterVirtual.h:23
JPH_OVERRIDE_NEW_DELETE CharacterVirtualSettings()=default
Constructor.
RefConst< Shape > mInnerBodyShape
Definition CharacterVirtual.h:60
CharacterVirtualSettings(const CharacterVirtualSettings &)=default
BodyID mInnerBodyIDOverride
Definition CharacterVirtual.h:64
Definition CharacterVirtual.h:155
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:182
void Add(CharacterVirtual *inCharacter)
Add a character to the list of characters to check collision against.
Definition CharacterVirtual.h:185
Array< CharacterVirtual * > mCharacters
The list of characters to check collision against.
Definition CharacterVirtual.h:194
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:103
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:903
JPH_INLINE Mat44 PreTranslated(Vec3Arg inTranslation) const
Pre multiply by translation matrix: result = this * Mat44::sTranslation(inTranslation)
Definition Mat44.inl:898
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:103
Definition Reference.h:163
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:186
virtual Vec3 GetCenterOfMass() const
All shapes are centered around their center of mass. This function returns the center of mass positio...
Definition Shape.h:211
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
Definition TempAllocator.h:16
Definition TransformedShape.h:26
Definition UnorderedMap.h:30
Definition Vec3.h:17
static JPH_INLINE Vec3 sZero()
Vector with all zeros.
Definition Vec3.inl:103
Encapsulates a collision contact.
Definition CharacterVirtual.h:483
EMotionType mMotionTypeB
Motion type of B, used to determine the priority of the contact.
Definition CharacterVirtual.h:494
Vec3 mContactNormal
Contact normal, pointing towards the character.
Definition CharacterVirtual.h:490
const PhysicsMaterial * mMaterial
Material of B.
Definition CharacterVirtual.h:498
float mFraction
Fraction along the path where this contact takes place.
Definition CharacterVirtual.h:493
uint64 mUserData
User data of B.
Definition CharacterVirtual.h:497
Vec3 mLinearVelocity
Velocity of the contact point.
Definition CharacterVirtual.h:489
float mDistance
Distance to the contact <= 0 means that it is an actual contact, > 0 means predictive.
Definition CharacterVirtual.h:492
Vec3 mSurfaceNormal
Surface normal of the contact.
Definition CharacterVirtual.h:491
RVec3 mPosition
Position where the character makes contact.
Definition CharacterVirtual.h:488
bool mIsSensorB
If B is a sensor.
Definition CharacterVirtual.h:495
Settings struct with settings for ExtendedUpdate.
Definition CharacterVirtual.h:365