0
0
Fork 0
mirror of https://github.com/liabru/matter-js.git synced 2025-01-21 17:14:38 -05:00

Merge pull request #1238 from liabru/performance-2

Improved performance and reduced memory usage
This commit is contained in:
liabru 2024-03-10 20:06:24 +00:00 committed by GitHub
commit 4e6a8d90ff
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 197 additions and 158 deletions

View file

@ -13,8 +13,11 @@ Example.remove = function() {
Events = Matter.Events; Events = Matter.Events;
// create engine // create engine
var engine = Engine.create(), var engine = Engine.create({
world = engine.world; enableSleeping: true
});
var world = engine.world;
// create renderer // create renderer
var render = Render.create({ var render = Render.create({
@ -24,6 +27,7 @@ Example.remove = function() {
width: 800, width: 800,
height: 600, height: 600,
showAngleIndicator: true, showAngleIndicator: true,
showSleeping: true
} }
}); });
@ -33,9 +37,6 @@ Example.remove = function() {
var runner = Runner.create(); var runner = Runner.create();
Runner.run(runner, engine); Runner.run(runner, engine);
var stack = null,
lastTimestamp = 0;
var createStack = function() { var createStack = function() {
return Composites.stack(20, 20, 10, 5, 0, 0, function(x, y) { return Composites.stack(20, 20, 10, 5, 0, 0, function(x, y) {
var sides = Math.round(Common.random(1, 8)); var sides = Math.round(Common.random(1, 8));
@ -61,15 +62,28 @@ Example.remove = function() {
}); });
}; };
// add and remove stacks every few updates var stack = null,
bottomStack = createStack(),
lastTimestamp = 0;
// add and remove bodies and composites every few updates
Events.on(engine, 'afterUpdate', function(event) { Events.on(engine, 'afterUpdate', function(event) {
// limit rate // limit rate
if (stack && event.timestamp - lastTimestamp < 800) { if (event.timestamp - lastTimestamp < 800) {
return; return;
} }
lastTimestamp = event.timestamp; lastTimestamp = event.timestamp;
// remove an old body
Composite.remove(bottomStack, bottomStack.bodies[0]);
// add a new body
Composite.add(
bottomStack,
Bodies.rectangle(Common.random(100, 500), 50, Common.random(25, 50), Common.random(25, 50))
);
// remove last stack // remove last stack
if (stack) { if (stack) {
Composite.remove(world, stack); Composite.remove(world, stack);
@ -82,10 +96,9 @@ Example.remove = function() {
Composite.add(world, stack); Composite.add(world, stack);
}); });
// add another stack that will not be removed
Composite.add(world, createStack());
Composite.add(world, [ Composite.add(world, [
bottomStack,
// walls // walls
Bodies.rectangle(400, 0, 800, 50, { isStatic: true }), Bodies.rectangle(400, 0, 800, 50, { isStatic: true }),
Bodies.rectangle(400, 600, 800, 50, { isStatic: true }), Bodies.rectangle(400, 600, 800, 50, { isStatic: true }),

View file

@ -192,8 +192,15 @@ var Body = require('./Body');
*/ */
Composite.removeComposite = function(compositeA, compositeB, deep) { Composite.removeComposite = function(compositeA, compositeB, deep) {
var position = Common.indexOf(compositeA.composites, compositeB); var position = Common.indexOf(compositeA.composites, compositeB);
if (position !== -1) { if (position !== -1) {
var bodies = Composite.allBodies(compositeB);
Composite.removeCompositeAt(compositeA, position); Composite.removeCompositeAt(compositeA, position);
for (var i = 0; i < bodies.length; i++) {
bodies[i].sleepCounter = 0;
}
} }
if (deep) { if (deep) {
@ -244,8 +251,10 @@ var Body = require('./Body');
*/ */
Composite.removeBody = function(composite, body, deep) { Composite.removeBody = function(composite, body, deep) {
var position = Common.indexOf(composite.bodies, body); var position = Common.indexOf(composite.bodies, body);
if (position !== -1) { if (position !== -1) {
Composite.removeBodyAt(composite, position); Composite.removeBodyAt(composite, position);
body.sleepCounter = 0;
} }
if (deep) { if (deep) {
@ -296,6 +305,7 @@ var Body = require('./Body');
*/ */
Composite.removeConstraint = function(composite, constraint, deep) { Composite.removeConstraint = function(composite, constraint, deep) {
var position = Common.indexOf(composite.constraints, constraint); var position = Common.indexOf(composite.constraints, constraint);
if (position !== -1) { if (position !== -1) {
Composite.removeConstraintAt(composite, position); Composite.removeConstraintAt(composite, position);
} }

View file

@ -47,7 +47,8 @@ var Pair = require('./Pair');
normal: { x: 0, y: 0 }, normal: { x: 0, y: 0 },
tangent: { x: 0, y: 0 }, tangent: { x: 0, y: 0 },
penetration: { x: 0, y: 0 }, penetration: { x: 0, y: 0 },
supports: [] supports: [null, null],
supportCount: 0
}; };
}; };
@ -99,27 +100,32 @@ var Pair = require('./Pair');
} }
var normal = collision.normal, var normal = collision.normal,
tangent = collision.tangent,
penetration = collision.penetration,
supports = collision.supports, supports = collision.supports,
depth = minOverlap.overlap,
minAxis = minOverlap.axis, minAxis = minOverlap.axis,
minAxisX = minAxis.x, normalX = minAxis.x,
minAxisY = minAxis.y; normalY = minAxis.y,
deltaX = bodyB.position.x - bodyA.position.x,
deltaY = bodyB.position.y - bodyA.position.y;
// ensure normal is facing away from bodyA // ensure normal is facing away from bodyA
if (minAxisX * (bodyB.position.x - bodyA.position.x) + minAxisY * (bodyB.position.y - bodyA.position.y) < 0) { if (normalX * deltaX + normalY * deltaY >= 0) {
normal.x = minAxisX; normalX = -normalX;
normal.y = minAxisY; normalY = -normalY;
} else {
normal.x = -minAxisX;
normal.y = -minAxisY;
} }
normal.x = normalX;
normal.y = normalY;
collision.tangent.x = -normal.y; tangent.x = -normalY;
collision.tangent.y = normal.x; tangent.y = normalX;
collision.depth = minOverlap.overlap; penetration.x = normalX * depth;
penetration.y = normalY * depth;
collision.penetration.x = normal.x * collision.depth; collision.depth = depth;
collision.penetration.y = normal.y * collision.depth;
// find support points, there is always either exactly one or two // find support points, there is always either exactly one or two
var supportsB = Collision._findSupports(bodyA, bodyB, normal, 1), var supportsB = Collision._findSupports(bodyA, bodyB, normal, 1),
@ -152,8 +158,8 @@ var Pair = require('./Pair');
supports[supportCount++] = supportsB[0]; supports[supportCount++] = supportsB[0];
} }
// update supports array size // update support count
supports.length = supportCount; collision.supportCount = supportCount;
return collision; return collision;
}; };
@ -232,32 +238,6 @@ var Pair = require('./Pair');
result.overlap = overlapMin; result.overlap = overlapMin;
}; };
/**
* Projects vertices on an axis and returns an interval.
* @method _projectToAxis
* @private
* @param {} projection
* @param {} vertices
* @param {} axis
*/
Collision._projectToAxis = function(projection, vertices, axis) {
var min = vertices[0].x * axis.x + vertices[0].y * axis.y,
max = min;
for (var i = 1; i < vertices.length; i += 1) {
var dot = vertices[i].x * axis.x + vertices[i].y * axis.y;
if (dot > max) {
max = dot;
} else if (dot < min) {
min = dot;
}
}
projection.min = min;
projection.max = max;
};
/** /**
* Finds supporting vertices given two bodies along a given direction using hill-climbing. * Finds supporting vertices given two bodies along a given direction using hill-climbing.
* @method _findSupports * @method _findSupports
@ -275,15 +255,15 @@ var Pair = require('./Pair');
bodyAPositionY = bodyA.position.y, bodyAPositionY = bodyA.position.y,
normalX = normal.x * direction, normalX = normal.x * direction,
normalY = normal.y * direction, normalY = normal.y * direction,
nearestDistance = Number.MAX_VALUE, vertexA = vertices[0],
vertexA, vertexB = vertexA,
vertexB, nearestDistance = normalX * (bodyAPositionX - vertexB.x) + normalY * (bodyAPositionY - vertexB.y),
vertexC, vertexC,
distance, distance,
j; j;
// find deepest vertex relative to the axis // find deepest vertex relative to the axis
for (j = 0; j < verticesLength; j += 1) { for (j = 1; j < verticesLength; j += 1) {
vertexB = vertices[j]; vertexB = vertices[j];
distance = normalX * (bodyAPositionX - vertexB.x) + normalY * (bodyAPositionY - vertexB.y); distance = normalX * (bodyAPositionX - vertexB.x) + normalY * (bodyAPositionY - vertexB.y);
@ -398,6 +378,10 @@ var Pair = require('./Pair');
/** /**
* An array of body vertices that represent the support points in the collision. * An array of body vertices that represent the support points in the collision.
*
* _Note:_ Only the first `collision.supportCount` items of `collision.supports` are active.
* Therefore use `collision.supportCount` instead of `collision.supports.length` when iterating the active supports.
*
* These are the deepest vertices (along the collision normal) of each body that are contained by the other body's vertices. * These are the deepest vertices (along the collision normal) of each body that are contained by the other body's vertices.
* *
* @property supports * @property supports
@ -405,4 +389,15 @@ var Pair = require('./Pair');
* @default [] * @default []
*/ */
/**
* The number of active supports for this collision found in `collision.supports`.
*
* _Note:_ Only the first `collision.supportCount` items of `collision.supports` are active.
* Therefore use `collision.supportCount` instead of `collision.supports.length` when iterating the active supports.
*
* @property supportCount
* @type number
* @default 0
*/
})(); })();

View file

@ -13,7 +13,7 @@ module.exports = Contact;
/** /**
* Creates a new contact. * Creates a new contact.
* @method create * @method create
* @param {vertex} vertex * @param {vertex} [vertex]
* @return {contact} A new contact * @return {contact} A new contact
*/ */
Contact.create = function(vertex) { Contact.create = function(vertex) {

View file

@ -22,6 +22,7 @@ var Collision = require('./Collision');
Detector.create = function(options) { Detector.create = function(options) {
var defaults = { var defaults = {
bodies: [], bodies: [],
collisions: [],
pairs: null pairs: null
}; };
@ -45,6 +46,7 @@ var Collision = require('./Collision');
*/ */
Detector.clear = function(detector) { Detector.clear = function(detector) {
detector.bodies = []; detector.bodies = [];
detector.collisions = [];
}; };
/** /**
@ -57,12 +59,13 @@ var Collision = require('./Collision');
* @return {collision[]} collisions * @return {collision[]} collisions
*/ */
Detector.collisions = function(detector) { Detector.collisions = function(detector) {
var collisions = [], var pairs = detector.pairs,
pairs = detector.pairs,
bodies = detector.bodies, bodies = detector.bodies,
bodiesLength = bodies.length, bodiesLength = bodies.length,
canCollide = Detector.canCollide, canCollide = Detector.canCollide,
collides = Collision.collides, collides = Collision.collides,
collisions = detector.collisions,
collisionIndex = 0,
i, i,
j; j;
@ -104,7 +107,7 @@ var Collision = require('./Collision');
var collision = collides(bodyA, bodyB, pairs); var collision = collides(bodyA, bodyB, pairs);
if (collision) { if (collision) {
collisions.push(collision); collisions[collisionIndex++] = collision;
} }
} else { } else {
var partsAStart = partsALength > 1 ? 1 : 0, var partsAStart = partsALength > 1 ? 1 : 0,
@ -126,7 +129,7 @@ var Collision = require('./Collision');
var collision = collides(partA, partB, pairs); var collision = collides(partA, partB, pairs);
if (collision) { if (collision) {
collisions.push(collision); collisions[collisionIndex++] = collision;
} }
} }
} }
@ -134,6 +137,10 @@ var Collision = require('./Collision');
} }
} }
if (collisions.length !== collisionIndex) {
collisions.length = collisionIndex;
}
return collisions; return collisions;
}; };
@ -180,6 +187,13 @@ var Collision = require('./Collision');
* @default [] * @default []
*/ */
/**
* The array of `Matter.Collision` found in the last call to `Detector.collisions` on this detector.
* @property collisions
* @type collision[]
* @default []
*/
/** /**
* Optional. A `Matter.Pairs` object from which previous collision objects may be reused. Intended for internal `Matter.Engine` usage. * Optional. A `Matter.Pairs` object from which previous collision objects may be reused. Intended for internal `Matter.Engine` usage.
* @property pairs * @property pairs

View file

@ -28,11 +28,10 @@ var Contact = require('./Contact');
bodyA: bodyA, bodyA: bodyA,
bodyB: bodyB, bodyB: bodyB,
collision: collision, collision: collision,
contacts: [], contacts: [Contact.create(), Contact.create()],
activeContacts: [], contactCount: 0,
separation: 0, separation: 0,
isActive: true, isActive: true,
confirmedActive: true,
isSensor: bodyA.isSensor || bodyB.isSensor, isSensor: bodyA.isSensor || bodyB.isSensor,
timeCreated: timestamp, timeCreated: timestamp,
timeUpdated: timestamp, timeUpdated: timestamp,
@ -56,12 +55,11 @@ var Contact = require('./Contact');
* @param {number} timestamp * @param {number} timestamp
*/ */
Pair.update = function(pair, collision, timestamp) { Pair.update = function(pair, collision, timestamp) {
var contacts = pair.contacts, var supports = collision.supports,
supports = collision.supports, supportCount = collision.supportCount,
activeContacts = pair.activeContacts, contacts = pair.contacts,
parentA = collision.parentA, parentA = collision.parentA,
parentB = collision.parentB, parentB = collision.parentB;
parentAVerticesLength = parentA.vertices.length;
pair.isActive = true; pair.isActive = true;
pair.timeUpdated = timestamp; pair.timeUpdated = timestamp;
@ -73,20 +71,24 @@ var Contact = require('./Contact');
pair.restitution = parentA.restitution > parentB.restitution ? parentA.restitution : parentB.restitution; pair.restitution = parentA.restitution > parentB.restitution ? parentA.restitution : parentB.restitution;
pair.slop = parentA.slop > parentB.slop ? parentA.slop : parentB.slop; pair.slop = parentA.slop > parentB.slop ? parentA.slop : parentB.slop;
pair.contactCount = supportCount;
collision.pair = pair; collision.pair = pair;
activeContacts.length = 0;
for (var i = 0; i < supports.length; i++) {
var support = supports[i],
contactId = support.body === parentA ? support.index : parentAVerticesLength + support.index,
contact = contacts[contactId];
if (contact) { var supportA = supports[0],
activeContacts.push(contact); contactA = contacts[0],
} else { supportB = supports[1],
activeContacts.push(contacts[contactId] = Contact.create(support)); contactB = contacts[1];
}
// match contacts to supports
if (contactB.vertex === supportA || contactA.vertex === supportB) {
contacts[1] = contactA;
contacts[0] = contactA = contactB;
contactB = contacts[1];
} }
// update contacts
contactA.vertex = supportA;
contactB.vertex = supportB;
}; };
/** /**
@ -102,7 +104,7 @@ var Contact = require('./Contact');
pair.timeUpdated = timestamp; pair.timeUpdated = timestamp;
} else { } else {
pair.isActive = false; pair.isActive = false;
pair.activeContacts.length = 0; pair.contactCount = 0;
} }
}; };
@ -114,11 +116,8 @@ var Contact = require('./Contact');
* @return {string} Unique pairId * @return {string} Unique pairId
*/ */
Pair.id = function(bodyA, bodyB) { Pair.id = function(bodyA, bodyB) {
if (bodyA.id < bodyB.id) { return bodyA.id < bodyB.id ? bodyA.id.toString(36) + ':' + bodyB.id.toString(36)
return 'A' + bodyA.id + 'B' + bodyB.id; : bodyB.id.toString(36) + ':' + bodyA.id.toString(36);
} else {
return 'A' + bodyB.id + 'B' + bodyA.id;
}
}; };
})(); })();

