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