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:
parent
4c56e5b11d
commit
f9208df1db
5 changed files with 64 additions and 30 deletions
|
@ -152,8 +152,10 @@ var Pair = require('./Pair');
|
||||||
supports[supportCount++] = supportsB[0];
|
supports[supportCount++] = supportsB[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
// update supports array size
|
// update supports array size if changed
|
||||||
|
if (supports.length !== supportCount) {
|
||||||
supports.length = supportCount;
|
supports.length = supportCount;
|
||||||
|
}
|
||||||
|
|
||||||
return collision;
|
return collision;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -74,19 +74,27 @@ var Contact = require('./Contact');
|
||||||
pair.slop = parentA.slop > parentB.slop ? parentA.slop : parentB.slop;
|
pair.slop = parentA.slop > parentB.slop ? parentA.slop : parentB.slop;
|
||||||
|
|
||||||
collision.pair = pair;
|
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],
|
var support = supports[i],
|
||||||
contactId = support.body === parentA ? support.index : parentAVerticesLength + support.index,
|
contactId = support.body === parentA ? support.index : parentAVerticesLength + support.index,
|
||||||
contact = contacts[contactId];
|
contact = contacts[contactId];
|
||||||
|
|
||||||
if (contact) {
|
if (contact) {
|
||||||
activeContacts.push(contact);
|
activeContacts[activeContactIndex++] = contact;
|
||||||
} else {
|
} 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;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -39,21 +39,19 @@ var Common = require('../core/Common');
|
||||||
Pairs.update = function(pairs, collisions, timestamp) {
|
Pairs.update = function(pairs, collisions, timestamp) {
|
||||||
var pairsList = pairs.list,
|
var pairsList = pairs.list,
|
||||||
pairsListLength = pairsList.length,
|
pairsListLength = pairsList.length,
|
||||||
|
pairsListIndex = pairsListLength,
|
||||||
pairsTable = pairs.table,
|
pairsTable = pairs.table,
|
||||||
collisionsLength = collisions.length,
|
collisionsLength = collisions.length,
|
||||||
collisionStart = pairs.collisionStart,
|
collisionStart = pairs.collisionStart,
|
||||||
collisionEnd = pairs.collisionEnd,
|
collisionEnd = pairs.collisionEnd,
|
||||||
collisionActive = pairs.collisionActive,
|
collisionActive = pairs.collisionActive,
|
||||||
|
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++) {
|
for (i = 0; i < pairsListLength; i++) {
|
||||||
pairsList[i].confirmedActive = false;
|
pairsList[i].confirmedActive = false;
|
||||||
}
|
}
|
||||||
|
@ -66,10 +64,10 @@ 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 {
|
} else {
|
||||||
// pair exists but was inactive, so a collision has just started again
|
// pair exists but was inactive, so a collision has just started again
|
||||||
collisionStart.push(pair);
|
collisionStart[collisionStartIndex++] = pair;
|
||||||
}
|
}
|
||||||
|
|
||||||
// update the pair
|
// update the pair
|
||||||
|
@ -80,14 +78,14 @@ var Common = require('../core/Common');
|
||||||
pair = Pair.create(collision, timestamp);
|
pair = Pair.create(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++) {
|
||||||
|
@ -95,20 +93,32 @@ var Common = require('../core/Common');
|
||||||
|
|
||||||
if (!pair.confirmedActive) {
|
if (!pair.confirmedActive) {
|
||||||
Pair.setActive(pair, false, timestamp);
|
Pair.setActive(pair, false, timestamp);
|
||||||
collisionEnd.push(pair);
|
collisionEnd[collisionEndIndex++] = pair;
|
||||||
|
|
||||||
|
// remove inactive pairs
|
||||||
if (!pair.collision.bodyA.isSleeping && !pair.collision.bodyB.isSleeping) {
|
if (!pair.collision.bodyA.isSleeping && !pair.collision.bodyB.isSleeping) {
|
||||||
removePairIndex.push(i);
|
delete pairsTable[pair.id];
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
pairsList[pairsListIndex++] = pair;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue