0
0
Fork 0
mirror of https://github.com/liabru/matter-js.git synced 2024-11-27 09:50:52 -05:00

optimised contacts and supports memory and gc use

This commit is contained in:
liabru 2023-07-23 12:50:21 +01:00
parent f9208df1db
commit 97d502ea97
5 changed files with 66 additions and 49 deletions

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
}; };
}; };
@ -152,10 +153,8 @@ var Pair = require('./Pair');
supports[supportCount++] = supportsB[0]; supports[supportCount++] = supportsB[0];
} }
// update supports array size if changed // update support count
if (supports.length !== supportCount) { collision.supportCount = supportCount;
supports.length = supportCount;
}
return collision; return collision;
}; };
@ -374,6 +373,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
@ -381,4 +384,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

@ -28,8 +28,8 @@ 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, confirmedActive: true,
@ -56,12 +56,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,27 +72,31 @@ 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;
var activeContactIndex = 0, var support = supports[0],
supportsLength = supports.length; contact = contacts[0];
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) { // reset first contact if support changed
activeContacts[activeContactIndex++] = contact; if (contact.vertex !== support) {
} else { contact.vertex = support;
contact = Contact.create(support); contact.normalImpulse = 0;
activeContacts[activeContactIndex++] = contact; contact.tangentImpulse = 0;
contacts[contactId] = contact;
}
} }
if (activeContacts.length !== activeContactIndex) { if (supportCount < 2) {
activeContacts.length = activeContactIndex; return;
}
support = supports[1];
contact = contacts[1];
// reset second contact if support changed
if (contact.vertex !== support) {
contact.vertex = support;
contact.normalImpulse = 0;
contact.tangentImpulse = 0;
} }
}; };
@ -110,7 +113,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;
} }
}; };

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;
} }
}; };
@ -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,
@ -254,9 +254,9 @@ var Bounds = require('../geometry/Bounds');
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, contacts = pair.contacts,
contactsLength = contacts.length, contactCount = pair.contactCount,
contactShare = 1 / contactsLength, contactShare = 1 / contactCount,
inverseMassTotal = bodyA.inverseMass + bodyB.inverseMass, inverseMassTotal = bodyA.inverseMass + bodyB.inverseMass,
friction = pair.friction * pair.frictionStatic * frictionNormalMultiplier; friction = pair.friction * pair.frictionStatic * frictionNormalMultiplier;
@ -269,7 +269,7 @@ var Bounds = require('../geometry/Bounds');
bodyB.angularVelocity = bodyB.angle - bodyB.anglePrev; bodyB.angularVelocity = 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;

View file

@ -1205,8 +1205,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);
} }
@ -1230,13 +1230,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) {