mirror of
https://github.com/liabru/matter-js.git
synced 2025-02-01 18:24:54 -05:00
improved delta consistency
This commit is contained in:
parent
11d5e73c1f
commit
87af8a1740
3 changed files with 27 additions and 28 deletions
|
@ -9,17 +9,17 @@ var Resolver = {};
|
||||||
module.exports = Resolver;
|
module.exports = Resolver;
|
||||||
|
|
||||||
var Vertices = require('../geometry/Vertices');
|
var Vertices = require('../geometry/Vertices');
|
||||||
var Vector = require('../geometry/Vector');
|
|
||||||
var Common = require('../core/Common');
|
var Common = require('../core/Common');
|
||||||
var Bounds = require('../geometry/Bounds');
|
var Bounds = require('../geometry/Bounds');
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
|
||||||
Resolver._restingThresh = 4;
|
Resolver._restingThresh = 2;
|
||||||
Resolver._restingThreshTangent = 6;
|
Resolver._restingThreshTangent = Math.sqrt(6);
|
||||||
Resolver._positionDampen = 0.9;
|
Resolver._positionDampen = 0.9;
|
||||||
Resolver._positionWarming = 0.8;
|
Resolver._positionWarming = 0.8;
|
||||||
Resolver._frictionNormalMultiplier = 5;
|
Resolver._frictionNormalMultiplier = 5;
|
||||||
|
Resolver._frictionMaxStatic = Number.MAX_VALUE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepare pairs for position solving.
|
* Prepare pairs for position solving.
|
||||||
|
@ -49,9 +49,9 @@ var Bounds = require('../geometry/Bounds');
|
||||||
* Find a solution for pair positions.
|
* Find a solution for pair positions.
|
||||||
* @method solvePosition
|
* @method solvePosition
|
||||||
* @param {pair[]} pairs
|
* @param {pair[]} pairs
|
||||||
* @param {number} delta
|
* @param {number} positionIterations
|
||||||
*/
|
*/
|
||||||
Resolver.solvePosition = function(pairs, delta) {
|
Resolver.solvePosition = function(pairs, positionIterations) {
|
||||||
var i,
|
var i,
|
||||||
pair,
|
pair,
|
||||||
collision,
|
collision,
|
||||||
|
@ -60,9 +60,7 @@ var Bounds = require('../geometry/Bounds');
|
||||||
normal,
|
normal,
|
||||||
contactShare,
|
contactShare,
|
||||||
positionImpulse,
|
positionImpulse,
|
||||||
timeScale = delta / Common._timeUnit,
|
positionDampen = Resolver._positionDampen * Common.clamp(20 / positionIterations, 0, 1),
|
||||||
damping = Common.clamp(Resolver._positionDampen * timeScale, 0, 1),
|
|
||||||
positionDampen = Resolver._positionDampen,
|
|
||||||
pairsLength = pairs.length;
|
pairsLength = pairs.length;
|
||||||
|
|
||||||
// find impulses required to resolve penetration
|
// find impulses required to resolve penetration
|
||||||
|
@ -93,7 +91,7 @@ var Bounds = require('../geometry/Bounds');
|
||||||
bodyA = collision.parentA;
|
bodyA = collision.parentA;
|
||||||
bodyB = collision.parentB;
|
bodyB = collision.parentB;
|
||||||
normal = collision.normal;
|
normal = collision.normal;
|
||||||
positionImpulse = (pair.separation - pair.slop) * damping;
|
positionImpulse = pair.separation - pair.slop;
|
||||||
|
|
||||||
if (bodyA.isStatic || bodyB.isStatic)
|
if (bodyA.isStatic || bodyB.isStatic)
|
||||||
positionImpulse *= 2;
|
positionImpulse *= 2;
|
||||||
|
@ -227,12 +225,12 @@ var Bounds = require('../geometry/Bounds');
|
||||||
*/
|
*/
|
||||||
Resolver.solveVelocity = function(pairs, delta) {
|
Resolver.solveVelocity = function(pairs, delta) {
|
||||||
var timeScale = delta / Common._timeUnit,
|
var timeScale = delta / Common._timeUnit,
|
||||||
timeScale2 = timeScale * timeScale,
|
timeScaleSquared = timeScale * timeScale,
|
||||||
timeScale3 = timeScale2 * timeScale,
|
timeScaleCubed = timeScaleSquared * timeScale,
|
||||||
restingThresh = Resolver._restingThresh * timeScale2,
|
restingThresh = -Resolver._restingThresh * timeScale,
|
||||||
frictionNormalMultiplier = Resolver._frictionNormalMultiplier,
|
frictionNormalMultiplier = Resolver._frictionNormalMultiplier,
|
||||||
restingThreshTangent = Resolver._restingThreshTangent * timeScale2,
|
restingThreshTangent = Resolver._restingThreshTangent * timeScale,
|
||||||
NumberMaxValue = Number.MAX_VALUE,
|
frictionMaxStatic = Resolver._frictionMaxStatic * timeScale,
|
||||||
pairsLength = pairs.length,
|
pairsLength = pairs.length,
|
||||||
tangentImpulse,
|
tangentImpulse,
|
||||||
maxFriction,
|
maxFriction,
|
||||||
|
@ -258,7 +256,7 @@ var Bounds = require('../geometry/Bounds');
|
||||||
contactsLength = contacts.length,
|
contactsLength = contacts.length,
|
||||||
contactShare = 1 / contactsLength,
|
contactShare = 1 / contactsLength,
|
||||||
inverseMassTotal = bodyA.inverseMass + bodyB.inverseMass,
|
inverseMassTotal = bodyA.inverseMass + bodyB.inverseMass,
|
||||||
friction = pair.friction * pair.frictionStatic * frictionNormalMultiplier * timeScale2;
|
friction = pair.friction * pair.frictionStatic * frictionNormalMultiplier * timeScale;
|
||||||
|
|
||||||
// update body velocities
|
// update body velocities
|
||||||
bodyAVelocity.x = bodyA.position.x - bodyA.positionPrev.x;
|
bodyAVelocity.x = bodyA.position.x - bodyA.positionPrev.x;
|
||||||
|
@ -291,14 +289,14 @@ var Bounds = require('../geometry/Bounds');
|
||||||
|
|
||||||
// coulomb friction
|
// coulomb friction
|
||||||
var normalOverlap = pair.separation + normalVelocity;
|
var normalOverlap = pair.separation + normalVelocity;
|
||||||
var normalForce = Math.min(normalOverlap, 1) * timeScale3;
|
var normalForce = Math.min(normalOverlap, 1);
|
||||||
normalForce = normalOverlap < 0 ? 0 : normalForce;
|
normalForce = normalOverlap < 0 ? 0 : normalForce;
|
||||||
|
|
||||||
var frictionLimit = normalForce * friction;
|
var frictionLimit = normalForce * friction;
|
||||||
|
|
||||||
if (tangentVelocity > frictionLimit || -tangentVelocity > frictionLimit) {
|
if (tangentVelocity < -frictionLimit || tangentVelocity > frictionLimit) {
|
||||||
maxFriction = (tangentVelocity > 0 ? tangentVelocity : -tangentVelocity) * timeScale;
|
maxFriction = (tangentVelocity > 0 ? tangentVelocity : -tangentVelocity);
|
||||||
tangentImpulse = pair.friction * (tangentVelocity > 0 ? 1 : -1) * timeScale3;
|
tangentImpulse = pair.friction * (tangentVelocity > 0 ? 1 : -1) * timeScaleCubed;
|
||||||
|
|
||||||
if (tangentImpulse < -maxFriction) {
|
if (tangentImpulse < -maxFriction) {
|
||||||
tangentImpulse = -maxFriction;
|
tangentImpulse = -maxFriction;
|
||||||
|
@ -307,7 +305,7 @@ var Bounds = require('../geometry/Bounds');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
tangentImpulse = tangentVelocity;
|
tangentImpulse = tangentVelocity;
|
||||||
maxFriction = NumberMaxValue;
|
maxFriction = frictionMaxStatic;
|
||||||
}
|
}
|
||||||
|
|
||||||
// account for mass, inertia and contact offset
|
// account for mass, inertia and contact offset
|
||||||
|
@ -320,7 +318,7 @@ var Bounds = require('../geometry/Bounds');
|
||||||
tangentImpulse *= share;
|
tangentImpulse *= share;
|
||||||
|
|
||||||
// handle high velocity and resting collisions separately
|
// handle high velocity and resting collisions separately
|
||||||
if (normalVelocity < 0 && normalVelocity * normalVelocity > restingThresh) {
|
if (normalVelocity < restingThresh) {
|
||||||
// high normal velocity so clear cached contact normal impulse
|
// high normal velocity so clear cached contact normal impulse
|
||||||
contact.normalImpulse = 0;
|
contact.normalImpulse = 0;
|
||||||
} else {
|
} else {
|
||||||
|
@ -328,12 +326,12 @@ var Bounds = require('../geometry/Bounds');
|
||||||
// impulse constraint tends to 0
|
// impulse constraint tends to 0
|
||||||
var contactNormalImpulse = contact.normalImpulse;
|
var contactNormalImpulse = contact.normalImpulse;
|
||||||
contact.normalImpulse += normalImpulse;
|
contact.normalImpulse += normalImpulse;
|
||||||
contact.normalImpulse = Math.min(contact.normalImpulse, 0);
|
if (contact.normalImpulse > 0) contact.normalImpulse = 0;
|
||||||
normalImpulse = contact.normalImpulse - contactNormalImpulse;
|
normalImpulse = contact.normalImpulse - contactNormalImpulse;
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle high velocity and resting collisions separately
|
// handle high velocity and resting collisions separately
|
||||||
if (tangentVelocity * tangentVelocity > restingThreshTangent) {
|
if (tangentVelocity < -restingThreshTangent || tangentVelocity > restingThreshTangent) {
|
||||||
// high tangent velocity so clear cached contact tangent impulse
|
// high tangent velocity so clear cached contact tangent impulse
|
||||||
contact.tangentImpulse = 0;
|
contact.tangentImpulse = 0;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -154,7 +154,7 @@ var Body = require('../body/Body');
|
||||||
// iteratively resolve position between collisions
|
// iteratively resolve position between collisions
|
||||||
Resolver.preSolvePosition(pairs.list);
|
Resolver.preSolvePosition(pairs.list);
|
||||||
for (i = 0; i < engine.positionIterations; i++) {
|
for (i = 0; i < engine.positionIterations; i++) {
|
||||||
Resolver.solvePosition(pairs.list, delta);
|
Resolver.solvePosition(pairs.list, engine.positionIterations);
|
||||||
}
|
}
|
||||||
Resolver.postSolvePosition(allBodies);
|
Resolver.postSolvePosition(allBodies);
|
||||||
|
|
||||||
|
|
|
@ -25,8 +25,8 @@ var Common = require('./Common');
|
||||||
*/
|
*/
|
||||||
Sleeping.update = function(bodies, delta) {
|
Sleeping.update = function(bodies, delta) {
|
||||||
var timeScale = delta / Common._timeUnit,
|
var timeScale = delta / Common._timeUnit,
|
||||||
timeScale2 = timeScale * timeScale,
|
timeScaleSquared = timeScale * timeScale,
|
||||||
motionSleepThreshold = Sleeping._motionSleepThreshold * timeScale2;
|
motionSleepThreshold = Sleeping._motionSleepThreshold * timeScaleSquared;
|
||||||
|
|
||||||
// update bodies sleeping status
|
// update bodies sleeping status
|
||||||
for (var i = 0; i < bodies.length; i++) {
|
for (var i = 0; i < bodies.length; i++) {
|
||||||
|
@ -64,7 +64,8 @@ var Common = require('./Common');
|
||||||
* @param {number} delta
|
* @param {number} delta
|
||||||
*/
|
*/
|
||||||
Sleeping.afterCollisions = function(pairs, delta) {
|
Sleeping.afterCollisions = function(pairs, delta) {
|
||||||
var timeScale = delta / Common._timeUnit;
|
var timeScale = delta / Common._timeUnit,
|
||||||
|
motionSleepThreshold = Sleeping._motionSleepThreshold * timeScale * timeScale;
|
||||||
|
|
||||||
// wake up bodies involved in collisions
|
// wake up bodies involved in collisions
|
||||||
for (var i = 0; i < pairs.length; i++) {
|
for (var i = 0; i < pairs.length; i++) {
|
||||||
|
@ -86,7 +87,7 @@ var Common = require('./Common');
|
||||||
var sleepingBody = (bodyA.isSleeping && !bodyA.isStatic) ? bodyA : bodyB,
|
var sleepingBody = (bodyA.isSleeping && !bodyA.isStatic) ? bodyA : bodyB,
|
||||||
movingBody = sleepingBody === bodyA ? bodyB : bodyA;
|
movingBody = sleepingBody === bodyA ? bodyB : bodyA;
|
||||||
|
|
||||||
if (!sleepingBody.isStatic && movingBody.motion > Sleeping._motionWakeThreshold * timeScale * timeScale) {
|
if (!sleepingBody.isStatic && movingBody.motion > motionSleepThreshold) {
|
||||||
Sleeping.set(sleepingBody, false);
|
Sleeping.set(sleepingBody, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue