Skip to content

Commit 1db98a3

Browse files
committed
fixed issues with friction stability
1 parent 3de9d00 commit 1db98a3

1 file changed

Lines changed: 20 additions & 11 deletions

File tree

src/collision/Resolver.js

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ var Bounds = require('../geometry/Bounds');
1616
(function() {
1717

1818
Resolver._restingThresh = 4;
19+
Resolver._restingThreshTangent = 6;
1920
Resolver._positionDampen = 0.9;
2021
Resolver._positionWarming = 0.8;
2122
Resolver._frictionNormalMultiplier = 5;
@@ -281,37 +282,45 @@ var Bounds = require('../geometry/Bounds');
281282
maxFriction = Infinity;
282283

283284
if (tangentSpeed > pair.friction * pair.frictionStatic * normalForce * timeScaleSquared) {
284-
tangentImpulse = pair.friction * tangentVelocityDirection * timeScaleSquared;
285285
maxFriction = tangentSpeed;
286+
tangentImpulse = Common.clamp(
287+
pair.friction * tangentVelocityDirection * timeScaleSquared,
288+
-maxFriction, maxFriction
289+
);
286290
}
287291

288292
// modify impulses accounting for mass, inertia and offset
289293
var oAcN = Vector.cross(offsetA, normal),
290294
oBcN = Vector.cross(offsetB, normal),
291-
denom = bodyA.inverseMass + bodyB.inverseMass + bodyA.inverseInertia * oAcN * oAcN + bodyB.inverseInertia * oBcN * oBcN;
295+
share = contactShare / (bodyA.inverseMass + bodyB.inverseMass + bodyA.inverseInertia * oAcN * oAcN + bodyB.inverseInertia * oBcN * oBcN);
292296

293-
normalImpulse *= contactShare / denom;
294-
tangentImpulse *= contactShare / (1 + denom);
297+
normalImpulse *= share;
298+
tangentImpulse *= share;
295299

296300
// handle high velocity and resting collisions separately
297301
if (normalVelocity < 0 && normalVelocity * normalVelocity > Resolver._restingThresh * timeScaleSquared) {
298-
// high velocity so clear cached contact impulse
302+
// high normal velocity so clear cached contact normal impulse
299303
contact.normalImpulse = 0;
300-
contact.tangentImpulse = 0;
301304
} else {
302305
// solve resting collision constraints using Erin Catto's method (GDC08)
303-
304-
// impulse constraint, tends to 0
306+
// impulse constraint tends to 0
305307
var contactNormalImpulse = contact.normalImpulse;
306308
contact.normalImpulse = Math.min(contact.normalImpulse + normalImpulse, 0);
307309
normalImpulse = contact.normalImpulse - contactNormalImpulse;
308-
309-
// tangent impulse, tends to -maxFriction or maxFriction
310+
}
311+
312+
// handle high velocity and resting collisions separately
313+
if (tangentVelocity * tangentVelocity > Resolver._restingThreshTangent * timeScaleSquared) {
314+
// high tangent velocity so clear cached contact tangent impulse
315+
contact.tangentImpulse = 0;
316+
} else {
317+
// solve resting collision constraints using Erin Catto's method (GDC08)
318+
// tangent impulse tends to -tangentSpeed or +tangentSpeed
310319
var contactTangentImpulse = contact.tangentImpulse;
311320
contact.tangentImpulse = Common.clamp(contact.tangentImpulse + tangentImpulse, -maxFriction, maxFriction);
312321
tangentImpulse = contact.tangentImpulse - contactTangentImpulse;
313322
}
314-
323+
315324
// total impulse from contact
316325
impulse.x = (normal.x * normalImpulse) + (tangent.x * tangentImpulse);
317326
impulse.y = (normal.y * normalImpulse) + (tangent.y * tangentImpulse);

0 commit comments

Comments
 (0)