0
0
Fork 0
mirror of https://github.com/liabru/matter-js.git synced 2024-11-23 09:26:51 -05:00

optimised pairs and collisions memory and gc use

This commit is contained in:
liabru 2023-07-23 12:18:03 +01:00
parent 4c56e5b11d
commit f9208df1db
5 changed files with 64 additions and 30 deletions

View file

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

View file

@ -22,6 +22,7 @@ var Collision = require('./Collision');
Detector.create = function(options) {
var defaults = {
bodies: [],
collisions: [],
pairs: null
};
@ -45,6 +46,7 @@ var Collision = require('./Collision');
*/
Detector.clear = function(detector) {
detector.bodies = [];
detector.collisions = [];
};
/**
@ -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;
@ -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,
@ -126,7 +129,7 @@ var Collision = require('./Collision');
var collision = collides(partA, partB, pairs);
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;
};
@ -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

View file

@ -74,19 +74,27 @@ var Contact = require('./Contact');
pair.slop = parentA.slop > parentB.slop ? parentA.slop : parentB.slop;
collision.pair = pair;
activeContacts.length = 0;
for (var i = 0; i < supports.length; i++) {
var activeContactIndex = 0,
supportsLength = supports.length;
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;
}
};
/**

View file

@ -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;
}
@ -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
@ -80,14 +78,14 @@ 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++) {
@ -95,21 +93,33 @@ var Common = require('../core/Common');
if (!pair.confirmedActive) {
Pair.setActive(pair, false, timestamp);
collisionEnd.push(pair);
if (!pair.collision.bodyA.isSleeping && !pair.collision.bodyB.isSleeping) {
removePairIndex.push(i);
}
}
}
collisionEnd[collisionEndIndex++] = pair;
// remove inactive pairs
for (i = 0; i < removePairIndex.length; i++) {
pairIndex = removePairIndex[i] - i;
pair = pairsList[pairIndex];
pairsList.splice(pairIndex, 1);
if (!pair.collision.bodyA.isSleeping && !pair.collision.bodyB.isSleeping) {
delete pairsTable[pair.id];
}
} else {
pairsList[pairsListIndex++] = pair;
}
}
// 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;
}
};
/**

View file

@ -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: [] };
@ -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