Path: blob/master/thirdparty/jolt_physics/patches/0002-backport-upstream-commit-bc7f1fb8c.patch
45998 views
diff --git a/thirdparty/jolt_physics/Jolt/Physics/Constraints/ContactConstraintManager.cpp b/thirdparty/jolt_physics/Jolt/Physics/Constraints/ContactConstraintManager.cpp1index 7de3a4483e..972fc13583 1006442--- a/thirdparty/jolt_physics/Jolt/Physics/Constraints/ContactConstraintManager.cpp3+++ b/thirdparty/jolt_physics/Jolt/Physics/Constraints/ContactConstraintManager.cpp4@@ -46,7 +46,7 @@ void ContactConstraintManager::WorldContactPoint::CalculateNonPenetrationConstra5}67template <EMotionType Type1, EMotionType Type2>8-JPH_INLINE void ContactConstraintManager::WorldContactPoint::TemplatedCalculateFrictionAndNonPenetrationConstraintProperties(float inDeltaTime, float inGravityDeltaTimeDotNormal, const Body &inBody1, const Body &inBody2, float inInvM1, float inInvM2, Mat44Arg inInvI1, Mat44Arg inInvI2, RVec3Arg inWorldSpacePosition1, RVec3Arg inWorldSpacePosition2, Vec3Arg inWorldSpaceNormal, Vec3Arg inWorldSpaceTangent1, Vec3Arg inWorldSpaceTangent2, const ContactSettings &inSettings, float inMinVelocityForRestitution)9+JPH_INLINE void ContactConstraintManager::WorldContactPoint::TemplatedCalculateFrictionAndNonPenetrationConstraintProperties(float inDeltaTime, Vec3Arg inGravity, const Body &inBody1, const Body &inBody2, float inInvM1, float inInvM2, Mat44Arg inInvI1, Mat44Arg inInvI2, RVec3Arg inWorldSpacePosition1, RVec3Arg inWorldSpacePosition2, Vec3Arg inWorldSpaceNormal, Vec3Arg inWorldSpaceTangent1, Vec3Arg inWorldSpaceTangent2, const ContactSettings &inSettings, float inMinVelocityForRestitution)10{11JPH_DET_LOG("TemplatedCalculateFrictionAndNonPenetrationConstraintProperties: p1: " << inWorldSpacePosition1 << " p2: " << inWorldSpacePosition212<< " normal: " << inWorldSpaceNormal << " tangent1: " << inWorldSpaceTangent1 << " tangent2: " << inWorldSpaceTangent213@@ -58,39 +58,19 @@ JPH_INLINE void ContactConstraintManager::WorldContactPoint::TemplatedCalculateF14Vec3 r1 = Vec3(p - inBody1.GetCenterOfMassPosition());15Vec3 r2 = Vec3(p - inBody2.GetCenterOfMassPosition());1617- // The gravity is applied in the beginning of the time step. If we get here, there was a collision18- // at the beginning of the time step, so we've applied too much gravity. This means that our19- // calculated restitution can be too high, so when we apply restitution, we cancel the added20- // velocity due to gravity.21- float gravity_dt_dot_normal;22+ const MotionProperties *mp1 = inBody1.GetMotionPropertiesUnchecked();23+ const MotionProperties *mp2 = inBody2.GetMotionPropertiesUnchecked();2425// Calculate velocity of collision points26Vec3 relative_velocity;27if constexpr (Type1 != EMotionType::Static && Type2 != EMotionType::Static)28- {29- const MotionProperties *mp1 = inBody1.GetMotionPropertiesUnchecked();30- const MotionProperties *mp2 = inBody2.GetMotionPropertiesUnchecked();31relative_velocity = mp2->GetPointVelocityCOM(r2) - mp1->GetPointVelocityCOM(r1);32- gravity_dt_dot_normal = inGravityDeltaTimeDotNormal * (mp2->GetGravityFactor() - mp1->GetGravityFactor());33- }34else if constexpr (Type1 != EMotionType::Static)35- {36- const MotionProperties *mp1 = inBody1.GetMotionPropertiesUnchecked();37relative_velocity = -mp1->GetPointVelocityCOM(r1);38- gravity_dt_dot_normal = inGravityDeltaTimeDotNormal * mp1->GetGravityFactor();39- }40else if constexpr (Type2 != EMotionType::Static)41- {42- const MotionProperties *mp2 = inBody2.GetMotionPropertiesUnchecked();43relative_velocity = mp2->GetPointVelocityCOM(r2);44- gravity_dt_dot_normal = inGravityDeltaTimeDotNormal * mp2->GetGravityFactor();45- }46else47- {48- JPH_ASSERT(false); // Static vs static makes no sense49- relative_velocity = Vec3::sZero();50- gravity_dt_dot_normal = 0.0f;51- }52+ static_assert(false, "Static vs static makes no sense");53float normal_velocity = relative_velocity.Dot(inWorldSpaceNormal);5455// How much the shapes are penetrating (> 0 if penetrating, < 0 if separated)56@@ -114,11 +94,40 @@ JPH_INLINE void ContactConstraintManager::WorldContactPoint::TemplatedCalculateF57// position rather than from a position where it is touching the other object. This causes the object58// to appear to move faster for 1 frame (the opposite of time stealing).59if (normal_velocity < -speculative_contact_velocity_bias)60- normal_velocity_bias = inSettings.mCombinedRestitution * (normal_velocity - gravity_dt_dot_normal);61+ {62+ // The gravity / constant forces are applied in the beginning of the time step.63+ // If we get here, there was a collision at the beginning of the time step, so we've applied too much force.64+ // This means that our calculated restitution can be too high resulting in an increase in energy.65+ // So, when we apply restitution, we cancel the added velocity due to these forces.66+ Vec3 relative_acceleration;67+68+ // Calculate effect of gravity69+ if constexpr (Type1 != EMotionType::Static && Type2 != EMotionType::Static)70+ relative_acceleration = inGravity * (mp2->GetGravityFactor() - mp1->GetGravityFactor());71+ else if constexpr (Type1 != EMotionType::Static)72+ relative_acceleration = -inGravity * mp1->GetGravityFactor();73+ else if constexpr (Type2 != EMotionType::Static)74+ relative_acceleration = inGravity * mp2->GetGravityFactor();75+ else76+ static_assert(false, "Static vs static makes no sense");77+78+ // Calculate effect of accumulated forces79+ if constexpr (Type1 == EMotionType::Dynamic)80+ relative_acceleration -= mp1->GetAccumulatedForce() * mp1->GetInverseMass();81+ if constexpr (Type2 == EMotionType::Dynamic)82+ relative_acceleration += mp2->GetAccumulatedForce() * mp2->GetInverseMass();83+84+ // We only compensate forces towards the contact normal.85+ float force_delta_velocity = min(0.0f, relative_acceleration.Dot(inWorldSpaceNormal) * inDeltaTime);86+87+ normal_velocity_bias = inSettings.mCombinedRestitution * (normal_velocity - force_delta_velocity);88+ }89else90+ {91// In this case we have predicted that we don't hit the other object, but if we do (due to other constraints changing velocities)92// the speculative contact will prevent penetration but will not apply restitution leading to another artifact.93normal_velocity_bias = speculative_contact_velocity_bias;94+ }95}96else97{98@@ -706,7 +715,7 @@ void ContactConstraintManager::PrepareConstraintBuffer(PhysicsUpdateContext *inC99}100101template <EMotionType Type1, EMotionType Type2>102-JPH_INLINE void ContactConstraintManager::TemplatedCalculateFrictionAndNonPenetrationConstraintProperties(ContactConstraint &ioConstraint, const ContactSettings &inSettings, float inDeltaTime, Vec3Arg inGravityDeltaTime, RMat44Arg inTransformBody1, RMat44Arg inTransformBody2, const Body &inBody1, const Body &inBody2)103+JPH_INLINE void ContactConstraintManager::TemplatedCalculateFrictionAndNonPenetrationConstraintProperties(ContactConstraint &ioConstraint, const ContactSettings &inSettings, float inDeltaTime, Vec3Arg inGravity, RMat44Arg inTransformBody1, RMat44Arg inTransformBody2, const Body &inBody1, const Body &inBody2)104{105// Calculate scaled mass and inertia106Mat44 inv_i1;107@@ -737,20 +746,17 @@ JPH_INLINE void ContactConstraintManager::TemplatedCalculateFrictionAndNonPenetr108109Vec3 ws_normal = ioConstraint.GetWorldSpaceNormal();110111- // Calculate value for restitution correction112- float gravity_dt_dot_normal = inGravityDeltaTime.Dot(ws_normal);113-114// Setup velocity constraint properties115float min_velocity_for_restitution = mPhysicsSettings.mMinVelocityForRestitution;116for (WorldContactPoint &wcp : ioConstraint.mContactPoints)117{118RVec3 p1 = inTransformBody1 * Vec3::sLoadFloat3Unsafe(wcp.mContactPoint->mPosition1);119RVec3 p2 = inTransformBody2 * Vec3::sLoadFloat3Unsafe(wcp.mContactPoint->mPosition2);120- wcp.TemplatedCalculateFrictionAndNonPenetrationConstraintProperties<Type1, Type2>(inDeltaTime, gravity_dt_dot_normal, inBody1, inBody2, ioConstraint.mInvMass1, ioConstraint.mInvMass2, inv_i1, inv_i2, p1, p2, ws_normal, t1, t2, inSettings, min_velocity_for_restitution);121+ wcp.TemplatedCalculateFrictionAndNonPenetrationConstraintProperties<Type1, Type2>(inDeltaTime, inGravity, inBody1, inBody2, ioConstraint.mInvMass1, ioConstraint.mInvMass2, inv_i1, inv_i2, p1, p2, ws_normal, t1, t2, inSettings, min_velocity_for_restitution);122}123}124125-inline void ContactConstraintManager::CalculateFrictionAndNonPenetrationConstraintProperties(ContactConstraint &ioConstraint, const ContactSettings &inSettings, float inDeltaTime, Vec3Arg inGravityDeltaTime, RMat44Arg inTransformBody1, RMat44Arg inTransformBody2, const Body &inBody1, const Body &inBody2)126+inline void ContactConstraintManager::CalculateFrictionAndNonPenetrationConstraintProperties(ContactConstraint &ioConstraint, const ContactSettings &inSettings, float inDeltaTime, Vec3Arg inGravity, RMat44Arg inTransformBody1, RMat44Arg inTransformBody2, const Body &inBody1, const Body &inBody2)127{128// Dispatch to the correct templated form129switch (inBody1.GetMotionType())130@@ -759,15 +765,15 @@ inline void ContactConstraintManager::CalculateFrictionAndNonPenetrationConstrai131switch (inBody2.GetMotionType())132{133case EMotionType::Dynamic:134- TemplatedCalculateFrictionAndNonPenetrationConstraintProperties<EMotionType::Dynamic, EMotionType::Dynamic>(ioConstraint, inSettings, inDeltaTime, inGravityDeltaTime, inTransformBody1, inTransformBody2, inBody1, inBody2);135+ TemplatedCalculateFrictionAndNonPenetrationConstraintProperties<EMotionType::Dynamic, EMotionType::Dynamic>(ioConstraint, inSettings, inDeltaTime, inGravity, inTransformBody1, inTransformBody2, inBody1, inBody2);136break;137138case EMotionType::Kinematic:139- TemplatedCalculateFrictionAndNonPenetrationConstraintProperties<EMotionType::Dynamic, EMotionType::Kinematic>(ioConstraint, inSettings, inDeltaTime, inGravityDeltaTime, inTransformBody1, inTransformBody2, inBody1, inBody2);140+ TemplatedCalculateFrictionAndNonPenetrationConstraintProperties<EMotionType::Dynamic, EMotionType::Kinematic>(ioConstraint, inSettings, inDeltaTime, inGravity, inTransformBody1, inTransformBody2, inBody1, inBody2);141break;142143case EMotionType::Static:144- TemplatedCalculateFrictionAndNonPenetrationConstraintProperties<EMotionType::Dynamic, EMotionType::Static>(ioConstraint, inSettings, inDeltaTime, inGravityDeltaTime, inTransformBody1, inTransformBody2, inBody1, inBody2);145+ TemplatedCalculateFrictionAndNonPenetrationConstraintProperties<EMotionType::Dynamic, EMotionType::Static>(ioConstraint, inSettings, inDeltaTime, inGravity, inTransformBody1, inTransformBody2, inBody1, inBody2);146break;147148default:149@@ -778,12 +784,12 @@ inline void ContactConstraintManager::CalculateFrictionAndNonPenetrationConstrai150151case EMotionType::Kinematic:152JPH_ASSERT(inBody2.IsDynamic());153- TemplatedCalculateFrictionAndNonPenetrationConstraintProperties<EMotionType::Kinematic, EMotionType::Dynamic>(ioConstraint, inSettings, inDeltaTime, inGravityDeltaTime, inTransformBody1, inTransformBody2, inBody1, inBody2);154+ TemplatedCalculateFrictionAndNonPenetrationConstraintProperties<EMotionType::Kinematic, EMotionType::Dynamic>(ioConstraint, inSettings, inDeltaTime, inGravity, inTransformBody1, inTransformBody2, inBody1, inBody2);155break;156157case EMotionType::Static:158JPH_ASSERT(inBody2.IsDynamic());159- TemplatedCalculateFrictionAndNonPenetrationConstraintProperties<EMotionType::Static, EMotionType::Dynamic>(ioConstraint, inSettings, inDeltaTime, inGravityDeltaTime, inTransformBody1, inTransformBody2, inBody1, inBody2);160+ TemplatedCalculateFrictionAndNonPenetrationConstraintProperties<EMotionType::Static, EMotionType::Dynamic>(ioConstraint, inSettings, inDeltaTime, inGravity, inTransformBody1, inTransformBody2, inBody1, inBody2);161break;162163default:164@@ -863,11 +869,9 @@ void ContactConstraintManager::GetContactsFromCache(ContactAllocator &ioContactA165RMat44 transform_body1 = body1->GetCenterOfMassTransform();166RMat44 transform_body2 = body2->GetCenterOfMassTransform();167168- // Get time step169+ // Get time step and gravity170float delta_time = mUpdateContext->mStepDeltaTime;171-172- // Calculate value for restitution correction173- Vec3 gravity_dt = mUpdateContext->mPhysicsSystem->GetGravity() * delta_time;174+ Vec3 gravity = mUpdateContext->mPhysicsSystem->GetGravity();175176// Copy manifolds177uint32 output_handle = ManifoldMap::cInvalidHandle;178@@ -970,7 +974,7 @@ void ContactConstraintManager::GetContactsFromCache(ContactAllocator &ioContactA179JPH_DET_LOG("GetContactsFromCache: id1: " << constraint.mBody1->GetID() << " id2: " << constraint.mBody2->GetID() << " key: " << constraint.mSortKey);180181// Calculate friction and non-penetration constraint properties for all contact points182- CalculateFrictionAndNonPenetrationConstraintProperties(constraint, settings, delta_time, gravity_dt, transform_body1, transform_body2, *body1, *body2);183+ CalculateFrictionAndNonPenetrationConstraintProperties(constraint, settings, delta_time, gravity, transform_body1, transform_body2, *body1, *body2);184185// Notify island builder186mUpdateContext->mIslandBuilder->LinkContact(constraint_idx, body1->GetIndexInActiveBodiesInternal(), body2->GetIndexInActiveBodiesInternal());187@@ -1144,11 +1148,9 @@ bool ContactConstraintManager::TemplatedAddContactConstraint(ContactAllocator &i188// Notify island builder189mUpdateContext->mIslandBuilder->LinkContact(constraint_idx, inBody1.GetIndexInActiveBodiesInternal(), inBody2.GetIndexInActiveBodiesInternal());190191- // Get time step192+ // Get time step and gravity193float delta_time = mUpdateContext->mStepDeltaTime;194-195- // Calculate value for restitution correction196- float gravity_dt_dot_normal = inManifold.mWorldSpaceNormal.Dot(mUpdateContext->mPhysicsSystem->GetGravity() * delta_time);197+ Vec3 gravity = mUpdateContext->mPhysicsSystem->GetGravity();198199// Calculate scaled mass and inertia200float inv_m1;201@@ -1222,7 +1224,7 @@ bool ContactConstraintManager::TemplatedAddContactConstraint(ContactAllocator &i202wcp.mContactPoint = &cp;203204// Setup velocity constraint205- wcp.TemplatedCalculateFrictionAndNonPenetrationConstraintProperties<Type1, Type2>(delta_time, gravity_dt_dot_normal, inBody1, inBody2, inv_m1, inv_m2, inv_i1, inv_i2, p1_ws, p2_ws, inManifold.mWorldSpaceNormal, t1, t2, settings, mPhysicsSettings.mMinVelocityForRestitution);206+ wcp.TemplatedCalculateFrictionAndNonPenetrationConstraintProperties<Type1, Type2>(delta_time, gravity, inBody1, inBody2, inv_m1, inv_m2, inv_i1, inv_i2, p1_ws, p2_ws, inManifold.mWorldSpaceNormal, t1, t2, settings, mPhysicsSettings.mMinVelocityForRestitution);207}208209#ifdef JPH_DEBUG_RENDERER210diff --git a/thirdparty/jolt_physics/Jolt/Physics/Constraints/ContactConstraintManager.h b/thirdparty/jolt_physics/Jolt/Physics/Constraints/ContactConstraintManager.h211index 0b5938b77e..dfe5fc8c38 100644212--- a/thirdparty/jolt_physics/Jolt/Physics/Constraints/ContactConstraintManager.h213+++ b/thirdparty/jolt_physics/Jolt/Physics/Constraints/ContactConstraintManager.h214@@ -427,7 +427,7 @@ private:215void CalculateNonPenetrationConstraintProperties(const Body &inBody1, float inInvMass1, float inInvInertiaScale1, const Body &inBody2, float inInvMass2, float inInvInertiaScale2, RVec3Arg inWorldSpacePosition1, RVec3Arg inWorldSpacePosition2, Vec3Arg inWorldSpaceNormal);216217template <EMotionType Type1, EMotionType Type2>218- JPH_INLINE void TemplatedCalculateFrictionAndNonPenetrationConstraintProperties(float inDeltaTime, float inGravityDeltaTimeDotNormal, const Body &inBody1, const Body &inBody2, float inInvM1, float inInvM2, Mat44Arg inInvI1, Mat44Arg inInvI2, RVec3Arg inWorldSpacePosition1, RVec3Arg inWorldSpacePosition2, Vec3Arg inWorldSpaceNormal, Vec3Arg inWorldSpaceTangent1, Vec3Arg inWorldSpaceTangent2, const ContactSettings &inSettings, float inMinVelocityForRestitution);219+ JPH_INLINE void TemplatedCalculateFrictionAndNonPenetrationConstraintProperties(float inDeltaTime, Vec3Arg inGravity, const Body &inBody1, const Body &inBody2, float inInvM1, float inInvM2, Mat44Arg inInvI1, Mat44Arg inInvI2, RVec3Arg inWorldSpacePosition1, RVec3Arg inWorldSpacePosition2, Vec3Arg inWorldSpaceNormal, Vec3Arg inWorldSpaceTangent1, Vec3Arg inWorldSpaceTangent2, const ContactSettings &inSettings, float inMinVelocityForRestitution);220221/// The constraint parts222AxisConstraintPart mNonPenetrationConstraint;223@@ -485,10 +485,10 @@ public:224private:225/// Internal helper function to calculate the friction and non-penetration constraint properties. Templated to the motion type to reduce the amount of branches and calculations.226template <EMotionType Type1, EMotionType Type2>227- JPH_INLINE void TemplatedCalculateFrictionAndNonPenetrationConstraintProperties(ContactConstraint &ioConstraint, const ContactSettings &inSettings, float inDeltaTime, Vec3Arg inGravityDeltaTime, RMat44Arg inTransformBody1, RMat44Arg inTransformBody2, const Body &inBody1, const Body &inBody2);228+ JPH_INLINE void TemplatedCalculateFrictionAndNonPenetrationConstraintProperties(ContactConstraint &ioConstraint, const ContactSettings &inSettings, float inDeltaTime, Vec3Arg inGravity, RMat44Arg inTransformBody1, RMat44Arg inTransformBody2, const Body &inBody1, const Body &inBody2);229230/// Internal helper function to calculate the friction and non-penetration constraint properties.231- inline void CalculateFrictionAndNonPenetrationConstraintProperties(ContactConstraint &ioConstraint, const ContactSettings &inSettings, float inDeltaTime, Vec3Arg inGravityDeltaTime, RMat44Arg inTransformBody1, RMat44Arg inTransformBody2, const Body &inBody1, const Body &inBody2);232+ inline void CalculateFrictionAndNonPenetrationConstraintProperties(ContactConstraint &ioConstraint, const ContactSettings &inSettings, float inDeltaTime, Vec3Arg inGravity, RMat44Arg inTransformBody1, RMat44Arg inTransformBody2, const Body &inBody1, const Body &inBody2);233234/// Internal helper function to add a contact constraint. Templated to the motion type to reduce the amount of branches and calculations.235template <EMotionType Type1, EMotionType Type2>236237238