View file

@ -37,27 +37,24 @@ var Common = require('../core/Common');
* @param {number} timestamp * @param {number} timestamp
*/ */
Pairs.update = function(pairs, collisions, timestamp) { Pairs.update = function(pairs, collisions, timestamp) {
var pairsList = pairs.list, var pairUpdate = Pair.update,
pairsListLength = pairsList.length, pairCreate = Pair.create,
pairSetActive = Pair.setActive,
pairsTable = pairs.table, pairsTable = pairs.table,
collisionsLength = collisions.length, pairsList = pairs.list,
pairsListLength = pairsList.length,
pairsListIndex = pairsListLength,
collisionStart = pairs.collisionStart, collisionStart = pairs.collisionStart,
collisionEnd = pairs.collisionEnd, collisionEnd = pairs.collisionEnd,
collisionActive = pairs.collisionActive, collisionActive = pairs.collisionActive,
collisionsLength = collisions.length,
collisionStartIndex = 0,
collisionEndIndex = 0,
collisionActiveIndex = 0,
collision, collision,
pairIndex,
pair, pair,
i; i;
// clear collision state arrays, but maintain old reference
collisionStart.length = 0;
collisionEnd.length = 0;
collisionActive.length = 0;
for (i = 0; i < pairsListLength; i++) {
pairsList[i].confirmedActive = false;
}
for (i = 0; i < collisionsLength; i++) { for (i = 0; i < collisionsLength; i++) {
collision = collisions[i]; collision = collisions[i];
pair = collision.pair; pair = collision.pair;
@ -66,49 +63,62 @@ var Common = require('../core/Common');
// pair already exists (but may or may not be active) // pair already exists (but may or may not be active)
if (pair.isActive) { if (pair.isActive) {
// pair exists and is active // pair exists and is active
collisionActive.push(pair); collisionActive[collisionActiveIndex++] = pair;
} else {
// pair exists but was inactive, so a collision has just started again
collisionStart.push(pair);
} }
// update the pair // update the pair
Pair.update(pair, collision, timestamp); pairUpdate(pair, collision, timestamp);
pair.confirmedActive = true;
} else { } else {
// pair did not exist, create a new pair // pair did not exist, create a new pair
pair = Pair.create(collision, timestamp); pair = pairCreate(collision, timestamp);
pairsTable[pair.id] = pair; pairsTable[pair.id] = pair;
// push the new pair // add the new pair
collisionStart.push(pair); collisionStart[collisionStartIndex++] = pair;
pairsList.push(pair); pairsList[pairsListIndex++] = pair;
} }
} }
// find pairs that are no longer active // find pairs that are no longer active
var removePairIndex = []; pairsListIndex = 0;
pairsListLength = pairsList.length; pairsListLength = pairsList.length;
for (i = 0; i < pairsListLength; i++) { for (i = 0; i < pairsListLength; i++) {
pair = pairsList[i]; pair = pairsList[i];
if (!pair.confirmedActive) { // pair is active if updated this timestep
Pair.setActive(pair, false, timestamp); if (pair.timeUpdated >= timestamp) {
collisionEnd.push(pair); // keep active pairs
pairsList[pairsListIndex++] = pair;
} else {
pairSetActive(pair, false, timestamp);
if (!pair.collision.bodyA.isSleeping && !pair.collision.bodyB.isSleeping) { // keep inactive pairs if both bodies may be sleeping
removePairIndex.push(i); if (pair.collision.bodyA.sleepCounter > 0 && pair.collision.bodyB.sleepCounter > 0) {
pairsList[pairsListIndex++] = pair;
} else {
// remove inactive pairs if either body awake
collisionEnd[collisionEndIndex++] = pair;
delete pairsTable[pair.id];
} }
} }
} }
// remove inactive pairs // update array lengths if changed
for (i = 0; i < removePairIndex.length; i++) { if (pairsList.length !== pairsListIndex) {
pairIndex = removePairIndex[i] - i; pairsList.length = pairsListIndex;
pair = pairsList[pairIndex]; }
pairsList.splice(pairIndex, 1);
delete pairsTable[pair.id]; if (collisionStart.length !== collisionStartIndex) {
collisionStart.length = collisionStartIndex;
}
if (collisionEnd.length !== collisionEndIndex) {
collisionEnd.length = collisionEndIndex;
}
if (collisionActive.length !== collisionActiveIndex) {
collisionActive.length = collisionActiveIndex;
} }
}; };

