Skip to content

Commit 87af8a1

Browse files
committed
improved delta consistency
1 parent 11d5e73 commit 87af8a1

3 files changed

Lines changed: 27 additions & 28 deletions

File tree

src/collision/Resolver.js

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,17 @@ var Resolver = {};
99
module.exports = Resolver;
1010

1111
var Vertices = require('../geometry/Vertices');
12-
var Vector = require('../geometry/Vector');
1312
var Common = require('../core/Common');
1413
var Bounds = require('../geometry/Bounds');
1514

1615
(function() {
1716

18-
Resolver._restingThresh = 4;
19-
Resolver._restingThreshTangent = 6;
17+
Resolver._restingThresh = 2;
18+
Resolver._restingThreshTangent = Math.sqrt(6);
2019
Resolver._positionDampen = 0.9;
2120
Resolver._positionWarming = 0.8;
2221
Resolver._frictionNormalMultiplier = 5;
22+
Resolver._frictionMaxStatic = Number.MAX_VALUE;
2323

2424
/**
2525
* Prepare pairs for position solving.
@@ -49,9 +49,9 @@ var Bounds = require('../geometry/Bounds');
4949
* Find a solution for pair positions.
5050
* @method solvePosition
5151
* @param {pair[]} pairs
52-
* @param {number} delta
52+
* @param {number} positionIterations
5353
*/
54-
Resolver.solvePosition = function(pairs, delta) {
54+
Resolver.solvePosition = function(pairs, positionIterations) {
5555
var i,
5656
pair,
5757
collision,
@@ -60,9 +60,7 @@ var Bounds = require('../geometry/Bounds');
6060
normal,
6161
contactShare,
6262
positionImpulse,
63-
timeScale = delta / Common._timeUnit,
64-
damping = Common.clamp(Resolver._positionDampen * timeScale, 0, 1),
65-
positionDampen = Resolver._positionDampen,
63+
positionDampen = Resolver._positionDampen * Common.clamp(20 / positionIterations, 0, 1),
6664
pairsLength = pairs.length;
6765

6866
// find impulses required to resolve penetration
@@ -93,7 +91,7 @@ var Bounds = require('../geometry/Bounds');
9391
bodyA = collision.parentA;
9492
bodyB = collision.parentB;
9593
normal = collision.normal;
96-
positionImpulse = (pair.separation - pair.slop) * damping;
94+
positionImpulse = pair.separation - pair.slop;
9795

9896
if (bodyA.isStatic || bodyB.isStatic)
9997
positionImpulse *= 2;
@@ -227,12 +225,12 @@ var Bounds = require('../geometry/Bounds');
227225
*/
228226
Resolver.solveVelocity = function(pairs, delta) {
229227
var timeScale = delta / Common._timeUnit,
230-
timeScale2 = timeScale * timeScale,
231-
timeScale3 = timeScale2 * timeScale,
232-
restingThresh = Resolver._restingThresh * timeScale2,
228+
timeScaleSquared = timeScale * timeScale,
229+
timeScaleCubed = timeScaleSquared * timeScale,
230+
restingThresh = -Resolver._restingThresh * timeScale,
233231
frictionNormalMultiplier = Resolver._frictionNormalMultiplier,
234-
restingThreshTangent = Resolver._restingThreshTangent * timeScale2,
235-
NumberMaxValue = Number.MAX_VALUE,
232+
restingThreshTangent = Resolver._restingThreshTangent * timeScale,
233+
frictionMaxStatic = Resolver._frictionMaxStatic * timeScale,
236234
pairsLength = pairs.length,
237235
tangentImpulse,
238236
maxFriction,
@@ -258,7 +256,7 @@ var Bounds = require('../geometry/Bounds');
258256
contactsLength = contacts.length,
259257
contactShare = 1 / contactsLength,
260258
inverseMassTotal = bodyA.inverseMass + bodyB.inverseMass,
261-
friction = pair.friction * pair.frictionStatic * frictionNormalMultiplier * timeScale2;
259+
friction = pair.friction * pair.frictionStatic * frictionNormalMultiplier * timeScale;
262260

263261
// update body velocities
264262
bodyAVelocity.x = bodyA.position.x - bodyA.positionPrev.x;
@@ -291,14 +289,14 @@ var Bounds = require('../geometry/Bounds');
291289

292290
// coulomb friction
293291
var normalOverlap = pair.separation + normalVelocity;
294-
var normalForce = Math.min(normalOverlap, 1) * timeScale3;
292+
var normalForce = Math.min(normalOverlap, 1);
295293
normalForce = normalOverlap < 0 ? 0 : normalForce;
296294

297295
var frictionLimit = normalForce * friction;
298296

299-
if (tangentVelocity > frictionLimit || -tangentVelocity > frictionLimit) {
300-
maxFriction = (tangentVelocity > 0 ? tangentVelocity : -tangentVelocity) * timeScale;
301-
tangentImpulse = pair.friction * (tangentVelocity > 0 ? 1 : -1) * timeScale3;
297+
if (tangentVelocity < -frictionLimit || tangentVelocity > frictionLimit) {
298+
maxFriction = (tangentVelocity > 0 ? tangentVelocity : -tangentVelocity);
299+
tangentImpulse = pair.friction * (tangentVelocity > 0 ? 1 : -1) * timeScaleCubed;
302300

303301
if (tangentImpulse < -maxFriction) {
304302
tangentImpulse = -maxFriction;
@@ -307,7 +305,7 @@ var Bounds = require('../geometry/Bounds');
307305
}
308306
} else {
309307
tangentImpulse = tangentVelocity;
310-
maxFriction = NumberMaxValue;
308+
maxFriction = frictionMaxStatic;
311309
}
312310

313311
// account for mass, inertia and contact offset
@@ -320,20 +318,20 @@ var Bounds = require('../geometry/Bounds');
320318
tangentImpulse *= share;
321319

322320
// handle high velocity and resting collisions separately
323-
if (normalVelocity < 0 && normalVelocity * normalVelocity > restingThresh) {
321+
if (normalVelocity < restingThresh) {
324322
// high normal velocity so clear cached contact normal impulse
325323
contact.normalImpulse = 0;
326324
} else {
327325
// solve resting collision constraints using Erin Catto's method (GDC08)
328326
// impulse constraint tends to 0
329327
var contactNormalImpulse = contact.normalImpulse;
330328
contact.normalImpulse += normalImpulse;
331-
contact.normalImpulse = Math.min(contact.normalImpulse, 0);
329+
if (contact.normalImpulse > 0) contact.normalImpulse = 0;
332330
normalImpulse = contact.normalImpulse - contactNormalImpulse;
333331
}
334332

335333
// handle high velocity and resting collisions separately
336-
if (tangentVelocity * tangentVelocity > restingThreshTangent) {
334+
if (tangentVelocity < -restingThreshTangent || tangentVelocity > restingThreshTangent) {
337335
// high tangent velocity so clear cached contact tangent impulse
338336
contact.tangentImpulse = 0;
339337
} else {

src/core/Engine.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ var Body = require('../body/Body');
154154
// iteratively resolve position between collisions
155155
Resolver.preSolvePosition(pairs.list);
156156
for (i = 0; i < engine.positionIterations; i++) {
157-
Resolver.solvePosition(pairs.list, delta);
157+
Resolver.solvePosition(pairs.list, engine.positionIterations);
158158
}
159159
Resolver.postSolvePosition(allBodies);
160160

src/core/Sleeping.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ var Common = require('./Common');
2525
*/
2626
Sleeping.update = function(bodies, delta) {
2727
var timeScale = delta / Common._timeUnit,
28-
timeScale2 = timeScale * timeScale,
29-
motionSleepThreshold = Sleeping._motionSleepThreshold * timeScale2;
28+
timeScaleSquared = timeScale * timeScale,
29+
motionSleepThreshold = Sleeping._motionSleepThreshold * timeScaleSquared;
3030

3131
// update bodies sleeping status
3232
for (var i = 0; i < bodies.length; i++) {
@@ -64,7 +64,8 @@ var Common = require('./Common');
6464
* @param {number} delta
6565
*/
6666
Sleeping.afterCollisions = function(pairs, delta) {
67-
var timeScale = delta / Common._timeUnit;
67+
var timeScale = delta / Common._timeUnit,
68+
motionSleepThreshold = Sleeping._motionSleepThreshold * timeScale * timeScale;
6869

6970
// wake up bodies involved in collisions
7071
for (var i = 0; i < pairs.length; i++) {
@@ -86,7 +87,7 @@ var Common = require('./Common');
8687
var sleepingBody = (bodyA.isSleeping && !bodyA.isStatic) ? bodyA : bodyB,
8788
movingBody = sleepingBody === bodyA ? bodyB : bodyA;
8889

89-
if (!sleepingBody.isStatic && movingBody.motion > Sleeping._motionWakeThreshold * timeScale * timeScale) {
90+
if (!sleepingBody.isStatic && movingBody.motion > motionSleepThreshold) {
9091
Sleeping.set(sleepingBody, false);
9192
}
9293
}

0 commit comments

Comments
 (0)