0
0
Fork 0
mirror of https://github.com/liabru/matter-js.git synced 2024-12-25 13:39:06 -05:00

Optimization of Resolver.solvePosition method

This commit is contained in:
Brice Chevalier 2017-11-24 17:38:24 +09:00
parent 0895d81fa1
commit 2eab580b68
3 changed files with 42 additions and 32 deletions

View file

@ -49,6 +49,7 @@ var Axes = require('../geometry/Axes');
force: { x: 0, y: 0 },
torque: 0,
positionImpulse: { x: 0, y: 0 },
previousPositionImpulse: { x: 0, y: 0 },
constraintImpulse: { x: 0, y: 0, angle: 0 },
totalContacts: 0,
speed: 0,

View file

@ -50,21 +50,31 @@ var Bounds = require('../geometry/Bounds');
* @param {pair[]} pairs
* @param {number} timeScale
*/
Resolver.solvePosition = function(pairs, timeScale) {
Resolver.solvePosition = function(pairs, bodies, timeScale) {
var i,
normalX,
normalY,
pair,
collision,
bodyA,
bodyB,
normal,
bodyBtoA,
separation,
penetration,
positionImpulseA,
positionImpulseB,
contactShare,
bodyBtoAX,
bodyBtoAY,
positionImpulse,
contactCount = {},
tempA = Vector._temp[0],
tempB = Vector._temp[1],
tempC = Vector._temp[2],
tempD = Vector._temp[3];
impulseCoefficient = timeScale * Resolver._positionDampen;
for (i = 0; i < bodies.length; i++) {
var body = bodies[i];
body.previousPositionImpulse.x = body.positionImpulse.x;
body.previousPositionImpulse.y = body.positionImpulse.y;
}
// find impulses required to resolve penetration
for (i = 0; i < pairs.length; i++) {
@ -78,43 +88,42 @@ var Bounds = require('../geometry/Bounds');
bodyB = collision.parentB;
normal = collision.normal;
// get current separation between body edges involved in collision
bodyBtoA = Vector.sub(Vector.add(bodyB.positionImpulse, bodyB.position, tempA),
Vector.add(bodyA.positionImpulse,
Vector.sub(bodyB.position, collision.penetration, tempB), tempC), tempD);
positionImpulseA = bodyA.previousPositionImpulse;
positionImpulseB = bodyB.previousPositionImpulse;
pair.separation = Vector.dot(normal, bodyBtoA);
}
penetration = collision.penetration;
for (i = 0; i < pairs.length; i++) {
pair = pairs[i];
// bodyBtoA = positionImpulseB - positionImpulseA + penetration
bodyBtoAX = positionImpulseB.x - positionImpulseA.x + penetration.x;
bodyBtoAY = positionImpulseB.y - positionImpulseA.y + penetration.y;
if (!pair.isActive || pair.isSensor)
continue;
normalX = normal.x;
normalY = normal.y;
collision = pair.collision;
bodyA = collision.parentA;
bodyB = collision.parentB;
normal = collision.normal;
positionImpulse = (pair.separation - pair.slop) * timeScale;
// separation = dot(normal, bodyBtoA)
separation = normalX * bodyBtoAX + normalY * bodyBtoAY;
pair.separation = separation;
positionImpulse = (separation - pair.slop) * impulseCoefficient;
if (bodyA.isStatic || bodyB.isStatic)
positionImpulse *= 2;
if (!(bodyA.isStatic || bodyA.isSleeping)) {
contactShare = Resolver._positionDampen / bodyA.totalContacts;
bodyA.positionImpulse.x += normal.x * positionImpulse * contactShare;
bodyA.positionImpulse.y += normal.y * positionImpulse * contactShare;
contactShare = positionImpulse / bodyA.totalContacts;
bodyA.positionImpulse.x += normalX * contactShare;
bodyA.positionImpulse.y += normalY * contactShare;
}
if (!(bodyB.isStatic || bodyB.isSleeping)) {
contactShare = Resolver._positionDampen / bodyB.totalContacts;
bodyB.positionImpulse.x -= normal.x * positionImpulse * contactShare;
bodyB.positionImpulse.y -= normal.y * positionImpulse * contactShare;
contactShare = positionImpulse / bodyB.totalContacts;
bodyB.positionImpulse.x -= normalX * contactShare;
bodyB.positionImpulse.y -= normalY * contactShare;
}
}
};
/**
* Apply position resolution.
* @method postSolvePosition

View file

@ -195,7 +195,7 @@ var Body = require('../body/Body');
// iteratively resolve position between collisions
Resolver.preSolvePosition(pairs.list);
for (i = 0; i < engine.positionIterations; i++) {
Resolver.solvePosition(pairs.list, timing.timeScale);
Resolver.solvePosition(pairs.list, allBodies, timing.timeScale);
}
Resolver.postSolvePosition(allBodies);