Path: blob/master/thirdparty/jolt_physics/patches/0006-backport-upstream-commit-63765d1.patch
59211 views
diff --git a/thirdparty/jolt_physics/Jolt/Physics/PhysicsSystem.cpp b/thirdparty/jolt_physics/Jolt/Physics/PhysicsSystem.cpp1index d972dd2c..0a3f21b8 1006442--- a/thirdparty/jolt_physics/Jolt/Physics/PhysicsSystem.cpp3+++ b/thirdparty/jolt_physics/Jolt/Physics/PhysicsSystem.cpp4@@ -26,6 +26,7 @@5#include <Jolt/Physics/DeterminismLog.h>6#include <Jolt/Physics/SoftBody/SoftBodyMotionProperties.h>7#include <Jolt/Physics/SoftBody/SoftBodyShape.h>8+#include <Jolt/Physics/SoftBody/SoftBodyContactListener.h>9#include <Jolt/Geometry/RayAABox.h>10#include <Jolt/Geometry/ClosestPoint.h>11#include <Jolt/Core/JobSystem.h>12@@ -1833,9 +1834,10 @@ void PhysicsSystem::JobFindCCDContacts(const PhysicsUpdateContext *ioContext, Ph13class CCDNarrowPhaseCollector : public CastShapeCollector14{15public:16- CCDNarrowPhaseCollector(const BodyManager &inBodyManager, ContactConstraintManager &inContactConstraintManager, CCDBody &inCCDBody, ShapeCastResult &inResult, float inDeltaTime) :17+ CCDNarrowPhaseCollector(const BodyManager &inBodyManager, ContactConstraintManager &inContactConstraintManager, SoftBodyContactListener *inSoftBodyContactListener, CCDBody &inCCDBody, ShapeCastResult &inResult, float inDeltaTime) :18mBodyManager(inBodyManager),19mContactConstraintManager(inContactConstraintManager),20+ mSoftBodyContactListener(inSoftBodyContactListener),21mCCDBody(inCCDBody),22mResult(inResult),23mDeltaTime(inDeltaTime)24@@ -1871,26 +1873,53 @@ void PhysicsSystem::JobFindCCDContacts(const PhysicsUpdateContext *ioContext, Ph25{26// Validate the contact result27const Body &body1 = mBodyManager.GetBody(mCCDBody.mBodyID1);28- ValidateResult validate_result = mContactConstraintManager.ValidateContactPoint(body1, body2, body1.GetCenterOfMassPosition(), inResult); // Note that the center of mass of body 1 is the start of the sweep and is used as base offset below29- switch (validate_result)30+ if (body2.IsRigidBody())31{32- case ValidateResult::AcceptContact:33- // Just continue34- break;35-36- case ValidateResult::AcceptAllContactsForThisBodyPair:37- // Accept this and all following contacts from this body38- mValidateBodyPair = false;39- break;40-41- case ValidateResult::RejectContact:42- return;43-44- case ValidateResult::RejectAllContactsForThisBodyPair:45- // Reject this and all following contacts from this body46- mRejectAll = true;47- ForceEarlyOut();48- return;49+ ValidateResult validate_result = mContactConstraintManager.ValidateContactPoint(body1, body2, body1.GetCenterOfMassPosition(), inResult); // Note that the center of mass of body 1 is the start of the sweep and is used as base offset below50+ switch (validate_result)51+ {52+ case ValidateResult::AcceptContact:53+ // Just continue54+ break;55+56+ case ValidateResult::AcceptAllContactsForThisBodyPair:57+ // Accept this and all following contacts from this body58+ mValidateBodyPair = false;59+ break;60+61+ case ValidateResult::RejectContact:62+ return;63+64+ case ValidateResult::RejectAllContactsForThisBodyPair:65+ // Reject this and all following contacts from this body66+ mRejectAll = true;67+ ForceEarlyOut();68+ return;69+ }70+ }71+ else72+ {73+ SoftBodyContactSettings sb_settings;74+ sb_settings.mIsSensor = false;75+ if ((mSoftBodyContactListener == nullptr76+ || mSoftBodyContactListener->OnSoftBodyContactValidate(body2, body1, sb_settings) == SoftBodyValidateResult::AcceptContact) // Note reversal, soft body needs to be first parameter77+ && !sb_settings.mIsSensor) // If the contact listener turned this into a sensor, we want to ignore it78+ {79+ // Convert the soft body contact settings (note bodies are swapped)80+ mCCDBody.mContactSettings.mInvMassScale1 = sb_settings.mInvMassScale2;81+ mCCDBody.mContactSettings.mInvMassScale2 = sb_settings.mInvMassScale1;82+ mCCDBody.mContactSettings.mInvInertiaScale1 = sb_settings.mInvInertiaScale2;83+84+ // Accept this and all following contacts from this body85+ mValidateBodyPair = false;86+ }87+ else88+ {89+ // Reject this and all following contacts from this body90+ mRejectAll = true;91+ ForceEarlyOut();92+ return;93+ }94}95}9697@@ -1927,6 +1956,7 @@ void PhysicsSystem::JobFindCCDContacts(const PhysicsUpdateContext *ioContext, Ph98private:99const BodyManager & mBodyManager;100ContactConstraintManager & mContactConstraintManager;101+ SoftBodyContactListener * mSoftBodyContactListener;102CCDBody & mCCDBody;103ShapeCastResult & mResult;104float mDeltaTime;105@@ -1935,7 +1965,7 @@ void PhysicsSystem::JobFindCCDContacts(const PhysicsUpdateContext *ioContext, Ph106107// Narrowphase collector108ShapeCastResult cast_shape_result;109- CCDNarrowPhaseCollector np_collector(mBodyManager, mContactManager, ccd_body, cast_shape_result, ioContext->mStepDeltaTime);110+ CCDNarrowPhaseCollector np_collector(mBodyManager, mContactManager, mSoftBodyContactListener, ccd_body, cast_shape_result, ioContext->mStepDeltaTime);111112// This collector wraps the narrowphase collector and collects the closest hit113class CCDBroadPhaseCollector : public CastShapeBodyCollector114@@ -2058,7 +2088,15 @@ void PhysicsSystem::JobFindCCDContacts(const PhysicsUpdateContext *ioContext, Ph115manifold.mWorldSpaceNormal = ccd_body.mContactNormal;116117// Call contact point callbacks118- mContactManager.OnCCDContactAdded(contact_allocator, body, body2, manifold, ccd_body.mContactSettings);119+ if (body2.IsRigidBody())120+ mContactManager.OnCCDContactAdded(contact_allocator, body, body2, manifold, ccd_body.mContactSettings);121+ else122+ {123+ // We already have mass and inertia scale from the OnSoftBodyContactValidate callback, but we need to fill in the rest of the contact settings124+ ccd_body.mContactSettings.mCombinedFriction = 0.0f; // Soft bodies CCD contacts don't apply friction125+ ccd_body.mContactSettings.mCombinedRestitution = mContactManager.GetCombineRestitution()(body, SubShapeID(), body2, SubShapeID()); // Soft bodies don't pass sub shape IDs because the restitution is uniform across the entire body126+ ccd_body.mContactSettings.mIsSensor = false; // We've filtered out sensors already127+ }128129if (ccd_body.mContactSettings.mIsSensor)130{131@@ -2281,6 +2319,19 @@ void PhysicsSystem::JobResolveCCDContacts(PhysicsUpdateContext *ioContext, Physi132vtx0.mVelocity += delta_v2 * vtx0.mInvMass;133vtx1.mVelocity += delta_v2 * vtx1.mInvMass;134vtx2.mVelocity += delta_v2 * vtx2.mInvMass;135+136+ // If there's a contact listener, we need to flag this vertex as having had collision and force a contact callback.137+ // Note that during the soft body update that follows this, it is likely that a new collision will be found and that this will be overwritten.138+ if (mSoftBodyContactListener != nullptr)139+ {140+ BodyID body_id = ccd_body->mBodyID1;141+ Vec3 local_normal = inv_body2_transform.Multiply3x3(ccd_body->mContactNormal);142+ Plane contact_plane = Plane::sFromPointAndNormal(local_contact, local_normal);143+ vtx0.MarkCCDContact(body_id, contact_plane);144+ vtx1.MarkCCDContact(body_id, contact_plane);145+ vtx2.MarkCCDContact(body_id, contact_plane);146+ soft_mp->RequestContactCallback();147+ }148}149150// Clamp velocity of body 1151diff --git a/thirdparty/jolt_physics/Jolt/Physics/SoftBody/SoftBodyManifold.h b/thirdparty/jolt_physics/Jolt/Physics/SoftBody/SoftBodyManifold.h152index de21ec50..57a244ad 100644153--- a/thirdparty/jolt_physics/Jolt/Physics/SoftBody/SoftBodyManifold.h154+++ b/thirdparty/jolt_physics/Jolt/Physics/SoftBody/SoftBodyManifold.h155@@ -36,7 +36,15 @@ public:156/// Get the body with which the vertex has collided in this update157JPH_INLINE BodyID GetContactBodyID(const SoftBodyVertex &inVertex) const158{159- return inVertex.mHasContact? mCollidingShapes[inVertex.mCollidingShapeIndex].mBodyID : BodyID();160+ if (!inVertex.mHasContact)161+ return BodyID();162+163+ // If this is a CCD contact, the BodyID is encoded in mCollidingShapeIndex164+ if (inVertex.mCollidingShapeIndex & int(BodyID::cBroadPhaseBit))165+ return BodyID(uint32(inVertex.mCollidingShapeIndex) ^ BodyID::cBroadPhaseBit);166+167+ // Otherwise we can get it from mCollidingShapes168+ return mCollidingShapes[inVertex.mCollidingShapeIndex].mBodyID;169}170171/// Get the number of sensors that are in contact with the soft body172diff --git a/thirdparty/jolt_physics/Jolt/Physics/SoftBody/SoftBodyMotionProperties.cpp b/thirdparty/jolt_physics/Jolt/Physics/SoftBody/SoftBodyMotionProperties.cpp173index 4aa88d20..327145ed 100644174--- a/thirdparty/jolt_physics/Jolt/Physics/SoftBody/SoftBodyMotionProperties.cpp175+++ b/thirdparty/jolt_physics/Jolt/Physics/SoftBody/SoftBodyMotionProperties.cpp176@@ -121,15 +121,13 @@ void SoftBodyMotionProperties::DetermineCollidingShapes(const SoftBodyUpdateCont177{178JPH_PROFILE_FUNCTION();179180- // Reset flag prior to collision detection181- mNeedContactCallback.store(false, memory_order_relaxed);182-183struct Collector : public CollideShapeBodyCollector184{185- Collector(const SoftBodyUpdateContext &inContext, const PhysicsSystem &inSystem, const BodyLockInterface &inBodyLockInterface, const AABox &inLocalBounds, SimShapeFilterWrapper &inShapeFilter, Array<CollidingShape> &ioHits, Array<CollidingSensor> &ioSensors) :186+ Collector(const SoftBodyUpdateContext &inContext, const PhysicsSystem &inSystem, const BodyLockInterface &inBodyLockInterface, const AABox &inLocalBounds, const AABox &inWorldBounds, SimShapeFilterWrapper &inShapeFilter, Array<CollidingShape> &ioHits, Array<CollidingSensor> &ioSensors) :187mContext(inContext),188mInverseTransform(inContext.mCenterOfMassTransform.InversedRotationTranslation()),189mLocalBounds(inLocalBounds),190+ mWorldBounds(inWorldBounds),191mBodyLockInterface(inBodyLockInterface),192mCombineFriction(inSystem.GetCombineFriction()),193mCombineRestitution(inSystem.GetCombineRestitution()),194@@ -147,7 +145,8 @@ void SoftBodyMotionProperties::DetermineCollidingShapes(const SoftBodyUpdateCont195const Body &soft_body = *mContext.mBody;196const Body &body = lock.GetBody();197if (body.IsRigidBody() // TODO: We should support soft body vs soft body198- && soft_body.GetCollisionGroup().CanCollide(body.GetCollisionGroup()))199+ && soft_body.GetCollisionGroup().CanCollide(body.GetCollisionGroup())200+ && mWorldBounds.Overlaps(body.GetWorldSpaceBounds())) // In the broadphase we widen the bounding box when a body moves, do a final check to see if the bounding boxes actually overlap201{202SoftBodyContactSettings settings;203settings.mIsSensor = body.IsSensor();204@@ -227,6 +226,7 @@ void SoftBodyMotionProperties::DetermineCollidingShapes(const SoftBodyUpdateCont205const SoftBodyUpdateContext &mContext;206RMat44 mInverseTransform;207AABox mLocalBounds;208+ AABox mWorldBounds;209const BodyLockInterface & mBodyLockInterface;210ContactConstraintManager::CombineFunction mCombineFriction;211ContactConstraintManager::CombineFunction mCombineRestitution;212@@ -246,7 +246,7 @@ void SoftBodyMotionProperties::DetermineCollidingShapes(const SoftBodyUpdateCont213// Create shape filter214SimShapeFilterWrapper shape_filter(inContext.mSimShapeFilter, inContext.mBody);215216- Collector collector(inContext, inSystem, inBodyLockInterface, local_bounds, shape_filter, mCollidingShapes, mCollidingSensors);217+ Collector collector(inContext, inSystem, inBodyLockInterface, local_bounds, world_bounds, shape_filter, mCollidingShapes, mCollidingSensors);218ObjectLayer layer = inContext.mBody->GetObjectLayer();219DefaultBroadPhaseLayerFilter broadphase_layer_filter = inSystem.GetDefaultBroadPhaseLayerFilter(layer);220DefaultObjectLayerFilter object_layer_filter = inSystem.GetDefaultLayerFilter(layer);221@@ -285,7 +285,7 @@ void SoftBodyMotionProperties::DetermineSensorCollisions(CollidingSensor &ioSens222223// We need a contact callback if one of the sensors collided224if (ioSensor.mHasContact)225- mNeedContactCallback.store(true, memory_order_relaxed);226+ RequestContactCallback();227}228229void SoftBodyMotionProperties::ApplyPressure(const SoftBodyUpdateContext &inContext)230@@ -714,6 +714,7 @@ void SoftBodyMotionProperties::ApplyCollisionConstraintsAndUpdateVelocities(cons231v.mVelocity = (v.mPosition - v.mPreviousPosition) / dt;232233// Satisfy collision constraint234+ static_assert(int(BodyID::cBroadPhaseBit) < 0); // CCD contacts should be negative too (see: SoftBodyVertex::MarkCCDContact)235if (v.mCollidingShapeIndex >= 0)236{237// Check if there is a collision238@@ -724,7 +725,7 @@ void SoftBodyMotionProperties::ApplyCollisionConstraintsAndUpdateVelocities(cons239v.mHasContact = true;240241// We need a contact callback if one of the vertices collided242- mNeedContactCallback.store(true, memory_order_relaxed);243+ RequestContactCallback();244245// Note that we already calculated the velocity, so this does not affect the velocity (next iteration starts by setting previous position to current position)246CollidingShape &cs = mCollidingShapes[v.mCollidingShapeIndex];247@@ -839,6 +840,8 @@ void SoftBodyMotionProperties::UpdateSoftBodyState(SoftBodyUpdateContext &ioCont248}249250ioContext.mContactListener->OnSoftBodyContactAdded(*ioContext.mBody, SoftBodyManifold(this));251+252+ mNeedContactCallback.store(false, memory_order_relaxed);253}254255// Loop through vertices once more to update the global state256diff --git a/thirdparty/jolt_physics/Jolt/Physics/SoftBody/SoftBodyMotionProperties.h b/thirdparty/jolt_physics/Jolt/Physics/SoftBody/SoftBodyMotionProperties.h257index 8768efd6..918ce366 100644258--- a/thirdparty/jolt_physics/Jolt/Physics/SoftBody/SoftBodyMotionProperties.h259+++ b/thirdparty/jolt_physics/Jolt/Physics/SoftBody/SoftBodyMotionProperties.h260@@ -176,6 +176,9 @@ public:261/// Update the velocities of all rigid bodies that we collided with. Not part of the public API.262void UpdateRigidBodyVelocities(const SoftBodyUpdateContext &inContext, BodyInterface &inBodyInterface);263264+ /// Set a flag to indicate that the ContactListener::OnSoftBodyContactAdded should be called265+ inline void RequestContactCallback() { mNeedContactCallback.store(true, memory_order_relaxed); }266+267private:268// SoftBodyManifold needs to have access to CollidingShape269friend class SoftBodyManifold;270diff --git a/thirdparty/jolt_physics/Jolt/Physics/SoftBody/SoftBodyVertex.h b/thirdparty/jolt_physics/Jolt/Physics/SoftBody/SoftBodyVertex.h271index 72d4291e..261362ef 100644272--- a/thirdparty/jolt_physics/Jolt/Physics/SoftBody/SoftBodyVertex.h273+++ b/thirdparty/jolt_physics/Jolt/Physics/SoftBody/SoftBodyVertex.h274@@ -23,6 +23,14 @@ public:275mHasContact = false;276}277278+ /// Mark this vertex as being in contact with inBodyID279+ inline void MarkCCDContact(const BodyID &inBodyID, const Plane &inContactPlane)280+ {281+ mCollisionPlane = inContactPlane;282+ mCollidingShapeIndex = int(inBodyID.GetIndexAndSequenceNumber() | BodyID::cBroadPhaseBit); // We reuse the broad phase bit to indicate this is a CCD contact283+ mHasContact = true;284+ }285+286Vec3 mPreviousPosition; ///< Internal use only. Position at the previous time step287Vec3 mPosition; ///< Position, relative to the center of mass of the soft body288Vec3 mVelocity; ///< Velocity, relative to the center of mass of the soft body289290291