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
82};
83
87{
88public:
90 virtual ~CharacterContactListener() = default;
91
94 virtual void OnAdjustBodyVelocity(const CharacterVirtual *inCharacter, const Body &inBody2, Vec3 &ioLinearVelocity, Vec3 &ioAngularVelocity) { /* Do nothing, the linear and angular velocity are already filled in */ }
95
97 virtual bool OnContactValidate(const CharacterVirtual *inCharacter, const BodyID &inBodyID2, const SubShapeID &inSubShapeID2) { return true; }
98
100 virtual bool OnCharacterContactValidate(const CharacterVirtual *inCharacter, const CharacterVirtual *inOtherCharacter, const SubShapeID &inSubShapeID2) { return true; }
101
109 virtual void OnContactAdded(const CharacterVirtual *inCharacter, const BodyID &inBodyID2, const SubShapeID &inSubShapeID2, RVec3Arg inContactPosition, Vec3Arg inContactNormal, CharacterContactSettings &ioSettings) { /* Default do nothing */ }
110
118 virtual void OnContactPersisted(const CharacterVirtual *inCharacter, const BodyID &inBodyID2, const SubShapeID &inSubShapeID2, RVec3Arg inContactPosition, Vec3Arg inContactNormal, CharacterContactSettings &ioSettings) { /* Default do nothing */ }
119
125 virtual void OnContactRemoved(const CharacterVirtual *inCharacter, const BodyID &inBodyID2, const SubShapeID &inSubShapeID2) { /* Default do nothing */ }
126
128 virtual void OnCharacterContactAdded(const CharacterVirtual *inCharacter, const CharacterVirtual *inOtherCharacter, const SubShapeID &inSubShapeID2, RVec3Arg inContactPosition, Vec3Arg inContactNormal, CharacterContactSettings &ioSettings) { /* Default do nothing */ }
129
131 virtual void OnCharacterContactPersisted(const CharacterVirtual *inCharacter, const CharacterVirtual *inOtherCharacter, const SubShapeID &inSubShapeID2, RVec3Arg inContactPosition, Vec3Arg inContactNormal, CharacterContactSettings &ioSettings) { /* Default do nothing */ }
132
135 virtual void OnCharacterContactRemoved(const CharacterVirtual *inCharacter, const CharacterID &inOtherCharacterID, const SubShapeID &inSubShapeID2) { /* Default do nothing */ }
136
147 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 */ }
148
150 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 */ }
151};
152
157{
158public:
160
167 virtual void CollideCharacter(const CharacterVirtual *inCharacter, RMat44Arg inCenterOfMassTransform, const CollideShapeSettings &inCollideShapeSettings, RVec3Arg inBaseOffset, CollideShapeCollector &ioCollector) const = 0;
168
176 virtual void CastCharacter(const CharacterVirtual *inCharacter, RMat44Arg inCenterOfMassTransform, Vec3Arg inDirection, const ShapeCastSettings &inShapeCastSettings, RVec3Arg inBaseOffset, CastShapeCollector &ioCollector) const = 0;
177};
178
184{
185public:
187 void Add(CharacterVirtual *inCharacter) { mCharacters.push_back(inCharacter); }
188
190 void Remove(const CharacterVirtual *inCharacter);
191
192 // See: CharacterVsCharacterCollision
193 virtual void CollideCharacter(const CharacterVirtual *inCharacter, RMat44Arg inCenterOfMassTransform, const CollideShapeSettings &inCollideShapeSettings, RVec3Arg inBaseOffset, CollideShapeCollector &ioCollector) const override;
194 virtual void CastCharacter(const CharacterVirtual *inCharacter, RMat44Arg inCenterOfMassTransform, Vec3Arg inDirection, const ShapeCastSettings &inShapeCastSettings, RVec3Arg inBaseOffset, CastShapeCollector &ioCollector) const override;
195
197};
198
206{
207public:
209
216 CharacterVirtual(const CharacterVirtualSettings *inSettings, RVec3Arg inPosition, QuatArg inRotation, uint64 inUserData, PhysicsSystem *inSystem);
217
219 CharacterVirtual(const CharacterVirtualSettings *inSettings, RVec3Arg inPosition, QuatArg inRotation, PhysicsSystem *inSystem) : CharacterVirtual(inSettings, inPosition, inRotation, 0, inSystem) { }
220
222 virtual ~CharacterVirtual() override;
223
225 inline const CharacterID & GetID() const { return mID; }
226
228 void SetListener(CharacterContactListener *inListener) { mListener = inListener; }
229
231 CharacterContactListener * GetListener() const { return mListener; }
232
234 void SetCharacterVsCharacterCollision(CharacterVsCharacterCollision *inCharacterVsCharacterCollision) { mCharacterVsCharacterCollision = inCharacterVsCharacterCollision; }
235
237 Vec3 GetLinearVelocity() const { return mLinearVelocity; }
238
240 void SetLinearVelocity(Vec3Arg inLinearVelocity) { mLinearVelocity = inLinearVelocity; }
241
243 RVec3 GetPosition() const { return mPosition; }
244
246 void SetPosition(RVec3Arg inPosition) { mPosition = inPosition; UpdateInnerBodyTransform(); }
247
249 Quat GetRotation() const { return mRotation; }
250
252 void SetRotation(QuatArg inRotation) { mRotation = inRotation; UpdateInnerBodyTransform(); }
253
254 // Get the center of mass position of the shape
255 inline RVec3 GetCenterOfMassPosition() const { return mPosition + (mRotation * (mShapeOffset + mShape->GetCenterOfMass()) + mCharacterPadding * mUp); }
256
258 RMat44 GetWorldTransform() const { return RMat44::sRotationTranslation(mRotation, mPosition); }
259
261 RMat44 GetCenterOfMassTransform() const { return GetCenterOfMassTransform(mPosition, mRotation, mShape); }
262
264 float GetMass() const { return mMass; }
265 void SetMass(float inMass) { mMass = inMass; }
266
268 float GetMaxStrength() const { return mMaxStrength; }
269 void SetMaxStrength(float inMaxStrength) { mMaxStrength = inMaxStrength; }
270
272 float GetPenetrationRecoverySpeed() const { return mPenetrationRecoverySpeed; }
273 void SetPenetrationRecoverySpeed(float inSpeed) { mPenetrationRecoverySpeed = inSpeed; }
274
277 void SetEnhancedInternalEdgeRemoval(bool inApply) { mEnhancedInternalEdgeRemoval = inApply; }
278
280 float GetCharacterPadding() const { return mCharacterPadding; }
281
283 uint GetMaxNumHits() const { return mMaxNumHits; }
284 void SetMaxNumHits(uint inMaxHits) { mMaxNumHits = inMaxHits; }
285
287 float GetHitReductionCosMaxAngle() const { return mHitReductionCosMaxAngle; }
288 void SetHitReductionCosMaxAngle(float inCosMaxAngle) { mHitReductionCosMaxAngle = inCosMaxAngle; }
289
294 bool GetMaxHitsExceeded() const { return mMaxHitsExceeded; }
295
297 Vec3 GetShapeOffset() const { return mShapeOffset; }
298 void SetShapeOffset(Vec3Arg inShapeOffset) { mShapeOffset = inShapeOffset; UpdateInnerBodyTransform(); }
299
301 uint64 GetUserData() const { return mUserData; }
302 void SetUserData(uint64 inUserData);
303
305 BodyID GetInnerBodyID() const { return mInnerBodyID; }
306
311 Vec3 CancelVelocityTowardsSteepSlopes(Vec3Arg inDesiredVelocity) const;
312
317 void StartTrackingContactChanges();
318
320 void FinishTrackingContactChanges();
321
332 void Update(float inDeltaTime, Vec3Arg inGravity, const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter, const BodyFilter &inBodyFilter, const ShapeFilter &inShapeFilter, TempAllocator &inAllocator);
333
337 bool CanWalkStairs(Vec3Arg inLinearVelocity) const;
338
351 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);
352
363 bool StickToFloor(Vec3Arg inStepDown, const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter, const BodyFilter &inBodyFilter, const ShapeFilter &inShapeFilter, TempAllocator &inAllocator);
364
367 {
368 Vec3 mStickToFloorStepDown { 0, -0.5f, 0 };
369 Vec3 mWalkStairsStepUp { 0, 0.4f, 0 };
370 float mWalkStairsMinStepForward { 0.02f };
371 float mWalkStairsStepForwardTest { 0.15f };
372 float mWalkStairsCosAngleForwardContact { Cos(DegreesToRadians(75.0f)) };
373 Vec3 mWalkStairsStepDownExtra { Vec3::sZero() };
374 };
375
388 void ExtendedUpdate(float inDeltaTime, Vec3Arg inGravity, const ExtendedUpdateSettings &inSettings, const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter, const BodyFilter &inBodyFilter, const ShapeFilter &inShapeFilter, TempAllocator &inAllocator);
389
391 void RefreshContacts(const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter, const BodyFilter &inBodyFilter, const ShapeFilter &inShapeFilter, TempAllocator &inAllocator);
392
395 void UpdateGroundVelocity();
396
406 bool SetShape(const Shape *inShape, float inMaxPenetrationDepth, const BroadPhaseLayerFilter &inBroadPhaseLayerFilter, const ObjectLayerFilter &inObjectLayerFilter, const BodyFilter &inBodyFilter, const ShapeFilter &inShapeFilter, TempAllocator &inAllocator);
407
409 void SetInnerBodyShape(const Shape *inShape);
410
412 TransformedShape GetTransformedShape() const { return TransformedShape(GetCenterOfMassPosition(), mRotation, mShape, mInnerBodyID); }
413
427 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;
428
430 CharacterVirtualSettings GetCharacterVirtualSettings() const;
431
432 // Saving / restoring state for replay
433 virtual void SaveState(StateRecorder &inStream) const override;
434 virtual void RestoreState(StateRecorder &inStream) override;
435
436#ifdef JPH_DEBUG_RENDERER
437 static inline bool sDrawConstraints = false;
438 static inline bool sDrawWalkStairs = false;
439 static inline bool sDrawStickToFloor = false;
440#endif
441
444 {
445 public:
447 ContactKey() = default;
448 ContactKey(const ContactKey &inContact) = default;
449 ContactKey(const BodyID &inBodyB, const SubShapeID &inSubShapeID) : mBodyB(inBodyB), mSubShapeIDB(inSubShapeID) { }
450 ContactKey(const CharacterID &inCharacterIDB, const SubShapeID &inSubShapeID) : mCharacterIDB(inCharacterIDB), mSubShapeIDB(inSubShapeID) { }
451 ContactKey & operator = (const ContactKey &inContact) = default;
452
454 inline bool IsSameBody(const ContactKey &inOther) const { return mBodyB == inOther.mBodyB && mCharacterIDB == inOther.mCharacterIDB; }
455
457 bool operator == (const ContactKey &inRHS) const
458 {
459 return mBodyB == inRHS.mBodyB && mCharacterIDB == inRHS.mCharacterIDB && mSubShapeIDB == inRHS.mSubShapeIDB;
460 }
461
462 bool operator != (const ContactKey &inRHS) const
463 {
464 return !(*this == inRHS);
465 }
466
469 {
470 static_assert(sizeof(BodyID) + sizeof(CharacterID) + sizeof(SubShapeID) == sizeof(ContactKey), "No padding expected");
471 return HashBytes(this, sizeof(ContactKey));
472 }
473
474 // Saving / restoring state for replay
475 void SaveState(StateRecorder &inStream) const;
476 void RestoreState(StateRecorder &inStream);
477
481 };
482
484 struct Contact : public ContactKey
485 {
486 // Saving / restoring state for replay
487 void SaveState(StateRecorder &inStream) const;
488 void RestoreState(StateRecorder &inStream);
489
494 float mDistance;
495 float mFraction;
498 const CharacterVirtual * mCharacterB = nullptr;
501 bool mHadCollision = false;
502 bool mWasDiscarded = false;
503 bool mCanPushCharacter = true;
504 };
505
508
511 const ContactList & GetActiveContacts() const { return mActiveContacts; }
512
514 bool HasCollidedWith(const BodyID &inBody) const
515 {
516 for (const CharacterVirtual::Contact &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 CharacterVirtual::Contact &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 Contact &inLHS, const Contact &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
553 using IgnoredContactList = Array<ContactKey, STLTempAllocator<ContactKey>>;
554
555 // A constraint that limits the movement of the character
556 struct Constraint
557 {
558 Contact * 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, Contact &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 Contact & 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, Contact &outContact, const Body &inBody, Vec3Arg inUp, RVec3Arg inBaseOffset, const taCollector &inCollector, const CollideShapeResult &inResult);
612 inline static void sFillCharacterContactProperties(Contact &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 Contact &inContact) const;
623
624 // Trigger the contact callback for inContact and get the contact settings
625 void ContactAdded(const Contact &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, Contact &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 Contact &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
737 using ListenerContacts = UnorderedMap<ContactKey, ListenerContactValue>;
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:275
std::uint64_t uint64
Definition Core.h:504
unsigned int uint
Definition Core.h:500
#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: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
Definition CharacterVirtual.h:87
virtual void OnContactAdded(const CharacterVirtual *inCharacter, const BodyID &inBodyID2, const SubShapeID &inSubShapeID2, RVec3Arg inContactPosition, Vec3Arg inContactNormal, CharacterContactSettings &ioSettings)
Definition CharacterVirtual.h:109
virtual ~CharacterContactListener()=default
Destructor.
virtual void OnContactRemoved(const CharacterVirtual *inCharacter, const BodyID &inBodyID2, const SubShapeID &inSubShapeID2)
Definition CharacterVirtual.h:125
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:97
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:147
virtual bool OnCharacterContactValidate(const CharacterVirtual *inCharacter, const CharacterVirtual *inOtherCharacter, const SubShapeID &inSubShapeID2)
Same as OnContactValidate but when colliding with a CharacterVirtual.
Definition CharacterVirtual.h:100
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:128
virtual void OnAdjustBodyVelocity(const CharacterVirtual *inCharacter, const Body &inBody2, Vec3 &ioLinearVelocity, Vec3 &ioAngularVelocity)
Definition CharacterVirtual.h:94
virtual void OnCharacterContactRemoved(const CharacterVirtual *inCharacter, const CharacterID &inOtherCharacterID, const SubShapeID &inSubShapeID2)
Definition CharacterVirtual.h:135
virtual void OnContactPersisted(const CharacterVirtual *inCharacter, const BodyID &inBodyID2, const SubShapeID &inSubShapeID2, RVec3Arg inContactPosition, Vec3Arg inContactNormal, CharacterContactSettings &ioSettings)
Definition CharacterVirtual.h:118
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:150
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:131
This class contains settings that allow you to override the behavior of a character's collision respo...
Definition CharacterVirtual.h:73
bool mCanPushCharacter
True when the object can push the virtual character.
Definition CharacterVirtual.h:76
bool mCanReceiveImpulses
Definition CharacterVirtual.h:81
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:444
BodyID mBodyB
ID of body we're colliding with (if not invalid)
Definition CharacterVirtual.h:478
ContactKey(const CharacterID &inCharacterIDB, const SubShapeID &inSubShapeID)
Definition CharacterVirtual.h:450
ContactKey()=default
Constructor.
ContactKey(const BodyID &inBodyB, const SubShapeID &inSubShapeID)
Definition CharacterVirtual.h:449
bool IsSameBody(const ContactKey &inOther) const
Checks if two contacts refer to the same body (or virtual character)
Definition CharacterVirtual.h:454
uint64 GetHash() const
Hash of this structure.
Definition CharacterVirtual.h:468
CharacterID mCharacterIDB
Character we're colliding with (if not invalid)
Definition CharacterVirtual.h:479
ContactKey(const ContactKey &inContact)=default
SubShapeID mSubShapeIDB
Sub shape ID of body or character we're colliding with.
Definition CharacterVirtual.h:480
Definition CharacterVirtual.h:206
void SetEnhancedInternalEdgeRemoval(bool inApply)
Definition CharacterVirtual.h:277
TransformedShape GetTransformedShape() const
Get the transformed shape that represents the volume of the character, can be used for collision chec...
Definition CharacterVirtual.h:412
float GetMass() const
Character mass (kg)
Definition CharacterVirtual.h:264
float GetPenetrationRecoverySpeed() const
This value governs how fast a penetration will be resolved, 0 = nothing is resolved,...
Definition CharacterVirtual.h:272
RVec3 GetPosition() const
Get the position of the character.
Definition CharacterVirtual.h:243
void SetLinearVelocity(Vec3Arg inLinearVelocity)
Set the linear velocity of the character (m / s)
Definition CharacterVirtual.h:240
const ContactList & GetActiveContacts() const
Definition CharacterVirtual.h:511
RMat44 GetWorldTransform() const
Calculate the world transform of the character.
Definition CharacterVirtual.h:258
void SetCharacterVsCharacterCollision(CharacterVsCharacterCollision *inCharacterVsCharacterCollision)
Set the character vs character collision interface.
Definition CharacterVirtual.h:234
RVec3 GetCenterOfMassPosition() const
Definition CharacterVirtual.h:255
bool GetMaxHitsExceeded() const
Definition CharacterVirtual.h:294
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:269
float GetCharacterPadding() const
Character padding.
Definition CharacterVirtual.h:280
void SetMaxNumHits(uint inMaxHits)
Definition CharacterVirtual.h:284
uint GetMaxNumHits() const
Max num hits to collect in order to avoid excess of contact points collection.
Definition CharacterVirtual.h:283
float GetMaxStrength() const
Maximum force with which the character can push other bodies (N)
Definition CharacterVirtual.h:268
void SetShapeOffset(Vec3Arg inShapeOffset)
Definition CharacterVirtual.h:298
BodyID GetInnerBodyID() const
Optional inner rigid body that proxies the character in the world. Can be used to update body propert...
Definition CharacterVirtual.h:305
void SetMass(float inMass)
Definition CharacterVirtual.h:265
bool GetEnhancedInternalEdgeRemoval() const
Set to indicate that extra effort should be made to try to remove ghost contacts (collisions with int...
Definition CharacterVirtual.h:276
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:237
CharacterContactListener * GetListener() const
Get the current contact listener.
Definition CharacterVirtual.h:231
RMat44 GetCenterOfMassTransform() const
Calculates the transform for this character's center of mass.
Definition CharacterVirtual.h:261
CharacterVirtual(const CharacterVirtualSettings *inSettings, RVec3Arg inPosition, QuatArg inRotation, PhysicsSystem *inSystem)
Constructor without user data.
Definition CharacterVirtual.h:219
void SetRotation(QuatArg inRotation)
Set the rotation of the character.
Definition CharacterVirtual.h:252
void SetHitReductionCosMaxAngle(float inCosMaxAngle)
Definition CharacterVirtual.h:288
uint64 GetUserData() const
Access to the user data, can be used for anything by the application.
Definition CharacterVirtual.h:301
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:297
void SetPenetrationRecoverySpeed(float inSpeed)
Definition CharacterVirtual.h:273
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:287
void SetPosition(RVec3Arg inPosition)
Set the position of the character.
Definition CharacterVirtual.h:246
const CharacterID & GetID() const
The ID of this character.
Definition CharacterVirtual.h:225
void SetListener(CharacterContactListener *inListener)
Set the contact listener.
Definition CharacterVirtual.h:228
Quat GetRotation() const
Get the rotation of the character.
Definition CharacterVirtual.h:249
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:157
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:184
void Add(CharacterVirtual *inCharacter)
Add a character to the list of characters to check collision against.
Definition CharacterVirtual.h:187
Array< CharacterVirtual * > mCharacters
The list of characters to check collision against.
Definition CharacterVirtual.h:196
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: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
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:103
Encapsulates a collision contact.
Definition CharacterVirtual.h:485
EMotionType mMotionTypeB
Motion type of B, used to determine the priority of the contact.
Definition CharacterVirtual.h:496
Vec3 mContactNormal
Contact normal, pointing towards the character.
Definition CharacterVirtual.h:492
const PhysicsMaterial * mMaterial
Material of B.
Definition CharacterVirtual.h:500
float mFraction
Fraction along the path where this contact takes place.
Definition CharacterVirtual.h:495
uint64 mUserData
User data of B.
Definition CharacterVirtual.h:499
Vec3 mLinearVelocity
Velocity of the contact point.
Definition CharacterVirtual.h:491
float mDistance
Distance to the contact <= 0 means that it is an actual contact, > 0 means predictive.
Definition CharacterVirtual.h:494
Vec3 mSurfaceNormal
Surface normal of the contact.
Definition CharacterVirtual.h:493
RVec3 mPosition
Position where the character makes contact.
Definition CharacterVirtual.h:490
bool mIsSensorB
If B is a sensor.
Definition CharacterVirtual.h:497
Settings struct with settings for ExtendedUpdate.
Definition CharacterVirtual.h:367