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