Skip to content

Commit

Permalink
optimised pairs and collisions memory and gc use
Browse files Browse the repository at this point in the history
  • Loading branch information
liabru committed Jul 23, 2023
1 parent 4c56e5b commit f9208df
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 30 deletions.
4 changes: 3 additions & 1 deletion src/collision/Collision.js
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,10 @@ var Pair = require('./Pair');
supports[supportCount++] = supportsB[0];
}

// update supports array size
// update supports array size if changed
if (supports.length !== supportCount) {
supports.length = supportCount;
}

return collision;
};
Expand Down
22 changes: 18 additions & 4 deletions src/collision/Detector.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ var Collision = require('./Collision');
Detector.create = function(options) {
var defaults = {
bodies: [],
collisions: [],
pairs: null
};

Expand All @@ -45,6 +46,7 @@ var Collision = require('./Collision');
*/
Detector.clear = function(detector) {
detector.bodies = [];
detector.collisions = [];
};

/**
Expand All @@ -57,12 +59,13 @@ var Collision = require('./Collision');
* @return {collision[]} collisions
*/
Detector.collisions = function(detector) {
var collisions = [],
pairs = detector.pairs,
var pairs = detector.pairs,
bodies = detector.bodies,
bodiesLength = bodies.length,
canCollide = Detector.canCollide,
collides = Collision.collides,
collisions = detector.collisions,
collisionIndex = 0,
i,
j;

Expand Down Expand Up @@ -104,7 +107,7 @@ var Collision = require('./Collision');
var collision = collides(bodyA, bodyB, pairs);

if (collision) {
collisions.push(collision);
collisions[collisionIndex++] = collision;
}
} else {
var partsAStart = partsALength > 1 ? 1 : 0,
Expand All @@ -126,14 +129,18 @@ var Collision = require('./Collision');
var collision = collides(partA, partB, pairs);

if (collision) {
collisions.push(collision);
collisions[collisionIndex++] = collision;
}
}
}
}
}
}

if (collisions.length !== collisionIndex) {
collisions.length = collisionIndex;
}

return collisions;
};

Expand Down Expand Up @@ -180,6 +187,13 @@ var Collision = require('./Collision');
* @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.
* @property pairs
Expand Down
16 changes: 12 additions & 4 deletions src/collision/Pair.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,19 +74,27 @@ var Contact = require('./Contact');
pair.slop = parentA.slop > parentB.slop ? parentA.slop : parentB.slop;

collision.pair = pair;
activeContacts.length = 0;

var activeContactIndex = 0,
supportsLength = supports.length;

for (var i = 0; i < supports.length; i++) {
for (var i = 0; i < supportsLength; i++) {
var support = supports[i],
contactId = support.body === parentA ? support.index : parentAVerticesLength + support.index,
contact = contacts[contactId];

if (contact) {
activeContacts.push(contact);
activeContacts[activeContactIndex++] = contact;
} else {
activeContacts.push(contacts[contactId] = Contact.create(support));
contact = Contact.create(support);
activeContacts[activeContactIndex++] = contact;
contacts[contactId] = contact;
}
}

if (activeContacts.length !== activeContactIndex) {
activeContacts.length = activeContactIndex;
}
};

/**
Expand Down
50 changes: 30 additions & 20 deletions src/collision/Pairs.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,21 +39,19 @@ var Common = require('../core/Common');
Pairs.update = function(pairs, collisions, timestamp) {
var pairsList = pairs.list,
pairsListLength = pairsList.length,
pairsListIndex = pairsListLength,
pairsTable = pairs.table,
collisionsLength = collisions.length,
collisionStart = pairs.collisionStart,
collisionEnd = pairs.collisionEnd,
collisionActive = pairs.collisionActive,
collisionStartIndex = 0,
collisionEndIndex = 0,
collisionActiveIndex = 0,
collision,
pairIndex,
pair,
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;
}
Expand All @@ -66,10 +64,10 @@ var Common = require('../core/Common');
// pair already exists (but may or may not be active)
if (pair.isActive) {
// 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);
collisionStart[collisionStartIndex++] = pair;
}

// update the pair
Expand All @@ -80,35 +78,47 @@ var Common = require('../core/Common');
pair = Pair.create(collision, timestamp);
pairsTable[pair.id] = pair;

// push the new pair
collisionStart.push(pair);
pairsList.push(pair);
// add the new pair
collisionStart[collisionStartIndex++] = pair;
pairsList[pairsListIndex++] = pair;
}
}

// find pairs that are no longer active
var removePairIndex = [];
pairsListIndex = 0;
pairsListLength = pairsList.length;

for (i = 0; i < pairsListLength; i++) {
pair = pairsList[i];

if (!pair.confirmedActive) {
Pair.setActive(pair, false, timestamp);
collisionEnd.push(pair);
collisionEnd[collisionEndIndex++] = pair;

// remove inactive pairs
if (!pair.collision.bodyA.isSleeping && !pair.collision.bodyB.isSleeping) {
removePairIndex.push(i);
delete pairsTable[pair.id];
}
} else {
pairsList[pairsListIndex++] = pair;
}
}

// remove inactive pairs
for (i = 0; i < removePairIndex.length; i++) {
pairIndex = removePairIndex[i] - i;
pair = pairsList[pairIndex];
pairsList.splice(pairIndex, 1);
delete pairsTable[pair.id];
// update array lengths if changed
if (pairsList.length !== pairsListIndex) {
pairsList.length = pairsListIndex;
}

if (collisionStart.length !== collisionStartIndex) {
collisionStart.length = collisionStartIndex;
}

if (collisionEnd.length !== collisionEndIndex) {
collisionEnd.length = collisionEndIndex;
}

if (collisionActive.length !== collisionActiveIndex) {
collisionActive.length = collisionActiveIndex;
}
};

Expand Down
2 changes: 1 addition & 1 deletion src/core/Engine.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ var Body = require('../body/Body');
engine.world = options.world || Composite.create({ label: 'World' });
engine.pairs = options.pairs || Pairs.create();
engine.detector = options.detector || Detector.create();
engine.detector.pairs = engine.pairs;

// for temporary back compatibility only
engine.grid = { buckets: [] };
Expand Down Expand Up @@ -138,7 +139,6 @@ var Body = require('../body/Body');
Constraint.postSolveAll(allBodies);

// find all collisions
detector.pairs = engine.pairs;
var collisions = Detector.collisions(detector);

// update collision pairs
Expand Down

0 comments on commit f9208df

Please sign in to comment.