mirror of
https://github.com/liabru/matter-js.git
synced 2024-12-26 13:49:01 -05:00
Optimization of Resolver.solvePosition method
This commit is contained in:
parent
0895d81fa1
commit
2eab580b68
3 changed files with 42 additions and 32 deletions
|
@ -49,6 +49,7 @@ var Axes = require('../geometry/Axes');
|
||||||
force: { x: 0, y: 0 },
|
force: { x: 0, y: 0 },
|
||||||
torque: 0,
|
torque: 0,
|
||||||
positionImpulse: { x: 0, y: 0 },
|
positionImpulse: { x: 0, y: 0 },
|
||||||
|
previousPositionImpulse: { x: 0, y: 0 },
|
||||||
constraintImpulse: { x: 0, y: 0, angle: 0 },
|
constraintImpulse: { x: 0, y: 0, angle: 0 },
|
||||||
totalContacts: 0,
|
totalContacts: 0,
|
||||||
speed: 0,
|
speed: 0,
|
||||||
|
|
|
@ -50,21 +50,31 @@ var Bounds = require('../geometry/Bounds');
|
||||||
* @param {pair[]} pairs
|
* @param {pair[]} pairs
|
||||||
* @param {number} timeScale
|
* @param {number} timeScale
|
||||||
*/
|
*/
|
||||||
Resolver.solvePosition = function(pairs, timeScale) {
|
Resolver.solvePosition = function(pairs, bodies, timeScale) {
|
||||||
var i,
|
var i,
|
||||||
|
normalX,
|
||||||
|
normalY,
|
||||||
pair,
|
pair,
|
||||||
collision,
|
collision,
|
||||||
bodyA,
|
bodyA,
|
||||||
bodyB,
|
bodyB,
|
||||||
normal,
|
normal,
|
||||||
bodyBtoA,
|
separation,
|
||||||
|
penetration,
|
||||||
|
positionImpulseA,
|
||||||
|
positionImpulseB,
|
||||||
contactShare,
|
contactShare,
|
||||||
|
bodyBtoAX,
|
||||||
|
bodyBtoAY,
|
||||||
positionImpulse,
|
positionImpulse,
|
||||||
contactCount = {},
|
impulseCoefficient = timeScale * Resolver._positionDampen;
|
||||||
tempA = Vector._temp[0],
|
|
||||||
tempB = Vector._temp[1],
|
|
||||||
tempC = Vector._temp[2],
|
for (i = 0; i < bodies.length; i++) {
|
||||||
tempD = Vector._temp[3];
|
var body = bodies[i];
|
||||||
|
body.previousPositionImpulse.x = body.positionImpulse.x;
|
||||||
|
body.previousPositionImpulse.y = body.positionImpulse.y;
|
||||||
|
}
|
||||||
|
|
||||||
// find impulses required to resolve penetration
|
// find impulses required to resolve penetration
|
||||||
for (i = 0; i < pairs.length; i++) {
|
for (i = 0; i < pairs.length; i++) {
|
||||||
|
@ -78,43 +88,42 @@ var Bounds = require('../geometry/Bounds');
|
||||||
bodyB = collision.parentB;
|
bodyB = collision.parentB;
|
||||||
normal = collision.normal;
|
normal = collision.normal;
|
||||||
|
|
||||||
// get current separation between body edges involved in collision
|
positionImpulseA = bodyA.previousPositionImpulse;
|
||||||
bodyBtoA = Vector.sub(Vector.add(bodyB.positionImpulse, bodyB.position, tempA),
|
positionImpulseB = bodyB.previousPositionImpulse;
|
||||||
Vector.add(bodyA.positionImpulse,
|
|
||||||
Vector.sub(bodyB.position, collision.penetration, tempB), tempC), tempD);
|
|
||||||
|
|
||||||
pair.separation = Vector.dot(normal, bodyBtoA);
|
penetration = collision.penetration;
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < pairs.length; i++) {
|
// bodyBtoA = positionImpulseB - positionImpulseA + penetration
|
||||||
pair = pairs[i];
|
bodyBtoAX = positionImpulseB.x - positionImpulseA.x + penetration.x;
|
||||||
|
bodyBtoAY = positionImpulseB.y - positionImpulseA.y + penetration.y;
|
||||||
|
|
||||||
if (!pair.isActive || pair.isSensor)
|
normalX = normal.x;
|
||||||
continue;
|
normalY = normal.y;
|
||||||
|
|
||||||
collision = pair.collision;
|
// separation = dot(normal, bodyBtoA)
|
||||||
bodyA = collision.parentA;
|
separation = normalX * bodyBtoAX + normalY * bodyBtoAY;
|
||||||
bodyB = collision.parentB;
|
pair.separation = separation;
|
||||||
normal = collision.normal;
|
|
||||||
positionImpulse = (pair.separation - pair.slop) * timeScale;
|
positionImpulse = (separation - pair.slop) * impulseCoefficient;
|
||||||
|
|
||||||
if (bodyA.isStatic || bodyB.isStatic)
|
if (bodyA.isStatic || bodyB.isStatic)
|
||||||
positionImpulse *= 2;
|
positionImpulse *= 2;
|
||||||
|
|
||||||
if (!(bodyA.isStatic || bodyA.isSleeping)) {
|
if (!(bodyA.isStatic || bodyA.isSleeping)) {
|
||||||
contactShare = Resolver._positionDampen / bodyA.totalContacts;
|
contactShare = positionImpulse / bodyA.totalContacts;
|
||||||
bodyA.positionImpulse.x += normal.x * positionImpulse * contactShare;
|
bodyA.positionImpulse.x += normalX * contactShare;
|
||||||
bodyA.positionImpulse.y += normal.y * positionImpulse * contactShare;
|
bodyA.positionImpulse.y += normalY * contactShare;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(bodyB.isStatic || bodyB.isSleeping)) {
|
if (!(bodyB.isStatic || bodyB.isSleeping)) {
|
||||||
contactShare = Resolver._positionDampen / bodyB.totalContacts;
|
contactShare = positionImpulse / bodyB.totalContacts;
|
||||||
bodyB.positionImpulse.x -= normal.x * positionImpulse * contactShare;
|
bodyB.positionImpulse.x -= normalX * contactShare;
|
||||||
bodyB.positionImpulse.y -= normal.y * positionImpulse * contactShare;
|
bodyB.positionImpulse.y -= normalY * contactShare;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply position resolution.
|
* Apply position resolution.
|
||||||
* @method postSolvePosition
|
* @method postSolvePosition
|
||||||
|
|
|
@ -195,7 +195,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, timing.timeScale);
|
Resolver.solvePosition(pairs.list, allBodies, timing.timeScale);
|
||||||
}
|
}
|
||||||
Resolver.postSolvePosition(allBodies);
|
Resolver.postSolvePosition(allBodies);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue