0
0
Fork 0
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:
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 }, 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,

View file

@ -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

View file

@ -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);