mirror of
https://github.com/liabru/matter-js.git
synced 2024-11-23 09:26:51 -05:00
optimised contacts and supports memory and gc use
This commit is contained in:
parent
f9208df1db
commit
97d502ea97
5 changed files with 66 additions and 49 deletions
|
@ -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
|
||||||
|
*/
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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++) {
|
// reset first contact if support changed
|
||||||
var support = supports[i],
|
if (contact.vertex !== support) {
|
||||||
contactId = support.body === parentA ? support.index : parentAVerticesLength + support.index,
|
contact.vertex = support;
|
||||||
contact = contacts[contactId];
|
contact.normalImpulse = 0;
|
||||||
|
contact.tangentImpulse = 0;
|
||||||
if (contact) {
|
|
||||||
activeContacts[activeContactIndex++] = contact;
|
|
||||||
} else {
|
|
||||||
contact = Contact.create(support);
|
|
||||||
activeContacts[activeContactIndex++] = contact;
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Reference in a new issue