From bfd08db9358055d739d60313696d5d5f776238ca Mon Sep 17 00:00:00 2001 From: Richard Davey Date: Thu, 9 Nov 2023 22:12:12 +0000 Subject: [PATCH] Merged all of the Matter JS "Improved performance and reduced memory usage" changes from PR 1238 --- .../matter-js/lib/collision/Collision.js | 82 ++++++++----------- .../matter-js/lib/collision/Contact.js | 2 +- .../matter-js/lib/collision/Detector.js | 28 +++++-- src/physics/matter-js/lib/collision/Pair.js | 63 +++++++------- src/physics/matter-js/lib/collision/Pairs.js | 76 +++++++++-------- .../matter-js/lib/collision/Resolver.js | 50 ++++++----- src/physics/matter-js/lib/core/Engine.js | 2 +- src/physics/matter-js/lib/render/Render.js | 46 +++++------ 8 files changed, 183 insertions(+), 166 deletions(-) diff --git a/src/physics/matter-js/lib/collision/Collision.js b/src/physics/matter-js/lib/collision/Collision.js index 40b6cdfb7..3e753b1b1 100644 --- a/src/physics/matter-js/lib/collision/Collision.js +++ b/src/physics/matter-js/lib/collision/Collision.js @@ -36,7 +36,7 @@ var Pair = require('./Pair'); * @return {collision} A new collision record */ Collision.create = function(bodyA, bodyB) { - return { + return { pair: null, collided: false, bodyA: bodyA, @@ -47,7 +47,8 @@ var Pair = require('./Pair'); normal: { x: 0, y: 0 }, tangent: { x: 0, y: 0 }, penetration: { x: 0, y: 0 }, - supports: [] + supports: [null, null], + supportCount: 0 }; }; @@ -112,7 +113,7 @@ var Pair = require('./Pair'); normal.x = -minAxisX; normal.y = -minAxisY; } - + collision.tangent.x = -normal.y; collision.tangent.y = normal.x; @@ -152,8 +153,8 @@ var Pair = require('./Pair'); supports[supportCount++] = supportsB[0]; } - // update supports array size - supports.length = supportCount; + // update support count + collision.supportCount = supportCount; return collision; }; @@ -192,13 +193,13 @@ var Pair = require('./Pair'); minB = verticesBX * axisX + verticesBY * axisY, maxA = minA, maxB = minB; - + for (j = 1; j < verticesALength; j += 1) { dot = verticesA[j].x * axisX + verticesA[j].y * axisY; - if (dot > maxA) { + if (dot > maxA) { maxA = dot; - } else if (dot < minA) { + } else if (dot < minA) { minA = dot; } } @@ -206,9 +207,9 @@ var Pair = require('./Pair'); for (j = 1; j < verticesBLength; j += 1) { dot = verticesB[j].x * axisX + verticesB[j].y * axisY; - if (dot > maxB) { + if (dot > maxB) { maxB = dot; - } else if (dot < minB) { + } else if (dot < minB) { minB = dot; } } @@ -225,39 +226,13 @@ var Pair = require('./Pair'); // can not be intersecting break; } - } + } } result.axis = axes[overlapAxisNumber]; result.overlap = overlapMin; }; - /** - * Projects vertices on an axis and returns an interval. - * @method _projectToAxis - * @private - * @param {} projection - * @param {} vertices - * @param {} axis - */ - Collision._projectToAxis = function(projection, vertices, axis) { - var min = vertices[0].x * axis.x + vertices[0].y * axis.y, - max = min; - - for (var i = 1; i < vertices.length; i += 1) { - var dot = vertices[i].x * axis.x + vertices[i].y * axis.y; - - if (dot > max) { - max = dot; - } else if (dot < min) { - min = dot; - } - } - - projection.min = min; - projection.max = max; - }; - /** * Finds supporting vertices given two bodies along a given direction using hill-climbing. * @method _findSupports @@ -275,15 +250,15 @@ var Pair = require('./Pair'); bodyAPositionY = bodyA.position.y, normalX = normal.x * direction, normalY = normal.y * direction, - nearestDistance = Number.MAX_VALUE, - vertexA, - vertexB, + vertexA = vertices[0], + vertexB = vertexA, + nearestDistance = normalX * (bodyAPositionX - vertexB.x) + normalY * (bodyAPositionY - vertexB.y), vertexC, distance, j; // find deepest vertex relative to the axis - for (j = 0; j < verticesLength; j += 1) { + for (j = 1; j < verticesLength; j += 1) { vertexB = vertices[j]; distance = normalX * (bodyAPositionX - vertexB.x) + normalY * (bodyAPositionY - vertexB.y); @@ -329,7 +304,7 @@ var Pair = require('./Pair'); /** * A flag that indicates if the bodies were colliding when the collision was last updated. - * + * * @property collided * @type boolean * @default false @@ -337,28 +312,28 @@ var Pair = require('./Pair'); /** * The first body part represented by the collision (see also `collision.parentA`). - * + * * @property bodyA * @type body */ /** * The second body part represented by the collision (see also `collision.parentB`). - * + * * @property bodyB * @type body */ /** * The first body represented by the collision (i.e. `collision.bodyA.parent`). - * + * * @property parentA * @type body */ /** * The second body represented by the collision (i.e. `collision.bodyB.parent`). - * + * * @property parentB * @type body */ @@ -398,6 +373,10 @@ var Pair = require('./Pair'); /** * 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. * * @property supports @@ -405,4 +384,15 @@ var Pair = require('./Pair'); * @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 + */ + })(); diff --git a/src/physics/matter-js/lib/collision/Contact.js b/src/physics/matter-js/lib/collision/Contact.js index 56f16cc0c..5ec9f0b4b 100644 --- a/src/physics/matter-js/lib/collision/Contact.js +++ b/src/physics/matter-js/lib/collision/Contact.js @@ -13,7 +13,7 @@ module.exports = Contact; /** * Creates a new contact. * @method create - * @param {vertex} vertex + * @param {vertex} [vertex] * @return {contact} A new contact */ Contact.create = function(vertex) { diff --git a/src/physics/matter-js/lib/collision/Detector.js b/src/physics/matter-js/lib/collision/Detector.js index a4626e296..67284f040 100644 --- a/src/physics/matter-js/lib/collision/Detector.js +++ b/src/physics/matter-js/lib/collision/Detector.js @@ -22,6 +22,7 @@ var Collision = require('./Collision'); Detector.create = function(options) { var defaults = { bodies: [], + collisions: [], pairs: null }; @@ -45,11 +46,12 @@ var Collision = require('./Collision'); */ Detector.clear = function(detector) { detector.bodies = []; + detector.collisions = []; }; /** * Efficiently finds all collisions among all the bodies in `detector.bodies` using a broadphase algorithm. - * + * * _Note:_ The specific ordering of collisions returned is not guaranteed between releases and may change for performance reasons. * If a specific ordering is required then apply a sort to the resulting array. * @method 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,12 +107,12 @@ 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, partsBStart = partsBLength > 1 ? 1 : 0; - + for (var k = partsAStart; k < partsALength; k++) { var partA = bodyA.parts[k], boundsA = partA.bounds; @@ -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; }; @@ -173,13 +180,20 @@ var Collision = require('./Collision'); /** * The array of `Matter.Body` between which the detector finds collisions. - * + * * _Note:_ The order of bodies in this array _is not fixed_ and will be continually managed by the detector. * @property bodies * @type body[] * @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 diff --git a/src/physics/matter-js/lib/collision/Pair.js b/src/physics/matter-js/lib/collision/Pair.js index 8f7ed810b..ef5739bdd 100644 --- a/src/physics/matter-js/lib/collision/Pair.js +++ b/src/physics/matter-js/lib/collision/Pair.js @@ -11,7 +11,7 @@ module.exports = Pair; var Contact = require('./Contact'); (function() { - + /** * Creates a pair. * @method create @@ -28,11 +28,10 @@ var Contact = require('./Contact'); bodyA: bodyA, bodyB: bodyB, collision: collision, - contacts: [], - activeContacts: [], + contacts: [Contact.create(), Contact.create()], + contactCount: 0, separation: 0, isActive: true, - confirmedActive: true, isSensor: bodyA.isSensor || bodyB.isSensor, timeCreated: timestamp, timeUpdated: timestamp, @@ -56,13 +55,12 @@ var Contact = require('./Contact'); * @param {number} timestamp */ Pair.update = function(pair, collision, timestamp) { - var contacts = pair.contacts, - supports = collision.supports, - activeContacts = pair.activeContacts, + var supports = collision.supports, + supportCount = collision.supportCount, + contacts = pair.contacts, parentA = collision.parentA, - parentB = collision.parentB, - parentAVerticesLength = parentA.vertices.length; - + parentB = collision.parentB; + pair.isActive = true; pair.timeUpdated = timestamp; pair.collision = collision; @@ -73,22 +71,34 @@ var Contact = require('./Contact'); pair.restitution = parentA.restitution > parentB.restitution ? parentA.restitution : parentB.restitution; pair.slop = parentA.slop > parentB.slop ? parentA.slop : parentB.slop; + pair.contactCount = supportCount; collision.pair = pair; - activeContacts.length = 0; - - for (var i = 0; i < supports.length; i++) { - var support = supports[i], - contactId = support.body === parentA ? support.index : parentAVerticesLength + support.index, - contact = contacts[contactId]; - if (contact) { - activeContacts.push(contact); - } else { - activeContacts.push(contacts[contactId] = Contact.create(support)); - } + var support = supports[0], + contact = contacts[0]; + + // reset first contact if support changed + if (contact.vertex !== support) { + contact.vertex = support; + contact.normalImpulse = 0; + contact.tangentImpulse = 0; + } + + if (supportCount < 2) { + 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; } }; - + /** * Set a pair as active or inactive. * @method setActive @@ -102,7 +112,7 @@ var Contact = require('./Contact'); pair.timeUpdated = timestamp; } else { pair.isActive = false; - pair.activeContacts.length = 0; + pair.contactCount = 0; } }; @@ -114,11 +124,8 @@ var Contact = require('./Contact'); * @return {string} Unique pairId */ Pair.id = function(bodyA, bodyB) { - if (bodyA.id < bodyB.id) { - return 'A' + bodyA.id + 'B' + bodyB.id; - } else { - return 'A' + bodyB.id + 'B' + bodyA.id; - } + return bodyA.id < bodyB.id ? bodyA.id.toString(36) + ':' + bodyB.id.toString(36) + : bodyB.id.toString(36) + ':' + bodyA.id.toString(36); }; })(); diff --git a/src/physics/matter-js/lib/collision/Pairs.js b/src/physics/matter-js/lib/collision/Pairs.js index 2c62cd366..211725587 100644 --- a/src/physics/matter-js/lib/collision/Pairs.js +++ b/src/physics/matter-js/lib/collision/Pairs.js @@ -20,7 +20,7 @@ var Common = require('../core/Common'); * @return {pairs} A new pairs structure */ Pairs.create = function(options) { - return Common.extend({ + return Common.extend({ table: {}, list: [], collisionStart: [], @@ -37,27 +37,24 @@ var Common = require('../core/Common'); * @param {number} timestamp */ Pairs.update = function(pairs, collisions, timestamp) { - var pairsList = pairs.list, - pairsListLength = pairsList.length, + var pairUpdate = Pair.update, + pairCreate = Pair.create, + pairSetActive = Pair.setActive, pairsTable = pairs.table, - collisionsLength = collisions.length, + pairsList = pairs.list, + pairsListLength = pairsList.length, + pairsListIndex = pairsListLength, collisionStart = pairs.collisionStart, collisionEnd = pairs.collisionEnd, collisionActive = pairs.collisionActive, + collisionsLength = collisions.length, + 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; - } - for (i = 0; i < collisionsLength; i++) { collision = collisions[i]; pair = collision.pair; @@ -66,49 +63,60 @@ 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 - Pair.update(pair, collision, timestamp); - pair.confirmedActive = true; + pairUpdate(pair, collision, timestamp); } else { // pair did not exist, create a new pair - pair = Pair.create(collision, timestamp); + pair = pairCreate(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); + if (pair.timeUpdated < timestamp) { + pairSetActive(pair, false, timestamp); + 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; } }; diff --git a/src/physics/matter-js/lib/collision/Resolver.js b/src/physics/matter-js/lib/collision/Resolver.js index 7c05e1986..1671e5dfa 100644 --- a/src/physics/matter-js/lib/collision/Resolver.js +++ b/src/physics/matter-js/lib/collision/Resolver.js @@ -29,7 +29,7 @@ var Bounds = require('../geometry/Bounds'); Resolver.preSolvePosition = function(pairs) { var i, pair, - activeCount, + contactCount, pairsLength = pairs.length; // find total contacts on each body @@ -39,9 +39,9 @@ var Bounds = require('../geometry/Bounds'); if (!pair.isActive) continue; - activeCount = pair.activeContacts.length; - pair.collision.parentA.totalContacts += activeCount; - pair.collision.parentB.totalContacts += activeCount; + contactCount = pair.contactCount; + pair.collision.parentA.totalContacts += contactCount; + pair.collision.parentB.totalContacts += contactCount; } }; @@ -176,8 +176,8 @@ var Bounds = require('../geometry/Bounds'); if (!pair.isActive || pair.isSensor) continue; - var contacts = pair.activeContacts, - contactsLength = contacts.length, + var contacts = pair.contacts, + contactCount = pair.contactCount, collision = pair.collision, bodyA = collision.parentA, bodyB = collision.parentB, @@ -185,7 +185,7 @@ var Bounds = require('../geometry/Bounds'); tangent = collision.tangent; // resolve each contact - for (j = 0; j < contactsLength; j++) { + for (j = 0; j < contactCount; j++) { var contact = contacts[j], contactVertex = contact.vertex, normalImpulse = contact.normalImpulse, @@ -248,28 +248,26 @@ var Bounds = require('../geometry/Bounds'); var collision = pair.collision, bodyA = collision.parentA, bodyB = collision.parentB, - bodyAVelocity = bodyA.velocity, - bodyBVelocity = bodyB.velocity, normalX = collision.normal.x, normalY = collision.normal.y, tangentX = collision.tangent.x, tangentY = collision.tangent.y, - contacts = pair.activeContacts, - contactsLength = contacts.length, - contactShare = 1 / contactsLength, - inverseMassTotal = bodyA.inverseMass + bodyB.inverseMass, - friction = pair.friction * pair.frictionStatic * frictionNormalMultiplier; + inverseMassTotal = pair.inverseMass, + friction = pair.friction * pair.frictionStatic * frictionNormalMultiplier, + contacts = pair.contacts, + contactCount = pair.contactCount, + contactShare = 1 / contactCount; - // update body velocities - bodyAVelocity.x = bodyA.position.x - bodyA.positionPrev.x; - bodyAVelocity.y = bodyA.position.y - bodyA.positionPrev.y; - bodyBVelocity.x = bodyB.position.x - bodyB.positionPrev.x; - bodyBVelocity.y = bodyB.position.y - bodyB.positionPrev.y; - bodyA.angularVelocity = bodyA.angle - bodyA.anglePrev; - bodyB.angularVelocity = bodyB.angle - bodyB.anglePrev; + // get body velocities + var bodyAVelocityX = bodyA.position.x - bodyA.positionPrev.x, + bodyAVelocityY = bodyA.position.y - bodyA.positionPrev.y, + bodyAAngularVelocity = bodyA.angle - bodyA.anglePrev, + bodyBVelocityX = bodyB.position.x - bodyB.positionPrev.x, + bodyBVelocityY = bodyB.position.y - bodyB.positionPrev.y, + bodyBAngularVelocity = bodyB.angle - bodyB.anglePrev; // resolve each contact - for (j = 0; j < contactsLength; j++) { + for (j = 0; j < contactCount; j++) { var contact = contacts[j], contactVertex = contact.vertex; @@ -278,10 +276,10 @@ var Bounds = require('../geometry/Bounds'); offsetBX = contactVertex.x - bodyB.position.x, offsetBY = contactVertex.y - bodyB.position.y; - var velocityPointAX = bodyAVelocity.x - offsetAY * bodyA.angularVelocity, - velocityPointAY = bodyAVelocity.y + offsetAX * bodyA.angularVelocity, - velocityPointBX = bodyBVelocity.x - offsetBY * bodyB.angularVelocity, - velocityPointBY = bodyBVelocity.y + offsetBX * bodyB.angularVelocity; + var velocityPointAX = bodyAVelocityX - offsetAY * bodyAAngularVelocity, + velocityPointAY = bodyAVelocityY + offsetAX * bodyAAngularVelocity, + velocityPointBX = bodyBVelocityX - offsetBY * bodyBAngularVelocity, + velocityPointBY = bodyBVelocityY + offsetBX * bodyBAngularVelocity; var relativeVelocityX = velocityPointAX - velocityPointBX, relativeVelocityY = velocityPointAY - velocityPointBY; diff --git a/src/physics/matter-js/lib/core/Engine.js b/src/physics/matter-js/lib/core/Engine.js index 54aa1d6b8..00f5e8e29 100644 --- a/src/physics/matter-js/lib/core/Engine.js +++ b/src/physics/matter-js/lib/core/Engine.js @@ -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 diff --git a/src/physics/matter-js/lib/render/Render.js b/src/physics/matter-js/lib/render/Render.js index b9728870d..e9613392c 100644 --- a/src/physics/matter-js/lib/render/Render.js +++ b/src/physics/matter-js/lib/render/Render.js @@ -139,7 +139,7 @@ var Vector = require('../geometry/Vector'); Render.run = function(render) { (function loop(time){ render.frameRequestId = _requestAnimationFrame(loop); - + _updateTiming(render, time); Render.world(render, time); @@ -188,14 +188,14 @@ var Vector = require('../geometry/Vector'); /** * Sets the render `width` and `height`. - * - * Updates the canvas accounting for `render.options.pixelRatio`. - * + * + * Updates the canvas accounting for `render.options.pixelRatio`. + * * Updates the bottom right render bound `render.bounds.max` relative to the provided `width` and `height`. * The top left render bound `render.bounds.min` isn't changed. - * + * * Follow this call with `Render.lookAt` if you need to change the render bounds. - * + * * See also `Render.setPixelRatio`. * @method setSize * @param {render} render @@ -326,10 +326,10 @@ var Vector = require('../geometry/Vector'); boundsScaleY = boundsHeight / render.options.height; render.context.setTransform( - render.options.pixelRatio / boundsScaleX, 0, 0, + render.options.pixelRatio / boundsScaleX, 0, 0, render.options.pixelRatio / boundsScaleY, 0, 0 ); - + render.context.translate(-render.bounds.min.x, -render.bounds.min.y); }; @@ -496,7 +496,7 @@ var Vector = require('../geometry/Vector'); height = 44, x = 0, y = 0; - + // count parts for (var i = 0; i < bodies.length; i += 1) { parts += bodies[i].parts.length; @@ -550,7 +550,7 @@ var Vector = require('../geometry/Vector'); engineDeltaHistory = timing.engineDeltaHistory, engineElapsedHistory = timing.engineElapsedHistory, lastEngineDelta = engine.timing.lastDelta; - + var deltaMean = _mean(deltaHistory), elapsedMean = _mean(elapsedHistory), engineDeltaMean = _mean(engineDeltaHistory), @@ -572,8 +572,8 @@ var Vector = require('../geometry/Vector'); // show FPS Render.status( - context, x, y, width, graphHeight, deltaHistory.length, - Math.round(fps) + ' fps', + context, x, y, width, graphHeight, deltaHistory.length, + Math.round(fps) + ' fps', fps / Render._goodFps, function(i) { return (deltaHistory[i] / deltaMean) - 1; } ); @@ -581,7 +581,7 @@ var Vector = require('../geometry/Vector'); // show engine delta Render.status( context, x + gap + width, y, width, graphHeight, engineDeltaHistory.length, - lastEngineDelta.toFixed(2) + ' dt', + lastEngineDelta.toFixed(2) + ' dt', Render._goodDelta / lastEngineDelta, function(i) { return (engineDeltaHistory[i] / engineDeltaMean) - 1; } ); @@ -589,7 +589,7 @@ var Vector = require('../geometry/Vector'); // show engine update time Render.status( context, x + (gap + width) * 2, y, width, graphHeight, engineElapsedHistory.length, - engineElapsedMean.toFixed(2) + ' ut', + engineElapsedMean.toFixed(2) + ' ut', 1 - (engineElapsedMean / Render._goodFps), function(i) { return (engineElapsedHistory[i] / engineElapsedMean) - 1; } ); @@ -597,15 +597,15 @@ var Vector = require('../geometry/Vector'); // show render time Render.status( context, x + (gap + width) * 3, y, width, graphHeight, elapsedHistory.length, - elapsedMean.toFixed(2) + ' rt', + elapsedMean.toFixed(2) + ' rt', 1 - (elapsedMean / Render._goodFps), function(i) { return (elapsedHistory[i] / elapsedMean) - 1; } ); // show effective speed Render.status( - context, x + (gap + width) * 4, y, width, graphHeight, timestampElapsedHistory.length, - rateMean.toFixed(2) + ' x', + context, x + (gap + width) * 4, y, width, graphHeight, timestampElapsedHistory.length, + rateMean.toFixed(2) + ' x', rateMean * rateMean * rateMean, function(i) { return (((timestampElapsedHistory[i] / deltaHistory[i]) / rateMean) || 0) - 1; } ); @@ -1205,8 +1205,8 @@ var Vector = require('../geometry/Vector'); continue; collision = pair.collision; - for (j = 0; j < pair.activeContacts.length; j++) { - var contact = pair.activeContacts[j], + for (j = 0; j < pair.contactCount; j++) { + var contact = pair.contacts[j], vertex = contact.vertex; c.rect(vertex.x - 1.5, vertex.y - 1.5, 3.5, 3.5); } @@ -1686,7 +1686,7 @@ var Vector = require('../geometry/Vector'); */ /** - * A flag to enable or disable all debug information overlays together. + * A flag to enable or disable all debug information overlays together. * This includes and has priority over the values of: * * - `render.options.showStats` @@ -1698,7 +1698,7 @@ var Vector = require('../geometry/Vector'); */ /** - * A flag to enable or disable the engine stats info overlay. + * A flag to enable or disable the engine stats info overlay. * From left to right, the values shown are: * * - body parts total @@ -1713,7 +1713,7 @@ var Vector = require('../geometry/Vector'); */ /** - * A flag to enable or disable performance charts. + * A flag to enable or disable performance charts. * From left to right, the values shown are: * * - average render frequency (e.g. 60 fps) @@ -1731,7 +1731,7 @@ var Vector = require('../geometry/Vector'); * @type boolean * @default false */ - + /** * A flag to enable or disable rendering entirely. *