View file

@ -29,7 +29,7 @@ var Bounds = require('../geometry/Bounds');
Resolver.preSolvePosition = function(pairs) { Resolver.preSolvePosition = function(pairs) {
var i, var i,
pair, pair,
activeCount, contactCount,
pairsLength = pairs.length; pairsLength = pairs.length;
// find total contacts on each body // find total contacts on each body
@ -39,9 +39,9 @@ var Bounds = require('../geometry/Bounds');
if (!pair.isActive) if (!pair.isActive)
continue; continue;
activeCount = pair.activeContacts.length; contactCount = pair.contactCount;
pair.collision.parentA.totalContacts += activeCount; pair.collision.parentA.totalContacts += contactCount;
pair.collision.parentB.totalContacts += activeCount; pair.collision.parentB.totalContacts += contactCount;
} }
}; };
@ -79,8 +79,8 @@ var Bounds = require('../geometry/Bounds');
// get current separation between body edges involved in collision // get current separation between body edges involved in collision
pair.separation = pair.separation =
normal.x * (bodyB.positionImpulse.x + collision.penetration.x - bodyA.positionImpulse.x) collision.depth + normal.x * (bodyB.positionImpulse.x - bodyA.positionImpulse.x)
+ normal.y * (bodyB.positionImpulse.y + collision.penetration.y - bodyA.positionImpulse.y); + normal.y * (bodyB.positionImpulse.y - bodyA.positionImpulse.y);
} }
for (i = 0; i < pairsLength; i++) { for (i = 0; i < pairsLength; i++) {
@ -176,8 +176,8 @@ var Bounds = require('../geometry/Bounds');
if (!pair.isActive || pair.isSensor) if (!pair.isActive || pair.isSensor)
continue; continue;
var contacts = pair.activeContacts, var contacts = pair.contacts,
contactsLength = contacts.length, contactCount = pair.contactCount,
collision = pair.collision, collision = pair.collision,
bodyA = collision.parentA, bodyA = collision.parentA,
bodyB = collision.parentB, bodyB = collision.parentB,
@ -185,7 +185,7 @@ var Bounds = require('../geometry/Bounds');
tangent = collision.tangent; tangent = collision.tangent;
// resolve each contact // resolve each contact
for (j = 0; j < contactsLength; j++) { for (j = 0; j < contactCount; j++) {
var contact = contacts[j], var contact = contacts[j],
contactVertex = contact.vertex, contactVertex = contact.vertex,
normalImpulse = contact.normalImpulse, normalImpulse = contact.normalImpulse,
@ -248,28 +248,26 @@ var Bounds = require('../geometry/Bounds');
var collision = pair.collision, var collision = pair.collision,
bodyA = collision.parentA, bodyA = collision.parentA,
bodyB = collision.parentB, bodyB = collision.parentB,
bodyAVelocity = bodyA.velocity,
bodyBVelocity = bodyB.velocity,
normalX = collision.normal.x, normalX = collision.normal.x,
normalY = collision.normal.y, normalY = collision.normal.y,
tangentX = collision.tangent.x, tangentX = collision.tangent.x,
tangentY = collision.tangent.y, tangentY = collision.tangent.y,
contacts = pair.activeContacts, inverseMassTotal = pair.inverseMass,
contactsLength = contacts.length, friction = pair.friction * pair.frictionStatic * frictionNormalMultiplier,
contactShare = 1 / contactsLength, contacts = pair.contacts,
inverseMassTotal = bodyA.inverseMass + bodyB.inverseMass, contactCount = pair.contactCount,
friction = pair.friction * pair.frictionStatic * frictionNormalMultiplier; contactShare = 1 / contactCount;
// update body velocities // get body velocities
bodyAVelocity.x = bodyA.position.x - bodyA.positionPrev.x; var bodyAVelocityX = bodyA.position.x - bodyA.positionPrev.x,
bodyAVelocity.y = bodyA.position.y - bodyA.positionPrev.y; bodyAVelocityY = bodyA.position.y - bodyA.positionPrev.y,
bodyBVelocity.x = bodyB.position.x - bodyB.positionPrev.x; bodyAAngularVelocity = bodyA.angle - bodyA.anglePrev,
bodyBVelocity.y = bodyB.position.y - bodyB.positionPrev.y; bodyBVelocityX = bodyB.position.x - bodyB.positionPrev.x,
bodyA.angularVelocity = bodyA.angle - bodyA.anglePrev; bodyBVelocityY = bodyB.position.y - bodyB.positionPrev.y,
bodyB.angularVelocity = bodyB.angle - bodyB.anglePrev; bodyBAngularVelocity = bodyB.angle - bodyB.anglePrev;
// resolve each contact // resolve each contact
for (j = 0; j < contactsLength; j++) { for (j = 0; j < contactCount; j++) {
var contact = contacts[j], var contact = contacts[j],
contactVertex = contact.vertex; contactVertex = contact.vertex;
@ -278,10 +276,10 @@ var Bounds = require('../geometry/Bounds');
offsetBX = contactVertex.x - bodyB.position.x, offsetBX = contactVertex.x - bodyB.position.x,
offsetBY = contactVertex.y - bodyB.position.y; offsetBY = contactVertex.y - bodyB.position.y;
var velocityPointAX = bodyAVelocity.x - offsetAY * bodyA.angularVelocity, var velocityPointAX = bodyAVelocityX - offsetAY * bodyAAngularVelocity,
velocityPointAY = bodyAVelocity.y + offsetAX * bodyA.angularVelocity, velocityPointAY = bodyAVelocityY + offsetAX * bodyAAngularVelocity,
velocityPointBX = bodyBVelocity.x - offsetBY * bodyB.angularVelocity, velocityPointBX = bodyBVelocityX - offsetBY * bodyBAngularVelocity,
velocityPointBY = bodyBVelocity.y + offsetBX * bodyB.angularVelocity; velocityPointBY = bodyBVelocityY + offsetBX * bodyBAngularVelocity;
var relativeVelocityX = velocityPointAX - velocityPointBX, var relativeVelocityX = velocityPointAX - velocityPointBX,
relativeVelocityY = velocityPointAY - velocityPointBY; relativeVelocityY = velocityPointAY - velocityPointBY;

View file

@ -60,6 +60,7 @@ var Body = require('../body/Body');
engine.world = options.world || Composite.create({ label: 'World' }); engine.world = options.world || Composite.create({ label: 'World' });
engine.pairs = options.pairs || Pairs.create(); engine.pairs = options.pairs || Pairs.create();
engine.detector = options.detector || Detector.create(); engine.detector = options.detector || Detector.create();
engine.detector.pairs = engine.pairs;
// for temporary back compatibility only // for temporary back compatibility only
engine.grid = { buckets: [] }; engine.grid = { buckets: [] };
@ -138,7 +139,6 @@ var Body = require('../body/Body');
Constraint.postSolveAll(allBodies); Constraint.postSolveAll(allBodies);
// find all collisions // find all collisions
detector.pairs = engine.pairs;
var collisions = Detector.collisions(detector); var collisions = Detector.collisions(detector);
// update collision pairs // update collision pairs

View file

@ -1209,8 +1209,8 @@ var Mouse = require('../core/Mouse');
continue; continue;
collision = pair.collision; collision = pair.collision;
for (j = 0; j < pair.activeContacts.length; j++) { for (j = 0; j < pair.contactCount; j++) {
var contact = pair.activeContacts[j], var contact = pair.contacts[j],
vertex = contact.vertex; vertex = contact.vertex;
c.rect(vertex.x - 1.5, vertex.y - 1.5, 3.5, 3.5); c.rect(vertex.x - 1.5, vertex.y - 1.5, 3.5, 3.5);
} }
@ -1234,13 +1234,13 @@ var Mouse = require('../core/Mouse');
collision = pair.collision; collision = pair.collision;
if (pair.activeContacts.length > 0) { if (pair.contactCount > 0) {
var normalPosX = pair.activeContacts[0].vertex.x, var normalPosX = pair.contacts[0].vertex.x,
normalPosY = pair.activeContacts[0].vertex.y; normalPosY = pair.contacts[0].vertex.y;
if (pair.activeContacts.length === 2) { if (pair.contactCount === 2) {
normalPosX = (pair.activeContacts[0].vertex.x + pair.activeContacts[1].vertex.x) / 2; normalPosX = (pair.contacts[0].vertex.x + pair.contacts[1].vertex.x) / 2;
normalPosY = (pair.activeContacts[0].vertex.y + pair.activeContacts[1].vertex.y) / 2; normalPosY = (pair.contacts[0].vertex.y + pair.contacts[1].vertex.y) / 2;
} }
if (collision.bodyB === collision.supports[0].body || collision.bodyA.isStatic === true) { if (collision.bodyB === collision.supports[0].body || collision.bodyA.isStatic === true) {