diff --git a/build/matter.js b/build/matter.js index b36c3f5..4716aa8 100644 --- a/build/matter.js +++ b/build/matter.js @@ -1,5 +1,5 @@ /** -* matter-js 0.14.2 by @liabru 2018-06-11 +* matter-js 0.14.2-alpha by @liabru 2019-09-01 * http://brm.io/matter-js/ * License MIT */ @@ -46,13 +46,13 @@ module.exports = Body; var Vertices = _dereq_('../geometry/Vertices'); var Vector = _dereq_('../geometry/Vector'); var Sleeping = _dereq_('../core/Sleeping'); -var Render = _dereq_('../render/Render'); var Common = _dereq_('../core/Common'); var Bounds = _dereq_('../geometry/Bounds'); var Axes = _dereq_('../geometry/Axes'); (function() { + Body._timeCorrection = true; Body._inertiaScale = 4; Body._nextCollidingGroupId = 1; Body._nextNonCollidingGroupId = -1; @@ -80,6 +80,7 @@ var Axes = _dereq_('../geometry/Axes'); force: { x: 0, y: 0 }, torque: 0, positionImpulse: { x: 0, y: 0 }, + previousPositionImpulse: { x: 0, y: 0 }, constraintImpulse: { x: 0, y: 0, angle: 0 }, totalContacts: 0, speed: 0, @@ -113,7 +114,20 @@ var Axes = _dereq_('../geometry/Axes'); yOffset: 0 }, lineWidth: 0 - } + }, + events: null, + bounds: null, + chamfer: null, + circleRadius: 0, + positionPrev: null, + anglePrev: 0, + parent: null, + axes: null, + area: 0, + mass: 0, + inertia: 0, + deltaTime: null, + _original: null }; var body = Common.extend(defaults, options); @@ -210,11 +224,11 @@ var Axes = _dereq_('../geometry/Axes'); } for (property in settings) { - value = settings[property]; if (!settings.hasOwnProperty(property)) continue; + value = settings[property]; switch (property) { case 'isStatic': @@ -250,6 +264,9 @@ var Axes = _dereq_('../geometry/Axes'); case 'parts': Body.setParts(body, value); break; + case 'centre': + Body.setCentre(body, value); + break; default: body[property] = value; @@ -300,7 +317,7 @@ var Axes = _dereq_('../geometry/Axes'); part.inverseMass = part._original.inverseMass; part.inverseInertia = part._original.inverseInertia; - delete part._original; + part._original = null; } } }; @@ -333,7 +350,7 @@ var Axes = _dereq_('../geometry/Axes'); }; /** - * Sets the moment of inertia (i.e. second moment of area) of the body of the body. + * Sets the moment of inertia (i.e. second moment of area) of the body. * Inverse inertia is automatically updated to reflect the change. Mass is not changed. * @method setInertia * @param {body} body @@ -445,15 +462,51 @@ var Axes = _dereq_('../geometry/Axes'); }; /** - * Sets the position of the body instantly. Velocity, angle, force etc. are unchanged. + * Set the centre of mass of the body. + * The `centre` is a vector in world-space unless `relative` is set, in which case it is a translation. + * The centre of mass is the point the body rotates about and can be used to simulate non-uniform density. + * This is equal to moving `body.position` but not the `body.vertices`. + * Invalid if the `centre` falls outside the body's convex hull. + * @method setCentre + * @param {body} body + * @param {vector} centre + * @param {bool} relative + */ + Body.setCentre = function(body, centre, relative) { + if (!relative) { + body.positionPrev.x = centre.x - (body.position.x - body.positionPrev.x); + body.positionPrev.y = centre.y - (body.position.y - body.positionPrev.y); + body.position.x = centre.x; + body.position.y = centre.y; + } else { + body.positionPrev.x += centre.x; + body.positionPrev.y += centre.y; + body.position.x += centre.x; + body.position.y += centre.y; + } + }; + + /** + * Sets the position of the body instantly. By default velocity, angle, force etc. are unchanged. + * If `updateVelocity` is `true` then velocity is inferred from the change in position. * @method setPosition * @param {body} body * @param {vector} position + * @param {boolean} [updateVelocity=false] */ - Body.setPosition = function(body, position) { + Body.setPosition = function(body, position, updateVelocity) { var delta = Vector.sub(position, body.position); - body.positionPrev.x += delta.x; - body.positionPrev.y += delta.y; + + if (updateVelocity) { + body.positionPrev.x = body.position.x; + body.positionPrev.y = body.position.y; + body.velocity.x = delta.x; + body.velocity.y = delta.y; + body.speed = Vector.magnitude(delta); + } else { + body.positionPrev.x += delta.x; + body.positionPrev.y += delta.y; + } for (var i = 0; i < body.parts.length; i++) { var part = body.parts[i]; @@ -465,14 +518,23 @@ var Axes = _dereq_('../geometry/Axes'); }; /** - * Sets the angle of the body instantly. Angular velocity, position, force etc. are unchanged. + * Sets the angle of the body instantly. By default angular velocity, position, force etc. are unchanged. + * If `updateVelocity` is `true` then angular velocity is inferred from the change in angle. * @method setAngle * @param {body} body * @param {number} angle + * @param {boolean} [updateVelocity=false] */ - Body.setAngle = function(body, angle) { + Body.setAngle = function(body, angle, updateVelocity) { var delta = angle - body.angle; - body.anglePrev += delta; + + if (updateVelocity) { + body.anglePrev = body.angle; + body.angularVelocity = delta; + body.angularSpeed = Math.abs(delta); + } else { + body.anglePrev += delta; + } for (var i = 0; i < body.parts.length; i++) { var part = body.parts[i]; @@ -493,13 +555,49 @@ var Axes = _dereq_('../geometry/Axes'); * @param {vector} velocity */ Body.setVelocity = function(body, velocity) { - body.positionPrev.x = body.position.x - velocity.x; - body.positionPrev.y = body.position.y - velocity.y; - body.velocity.x = velocity.x; - body.velocity.y = velocity.y; + var timeScale = body.deltaTime / Common._timeUnit; + body.positionPrev.x = body.position.x - velocity.x * timeScale; + body.positionPrev.y = body.position.y - velocity.y * timeScale; + body.velocity.x = velocity.x * timeScale; + body.velocity.y = velocity.y * timeScale; body.speed = Vector.magnitude(body.velocity); }; + /** + * Gets the linear velocity of the body. Use this instead of the internal `body.velocity`. + * @method getVelocity + * @param {body} body + * @return {vector} velocity + */ + Body.getVelocity = function(body) { + var timeScale = Common._timeUnit / body.deltaTime; + + return { + x: (body.position.x - body.positionPrev.x) * timeScale, + y: (body.position.y - body.positionPrev.y) * timeScale + }; + }; + + /** + * Gets the linear speed the body. Use this instead of the internal `body.speed`. + * @method getSpeed + * @param {body} body + * @return {number} speed + */ + Body.getSpeed = function(body) { + return Vector.magnitude(Body.getVelocity(body)); + }; + + /** + * Sets the linear speed of the body. Use this instead of the internal `body.speed`. + * @method setSpeed + * @param {body} body + * @param {number} speed + */ + Body.setSpeed = function(body, speed) { + Body.setVelocity(body, Vector.mult(Vector.normalise(Body.getVelocity(body)), speed)); + }; + /** * Sets the angular velocity of the body instantly. Position, angle, force etc. are unchanged. See also `Body.applyForce`. * @method setAngularVelocity @@ -507,31 +605,66 @@ var Axes = _dereq_('../geometry/Axes'); * @param {number} velocity */ Body.setAngularVelocity = function(body, velocity) { - body.anglePrev = body.angle - velocity; - body.angularVelocity = velocity; + var timeScale = body.deltaTime / Common._timeUnit; + body.anglePrev = body.angle - velocity * timeScale; + body.angularVelocity = velocity * timeScale; body.angularSpeed = Math.abs(body.angularVelocity); }; /** - * Moves a body by a given vector relative to its current position, without imparting any velocity. - * @method translate + * Gets the angular velocity of the body. Use this instead of the internal `body.angularVelocity`. + * @method getAngularVelocity * @param {body} body - * @param {vector} translation + * @return {number} angular velocity */ - Body.translate = function(body, translation) { - Body.setPosition(body, Vector.add(body.position, translation)); + Body.getAngularVelocity = function(body) { + return (body.angle - body.anglePrev) * Common._timeUnit / body.deltaTime; }; /** - * Rotates a body by a given angle relative to its current angle, without imparting any angular velocity. + * Gets the angular speed of the body. Use this instead of the internal `body.angularSpeed`. + * @method getAngularSpeed + * @param {body} body + * @return {number} angular speed + */ + Body.getAngularSpeed = function(body) { + return Math.abs(Body.getAngularVelocity(body)); + }; + + /** + * Sets the angular speed of the body. Use this instead of the internal `body.angularSpeed`. + * @method setAngularSpeed + * @param {body} body + * @param {number} speed + */ + Body.setAngularSpeed = function(body, speed) { + Body.setAngularVelocity(body, Common.sign(Body.getAngularVelocity(body)) * speed); + }; + + /** + * Moves a body by a given vector relative to its current position, without imparting any velocity by default. + * If `updateVelocity` is `true` then velocity is inferred from the change in position. + * @method translate + * @param {body} body + * @param {vector} translation + * @param {boolean} [updateVelocity=false] + */ + Body.translate = function(body, translation, updateVelocity) { + Body.setPosition(body, Vector.add(body.position, translation), updateVelocity); + }; + + /** + * Rotates a body by a given angle relative to its current angle, without imparting any angular velocity by default. + * If `updateVelocity` is `true` then angular velocity is inferred from the change in angle. * @method rotate * @param {body} body * @param {number} rotation * @param {vector} [point] + * @param {boolean} [updateVelocity=false] */ - Body.rotate = function(body, rotation, point) { + Body.rotate = function(body, rotation, point, updateVelocity) { if (!point) { - Body.setAngle(body, body.angle + rotation); + Body.setAngle(body, body.angle + rotation, updateVelocity); } else { var cos = Math.cos(rotation), sin = Math.sin(rotation), @@ -541,9 +674,9 @@ var Axes = _dereq_('../geometry/Axes'); Body.setPosition(body, { x: point.x + (dx * cos - dy * sin), y: point.y + (dx * sin + dy * cos) - }); + }, updateVelocity); - Body.setAngle(body, body.angle + rotation); + Body.setAngle(body, body.angle + rotation, updateVelocity); } }; @@ -615,26 +748,28 @@ var Axes = _dereq_('../geometry/Axes'); * Performs a simulation step for the given `body`, including updating position and angle using Verlet integration. * @method update * @param {body} body - * @param {number} deltaTime - * @param {number} timeScale - * @param {number} correction + * @param {number} [deltaTime=16.666] */ - Body.update = function(body, deltaTime, timeScale, correction) { - var deltaTimeSquared = Math.pow(deltaTime * timeScale * body.timeScale, 2); + Body.update = function(body, deltaTime) { + deltaTime = (typeof deltaTime !== 'undefined' ? deltaTime : Common._timeUnit) * body.timeScale; + + var deltaTimeSquared = deltaTime * deltaTime, + correction = Body._timeCorrection ? deltaTime / (body.deltaTime || deltaTime) : 1; // from the previous step - var frictionAir = 1 - body.frictionAir * timeScale * body.timeScale, - velocityPrevX = body.position.x - body.positionPrev.x, - velocityPrevY = body.position.y - body.positionPrev.y; + var frictionAir = 1 - body.frictionAir * (deltaTime / Common._timeUnit), + velocityPrevX = (body.position.x - body.positionPrev.x) * correction, + velocityPrevY = (body.position.y - body.positionPrev.y) * correction; // update velocity with Verlet integration - body.velocity.x = (velocityPrevX * frictionAir * correction) + (body.force.x / body.mass) * deltaTimeSquared; - body.velocity.y = (velocityPrevY * frictionAir * correction) + (body.force.y / body.mass) * deltaTimeSquared; + body.velocity.x = (velocityPrevX * frictionAir) + (body.force.x / body.mass) * deltaTimeSquared; + body.velocity.y = (velocityPrevY * frictionAir) + (body.force.y / body.mass) * deltaTimeSquared; body.positionPrev.x = body.position.x; body.positionPrev.y = body.position.y; body.position.x += body.velocity.x; body.position.y += body.velocity.y; + body.deltaTime = deltaTime; // update angular velocity with Verlet integration body.angularVelocity = ((body.angle - body.anglePrev) * frictionAir * correction) + (body.torque / body.inertia) * deltaTimeSquared; @@ -850,7 +985,7 @@ var Axes = _dereq_('../geometry/Axes'); */ /** - * A `Number` that _measures_ the current speed of the body after the last `Body.update`. It is read-only and always positive (it's the magnitude of `body.velocity`). + * Internal only. Use `Body.getSpeed` and `Body.setSpeed` instead. * * @readOnly * @property speed @@ -859,7 +994,7 @@ var Axes = _dereq_('../geometry/Axes'); */ /** - * A `Number` that _measures_ the current angular speed of the body after the last `Body.update`. It is read-only and always positive (it's the magnitude of `body.angularVelocity`). + * Internal only. Use `Body.getAngularSpeed` and `Body.setAngularSpeed` instead. * * @readOnly * @property angularSpeed @@ -868,9 +1003,8 @@ var Axes = _dereq_('../geometry/Axes'); */ /** - * A `Vector` that _measures_ the current velocity of the body after the last `Body.update`. It is read-only. - * If you need to modify a body's velocity directly, you should either apply a force or simply change the body's `position` (as the engine uses position-Verlet integration). - * + * Internal only. Use `Body.getVelocity` and `Body.setVelocity` instead. + * * @readOnly * @property velocity * @type vector @@ -878,8 +1012,7 @@ var Axes = _dereq_('../geometry/Axes'); */ /** - * A `Number` that _measures_ the current angular velocity of the body after the last `Body.update`. It is read-only. - * If you need to modify a body's angular velocity directly, you should apply a torque or simply change the body's `angle` (as the engine uses position-Verlet integration). + * Internal only. Use `Body.getAngularVelocity` and `Body.setAngularVelocity` instead. * * @readOnly * @property angularVelocity @@ -1099,6 +1232,16 @@ var Axes = _dereq_('../geometry/Axes'); * @default 1 */ + /** + * A `Number` that records the last delta time value used to update this body. + * This is automatically updated by the engine inside of `Body.update`. + * + * @readOnly + * @property deltaTime + * @type number + * @default null + */ + /** * An `Object` that defines the rendering properties to be consumed by the module `Matter.Render`. * @@ -1222,7 +1365,7 @@ var Axes = _dereq_('../geometry/Axes'); })(); -},{"../core/Common":14,"../core/Sleeping":22,"../geometry/Axes":25,"../geometry/Bounds":26,"../geometry/Vector":28,"../geometry/Vertices":29,"../render/Render":31}],2:[function(_dereq_,module,exports){ +},{"../core/Common":13,"../core/Sleeping":21,"../geometry/Axes":24,"../geometry/Bounds":25,"../geometry/Vector":27,"../geometry/Vertices":28}],2:[function(_dereq_,module,exports){ /** * The `Matter.Composite` module contains methods for creating and manipulating composite bodies. * A composite body is a collection of `Matter.Body`, `Matter.Constraint` and other `Matter.Composite`, therefore composites form a tree structure. @@ -1909,7 +2052,7 @@ var Body = _dereq_('./Body'); })(); -},{"../core/Common":14,"../core/Events":16,"../geometry/Bounds":26,"./Body":1}],3:[function(_dereq_,module,exports){ +},{"../core/Common":13,"../core/Events":15,"../geometry/Bounds":25,"./Body":1}],3:[function(_dereq_,module,exports){ /** * The `Matter.World` module contains methods for creating and manipulating the world composite. * A `Matter.World` is a `Matter.Composite` body, which is a collection of `Matter.Body`, `Matter.Constraint` and other `Matter.Composite`. @@ -2058,47 +2201,7 @@ var Common = _dereq_('../core/Common'); })(); -},{"../constraint/Constraint":12,"../core/Common":14,"./Composite":2}],4:[function(_dereq_,module,exports){ -/** -* The `Matter.Contact` module contains methods for creating and manipulating collision contacts. -* -* @class Contact -*/ - -var Contact = {}; - -module.exports = Contact; - -(function() { - - /** - * Creates a new contact. - * @method create - * @param {vertex} vertex - * @return {contact} A new contact - */ - Contact.create = function(vertex) { - return { - id: Contact.id(vertex), - vertex: vertex, - normalImpulse: 0, - tangentImpulse: 0 - }; - }; - - /** - * Generates a contact id. - * @method id - * @param {vertex} vertex - * @return {string} Unique contactID - */ - Contact.id = function(vertex) { - return vertex.body.id + '_' + vertex.index; - }; - -})(); - -},{}],5:[function(_dereq_,module,exports){ +},{"../constraint/Constraint":11,"../core/Common":13,"./Composite":2}],4:[function(_dereq_,module,exports){ /** * The `Matter.Detector` module contains methods for detecting collisions given a set of pairs. * @@ -2122,9 +2225,10 @@ var Bounds = _dereq_('../geometry/Bounds'); * @method collisions * @param {pair[]} broadphasePairs * @param {engine} engine + * @param {number} delta * @return {array} collisions */ - Detector.collisions = function(broadphasePairs, engine) { + Detector.collisions = function(broadphasePairs, engine, delta) { var collisions = [], pairsTable = engine.pairs.table; @@ -2161,7 +2265,7 @@ var Bounds = _dereq_('../geometry/Bounds'); } // narrow phase - var collision = SAT.collides(partA, partB, previousCollision); + var collision = SAT.collides(partA, partB, previousCollision, delta); if (collision.collided) { @@ -2193,7 +2297,7 @@ var Bounds = _dereq_('../geometry/Bounds'); })(); -},{"../geometry/Bounds":26,"./Pair":7,"./SAT":11}],6:[function(_dereq_,module,exports){ +},{"../geometry/Bounds":25,"./Pair":6,"./SAT":10}],5:[function(_dereq_,module,exports){ /** * The `Matter.Grid` module contains methods for creating and manipulating collision broadphase grid structures. * @@ -2509,7 +2613,7 @@ var Common = _dereq_('../core/Common'); })(); -},{"../core/Common":14,"./Detector":5,"./Pair":7}],7:[function(_dereq_,module,exports){ +},{"../core/Common":13,"./Detector":4,"./Pair":6}],6:[function(_dereq_,module,exports){ /** * The `Matter.Pair` module contains methods for creating and manipulating collision pairs. * @@ -2520,8 +2624,6 @@ var Pair = {}; module.exports = Pair; -var Contact = _dereq_('./Contact'); - (function() { /** @@ -2533,26 +2635,25 @@ var Contact = _dereq_('./Contact'); */ Pair.create = function(collision, timestamp) { var bodyA = collision.bodyA, - bodyB = collision.bodyB, - parentA = collision.parentA, - parentB = collision.parentB; + bodyB = collision.bodyB; var pair = { id: Pair.id(bodyA, bodyB), bodyA: bodyA, bodyB: bodyB, - contacts: {}, activeContacts: [], separation: 0, isActive: true, + confirmedActive: true, isSensor: bodyA.isSensor || bodyB.isSensor, timeCreated: timestamp, timeUpdated: timestamp, - inverseMass: parentA.inverseMass + parentB.inverseMass, - friction: Math.min(parentA.friction, parentB.friction), - frictionStatic: Math.max(parentA.frictionStatic, parentB.frictionStatic), - restitution: Math.max(parentA.restitution, parentB.restitution), - slop: Math.max(parentA.slop, parentB.slop) + collision: null, + inverseMass: 0, + friction: 0, + frictionStatic: 0, + restitution: 0, + slop: 0 }; Pair.update(pair, collision, timestamp); @@ -2568,31 +2669,28 @@ var Contact = _dereq_('./Contact'); * @param {number} timestamp */ Pair.update = function(pair, collision, timestamp) { - var contacts = pair.contacts, - supports = collision.supports, - activeContacts = pair.activeContacts, - parentA = collision.parentA, - parentB = collision.parentB; - pair.collision = collision; - pair.inverseMass = parentA.inverseMass + parentB.inverseMass; - pair.friction = Math.min(parentA.friction, parentB.friction); - pair.frictionStatic = Math.max(parentA.frictionStatic, parentB.frictionStatic); - pair.restitution = Math.max(parentA.restitution, parentB.restitution); - pair.slop = Math.max(parentA.slop, parentB.slop); - activeContacts.length = 0; - - if (collision.collided) { - for (var i = 0; i < supports.length; i++) { - var support = supports[i], - contactId = Contact.id(support), - contact = contacts[contactId]; - if (contact) { - activeContacts.push(contact); - } else { - activeContacts.push(contacts[contactId] = Contact.create(support)); - } + if (collision.collided) { + var supports = collision.supports, + activeContacts = pair.activeContacts, + parentA = collision.parentA, + parentB = collision.parentB; + + pair.inverseMass = parentA.inverseMass + parentB.inverseMass; + pair.friction = Math.min(parentA.friction, parentB.friction); + pair.frictionStatic = Math.max(parentA.frictionStatic, parentB.frictionStatic); + pair.restitution = Math.max(parentA.restitution, parentB.restitution); + pair.slop = Math.max(parentA.slop, parentB.slop); + + for (var i = 0; i < supports.length; i++) { + activeContacts[i] = supports[i].contact; + } + + // optimise array size + var supportCount = supports.length; + if (supportCount < activeContacts.length) { + activeContacts.length = supportCount; } pair.separation = collision.depth; @@ -2636,8 +2734,7 @@ var Contact = _dereq_('./Contact'); }; })(); - -},{"./Contact":4}],8:[function(_dereq_,module,exports){ +},{}],7:[function(_dereq_,module,exports){ /** * The `Matter.Pairs` module contains methods for creating and manipulating collision pair sets. * @@ -2684,7 +2781,6 @@ var Common = _dereq_('../core/Common'); collisionStart = pairs.collisionStart, collisionEnd = pairs.collisionEnd, collisionActive = pairs.collisionActive, - activePairIds = [], collision, pairId, pair, @@ -2695,12 +2791,15 @@ var Common = _dereq_('../core/Common'); collisionEnd.length = 0; collisionActive.length = 0; + for (i = 0; i < pairsList.length; i++) { + pairsList[i].confirmedActive = false; + } + for (i = 0; i < collisions.length; i++) { collision = collisions[i]; if (collision.collided) { pairId = Pair.id(collision.bodyA, collision.bodyB); - activePairIds.push(pairId); pair = pairsTable[pairId]; @@ -2716,6 +2815,7 @@ var Common = _dereq_('../core/Common'); // update the pair Pair.update(pair, collision, timestamp); + pair.confirmedActive = true; } else { // pair did not exist, create a new pair pair = Pair.create(collision, timestamp); @@ -2731,7 +2831,7 @@ var Common = _dereq_('../core/Common'); // deactivate previously active pairs that are now inactive for (i = 0; i < pairsList.length; i++) { pair = pairsList[i]; - if (pair.isActive && Common.indexOf(activePairIds, pair.id) === -1) { + if (pair.isActive && !pair.confirmedActive) { Pair.setActive(pair, false, timestamp); collisionEnd.push(pair); } @@ -2795,7 +2895,7 @@ var Common = _dereq_('../core/Common'); })(); -},{"../core/Common":14,"./Pair":7}],9:[function(_dereq_,module,exports){ +},{"../core/Common":13,"./Pair":6}],8:[function(_dereq_,module,exports){ /** * The `Matter.Query` module contains methods for performing collision queries. * @@ -2927,7 +3027,7 @@ var Vertices = _dereq_('../geometry/Vertices'); })(); -},{"../factory/Bodies":23,"../geometry/Bounds":26,"../geometry/Vector":28,"../geometry/Vertices":29,"./SAT":11}],10:[function(_dereq_,module,exports){ +},{"../factory/Bodies":22,"../geometry/Bounds":25,"../geometry/Vector":27,"../geometry/Vertices":28,"./SAT":10}],9:[function(_dereq_,module,exports){ /** * The `Matter.Resolver` module contains methods for resolving collision pairs. * @@ -2978,23 +3078,34 @@ var Bounds = _dereq_('../geometry/Bounds'); * Find a solution for pair positions. * @method solvePosition * @param {pair[]} pairs - * @param {number} timeScale + * @param {body[]} bodies + * @param {number} delta */ - Resolver.solvePosition = function(pairs, timeScale) { + Resolver.solvePosition = function(pairs, bodies, delta) { var i, + normalX, + normalY, pair, collision, bodyA, bodyB, normal, - bodyBtoA, + separation, + penetration, + positionImpulseA, + positionImpulseB, contactShare, + bodyBtoAX, + bodyBtoAY, positionImpulse, - contactCount = {}, - tempA = Vector._temp[0], - tempB = Vector._temp[1], - tempC = Vector._temp[2], - tempD = Vector._temp[3]; + timeScale = delta / Common._timeUnit, + impulseCoefficient = Resolver._positionDampen * timeScale; + + for (i = 0; i < bodies.length; i++) { + var body = bodies[i]; + body.previousPositionImpulse.x = body.positionImpulse.x; + body.previousPositionImpulse.y = body.positionImpulse.y; + } // find impulses required to resolve penetration for (i = 0; i < pairs.length; i++) { @@ -3008,39 +3119,35 @@ var Bounds = _dereq_('../geometry/Bounds'); bodyB = collision.parentB; normal = collision.normal; - // get current separation between body edges involved in collision - bodyBtoA = Vector.sub(Vector.add(bodyB.positionImpulse, bodyB.position, tempA), - Vector.add(bodyA.positionImpulse, - Vector.sub(bodyB.position, collision.penetration, tempB), tempC), tempD); + positionImpulseA = bodyA.previousPositionImpulse; + positionImpulseB = bodyB.previousPositionImpulse; - pair.separation = Vector.dot(normal, bodyBtoA); - } - - for (i = 0; i < pairs.length; i++) { - pair = pairs[i]; + penetration = collision.penetration; - if (!pair.isActive || pair.isSensor) - continue; - - collision = pair.collision; - bodyA = collision.parentA; - bodyB = collision.parentB; - normal = collision.normal; - positionImpulse = (pair.separation - pair.slop) * timeScale; + bodyBtoAX = positionImpulseB.x - positionImpulseA.x + penetration.x; + bodyBtoAY = positionImpulseB.y - positionImpulseA.y + penetration.y; + + normalX = normal.x; + normalY = normal.y; + + separation = normalX * bodyBtoAX + normalY * bodyBtoAY; + pair.separation = separation; + + positionImpulse = (separation - pair.slop) * impulseCoefficient; if (bodyA.isStatic || bodyB.isStatic) positionImpulse *= 2; if (!(bodyA.isStatic || bodyA.isSleeping)) { - contactShare = Resolver._positionDampen / bodyA.totalContacts; - bodyA.positionImpulse.x += normal.x * positionImpulse * contactShare; - bodyA.positionImpulse.y += normal.y * positionImpulse * contactShare; + contactShare = positionImpulse / bodyA.totalContacts; + bodyA.positionImpulse.x += normalX * contactShare; + bodyA.positionImpulse.y += normalY * contactShare; } if (!(bodyB.isStatic || bodyB.isSleeping)) { - contactShare = Resolver._positionDampen / bodyB.totalContacts; - bodyB.positionImpulse.x -= normal.x * positionImpulse * contactShare; - bodyB.positionImpulse.y -= normal.y * positionImpulse * contactShare; + contactShare = positionImpulse / bodyB.totalContacts; + bodyB.positionImpulse.x -= normalX * contactShare; + bodyB.positionImpulse.y -= normalY * contactShare; } } }; @@ -3155,10 +3262,12 @@ var Bounds = _dereq_('../geometry/Bounds'); * Find a solution for pair velocities. * @method solveVelocity * @param {pair[]} pairs - * @param {number} timeScale + * @param {number} delta */ - Resolver.solveVelocity = function(pairs, timeScale) { - var timeScaleSquared = timeScale * timeScale, + Resolver.solveVelocity = function(pairs, delta) { + var timeScale = delta / Common._timeUnit, + timeScale2 = timeScale * timeScale, + timeScale3 = timeScale2 * timeScale, impulse = Vector._temp[0], tempA = Vector._temp[1], tempB = Vector._temp[2], @@ -3211,10 +3320,10 @@ var Bounds = _dereq_('../geometry/Bounds'); var tangentImpulse = tangentVelocity, maxFriction = Infinity; - if (tangentSpeed > pair.friction * pair.frictionStatic * normalForce * timeScaleSquared) { - maxFriction = tangentSpeed; + if (tangentSpeed > pair.friction * pair.frictionStatic * normalForce * timeScale3) { + maxFriction = tangentSpeed * timeScale; tangentImpulse = Common.clamp( - pair.friction * tangentVelocityDirection * timeScaleSquared, + pair.friction * tangentVelocityDirection * timeScale3, -maxFriction, maxFriction ); } @@ -3228,7 +3337,7 @@ var Bounds = _dereq_('../geometry/Bounds'); tangentImpulse *= share; // handle high velocity and resting collisions separately - if (normalVelocity < 0 && normalVelocity * normalVelocity > Resolver._restingThresh * timeScaleSquared) { + if (normalVelocity < 0 && normalVelocity * normalVelocity > Resolver._restingThresh * timeScale2) { // high normal velocity so clear cached contact normal impulse contact.normalImpulse = 0; } else { @@ -3240,7 +3349,7 @@ var Bounds = _dereq_('../geometry/Bounds'); } // handle high velocity and resting collisions separately - if (tangentVelocity * tangentVelocity > Resolver._restingThreshTangent * timeScaleSquared) { + if (tangentVelocity * tangentVelocity > Resolver._restingThreshTangent * timeScale2) { // high tangent velocity so clear cached contact tangent impulse contact.tangentImpulse = 0; } else { @@ -3272,8 +3381,7 @@ var Bounds = _dereq_('../geometry/Bounds'); }; })(); - -},{"../core/Common":14,"../geometry/Bounds":26,"../geometry/Vector":28,"../geometry/Vertices":29}],11:[function(_dereq_,module,exports){ +},{"../core/Common":13,"../geometry/Bounds":25,"../geometry/Vector":27,"../geometry/Vertices":28}],10:[function(_dereq_,module,exports){ /** * The `Matter.SAT` module contains methods for detecting collisions using the Separating Axis Theorem. * @@ -3288,23 +3396,30 @@ module.exports = SAT; var Vertices = _dereq_('../geometry/Vertices'); var Vector = _dereq_('../geometry/Vector'); +var Common = _dereq_('../core/Common'); (function() { + SAT._reuseMotionThresh = 0.2; + /** * Detect collision between two bodies using the Separating Axis Theorem. * @method collides * @param {body} bodyA * @param {body} bodyB * @param {collision} previousCollision + * @param {number} [delta=0] * @return {collision} collision */ - SAT.collides = function(bodyA, bodyB, previousCollision) { + SAT.collides = function(bodyA, bodyB, previousCollision, delta) { var overlapAB, overlapBA, minOverlap, collision, - canReusePrevCol = false; + canReusePrevCol = false, + timeScale = delta / Common._timeUnit; + + delta = typeof delta !== 'undefined' ? delta : 0; if (previousCollision) { // estimate total motion @@ -3315,7 +3430,7 @@ var Vector = _dereq_('../geometry/Vector'); // we may be able to (partially) reuse collision result // but only safe if collision was resting - canReusePrevCol = previousCollision && previousCollision.collided && motion < 0.2; + canReusePrevCol = previousCollision && previousCollision.collided && motion < SAT._reuseMotionThresh * timeScale * timeScale; // reuse collision object collision = previousCollision; @@ -3545,7 +3660,7 @@ var Vector = _dereq_('../geometry/Vector'); })(); -},{"../geometry/Vector":28,"../geometry/Vertices":29}],12:[function(_dereq_,module,exports){ +},{"../core/Common":13,"../geometry/Vector":27,"../geometry/Vertices":28}],11:[function(_dereq_,module,exports){ /** * The `Matter.Constraint` module contains methods for creating and manipulating constraints. * Constraints are used for specifying that a fixed distance must be maintained between two bodies (or a body and a fixed world-space position). @@ -3658,9 +3773,11 @@ var Common = _dereq_('../core/Common'); * @private * @method solveAll * @param {constraint[]} constraints - * @param {number} timeScale + * @param {number} delta */ - Constraint.solveAll = function(constraints, timeScale) { + Constraint.solveAll = function(constraints, delta) { + var timeScale = Common.clamp(delta / Common._timeUnit, 0, 1); + // Solve fixed constraints first. for (var i = 0; i < constraints.length; i += 1) { var constraint = constraints[i], @@ -3731,7 +3848,9 @@ var Common = _dereq_('../core/Common'); // solve distance constraint with Gauss-Siedel method var difference = (currentLength - constraint.length) / currentLength, - stiffness = constraint.stiffness < 1 ? constraint.stiffness * timeScale : constraint.stiffness, + isRigid = constraint.stiffness >= 1 || constraint.length === 0, + stiffness = isRigid ? constraint.stiffness : constraint.stiffness * timeScale * timeScale, + damping = constraint.damping * timeScale, force = Vector.mult(delta, difference * stiffness), massTotal = (bodyA ? bodyA.inverseMass : 0) + (bodyB ? bodyB.inverseMass : 0), inertiaTotal = (bodyA ? bodyA.inverseInertia : 0) + (bodyB ? bodyB.inverseInertia : 0), @@ -3741,8 +3860,8 @@ var Common = _dereq_('../core/Common'); normal, normalVelocity, relativeVelocity; - - if (constraint.damping) { + + if (damping > 0) { var zero = Vector.create(); normal = Vector.div(delta, currentLength); @@ -3766,9 +3885,9 @@ var Common = _dereq_('../core/Common'); bodyA.position.y -= force.y * share; // apply damping - if (constraint.damping) { - bodyA.positionPrev.x -= constraint.damping * normal.x * normalVelocity * share; - bodyA.positionPrev.y -= constraint.damping * normal.y * normalVelocity * share; + if (damping > 0) { + bodyA.positionPrev.x -= damping * normal.x * normalVelocity * share; + bodyA.positionPrev.y -= damping * normal.y * normalVelocity * share; } // apply torque @@ -3789,9 +3908,9 @@ var Common = _dereq_('../core/Common'); bodyB.position.y += force.y * share; // apply damping - if (constraint.damping) { - bodyB.positionPrev.x += constraint.damping * normal.x * normalVelocity * share; - bodyB.positionPrev.y += constraint.damping * normal.y * normalVelocity * share; + if (damping > 0) { + bodyB.positionPrev.x += damping * normal.x * normalVelocity * share; + bodyB.positionPrev.y += damping * normal.y * normalVelocity * share; } // apply torque @@ -4000,7 +4119,7 @@ var Common = _dereq_('../core/Common'); })(); -},{"../core/Common":14,"../core/Sleeping":22,"../geometry/Axes":25,"../geometry/Bounds":26,"../geometry/Vector":28,"../geometry/Vertices":29}],13:[function(_dereq_,module,exports){ +},{"../core/Common":13,"../core/Sleeping":21,"../geometry/Axes":24,"../geometry/Bounds":25,"../geometry/Vector":27,"../geometry/Vertices":28}],12:[function(_dereq_,module,exports){ /** * The `Matter.MouseConstraint` module contains methods for creating mouse constraints. * Mouse constraints are used for allowing user interaction, providing the ability to move bodies via the mouse or touch. @@ -4263,7 +4382,7 @@ var Bounds = _dereq_('../geometry/Bounds'); })(); -},{"../body/Composite":2,"../collision/Detector":5,"../core/Common":14,"../core/Events":16,"../core/Mouse":19,"../core/Sleeping":22,"../geometry/Bounds":26,"../geometry/Vertices":29,"./Constraint":12}],14:[function(_dereq_,module,exports){ +},{"../body/Composite":2,"../collision/Detector":4,"../core/Common":13,"../core/Events":15,"../core/Mouse":18,"../core/Sleeping":21,"../geometry/Bounds":25,"../geometry/Vertices":28,"./Constraint":11}],13:[function(_dereq_,module,exports){ (function (global){ /** * The `Matter.Common` module contains utility functions that are common to all modules. @@ -4277,6 +4396,7 @@ module.exports = Common; (function() { + Common._timeUnit = 1000 / 60; Common._nextId = 0; Common._seed = 0; Common._nowStartTime = +(new Date()); @@ -4820,7 +4940,7 @@ module.exports = Common; })(); }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{}],15:[function(_dereq_,module,exports){ +},{}],14:[function(_dereq_,module,exports){ /** * The `Matter.Engine` module contains methods for creating and manipulating engines. * An engine is a controller that manages updating the simulation of the world. @@ -4917,35 +5037,29 @@ var Body = _dereq_('../body/Body'); /** * Moves the simulation forward in time by `delta` ms. - * The `correction` argument is an optional `Number` that specifies the time correction factor to apply to the update. - * This can help improve the accuracy of the simulation in cases where `delta` is changing between updates. - * The value of `correction` is defined as `delta / lastDelta`, i.e. the percentage change of `delta` over the last step. - * Therefore the value is always `1` (no correction) when `delta` constant (or when no correction is desired, which is the default). - * See the paper on Time Corrected Verlet for more information. - * * Triggers `beforeUpdate` and `afterUpdate` events. * Triggers `collisionStart`, `collisionActive` and `collisionEnd` events. * @method update * @param {engine} engine * @param {number} [delta=16.666] - * @param {number} [correction=1] */ - Engine.update = function(engine, delta, correction) { - delta = delta || 1000 / 60; - correction = correction || 1; - + Engine.update = function(engine, delta) { var world = engine.world, timing = engine.timing, broadphase = engine.broadphase, - broadphasePairs = [], + broadphasePairs, i; + delta = typeof delta !== 'undefined' ? delta : Common._timeUnit; + delta *= timing.timeScale; + // increment timestamp - timing.timestamp += delta * timing.timeScale; + timing.timestamp += delta; // create an event object var event = { - timestamp: timing.timestamp + timestamp: timing.timestamp, + delta: delta }; Events.trigger(engine, 'beforeUpdate', event); @@ -4957,18 +5071,20 @@ var Body = _dereq_('../body/Body'); // if sleeping enabled, call the sleeping controller if (engine.enableSleeping) - Sleeping.update(allBodies, timing.timeScale); + Sleeping.update(allBodies, delta); // applies gravity to all bodies Engine._bodiesApplyGravity(allBodies, world.gravity); // update all body position and rotation by integration - Engine._bodiesUpdate(allBodies, delta, timing.timeScale, correction, world.bounds); + if (delta > 0) { + Engine._bodiesUpdate(allBodies, delta); + } // update all constraints (first pass) Constraint.preSolveAll(allBodies); for (i = 0; i < engine.constraintIterations; i++) { - Constraint.solveAll(allConstraints, timing.timeScale); + Constraint.solveAll(allConstraints, delta); } Constraint.postSolveAll(allBodies); @@ -4992,7 +5108,7 @@ var Body = _dereq_('../body/Body'); } // narrowphase pass: find actual collisions, then create or update collision pairs - var collisions = broadphase.detector(broadphasePairs, engine); + var collisions = broadphase.detector(broadphasePairs, engine, delta); // update collision pairs var pairs = engine.pairs, @@ -5002,7 +5118,7 @@ var Body = _dereq_('../body/Body'); // wake up bodies involved in collisions if (engine.enableSleeping) - Sleeping.afterCollisions(pairs.list, timing.timeScale); + Sleeping.afterCollisions(pairs.list, delta); // trigger collision events if (pairs.collisionStart.length > 0) @@ -5011,21 +5127,21 @@ var Body = _dereq_('../body/Body'); // iteratively resolve position between collisions Resolver.preSolvePosition(pairs.list); for (i = 0; i < engine.positionIterations; i++) { - Resolver.solvePosition(pairs.list, timing.timeScale); + Resolver.solvePosition(pairs.list, allBodies, delta); } Resolver.postSolvePosition(allBodies); // update all constraints (second pass) Constraint.preSolveAll(allBodies); for (i = 0; i < engine.constraintIterations; i++) { - Constraint.solveAll(allConstraints, timing.timeScale); + Constraint.solveAll(allConstraints, delta); } Constraint.postSolveAll(allBodies); // iteratively resolve velocity between collisions Resolver.preSolveVelocity(pairs.list); for (i = 0; i < engine.velocityIterations; i++) { - Resolver.solveVelocity(pairs.list, timing.timeScale); + Resolver.solveVelocity(pairs.list, delta); } // trigger collision events @@ -5134,21 +5250,16 @@ var Body = _dereq_('../body/Body'); * @method _bodiesUpdate * @private * @param {body[]} bodies - * @param {number} deltaTime - * The amount of time elapsed between updates - * @param {number} timeScale - * @param {number} correction - * The Verlet correction factor (deltaTime / lastDeltaTime) - * @param {bounds} worldBounds + * @param {number} delta The amount of time elapsed between updates */ - Engine._bodiesUpdate = function(bodies, deltaTime, timeScale, correction, worldBounds) { + Engine._bodiesUpdate = function(bodies, delta) { for (var i = 0; i < bodies.length; i++) { var body = bodies[i]; if (body.isStatic || body.isSleeping) continue; - Body.update(body, deltaTime, timeScale, correction); + Body.update(body, delta); } }; @@ -5185,6 +5296,7 @@ var Body = _dereq_('../body/Body'); * @param {} event An event object * @param {} event.pairs List of affected pairs * @param {number} event.timestamp The engine.timing.timestamp of the event + * @param {number} event.delta The delta time in milliseconds value used in the update * @param {} event.source The source object of the event * @param {} event.name The name of the event */ @@ -5196,6 +5308,7 @@ var Body = _dereq_('../body/Body'); * @param {} event An event object * @param {} event.pairs List of affected pairs * @param {number} event.timestamp The engine.timing.timestamp of the event + * @param {number} event.delta The delta time in milliseconds value used in the update * @param {} event.source The source object of the event * @param {} event.name The name of the event */ @@ -5319,7 +5432,7 @@ var Body = _dereq_('../body/Body'); })(); -},{"../body/Body":1,"../body/Composite":2,"../body/World":3,"../collision/Grid":6,"../collision/Pairs":8,"../collision/Resolver":10,"../constraint/Constraint":12,"../render/Render":31,"./Common":14,"./Events":16,"./Metrics":18,"./Sleeping":22}],16:[function(_dereq_,module,exports){ +},{"../body/Body":1,"../body/Composite":2,"../body/World":3,"../collision/Grid":5,"../collision/Pairs":7,"../collision/Resolver":9,"../constraint/Constraint":11,"../render/Render":30,"./Common":13,"./Events":15,"./Metrics":17,"./Sleeping":21}],15:[function(_dereq_,module,exports){ /** * The `Matter.Events` module contains methods to fire and listen to events on other objects. * @@ -5406,7 +5519,9 @@ var Common = _dereq_('./Common'); callbacks, eventClone; - if (object.events) { + var events = object.events; + + if (events && Common.keys(events).length > 0) { if (!event) event = {}; @@ -5414,7 +5529,7 @@ var Common = _dereq_('./Common'); for (var i = 0; i < names.length; i++) { name = names[i]; - callbacks = object.events[name]; + callbacks = events[name]; if (callbacks) { eventClone = Common.clone(event, false); @@ -5431,7 +5546,7 @@ var Common = _dereq_('./Common'); })(); -},{"./Common":14}],17:[function(_dereq_,module,exports){ +},{"./Common":13}],16:[function(_dereq_,module,exports){ /** * The `Matter` module is the top level namespace. It also includes a function for installing plugins on top of the library. * @@ -5461,7 +5576,7 @@ var Common = _dereq_('./Common'); * @readOnly * @type {String} */ - Matter.version = '0.14.2'; + Matter.version = '0.14.2-alpha'; /** * A list of plugin dependencies to be installed. These are normally set and installed through `Matter.use`. @@ -5519,9 +5634,9 @@ var Common = _dereq_('./Common'); })(); -},{"./Common":14,"./Plugin":20}],18:[function(_dereq_,module,exports){ +},{"./Common":13,"./Plugin":19}],17:[function(_dereq_,module,exports){ -},{"../body/Composite":2,"./Common":14}],19:[function(_dereq_,module,exports){ +},{"../body/Composite":2,"./Common":13}],18:[function(_dereq_,module,exports){ /** * The `Matter.Mouse` module contains methods for creating and manipulating mouse inputs. * @@ -5558,7 +5673,7 @@ var Common = _dereq_('../core/Common'); mouse.scale = { x: 1, y: 1 }; mouse.wheelDelta = 0; mouse.button = -1; - mouse.pixelRatio = mouse.element.getAttribute('data-pixel-ratio') || 1; + mouse.pixelRatio = parseInt(mouse.element.getAttribute('data-pixel-ratio'), 10) || 1; mouse.sourceEvents = { mousemove: null, @@ -5724,7 +5839,7 @@ var Common = _dereq_('../core/Common'); })(); -},{"../core/Common":14}],20:[function(_dereq_,module,exports){ +},{"../core/Common":13}],19:[function(_dereq_,module,exports){ /** * The `Matter.Plugin` module contains functions for registering and installing plugins on modules. * @@ -6070,7 +6185,7 @@ var Common = _dereq_('./Common'); })(); -},{"./Common":14}],21:[function(_dereq_,module,exports){ +},{"./Common":13}],20:[function(_dereq_,module,exports){ /** * The `Matter.Runner` module is an optional utility which provides a game loop, * that handles continuously updating a `Matter.Engine` for you within a browser. @@ -6125,14 +6240,13 @@ var Common = _dereq_('./Common'); */ Runner.create = function(options) { var defaults = { + substeps: 1, fps: 60, - correction: 1, deltaSampleSize: 60, counterTimestamp: 0, frameCounter: 0, deltaHistory: [], timePrev: null, - timeScalePrev: 1, frameRequestId: null, isFixed: false, enabled: true @@ -6160,8 +6274,8 @@ var Common = _dereq_('./Common'); runner = Runner.create(); } - (function render(time){ - runner.frameRequestId = _requestAnimationFrame(render); + (function run(time){ + runner.frameRequestId = _requestAnimationFrame(run); if (time && runner.enabled) { Runner.tick(runner, engine, time); @@ -6173,7 +6287,7 @@ var Common = _dereq_('./Common'); /** * A game loop utility that updates the engine and renderer by one step (a 'tick'). - * Features delta smoothing, time correction and fixed or dynamic timing. + * Features delta smoothing and fixed or dynamic timing. * Triggers `beforeTick`, `tick` and `afterTick` events on the engine. * Consider just `Engine.update(engine, delta)` if you're using your own loop. * @method tick @@ -6183,17 +6297,8 @@ var Common = _dereq_('./Common'); */ Runner.tick = function(runner, engine, time) { var timing = engine.timing, - correction = 1, delta; - // create an event object - var event = { - timestamp: timing.timestamp - }; - - Events.trigger(runner, 'beforeTick', event); - Events.trigger(engine, 'beforeTick', event); // @deprecated - if (runner.isFixed) { // fixed timestep delta = runner.delta; @@ -6206,27 +6311,22 @@ var Common = _dereq_('./Common'); runner.deltaHistory.push(delta); runner.deltaHistory = runner.deltaHistory.slice(-runner.deltaSampleSize); delta = Math.min.apply(null, runner.deltaHistory); - + // limit delta delta = delta < runner.deltaMin ? runner.deltaMin : delta; delta = delta > runner.deltaMax ? runner.deltaMax : delta; - // correction for delta - correction = delta / runner.delta; - // update engine timing object runner.delta = delta; } - // time correction for time scaling - if (runner.timeScalePrev !== 0) - correction *= timing.timeScale / runner.timeScalePrev; + // create an event object + var event = { + timestamp: timing.timestamp + }; - if (timing.timeScale === 0) - correction = 0; - - runner.timeScalePrev = timing.timeScale; - runner.correction = correction; + Events.trigger(runner, 'beforeTick', event); + Events.trigger(engine, 'beforeTick', event); // @deprecated // fps counter runner.frameCounter += 1; @@ -6249,7 +6349,14 @@ var Common = _dereq_('./Common'); // update Events.trigger(runner, 'beforeUpdate', event); - Engine.update(engine, delta, correction); + + var substeps = runner.substeps, + subDelta = delta / substeps; + + for (var i = 0; i < substeps; i += 1) { + Engine.update(engine, subDelta); + } + Events.trigger(runner, 'afterUpdate', event); // render @@ -6380,6 +6487,16 @@ var Common = _dereq_('./Common'); * @default true */ + /** + * A `Number` integer that specifies the number of `Engine.update` calls made per-tick. + * Increasing the number of substeps improves accuracy at the cost of performance. + * By default `1` update is performed per tick with time `delta`. + * If `substeps > 1` then `substeps` updates are made with `delta` being `delta / substeps`. + * @property substeps + * @type number + * @default 1 + */ + /** * A `Boolean` that specifies if the runner should use a fixed timestep (otherwise it is variable). * If timing is fixed, then the apparent simulation speed will change depending on the frame rate (but behaviour will be deterministic). @@ -6402,7 +6519,7 @@ var Common = _dereq_('./Common'); })(); -},{"./Common":14,"./Engine":15,"./Events":16}],22:[function(_dereq_,module,exports){ +},{"./Common":13,"./Engine":14,"./Events":15}],21:[function(_dereq_,module,exports){ /** * The `Matter.Sleeping` module contains methods to manage the sleeping state of bodies. * @@ -6414,6 +6531,7 @@ var Sleeping = {}; module.exports = Sleeping; var Events = _dereq_('./Events'); +var Common = _dereq_('./Common'); (function() { @@ -6425,11 +6543,11 @@ var Events = _dereq_('./Events'); * Puts bodies to sleep or wakes them up depending on their motion. * @method update * @param {body[]} bodies - * @param {number} timeScale + * @param {number} delta */ - Sleeping.update = function(bodies, timeScale) { - var timeFactor = timeScale * timeScale * timeScale; - + Sleeping.update = function(bodies, delta) { + var timeScale = delta / Common._timeUnit; + // update bodies sleeping status for (var i = 0; i < bodies.length; i++) { var body = bodies[i], @@ -6446,11 +6564,11 @@ var Events = _dereq_('./Events'); // biased average motion estimation between frames body.motion = Sleeping._minBias * minMotion + (1 - Sleeping._minBias) * maxMotion; - - if (body.sleepThreshold > 0 && body.motion < Sleeping._motionSleepThreshold * timeFactor) { + + if (body.sleepThreshold > 0 && body.motion < Sleeping._motionSleepThreshold * timeScale * timeScale) { body.sleepCounter += 1; - if (body.sleepCounter >= body.sleepThreshold) + if (body.sleepCounter >= body.sleepThreshold / timeScale) Sleeping.set(body, true); } else if (body.sleepCounter > 0) { body.sleepCounter -= 1; @@ -6462,10 +6580,10 @@ var Events = _dereq_('./Events'); * Given a set of colliding pairs, wakes the sleeping bodies involved. * @method afterCollisions * @param {pair[]} pairs - * @param {number} timeScale + * @param {number} delta */ - Sleeping.afterCollisions = function(pairs, timeScale) { - var timeFactor = timeScale * timeScale * timeScale; + Sleeping.afterCollisions = function(pairs, delta) { + var timeScale = delta / Common._timeUnit; // wake up bodies involved in collisions for (var i = 0; i < pairs.length; i++) { @@ -6487,7 +6605,7 @@ var Events = _dereq_('./Events'); var sleepingBody = (bodyA.isSleeping && !bodyA.isStatic) ? bodyA : bodyB, movingBody = sleepingBody === bodyA ? bodyB : bodyA; - if (!sleepingBody.isStatic && movingBody.motion > Sleeping._motionWakeThreshold * timeFactor) { + if (!sleepingBody.isStatic && movingBody.motion > Sleeping._motionWakeThreshold * timeScale * timeScale) { Sleeping.set(sleepingBody, false); } } @@ -6533,7 +6651,7 @@ var Events = _dereq_('./Events'); })(); -},{"./Events":16}],23:[function(_dereq_,module,exports){ +},{"./Common":13,"./Events":15}],22:[function(_dereq_,module,exports){ /** * The `Matter.Bodies` module contains factory methods for creating rigid body models * with commonly used body configurations (such as rectangles, circles and other polygons). @@ -6870,7 +6988,7 @@ var decomp; })(); -},{"../body/Body":1,"../core/Common":14,"../geometry/Bounds":26,"../geometry/Vector":28,"../geometry/Vertices":29}],24:[function(_dereq_,module,exports){ +},{"../body/Body":1,"../core/Common":13,"../geometry/Bounds":25,"../geometry/Vector":27,"../geometry/Vertices":28}],23:[function(_dereq_,module,exports){ /** * The `Matter.Composites` module contains factory methods for creating composite bodies * with commonly used configurations (such as stacks and chains). @@ -7199,7 +7317,7 @@ var Bodies = _dereq_('./Bodies'); })(); -},{"../body/Body":1,"../body/Composite":2,"../constraint/Constraint":12,"../core/Common":14,"./Bodies":23}],25:[function(_dereq_,module,exports){ +},{"../body/Body":1,"../body/Composite":2,"../constraint/Constraint":11,"../core/Common":13,"./Bodies":22}],24:[function(_dereq_,module,exports){ /** * The `Matter.Axes` module contains methods for creating and manipulating sets of axes. * @@ -7265,7 +7383,7 @@ var Common = _dereq_('../core/Common'); })(); -},{"../core/Common":14,"../geometry/Vector":28}],26:[function(_dereq_,module,exports){ +},{"../core/Common":13,"../geometry/Vector":27}],25:[function(_dereq_,module,exports){ /** * The `Matter.Bounds` module contains methods for creating and manipulating axis-aligned bounding boxes (AABB). * @@ -7387,7 +7505,7 @@ module.exports = Bounds; })(); -},{}],27:[function(_dereq_,module,exports){ +},{}],26:[function(_dereq_,module,exports){ /** * The `Matter.Svg` module contains methods for converting SVG images into an array of vector points. * @@ -7614,7 +7732,7 @@ var Common = _dereq_('../core/Common'); }; })(); -},{"../core/Common":14,"../geometry/Bounds":26}],28:[function(_dereq_,module,exports){ +},{"../core/Common":13,"../geometry/Bounds":25}],27:[function(_dereq_,module,exports){ /** * The `Matter.Vector` module contains methods for creating and manipulating vectors. * Vectors are the basis of all the geometry related operations in the engine. @@ -7854,7 +7972,7 @@ module.exports = Vector; ]; })(); -},{}],29:[function(_dereq_,module,exports){ +},{}],28:[function(_dereq_,module,exports){ /** * The `Matter.Vertices` module contains methods for creating and manipulating sets of vertices. * A set of vertices is an array of `Matter.Vector` with additional indexing properties inserted by `Vertices.create`. @@ -7901,9 +8019,16 @@ var Common = _dereq_('../core/Common'); y: point.y, index: i, body: body, - isInternal: false + isInternal: false, + contact: null }; + vertex.contact = { + vertex: vertex, + normalImpulse: 0, + tangentImpulse: 0 + }; + vertices.push(vertex); } @@ -8302,15 +8427,13 @@ var Common = _dereq_('../core/Common'); }; })(); - -},{"../core/Common":14,"../geometry/Vector":28}],30:[function(_dereq_,module,exports){ +},{"../core/Common":13,"../geometry/Vector":27}],29:[function(_dereq_,module,exports){ var Matter = module.exports = _dereq_('../core/Matter'); Matter.Body = _dereq_('../body/Body'); Matter.Composite = _dereq_('../body/Composite'); Matter.World = _dereq_('../body/World'); -Matter.Contact = _dereq_('../collision/Contact'); Matter.Detector = _dereq_('../collision/Detector'); Matter.Grid = _dereq_('../collision/Grid'); Matter.Pairs = _dereq_('../collision/Pairs'); @@ -8353,7 +8476,7 @@ Matter.World.addConstraint = Matter.Composite.addConstraint; Matter.World.clear = Matter.Composite.clear; Matter.Engine.run = Matter.Runner.run; -},{"../body/Body":1,"../body/Composite":2,"../body/World":3,"../collision/Contact":4,"../collision/Detector":5,"../collision/Grid":6,"../collision/Pair":7,"../collision/Pairs":8,"../collision/Query":9,"../collision/Resolver":10,"../collision/SAT":11,"../constraint/Constraint":12,"../constraint/MouseConstraint":13,"../core/Common":14,"../core/Engine":15,"../core/Events":16,"../core/Matter":17,"../core/Metrics":18,"../core/Mouse":19,"../core/Plugin":20,"../core/Runner":21,"../core/Sleeping":22,"../factory/Bodies":23,"../factory/Composites":24,"../geometry/Axes":25,"../geometry/Bounds":26,"../geometry/Svg":27,"../geometry/Vector":28,"../geometry/Vertices":29,"../render/Render":31,"../render/RenderPixi":32}],31:[function(_dereq_,module,exports){ +},{"../body/Body":1,"../body/Composite":2,"../body/World":3,"../collision/Detector":4,"../collision/Grid":5,"../collision/Pair":6,"../collision/Pairs":7,"../collision/Query":8,"../collision/Resolver":9,"../collision/SAT":10,"../constraint/Constraint":11,"../constraint/MouseConstraint":12,"../core/Common":13,"../core/Engine":14,"../core/Events":15,"../core/Matter":16,"../core/Metrics":17,"../core/Mouse":18,"../core/Plugin":19,"../core/Runner":20,"../core/Sleeping":21,"../factory/Bodies":22,"../factory/Composites":23,"../geometry/Axes":24,"../geometry/Bounds":25,"../geometry/Svg":26,"../geometry/Vector":27,"../geometry/Vertices":28,"../render/Render":30,"../render/RenderPixi":31}],30:[function(_dereq_,module,exports){ /** * The `Matter.Render` module is a simple HTML5 canvas based renderer for visualising instances of `Matter.Engine`. * It is intended for development and debugging purposes, but may also be suitable for simple games. @@ -8511,7 +8634,6 @@ var Mouse = _dereq_('../core/Mouse'); canvas.height = options.height * pixelRatio; canvas.style.width = options.width + 'px'; canvas.style.height = options.height + 'px'; - render.context.scale(pixelRatio, pixelRatio); }; /** @@ -8623,7 +8745,11 @@ var Mouse = _dereq_('../core/Mouse'); boundsScaleX = boundsWidth / render.options.width, boundsScaleY = boundsHeight / render.options.height; - render.context.scale(1 / boundsScaleX, 1 / boundsScaleY); + render.context.setTransform( + render.options.pixelRatio / boundsScaleX, 0, 0, + render.options.pixelRatio / boundsScaleY, 0, 0 + ); + render.context.translate(-render.bounds.min.x, -render.bounds.min.y); }; @@ -8704,8 +8830,8 @@ var Mouse = _dereq_('../core/Mouse'); // update mouse if (render.mouse) { Mouse.setScale(render.mouse, { - x: (render.bounds.max.x - render.bounds.min.x) / render.canvas.width, - y: (render.bounds.max.y - render.bounds.min.y) / render.canvas.height + x: (render.bounds.max.x - render.bounds.min.x) / render.options.width, + y: (render.bounds.max.y - render.bounds.min.y) / render.options.height }); Mouse.setOffset(render.mouse, render.bounds.min); @@ -8713,6 +8839,10 @@ var Mouse = _dereq_('../core/Mouse'); } else { constraints = allConstraints; bodies = allBodies; + + if (render.options.pixelRatio !== 1) { + render.context.setTransform(render.options.pixelRatio, 0, 0, render.options.pixelRatio, 0, 0); + } } if (!options.wireframes || (engine.enableSleeping && options.showSleeping)) { @@ -9840,7 +9970,7 @@ var Mouse = _dereq_('../core/Mouse'); })(); -},{"../body/Composite":2,"../collision/Grid":6,"../core/Common":14,"../core/Events":16,"../core/Mouse":19,"../geometry/Bounds":26,"../geometry/Vector":28}],32:[function(_dereq_,module,exports){ +},{"../body/Composite":2,"../collision/Grid":5,"../core/Common":13,"../core/Events":15,"../core/Mouse":18,"../geometry/Bounds":25,"../geometry/Vector":27}],31:[function(_dereq_,module,exports){ /** * The `Matter.RenderPixi` module is an example renderer using pixi.js. * See also `Matter.Render` for a canvas based renderer. @@ -10357,5 +10487,5 @@ var Vector = _dereq_('../geometry/Vector'); })(); -},{"../body/Composite":2,"../core/Common":14,"../core/Events":16,"../geometry/Bounds":26,"../geometry/Vector":28}]},{},[30])(30) +},{"../body/Composite":2,"../core/Common":13,"../core/Events":15,"../geometry/Bounds":25,"../geometry/Vector":27}]},{},[29])(29) }); diff --git a/build/matter.min.js b/build/matter.min.js index 8255c59..134e9a3 100644 --- a/build/matter.min.js +++ b/build/matter.min.js @@ -1,96 +1,97 @@ /** -* matter-js 0.14.2 by @liabru 2018-06-11 +* matter-js 0.14.2-alpha by @liabru 2019-09-01 * http://brm.io/matter-js/ * License MIT */ -!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;t="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,t.Matter=e()}}(function(){return function(){function e(t,n,o){function i(s,a){if(!n[s]){if(!t[s]){var l="function"==typeof require&&require;if(!a&&l)return l(s,!0);if(r)return r(s,!0);var c=new Error("Cannot find module '"+s+"'");throw c.code="MODULE_NOT_FOUND",c}var d=n[s]={exports:{}};t[s][0].call(d.exports,function(e){return i(t[s][1][e]||e)},d,d.exports,e,t,n,o)}return n[s].exports}for(var r="function"==typeof require&&require,s=0;s0&&r.rotateAbout(s.position,n,e.position,s.position)}},o.setVelocity=function(e,t){e.positionPrev.x=e.position.x-t.x,e.positionPrev.y=e.position.y-t.y, -e.velocity.x=t.x,e.velocity.y=t.y,e.speed=r.magnitude(e.velocity)},o.setAngularVelocity=function(e,t){e.anglePrev=e.angle-t,e.angularVelocity=t,e.angularSpeed=Math.abs(e.angularVelocity)},o.translate=function(e,t){o.setPosition(e,r.add(e.position,t))},o.rotate=function(e,t,n){if(n){var i=Math.cos(t),r=Math.sin(t),s=e.position.x-n.x,a=e.position.y-n.y;o.setPosition(e,{x:n.x+(s*i-a*r),y:n.y+(s*r+a*i)}),o.setAngle(e,e.angle+t)}else o.setAngle(e,e.angle+t)},o.scale=function(e,t,n,r){var s=0,a=0;r=r||e.position;for(var d=0;d0&&(s+=u.area,a+=u.inertia),u.position.x=r.x+(u.position.x-r.x)*t,u.position.y=r.y+(u.position.y-r.y)*n,l.update(u.bounds,u.vertices,e.velocity) -}e.parts.length>1&&(e.area=s,e.isStatic||(o.setMass(e,e.density*s),o.setInertia(e,a))),e.circleRadius&&(t===n?e.circleRadius*=t:e.circleRadius=null)},o.update=function(e,t,n,o){var s=Math.pow(t*n*e.timeScale,2),a=1-e.frictionAir*n*e.timeScale,d=e.position.x-e.positionPrev.x,u=e.position.y-e.positionPrev.y;e.velocity.x=d*a*o+e.force.x/e.mass*s,e.velocity.y=u*a*o+e.force.y/e.mass*s,e.positionPrev.x=e.position.x,e.positionPrev.y=e.position.y,e.position.x+=e.velocity.x,e.position.y+=e.velocity.y,e.angularVelocity=(e.angle-e.anglePrev)*a*o+e.torque/e.inertia*s,e.anglePrev=e.angle,e.angle+=e.angularVelocity,e.speed=r.magnitude(e.velocity),e.angularSpeed=Math.abs(e.angularVelocity);for(var p=0;p0&&(f.position.x+=e.velocity.x,f.position.y+=e.velocity.y),0!==e.angularVelocity&&(i.rotate(f.vertices,e.angularVelocity,e.position),c.rotate(f.axes,e.angularVelocity), -p>0&&r.rotateAbout(f.position,e.angularVelocity,e.position,f.position)),l.update(f.bounds,f.vertices,e.velocity)}},o.applyForce=function(e,t,n){e.force.x+=n.x,e.force.y+=n.y;var o={x:t.x-e.position.x,y:t.y-e.position.y};e.torque+=o.x*n.y-o.y*n.x},o._totalProperties=function(e){for(var t={mass:0,area:0,inertia:0,centre:{x:0,y:0}},n=1===e.parts.length?0:1;n1?1:0;u1?1:0;f0:0!=(e.mask&t.category)&&0!=(t.mask&e.category)}}()},{"../geometry/Bounds":26,"./Pair":7,"./SAT":11}],6:[function(e,t,n){var o={};t.exports=o;var i=e("./Pair"),r=e("./Detector"),s=e("../core/Common");!function(){o.create=function(e){var t={controller:o,detector:r.collisions,buckets:{},pairs:{},pairsList:[],bucketWidth:48,bucketHeight:48};return s.extend(t,e)},o.update=function(e,t,n,i){ -var r,s,a,l,c,d=n.world,u=e.buckets,p=!1;for(r=0;rd.bounds.max.x||f.bounds.max.yd.bounds.max.y)){var m=o._getRegion(e,f);if(!f.region||m.id!==f.region.id||i){f.region&&!i||(f.region=m);var v=o._regionUnion(m,f.region);for(s=v.startCol;s<=v.endCol;s++)for(a=v.startRow;a<=v.endRow;a++){c=o._getBucketId(s,a),l=u[c];var y=s>=m.startCol&&s<=m.endCol&&a>=m.startRow&&a<=m.endRow,g=s>=f.region.startCol&&s<=f.region.endCol&&a>=f.region.startRow&&a<=f.region.endRow;!y&&g&&g&&l&&o._bucketRemoveBody(e,l,f),(f.region===m||y&&!g||i)&&(l||(l=o._createBucket(u,c)),o._bucketAddBody(e,l,f))}f.region=m,p=!0}}}p&&(e.pairsList=o._createActivePairsList(e))},o.clear=function(e){e.buckets={},e.pairs={},e.pairsList=[]},o._regionUnion=function(e,t){var n=Math.min(e.startCol,t.startCol),i=Math.max(e.endCol,t.endCol),r=Math.min(e.startRow,t.startRow),s=Math.max(e.endRow,t.endRow) -;return o._createRegion(n,i,r,s)},o._getRegion=function(e,t){var n=t.bounds,i=Math.floor(n.min.x/e.bucketWidth),r=Math.floor(n.max.x/e.bucketWidth),s=Math.floor(n.min.y/e.bucketHeight),a=Math.floor(n.max.y/e.bucketHeight);return o._createRegion(i,r,s,a)},o._createRegion=function(e,t,n,o){return{id:e+","+t+","+n+","+o,startCol:e,endCol:t,startRow:n,endRow:o}},o._getBucketId=function(e,t){return"C"+e+"R"+t},o._createBucket=function(e,t){return e[t]=[]},o._bucketAddBody=function(e,t,n){for(var o=0;o0?o.push(n):delete e.pairs[t[i]];return o}}()},{"../core/Common":14,"./Detector":5,"./Pair":7}], -7:[function(e,t,n){var o={};t.exports=o;var i=e("./Contact");!function(){o.create=function(e,t){var n=e.bodyA,i=e.bodyB,r=e.parentA,s=e.parentB,a={id:o.id(n,i),bodyA:n,bodyB:i,contacts:{},activeContacts:[],separation:0,isActive:!0,isSensor:n.isSensor||i.isSensor,timeCreated:t,timeUpdated:t,inverseMass:r.inverseMass+s.inverseMass,friction:Math.min(r.friction,s.friction),frictionStatic:Math.max(r.frictionStatic,s.frictionStatic),restitution:Math.max(r.restitution,s.restitution),slop:Math.max(r.slop,s.slop)};return o.update(a,e,t),a},o.update=function(e,t,n){var r=e.contacts,s=t.supports,a=e.activeContacts,l=t.parentA,c=t.parentB;if(e.collision=t,e.inverseMass=l.inverseMass+c.inverseMass,e.friction=Math.min(l.friction,c.friction),e.frictionStatic=Math.max(l.frictionStatic,c.frictionStatic),e.restitution=Math.max(l.restitution,c.restitution),e.slop=Math.max(l.slop,c.slop),a.length=0,t.collided){for(var d=0;do._pairMaxIdleLife&&c.push(s);for(s=0;sf.friction*f.frictionStatic*E*n&&(F=T,L=s.clamp(f.friction*R*n,-F,F));var O=r.cross(A,g),q=r.cross(P,g),W=b/(v.inverseMass+y.inverseMass+v.inverseInertia*O*O+y.inverseInertia*q*q);if(V*=W,L*=W,I<0&&I*I>o._restingThresh*n)S.normalImpulse=0;else{var D=S.normalImpulse;S.normalImpulse=Math.min(S.normalImpulse+V,0),V=S.normalImpulse-D}if(_*_>o._restingThreshTangent*n)S.tangentImpulse=0;else{var N=S.tangentImpulse;S.tangentImpulse=s.clamp(S.tangentImpulse+L,-F,F),L=S.tangentImpulse-N}i.x=g.x*V+x.x*L,i.y=g.y*V+x.y*L,v.isStatic||v.isSleeping||(v.positionPrev.x+=i.x*v.inverseMass,v.positionPrev.y+=i.y*v.inverseMass, -v.anglePrev+=r.cross(A,i)*v.inverseInertia),y.isStatic||y.isSleeping||(y.positionPrev.x-=i.x*y.inverseMass,y.positionPrev.y-=i.y*y.inverseMass,y.anglePrev-=r.cross(P,i)*y.inverseInertia)}}}}}()},{"../core/Common":14,"../geometry/Bounds":26,"../geometry/Vector":28,"../geometry/Vertices":29}],11:[function(e,t,n){var o={};t.exports=o;var i=e("../geometry/Vertices"),r=e("../geometry/Vector");!function(){o.collides=function(e,t,n){var s,a,l,c,d=!1;if(n){var u=e.parent,p=t.parent,f=u.speed*u.speed+u.angularSpeed*u.angularSpeed+p.speed*p.speed+p.angularSpeed*p.angularSpeed;d=n&&n.collided&&f<.2,c=n}else c={collided:!1,bodyA:e,bodyB:t};if(n&&d){var m=c.axisBody,v=m===e?t:e,y=[m.axes[n.axisNumber]];if(l=o._overlapAxes(m.vertices,v.vertices,y),c.reused=!0,l.overlap<=0)return c.collided=!1,c}else{if(s=o._overlapAxes(e.vertices,t.vertices,e.axes),s.overlap<=0)return c.collided=!1,c;if(a=o._overlapAxes(t.vertices,e.vertices,t.axes),a.overlap<=0)return c.collided=!1,c;s.overlapi?i=a:a=0?s.index-1:d.length-1],c.x=i.x-u.x,c.y=i.y-u.y,l=-r.dot(n,c),a=i,i=d[(s.index+1)%d.length],c.x=i.x-u.x,c.y=i.y-u.y,o=-r.dot(n,c),o0?1:.7),t.damping=t.damping||0,t.angularStiffness=t.angularStiffness||0,t.angleA=t.bodyA?t.bodyA.angle:t.angleA,t.angleB=t.bodyB?t.bodyB.angle:t.angleB,t.plugin={};var s={visible:!0,lineWidth:2,strokeStyle:"#ffffff",type:"line",anchors:!0};return 0===t.length&&t.stiffness>.1?(s.type="pin",s.anchors=!1):t.stiffness<.9&&(s.type="spring"),t.render=c.extend(s,t.render),t},o.preSolveAll=function(e){for(var t=0;t0&&(u.position.x+=c.x,u.position.y+=c.y),0!==c.angle&&(i.rotate(u.vertices,c.angle,n.position),l.rotate(u.axes,c.angle), -d>0&&r.rotateAbout(u.position,c.angle,n.position,u.position)),a.update(u.bounds,u.vertices,n.velocity)}c.angle*=o._warming,c.x*=o._warming,c.y*=o._warming}}}}()},{"../core/Common":14,"../core/Sleeping":22,"../geometry/Axes":25,"../geometry/Bounds":26,"../geometry/Vector":28,"../geometry/Vertices":29}],13:[function(e,t,n){var o={};t.exports=o;var i=e("../geometry/Vertices"),r=e("../core/Sleeping"),s=e("../core/Mouse"),a=e("../core/Events"),l=e("../collision/Detector"),c=e("./Constraint"),d=e("../body/Composite"),u=e("../core/Common"),p=e("../geometry/Bounds");!function(){o.create=function(e,t){var n=(e?e.mouse:null)||(t?t.mouse:null);n||(e&&e.render&&e.render.canvas?n=s.create(e.render.canvas):t&&t.element?n=s.create(t.element):(n=s.create(),u.warn("MouseConstraint.create: options.mouse was undefined, options.element was undefined, may not function as expected")));var i=c.create({label:"Mouse Constraint",pointA:n.position,pointB:{x:0,y:0},length:.01,stiffness:.1,angularStiffness:1, -render:{strokeStyle:"#90EE90",lineWidth:3}}),r={type:"mouseConstraint",mouse:n,element:null,body:null,constraint:i,collisionFilter:{category:1,mask:4294967295,group:0}},l=u.extend(r,t);return a.on(e,"beforeUpdate",function(){var t=d.allBodies(e.world);o.update(l,t),o._triggerEvents(l)}),l},o.update=function(e,t){var n=e.mouse,o=e.constraint,s=e.body;if(0===n.button){if(o.bodyB)r.set(o.bodyB,!1),o.pointA=n.position;else for(var c=0;c1?1:0;d0;t--){var n=Math.floor(o.random()*(t+1)),i=e[t];e[t]=e[n],e[n]=i}return e},o.choose=function(e){return e[Math.floor(o.random()*e.length)]},o.isElement=function(e){return"undefined"!=typeof HTMLElement?e instanceof HTMLElement:!!(e&&e.nodeType&&e.nodeName)},o.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)},o.isFunction=function(e){return"function"==typeof e},o.isPlainObject=function(e){return"object"==typeof e&&e.constructor===Object},o.isString=function(e){return"[object String]"===toString.call(e)},o.clamp=function(e,t,n){return en?n:e},o.sign=function(e){return e<0?-1:1},o.now=function(){ -if(window.performance){if(window.performance.now)return window.performance.now();if(window.performance.webkitNow)return window.performance.webkitNow()}return new Date-o._nowStartTime},o.random=function(e,n){return e=void 0!==e?e:0,n=void 0!==n?n:1,e+t()*(n-e)};var t=function(){return o._seed=(9301*o._seed+49297)%233280,o._seed/233280};o.colorToNumber=function(e){return e=e.replace("#",""),3==e.length&&(e=e.charAt(0)+e.charAt(0)+e.charAt(1)+e.charAt(1)+e.charAt(2)+e.charAt(2)),parseInt(e,16)},o.logLevel=1,o.log=function(){console&&o.logLevel>0&&o.logLevel<=3&&console.log.apply(console,["matter-js:"].concat(Array.prototype.slice.call(arguments)))},o.info=function(){console&&o.logLevel>0&&o.logLevel<=2&&console.info.apply(console,["matter-js:"].concat(Array.prototype.slice.call(arguments)))},o.warn=function(){console&&o.logLevel>0&&o.logLevel<=3&&console.warn.apply(console,["matter-js:"].concat(Array.prototype.slice.call(arguments)))},o.nextId=function(){return o._nextId++}, -o.indexOf=function(e,t){if(e.indexOf)return e.indexOf(t);for(var n=0;n0&&d.trigger(e,"collisionStart",{pairs:h.collisionStart}),s.preSolvePosition(h.list),i=0;i0&&d.trigger(e,"collisionActive",{pairs:h.collisionActive}),h.collisionEnd.length>0&&d.trigger(e,"collisionEnd",{pairs:h.collisionEnd}),o._bodiesClearForces(y),d.trigger(e,"afterUpdate",v),e},o.merge=function(e,t){if(f.extend(e,t),t.world){e.world=t.world,o.clear(e);for(var n=u.allBodies(e.world),i=0;ir?(i.warn("Plugin.register:",o.toString(t),"was upgraded to",o.toString(e)),o._registry[e.name]=e):n-1},o.isFor=function(e,t){var n=e.for&&o.dependencyParse(e.for) -;return!e.for||t.name===n.name&&o.versionSatisfies(t.version,n.range)},o.use=function(e,t){if(e.uses=(e.uses||[]).concat(t||[]),0===e.uses.length)return void i.warn("Plugin.use:",o.toString(e),"does not specify any dependencies to install.");for(var n=o.dependencies(e),r=i.topologicalSort(n),s=[],a=0;a0&&i.info(s.join(" "))},o.dependencies=function(e,t){var n=o.dependencyParse(e),r=n.name;if(t=t||{},!(r in t)){e=o.resolve(e)||e,t[r]=i.map(e.uses||[],function(t){o.isPlugin(t)&&o.register(t);var r=o.dependencyParse(t),s=o.resolve(t) +!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;t="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,t.Matter=e()}}(function(){return function(){function e(t,n,o){function i(s,a){if(!n[s]){if(!t[s]){var l="function"==typeof require&&require;if(!a&&l)return l(s,!0);if(r)return r(s,!0);var c=new Error("Cannot find module '"+s+"'");throw c.code="MODULE_NOT_FOUND",c}var u=n[s]={exports:{}};t[s][0].call(u.exports,function(e){return i(t[s][1][e]||e)},u,u.exports,e,t,n,o)}return n[s].exports}for(var r="function"==typeof require&&require,s=0;s0&&r.rotateAbout(a.position,o,e.position,a.position)}},o.setVelocity=function(e,t){var n=e.deltaTime/a._timeUnit;e.positionPrev.x=e.position.x-t.x*n,e.positionPrev.y=e.position.y-t.y*n,e.velocity.x=t.x*n,e.velocity.y=t.y*n,e.speed=r.magnitude(e.velocity)},o.getVelocity=function(e){var t=a._timeUnit/e.deltaTime;return{x:(e.position.x-e.positionPrev.x)*t,y:(e.position.y-e.positionPrev.y)*t}},o.getSpeed=function(e){return r.magnitude(o.getVelocity(e))},o.setSpeed=function(e,t){ +o.setVelocity(e,r.mult(r.normalise(o.getVelocity(e)),t))},o.setAngularVelocity=function(e,t){var n=e.deltaTime/a._timeUnit;e.anglePrev=e.angle-t*n,e.angularVelocity=t*n,e.angularSpeed=Math.abs(e.angularVelocity)},o.getAngularVelocity=function(e){return(e.angle-e.anglePrev)*a._timeUnit/e.deltaTime},o.getAngularSpeed=function(e){return Math.abs(o.getAngularVelocity(e))},o.setAngularSpeed=function(e,t){o.setAngularVelocity(e,a.sign(o.getAngularVelocity(e))*t)},o.translate=function(e,t,n){o.setPosition(e,r.add(e.position,t),n)},o.rotate=function(e,t,n,i){if(n){var r=Math.cos(t),s=Math.sin(t),a=e.position.x-n.x,l=e.position.y-n.y;o.setPosition(e,{x:n.x+(a*r-l*s),y:n.y+(a*s+l*r)},i),o.setAngle(e,e.angle+t,i)}else o.setAngle(e,e.angle+t,i)},o.scale=function(e,t,n,r){var s=0,a=0;r=r||e.position;for(var u=0;u0&&(s+=d.area,a+=d.inertia),d.position.x=r.x+(d.position.x-r.x)*t,d.position.y=r.y+(d.position.y-r.y)*n,l.update(d.bounds,d.vertices,e.velocity)}e.parts.length>1&&(e.area=s,e.isStatic||(o.setMass(e,e.density*s),o.setInertia(e,a))),e.circleRadius&&(t===n?e.circleRadius*=t:e.circleRadius=null)},o.update=function(e,t){t=(void 0!==t?t:a._timeUnit)*e.timeScale;var n=t*t,s=o._timeCorrection?t/(e.deltaTime||t):1,u=1-e.frictionAir*(t/a._timeUnit),d=(e.position.x-e.positionPrev.x)*s,p=(e.position.y-e.positionPrev.y)*s;e.velocity.x=d*u+e.force.x/e.mass*n,e.velocity.y=p*u+e.force.y/e.mass*n,e.positionPrev.x=e.position.x,e.positionPrev.y=e.position.y,e.position.x+=e.velocity.x,e.position.y+=e.velocity.y,e.deltaTime=t,e.angularVelocity=(e.angle-e.anglePrev)*u*s+e.torque/e.inertia*n,e.anglePrev=e.angle,e.angle+=e.angularVelocity, +e.speed=r.magnitude(e.velocity),e.angularSpeed=Math.abs(e.angularVelocity);for(var f=0;f0&&(m.position.x+=e.velocity.x,m.position.y+=e.velocity.y),0!==e.angularVelocity&&(i.rotate(m.vertices,e.angularVelocity,e.position),c.rotate(m.axes,e.angularVelocity),f>0&&r.rotateAbout(m.position,e.angularVelocity,e.position,m.position)),l.update(m.bounds,m.vertices,e.velocity)}},o.applyForce=function(e,t,n){e.force.x+=n.x,e.force.y+=n.y;var o={x:t.x-e.position.x,y:t.y-e.position.y};e.torque+=o.x*n.y-o.y*n.x},o._totalProperties=function(e){for(var t={mass:0,area:0,inertia:0,centre:{x:0,y:0}},n=1===e.parts.length?0:1;n1?1:0;p1?1:0;m0:0!=(e.mask&t.category)&&0!=(t.mask&e.category)}}()},{"../geometry/Bounds":25,"./Pair":6,"./SAT":10}],5:[function(e,t,n){var o={};t.exports=o;var i=e("./Pair"),r=e("./Detector"),s=e("../core/Common");!function(){ +o.create=function(e){var t={controller:o,detector:r.collisions,buckets:{},pairs:{},pairsList:[],bucketWidth:48,bucketHeight:48};return s.extend(t,e)},o.update=function(e,t,n,i){var r,s,a,l,c,u=n.world,d=e.buckets,p=!1;for(r=0;ru.bounds.max.x||f.bounds.max.yu.bounds.max.y)){var m=o._getRegion(e,f);if(!f.region||m.id!==f.region.id||i){f.region&&!i||(f.region=m);var v=o._regionUnion(m,f.region);for(s=v.startCol;s<=v.endCol;s++)for(a=v.startRow;a<=v.endRow;a++){c=o._getBucketId(s,a),l=d[c];var y=s>=m.startCol&&s<=m.endCol&&a>=m.startRow&&a<=m.endRow,g=s>=f.region.startCol&&s<=f.region.endCol&&a>=f.region.startRow&&a<=f.region.endRow;!y&&g&&g&&l&&o._bucketRemoveBody(e,l,f),(f.region===m||y&&!g||i)&&(l||(l=o._createBucket(d,c)),o._bucketAddBody(e,l,f))}f.region=m,p=!0}}}p&&(e.pairsList=o._createActivePairsList(e))},o.clear=function(e){e.buckets={},e.pairs={}, +e.pairsList=[]},o._regionUnion=function(e,t){var n=Math.min(e.startCol,t.startCol),i=Math.max(e.endCol,t.endCol),r=Math.min(e.startRow,t.startRow),s=Math.max(e.endRow,t.endRow);return o._createRegion(n,i,r,s)},o._getRegion=function(e,t){var n=t.bounds,i=Math.floor(n.min.x/e.bucketWidth),r=Math.floor(n.max.x/e.bucketWidth),s=Math.floor(n.min.y/e.bucketHeight),a=Math.floor(n.max.y/e.bucketHeight);return o._createRegion(i,r,s,a)},o._createRegion=function(e,t,n,o){return{id:e+","+t+","+n+","+o,startCol:e,endCol:t,startRow:n,endRow:o}},o._getBucketId=function(e,t){return"C"+e+"R"+t},o._createBucket=function(e,t){return e[t]=[]},o._bucketAddBody=function(e,t,n){for(var o=0;o0?o.push(n):delete e.pairs[t[i]];return o}}()},{"../core/Common":13,"./Detector":4,"./Pair":6}],6:[function(e,t,n){var o={};t.exports=o,function(){o.create=function(e,t){var n=e.bodyA,i=e.bodyB,r={id:o.id(n,i),bodyA:n,bodyB:i,activeContacts:[],separation:0,isActive:!0,confirmedActive:!0,isSensor:n.isSensor||i.isSensor,timeCreated:t,timeUpdated:t,collision:null,inverseMass:0,friction:0,frictionStatic:0,restitution:0,slop:0};return o.update(r,e,t),r},o.update=function(e,t,n){if(e.collision=t,t.collided){var i=t.supports,r=e.activeContacts,s=t.parentA,a=t.parentB;e.inverseMass=s.inverseMass+a.inverseMass,e.friction=Math.min(s.friction,a.friction),e.frictionStatic=Math.max(s.frictionStatic,a.frictionStatic),e.restitution=Math.max(s.restitution,a.restitution),e.slop=Math.max(s.slop,a.slop);for(var l=0;lo._pairMaxIdleLife&&c.push(s);for(s=0;sv.friction*v.frictionStatic*F*a&&(q=R*n,O=s.clamp(v.friction*E*a,-q,q));var W=r.cross(B,h),D=r.cross(M,h),U=S/(g.inverseMass+x.inverseMass+g.inverseInertia*W*W+x.inverseInertia*D*D);if(L*=U,O*=U,T<0&&T*T>o._restingThresh*i)A.normalImpulse=0;else{var N=A.normalImpulse;A.normalImpulse=Math.min(A.normalImpulse+L,0),L=A.normalImpulse-N}if(V*V>o._restingThreshTangent*i)A.tangentImpulse=0;else{var G=A.tangentImpulse;A.tangentImpulse=s.clamp(A.tangentImpulse+O,-q,q),O=A.tangentImpulse-G}l.x=h.x*L+b.x*O,l.y=h.y*L+b.y*O,g.isStatic||g.isSleeping||(g.positionPrev.x+=l.x*g.inverseMass,g.positionPrev.y+=l.y*g.inverseMass,g.anglePrev+=r.cross(B,l)*g.inverseInertia),x.isStatic||x.isSleeping||(x.positionPrev.x-=l.x*x.inverseMass,x.positionPrev.y-=l.y*x.inverseMass,x.anglePrev-=r.cross(M,l)*x.inverseInertia)}}}}}()},{"../core/Common":13,"../geometry/Bounds":25,"../geometry/Vector":27,"../geometry/Vertices":28}],10:[function(e,t,n){var o={};t.exports=o +;var i=e("../geometry/Vertices"),r=e("../geometry/Vector"),s=e("../core/Common");!function(){o._reuseMotionThresh=.2,o.collides=function(e,t,n,a){var l,c,u,d,p=!1,f=a/s._timeUnit;if(a=void 0!==a?a:0,n){var m=e.parent,v=t.parent,y=m.speed*m.speed+m.angularSpeed*m.angularSpeed+v.speed*v.speed+v.angularSpeed*v.angularSpeed;p=n&&n.collided&&yi?i=a:a=0?s.index-1:u.length-1],c.x=i.x-d.x,c.y=i.y-d.y,l=-r.dot(n,c),a=i,i=u[(s.index+1)%u.length],c.x=i.x-d.x,c.y=i.y-d.y,o=-r.dot(n,c),o0?1:.7),t.damping=t.damping||0,t.angularStiffness=t.angularStiffness||0,t.angleA=t.bodyA?t.bodyA.angle:t.angleA,t.angleB=t.bodyB?t.bodyB.angle:t.angleB,t.plugin={};var s={visible:!0,lineWidth:2,strokeStyle:"#ffffff",type:"line",anchors:!0};return 0===t.length&&t.stiffness>.1?(s.type="pin",s.anchors=!1):t.stiffness<.9&&(s.type="spring"),t.render=c.extend(s,t.render),t},o.preSolveAll=function(e){for(var t=0;t=1||0===e.length,h=x?e.stiffness:e.stiffness*t*t,b=e.damping*t,w=r.mult(u,g*h),S=(n?n.inverseMass:0)+(i?i.inverseMass:0),C=(n?n.inverseInertia:0)+(i?i.inverseInertia:0),A=S+C;if(b>0){var P=r.create();m=r.div(u,d),y=r.sub(i&&r.sub(i.position,i.positionPrev)||P,n&&r.sub(n.position,n.positionPrev)||P),v=r.dot(m,y)}n&&!n.isStatic&&(f=n.inverseMass/S,n.constraintImpulse.x-=w.x*f,n.constraintImpulse.y-=w.y*f,n.position.x-=w.x*f,n.position.y-=w.y*f,b>0&&(n.positionPrev.x-=b*m.x*v*f,n.positionPrev.y-=b*m.y*v*f),p=r.cross(s,w)/A*o._torqueDampen*n.inverseInertia*(1-e.angularStiffness), +n.constraintImpulse.angle-=p,n.angle-=p),i&&!i.isStatic&&(f=i.inverseMass/S,i.constraintImpulse.x+=w.x*f,i.constraintImpulse.y+=w.y*f,i.position.x+=w.x*f,i.position.y+=w.y*f,b>0&&(i.positionPrev.x+=b*m.x*v*f,i.positionPrev.y+=b*m.y*v*f),p=r.cross(a,w)/A*o._torqueDampen*i.inverseInertia*(1-e.angularStiffness),i.constraintImpulse.angle+=p,i.angle+=p)}}},o.postSolveAll=function(e){for(var t=0;t0&&(d.position.x+=c.x,d.position.y+=c.y),0!==c.angle&&(i.rotate(d.vertices,c.angle,n.position),l.rotate(d.axes,c.angle),u>0&&r.rotateAbout(d.position,c.angle,n.position,d.position)),a.update(d.bounds,d.vertices,n.velocity)}c.angle*=o._warming,c.x*=o._warming,c.y*=o._warming}}}}()},{"../core/Common":13,"../core/Sleeping":21,"../geometry/Axes":24,"../geometry/Bounds":25,"../geometry/Vector":27, +"../geometry/Vertices":28}],12:[function(e,t,n){var o={};t.exports=o;var i=e("../geometry/Vertices"),r=e("../core/Sleeping"),s=e("../core/Mouse"),a=e("../core/Events"),l=e("../collision/Detector"),c=e("./Constraint"),u=e("../body/Composite"),d=e("../core/Common"),p=e("../geometry/Bounds");!function(){o.create=function(e,t){var n=(e?e.mouse:null)||(t?t.mouse:null);n||(e&&e.render&&e.render.canvas?n=s.create(e.render.canvas):t&&t.element?n=s.create(t.element):(n=s.create(),d.warn("MouseConstraint.create: options.mouse was undefined, options.element was undefined, may not function as expected")));var i=c.create({label:"Mouse Constraint",pointA:n.position,pointB:{x:0,y:0},length:.01,stiffness:.1,angularStiffness:1,render:{strokeStyle:"#90EE90",lineWidth:3}}),r={type:"mouseConstraint",mouse:n,element:null,body:null,constraint:i,collisionFilter:{category:1,mask:4294967295,group:0}},l=d.extend(r,t);return a.on(e,"beforeUpdate",function(){var t=u.allBodies(e.world);o.update(l,t), +o._triggerEvents(l)}),l},o.update=function(e,t){var n=e.mouse,o=e.constraint,s=e.body;if(0===n.button){if(o.bodyB)r.set(o.bodyB,!1),o.pointA=n.position;else for(var c=0;c1?1:0;u0;t--){var n=Math.floor(o.random()*(t+1)),i=e[t];e[t]=e[n],e[n]=i}return e},o.choose=function(e){return e[Math.floor(o.random()*e.length)]},o.isElement=function(e){return"undefined"!=typeof HTMLElement?e instanceof HTMLElement:!!(e&&e.nodeType&&e.nodeName)},o.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)},o.isFunction=function(e){return"function"==typeof e},o.isPlainObject=function(e){return"object"==typeof e&&e.constructor===Object},o.isString=function(e){return"[object String]"===toString.call(e)},o.clamp=function(e,t,n){return en?n:e},o.sign=function(e){return e<0?-1:1},o.now=function(){if(window.performance){if(window.performance.now)return window.performance.now();if(window.performance.webkitNow)return window.performance.webkitNow()}return new Date-o._nowStartTime},o.random=function(e,n){return e=void 0!==e?e:0,n=void 0!==n?n:1,e+t()*(n-e)};var t=function(){ +return o._seed=(9301*o._seed+49297)%233280,o._seed/233280};o.colorToNumber=function(e){return e=e.replace("#",""),3==e.length&&(e=e.charAt(0)+e.charAt(0)+e.charAt(1)+e.charAt(1)+e.charAt(2)+e.charAt(2)),parseInt(e,16)},o.logLevel=1,o.log=function(){console&&o.logLevel>0&&o.logLevel<=3&&console.log.apply(console,["matter-js:"].concat(Array.prototype.slice.call(arguments)))},o.info=function(){console&&o.logLevel>0&&o.logLevel<=2&&console.info.apply(console,["matter-js:"].concat(Array.prototype.slice.call(arguments)))},o.warn=function(){console&&o.logLevel>0&&o.logLevel<=3&&console.warn.apply(console,["matter-js:"].concat(Array.prototype.slice.call(arguments)))},o.nextId=function(){return o._nextId++},o.indexOf=function(e,t){if(e.indexOf)return e.indexOf(t);for(var n=0;n0&&o._bodiesUpdate(y,t),p.preSolveAll(y),i=0;i0&&u.trigger(e,"collisionStart",{pairs:h.collisionStart}),s.preSolvePosition(h.list),i=0;i0&&u.trigger(e,"collisionActive",{pairs:h.collisionActive}),h.collisionEnd.length>0&&u.trigger(e,"collisionEnd",{pairs:h.collisionEnd}),o._bodiesClearForces(y),u.trigger(e,"afterUpdate",v),e},o.merge=function(e,t){if(f.extend(e,t),t.world){e.world=t.world,o.clear(e);for(var n=d.allBodies(e.world),i=0;i0){n||(n={}),o=t.split(" ");for(var c=0;cr?(i.warn("Plugin.register:",o.toString(t),"was upgraded to",o.toString(e)),o._registry[e.name]=e):n-1},o.isFor=function(e,t){var n=e.for&&o.dependencyParse(e.for);return!e.for||t.name===n.name&&o.versionSatisfies(t.version,n.range)},o.use=function(e,t){if(e.uses=(e.uses||[]).concat(t||[]), +0===e.uses.length)return void i.warn("Plugin.use:",o.toString(e),"does not specify any dependencies to install.");for(var n=o.dependencies(e),r=i.topologicalSort(n),s=[],a=0;a0&&i.info(s.join(" "))},o.dependencies=function(e,t){var n=o.dependencyParse(e),r=n.name;if(t=t||{},!(r in t)){e=o.resolve(e)||e,t[r]=i.map(e.uses||[],function(t){o.isPlugin(t)&&o.register(t);var r=o.dependencyParse(t),s=o.resolve(t) ;return s&&!o.versionSatisfies(s.version,r.range)?(i.warn("Plugin.dependencies:",o.toString(s),"does not satisfy",o.toString(r),"used by",o.toString(n)+"."),s._warned=!0,e._warned=!0):s||(i.warn("Plugin.dependencies:",o.toString(t),"used by",o.toString(n),"could not be resolved."),e._warned=!0),r.name});for(var s=0;s=i[2];if("^"===n.operator)return i[0]>0?s[0]===i[0]&&r.number>=n.number:i[1]>0?s[1]===i[1]&&s[2]>=i[2]:s[2]===i[2]}return e===t||"*"===e}}()},{"./Common":14}],21:[function(e,t,n){var o={};t.exports=o;var i=e("./Events"),r=e("./Engine"),s=e("./Common");!function(){var e,t;if("undefined"!=typeof window&&(e=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.msRequestAnimationFrame,t=window.cancelAnimationFrame||window.mozCancelAnimationFrame||window.webkitCancelAnimationFrame||window.msCancelAnimationFrame),!e){var n;e=function(e){n=setTimeout(function(){e(s.now())},1e3/60)},t=function(){clearTimeout(n)}}o.create=function(e){var t={fps:60,correction:1,deltaSampleSize:60, -counterTimestamp:0,frameCounter:0,deltaHistory:[],timePrev:null,timeScalePrev:1,frameRequestId:null,isFixed:!1,enabled:!0},n=s.extend(t,e);return n.delta=n.delta||1e3/n.fps,n.deltaMin=n.deltaMin||1e3/n.fps,n.deltaMax=n.deltaMax||1e3/(.5*n.fps),n.fps=1e3/n.delta,n},o.run=function(t,n){return void 0!==t.positionIterations&&(n=t,t=o.create()),function i(r){t.frameRequestId=e(i),r&&t.enabled&&o.tick(t,n,r)}(),t},o.tick=function(e,t,n){var o,s=t.timing,a=1,l={timestamp:s.timestamp};i.trigger(e,"beforeTick",l),i.trigger(t,"beforeTick",l),e.isFixed?o=e.delta:(o=n-e.timePrev||e.delta,e.timePrev=n,e.deltaHistory.push(o),e.deltaHistory=e.deltaHistory.slice(-e.deltaSampleSize),o=Math.min.apply(null,e.deltaHistory),o=oe.deltaMax?e.deltaMax:o,a=o/e.delta,e.delta=o),0!==e.timeScalePrev&&(a*=s.timeScale/e.timeScalePrev),0===s.timeScale&&(a=0),e.timeScalePrev=s.timeScale,e.correction=a,e.frameCounter+=1, -n-e.counterTimestamp>=1e3&&(e.fps=e.frameCounter*((n-e.counterTimestamp)/1e3),e.counterTimestamp=n,e.frameCounter=0),i.trigger(e,"tick",l),i.trigger(t,"tick",l),t.world.isModified&&t.render&&t.render.controller&&t.render.controller.clear&&t.render.controller.clear(t.render),i.trigger(e,"beforeUpdate",l),r.update(t,o,a),i.trigger(e,"afterUpdate",l),t.render&&t.render.controller&&(i.trigger(e,"beforeRender",l),i.trigger(t,"beforeRender",l),t.render.controller.world(t.render),i.trigger(e,"afterRender",l),i.trigger(t,"afterRender",l)),i.trigger(e,"afterTick",l),i.trigger(t,"afterTick",l)},o.stop=function(e){t(e.frameRequestId)},o.start=function(e,t){o.run(e,t)}}()},{"./Common":14,"./Engine":15,"./Events":16}],22:[function(e,t,n){var o={};t.exports=o;var i=e("./Events");!function(){o._motionWakeThreshold=.18,o._motionSleepThreshold=.08,o._minBias=.9,o.update=function(e,t){for(var n=t*t*t,i=0;i0&&r.motion=r.sleepThreshold&&o.set(r,!0)):r.sleepCounter>0&&(r.sleepCounter-=1)}else o.set(r,!1)}},o.afterCollisions=function(e,t){for(var n=t*t*t,i=0;io._motionWakeThreshold*n&&o.set(c,!1)}}}},o.set=function(e,t){var n=e.isSleeping;t?(e.isSleeping=!0,e.sleepCounter=e.sleepThreshold,e.positionImpulse.x=0,e.positionImpulse.y=0,e.positionPrev.x=e.position.x,e.positionPrev.y=e.position.y,e.anglePrev=e.angle,e.speed=0,e.angularSpeed=0,e.motion=0,n||i.trigger(e,"sleepStart")):(e.isSleeping=!1,e.sleepCounter=0,n&&i.trigger(e,"sleepEnd"))}}()},{ -"./Events":16}],23:[function(e,t,n){var o={};t.exports=o;var i,r=e("../geometry/Vertices"),s=e("../core/Common"),a=e("../body/Body"),l=e("../geometry/Bounds"),c=e("../geometry/Vector");!function(){o.rectangle=function(e,t,n,o,i){i=i||{};var l={label:"Rectangle Body",position:{x:e,y:t},vertices:r.fromPath("L 0 0 L "+n+" 0 L "+n+" "+o+" L 0 "+o)};if(i.chamfer){var c=i.chamfer;l.vertices=r.chamfer(l.vertices,c.radius,c.quality,c.qualityMin,c.qualityMax),delete i.chamfer}return a.create(s.extend({},l,i))},o.trapezoid=function(e,t,n,o,i,l){l=l||{},i*=.5;var c,d=(1-2*i)*n,u=n*i,p=u+d,f=p+u;c=i<.5?"L 0 0 L "+u+" "+-o+" L "+p+" "+-o+" L "+f+" 0":"L 0 0 L "+p+" "+-o+" L "+f+" 0";var m={label:"Trapezoid Body",position:{x:e,y:t},vertices:r.fromPath(c)};if(l.chamfer){var v=l.chamfer;m.vertices=r.chamfer(m.vertices,v.radius,v.quality,v.qualityMin,v.qualityMax),delete l.chamfer}return a.create(s.extend({},m,l))},o.circle=function(e,t,n,i,r){i=i||{};var a={label:"Circle Body",circleRadius:n};r=r||25 -;var l=Math.ceil(Math.max(10,Math.min(r,n)));return l%2==1&&(l+=1),o.polygon(e,t,l,n,s.extend({},a,i))},o.polygon=function(e,t,n,i,l){if(l=l||{},n<3)return o.circle(e,t,i,l);for(var c=2*Math.PI/n,d="",u=.5*c,p=0;p0&&r.area(P)1?(f=a.create(s.extend({parts:m.slice(0)},o)),a.setPosition(f,{x:e,y:t}),f):m[0]}}()},{"../body/Body":1,"../core/Common":14,"../geometry/Bounds":26,"../geometry/Vector":28,"../geometry/Vertices":29}],24:[function(e,t,n){var o={};t.exports=o -;var i=e("../body/Composite"),r=e("../constraint/Constraint"),s=e("../core/Common"),a=e("../body/Body"),l=e("./Bodies");!function(){o.stack=function(e,t,n,o,r,s,l){for(var c,d=i.create({label:"Stack"}),u=e,p=t,f=0,m=0;mv&&(v=x),a.translate(g,{x:.5*h,y:.5*x}),u=g.bounds.max.x+r,i.addBody(d,g),c=g,f+=1}else u+=r}p+=v+s,u=e}return d},o.chain=function(e,t,n,o,a,l){for(var c=e.bodies,d=1;d0)for(c=0;c0&&(p=f[c-1+(l-1)*t],i.addConstraint(e,r.create(s.extend({bodyA:p,bodyB:u},a)))),o&&cp)){c=p-c;var m=c,v=n-1-c;if(!(sv)){1===u&&a.translate(d,{x:(s+(n%2==1?1:-1))*f,y:0});return l(e+(d?s*f:0)+s*r,o,s,c,d,u)}}})},o.newtonsCradle=function(e,t,n,o,s){for(var a=i.create({label:"Newtons Cradle"}),c=0;ce.max.x&&(e.max.x=i.x),i.xe.max.y&&(e.max.y=i.y),i.y0?e.max.x+=n.x:e.min.x+=n.x,n.y>0?e.max.y+=n.y:e.min.y+=n.y)},o.contains=function(e,t){return t.x>=e.min.x&&t.x<=e.max.x&&t.y>=e.min.y&&t.y<=e.max.y},o.overlaps=function(e,t){return e.min.x<=t.max.x&&e.max.x>=t.min.x&&e.max.y>=t.min.y&&e.min.y<=t.max.y},o.translate=function(e,t){e.min.x+=t.x, -e.max.x+=t.x,e.min.y+=t.y,e.max.y+=t.y},o.shift=function(e,t){var n=e.max.x-e.min.x,o=e.max.y-e.min.y;e.min.x=t.x,e.max.x=t.x+n,e.min.y=t.y,e.max.y=t.y+o}}()},{}],27:[function(e,t,n){var o={};t.exports=o;var i=(e("../geometry/Bounds"),e("../core/Common"));!function(){o.pathToVertices=function(e,t){"undefined"==typeof window||"SVGPathSeg"in window||i.warn("Svg.pathToVertices: SVGPathSeg not defined, a polyfill is required.");var n,r,s,a,l,c,d,u,p,f,m,v,y=[],g=0,x=0,h=0;t=t||15;var b=function(e,t,n){var o=n%2==1&&n>1;if(!p||e!=p.x||t!=p.y){p&&o?(m=p.x,v=p.y):(m=0,v=0);var i={x:m+e,y:v+t};!o&&p||(p=i),y.push(i),x=m+e,h=v+t}},w=function(e){var t=e.pathSegTypeAsLetter.toUpperCase();if("Z"!==t){switch(t){case"M":case"L":case"T":case"C":case"S":case"Q":x=e.x,h=e.y;break;case"H":x=e.x;break;case"V":h=e.y}b(x,h,e.pathSegType)}};for(o._svgPathToAbsolute(e),s=e.getTotalLength(),c=[],n=0;n0)return!1}return!0},o.scale=function(e,t,n,r){if(1===t&&1===n)return e;r=r||o.centre(e);for(var s,a,l=0;l=0?l-1:e.length-1],d=e[l],u=e[(l+1)%e.length],p=t[l0&&(r|=2),3===r)return!1;return 0!==r||null},o.hull=function(e){var t,n,o=[],r=[];for(e=e.slice(0),e.sort(function(e,t){var n=e.x-t.x;return 0!==n?n:e.y-t.y}),n=0;n=2&&i.cross3(r[r.length-2],r[r.length-1],t)<=0;)r.pop();r.push(t)}for(n=e.length-1;n>=0;n-=1){for(t=e[n];o.length>=2&&i.cross3(o[o.length-2],o[o.length-1],t)<=0;)o.pop();o.push(t)}return o.pop(),r.pop(),o.concat(r)}}()},{"../core/Common":14,"../geometry/Vector":28}],30:[function(e,t,n){var o=t.exports=e("../core/Matter");o.Body=e("../body/Body"),o.Composite=e("../body/Composite"), -o.World=e("../body/World"),o.Contact=e("../collision/Contact"),o.Detector=e("../collision/Detector"),o.Grid=e("../collision/Grid"),o.Pairs=e("../collision/Pairs"),o.Pair=e("../collision/Pair"),o.Query=e("../collision/Query"),o.Resolver=e("../collision/Resolver"),o.SAT=e("../collision/SAT"),o.Constraint=e("../constraint/Constraint"),o.MouseConstraint=e("../constraint/MouseConstraint"),o.Common=e("../core/Common"),o.Engine=e("../core/Engine"),o.Events=e("../core/Events"),o.Mouse=e("../core/Mouse"),o.Runner=e("../core/Runner"),o.Sleeping=e("../core/Sleeping"),o.Plugin=e("../core/Plugin"),o.Bodies=e("../factory/Bodies"),o.Composites=e("../factory/Composites"),o.Axes=e("../geometry/Axes"),o.Bounds=e("../geometry/Bounds"),o.Svg=e("../geometry/Svg"),o.Vector=e("../geometry/Vector"),o.Vertices=e("../geometry/Vertices"),o.Render=e("../render/Render"),o.RenderPixi=e("../render/RenderPixi"),o.World.add=o.Composite.add,o.World.remove=o.Composite.remove, -o.World.addComposite=o.Composite.addComposite,o.World.addBody=o.Composite.addBody,o.World.addConstraint=o.Composite.addConstraint,o.World.clear=o.Composite.clear,o.Engine.run=o.Runner.run},{"../body/Body":1,"../body/Composite":2,"../body/World":3,"../collision/Contact":4,"../collision/Detector":5,"../collision/Grid":6,"../collision/Pair":7,"../collision/Pairs":8,"../collision/Query":9,"../collision/Resolver":10,"../collision/SAT":11,"../constraint/Constraint":12,"../constraint/MouseConstraint":13,"../core/Common":14,"../core/Engine":15,"../core/Events":16,"../core/Matter":17,"../core/Metrics":18,"../core/Mouse":19,"../core/Plugin":20,"../core/Runner":21,"../core/Sleeping":22,"../factory/Bodies":23,"../factory/Composites":24,"../geometry/Axes":25,"../geometry/Bounds":26,"../geometry/Svg":27,"../geometry/Vector":28,"../geometry/Vertices":29,"../render/Render":31,"../render/RenderPixi":32}],31:[function(e,t,n){var o={};t.exports=o -;var i=e("../core/Common"),r=e("../body/Composite"),s=e("../geometry/Bounds"),a=e("../core/Events"),l=e("../collision/Grid"),c=e("../geometry/Vector"),d=e("../core/Mouse");!function(){var e,t;"undefined"!=typeof window&&(e=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.msRequestAnimationFrame||function(e){window.setTimeout(function(){e(i.now())},1e3/60)},t=window.cancelAnimationFrame||window.mozCancelAnimationFrame||window.webkitCancelAnimationFrame||window.msCancelAnimationFrame),o.create=function(e){var t={controller:o,engine:null,element:null,canvas:null,mouse:null,frameRequestId:null,options:{width:800,height:600,pixelRatio:1,background:"#18181d",wireframeBackground:"#0f0f13",hasBounds:!!e.bounds,enabled:!0,wireframes:!0,showSleeping:!0,showDebug:!1,showBroadphase:!1,showBounds:!1,showVelocity:!1,showCollisions:!1,showSeparations:!1,showAxes:!1,showPositions:!1,showAngleIndicator:!1,showIds:!1,showShadows:!1, -showVertexNumbers:!1,showConvexHulls:!1,showInternalEdges:!1,showMousePosition:!1}},r=i.extend(t,e);return r.canvas&&(r.canvas.width=r.options.width||r.canvas.width,r.canvas.height=r.options.height||r.canvas.height),r.mouse=e.mouse,r.engine=e.engine,r.canvas=r.canvas||n(r.options.width,r.options.height),r.context=r.canvas.getContext("2d"),r.textures={},r.bounds=r.bounds||{min:{x:0,y:0},max:{x:r.canvas.width,y:r.canvas.height}},1!==r.options.pixelRatio&&o.setPixelRatio(r,r.options.pixelRatio),i.isElement(r.element)?r.element.appendChild(r.canvas):r.canvas.parentNode||i.log("Render.create: options.element was undefined, render.canvas was created but not appended","warn"),r},o.run=function(t){!function n(i){t.frameRequestId=e(n),o.world(t)}()},o.stop=function(e){t(e.frameRequestId)},o.setPixelRatio=function(e,t){var n=e.options,o=e.canvas;"auto"===t&&(t=u(o)),n.pixelRatio=t,o.setAttribute("data-pixel-ratio",t),o.width=n.width*t,o.height=n.height*t,o.style.width=n.width+"px", -o.style.height=n.height+"px",e.context.scale(t,t)},o.lookAt=function(e,t,n,o){o=void 0===o||o,t=i.isArray(t)?t:[t],n=n||{x:0,y:0};for(var r={min:{x:1/0,y:1/0},max:{x:-1/0,y:-1/0}},s=0;sr.max.x&&(r.max.x=c.x),l.yr.max.y&&(r.max.y=c.y))}var u=r.max.x-r.min.x+2*n.x,p=r.max.y-r.min.y+2*n.y,f=e.canvas.height,m=e.canvas.width,v=m/f,y=u/p,g=1,x=1;y>v?x=y/v:g=v/y,e.options.hasBounds=!0,e.bounds.min.x=r.min.x,e.bounds.max.x=r.min.x+u*g,e.bounds.min.y=r.min.y,e.bounds.max.y=r.min.y+p*x,o&&(e.bounds.min.x+=.5*u-u*g*.5,e.bounds.max.x+=.5*u-u*g*.5,e.bounds.min.y+=.5*p-p*x*.5,e.bounds.max.y+=.5*p-p*x*.5),e.bounds.min.x-=n.x,e.bounds.max.x-=n.x,e.bounds.min.y-=n.y,e.bounds.max.y-=n.y,e.mouse&&(d.setScale(e.mouse,{x:(e.bounds.max.x-e.bounds.min.x)/e.canvas.width,y:(e.bounds.max.y-e.bounds.min.y)/e.canvas.height}), -d.setOffset(e.mouse,e.bounds.min))},o.startViewTransform=function(e){var t=e.bounds.max.x-e.bounds.min.x,n=e.bounds.max.y-e.bounds.min.y,o=t/e.options.width,i=n/e.options.height;e.context.scale(1/o,1/i),e.context.translate(-e.bounds.min.x,-e.bounds.min.y)},o.endViewTransform=function(e){e.context.setTransform(e.options.pixelRatio,0,0,e.options.pixelRatio,0,0)},o.world=function(e){var t,n=e.engine,i=n.world,u=e.canvas,p=e.context,m=e.options,v=r.allBodies(i),y=r.allConstraints(i),g=m.wireframes?m.wireframeBackground:m.background,x=[],h=[],b={timestamp:n.timing.timestamp};if(a.trigger(e,"beforeRender",b),e.currentBackground!==g&&f(e,g),p.globalCompositeOperation="source-in",p.fillStyle="transparent",p.fillRect(0,0,u.width,u.height),p.globalCompositeOperation="source-over",m.hasBounds){for(t=0;t=500){var l="";s.timing&&(l+="fps: "+Math.round(s.timing.fps)+" "),e.debugString=l,e.debugTimestamp=o.timing.timestamp}if(e.debugString){n.font="12px Arial",a.wireframes?n.fillStyle="rgba(255,255,255,0.5)":n.fillStyle="rgba(0,0,0,0.5)";for(var c=e.debugString.split("\n"),d=0;d1?1:0;s1?1:0;a1?1:0;r1?1:0;a1?1:0;r1?1:0;r1?1:0;i0)){var u=o.activeContacts[0].vertex.x,p=o.activeContacts[0].vertex.y;2===o.activeContacts.length&&(u=(o.activeContacts[0].vertex.x+o.activeContacts[1].vertex.x)/2,p=(o.activeContacts[0].vertex.y+o.activeContacts[1].vertex.y)/2),i.bodyB===i.supports[0].body||!0===i.bodyA.isStatic?a.moveTo(u-8*i.normal.x,p-8*i.normal.y):a.moveTo(u+8*i.normal.x,p+8*i.normal.y),a.lineTo(u,p)} -l.wireframes?a.strokeStyle="rgba(255,165,0,0.7)":a.strokeStyle="orange",a.lineWidth=1,a.stroke()},o.separations=function(e,t,n){var o,i,r,s,a,l=n,c=e.options;for(l.beginPath(),a=0;a1?1:0;p=i[2];if("^"===n.operator)return i[0]>0?s[0]===i[0]&&r.number>=n.number:i[1]>0?s[1]===i[1]&&s[2]>=i[2]:s[2]===i[2]}return e===t||"*"===e}}()},{"./Common":13}],20:[function(e,t,n){var o={};t.exports=o;var i=e("./Events"),r=e("./Engine"),s=e("./Common");!function(){var e,t;if("undefined"!=typeof window&&(e=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.msRequestAnimationFrame,t=window.cancelAnimationFrame||window.mozCancelAnimationFrame||window.webkitCancelAnimationFrame||window.msCancelAnimationFrame),!e){var n;e=function(e){n=setTimeout(function(){e(s.now())},1e3/60)},t=function(){clearTimeout(n)}}o.create=function(e){var t={substeps:1,fps:60,deltaSampleSize:60, +counterTimestamp:0,frameCounter:0,deltaHistory:[],timePrev:null,frameRequestId:null,isFixed:!1,enabled:!0},n=s.extend(t,e);return n.delta=n.delta||1e3/n.fps,n.deltaMin=n.deltaMin||1e3/n.fps,n.deltaMax=n.deltaMax||1e3/(.5*n.fps),n.fps=1e3/n.delta,n},o.run=function(t,n){return void 0!==t.positionIterations&&(n=t,t=o.create()),function i(r){t.frameRequestId=e(i),r&&t.enabled&&o.tick(t,n,r)}(),t},o.tick=function(e,t,n){var o,s=t.timing;e.isFixed?o=e.delta:(o=n-e.timePrev||e.delta,e.timePrev=n,e.deltaHistory.push(o),e.deltaHistory=e.deltaHistory.slice(-e.deltaSampleSize),o=Math.min.apply(null,e.deltaHistory),o=oe.deltaMax?e.deltaMax:o,e.delta=o);var a={timestamp:s.timestamp};i.trigger(e,"beforeTick",a),i.trigger(t,"beforeTick",a),e.frameCounter+=1,n-e.counterTimestamp>=1e3&&(e.fps=e.frameCounter*((n-e.counterTimestamp)/1e3),e.counterTimestamp=n,e.frameCounter=0),i.trigger(e,"tick",a),i.trigger(t,"tick",a), +t.world.isModified&&t.render&&t.render.controller&&t.render.controller.clear&&t.render.controller.clear(t.render),i.trigger(e,"beforeUpdate",a);for(var l=e.substeps,c=o/l,u=0;u0&&s.motion=s.sleepThreshold/n&&o.set(s,!0)):s.sleepCounter>0&&(s.sleepCounter-=1)}else o.set(s,!1)}},o.afterCollisions=function(e,t){for(var n=t/r._timeUnit,i=0;io._motionWakeThreshold*n*n&&o.set(u,!1)}}}},o.set=function(e,t){var n=e.isSleeping;t?(e.isSleeping=!0,e.sleepCounter=e.sleepThreshold,e.positionImpulse.x=0,e.positionImpulse.y=0,e.positionPrev.x=e.position.x,e.positionPrev.y=e.position.y,e.anglePrev=e.angle,e.speed=0,e.angularSpeed=0,e.motion=0,n||i.trigger(e,"sleepStart")):(e.isSleeping=!1,e.sleepCounter=0,n&&i.trigger(e,"sleepEnd"))}}()},{"./Common":13,"./Events":15}],22:[function(e,t,n){var o={};t.exports=o +;var i,r=e("../geometry/Vertices"),s=e("../core/Common"),a=e("../body/Body"),l=e("../geometry/Bounds"),c=e("../geometry/Vector");!function(){o.rectangle=function(e,t,n,o,i){i=i||{};var l={label:"Rectangle Body",position:{x:e,y:t},vertices:r.fromPath("L 0 0 L "+n+" 0 L "+n+" "+o+" L 0 "+o)};if(i.chamfer){var c=i.chamfer;l.vertices=r.chamfer(l.vertices,c.radius,c.quality,c.qualityMin,c.qualityMax),delete i.chamfer}return a.create(s.extend({},l,i))},o.trapezoid=function(e,t,n,o,i,l){l=l||{},i*=.5;var c,u=(1-2*i)*n,d=n*i,p=d+u,f=p+d;c=i<.5?"L 0 0 L "+d+" "+-o+" L "+p+" "+-o+" L "+f+" 0":"L 0 0 L "+p+" "+-o+" L "+f+" 0";var m={label:"Trapezoid Body",position:{x:e,y:t},vertices:r.fromPath(c)};if(l.chamfer){var v=l.chamfer;m.vertices=r.chamfer(m.vertices,v.radius,v.quality,v.qualityMin,v.qualityMax),delete l.chamfer}return a.create(s.extend({},m,l))},o.circle=function(e,t,n,i,r){i=i||{};var a={label:"Circle Body",circleRadius:n};r=r||25;var l=Math.ceil(Math.max(10,Math.min(r,n))) +;return l%2==1&&(l+=1),o.polygon(e,t,l,n,s.extend({},a,i))},o.polygon=function(e,t,n,i,l){if(l=l||{},n<3)return o.circle(e,t,i,l);for(var c=2*Math.PI/n,u="",d=.5*c,p=0;p0&&r.area(P)1?(f=a.create(s.extend({parts:m.slice(0)},o)),a.setPosition(f,{x:e,y:t}),f):m[0]}}()},{"../body/Body":1,"../core/Common":13,"../geometry/Bounds":25,"../geometry/Vector":27,"../geometry/Vertices":28}],23:[function(e,t,n){var o={};t.exports=o;var i=e("../body/Composite"),r=e("../constraint/Constraint"),s=e("../core/Common"),a=e("../body/Body"),l=e("./Bodies") +;!function(){o.stack=function(e,t,n,o,r,s,l){for(var c,u=i.create({label:"Stack"}),d=e,p=t,f=0,m=0;mv&&(v=x),a.translate(g,{x:.5*h,y:.5*x}),d=g.bounds.max.x+r,i.addBody(u,g),c=g,f+=1}else d+=r}p+=v+s,d=e}return u},o.chain=function(e,t,n,o,a,l){for(var c=e.bodies,u=1;u0)for(c=0;c0&&(p=f[c-1+(l-1)*t], +i.addConstraint(e,r.create(s.extend({bodyA:p,bodyB:d},a)))),o&&cp)){c=p-c;var m=c,v=n-1-c;if(!(sv)){1===d&&a.translate(u,{x:(s+(n%2==1?1:-1))*f,y:0});return l(e+(u?s*f:0)+s*r,o,s,c,u,d)}}})},o.newtonsCradle=function(e,t,n,o,s){for(var a=i.create({label:"Newtons Cradle"}),c=0;ce.max.x&&(e.max.x=i.x),i.xe.max.y&&(e.max.y=i.y),i.y0?e.max.x+=n.x:e.min.x+=n.x,n.y>0?e.max.y+=n.y:e.min.y+=n.y)},o.contains=function(e,t){return t.x>=e.min.x&&t.x<=e.max.x&&t.y>=e.min.y&&t.y<=e.max.y},o.overlaps=function(e,t){return e.min.x<=t.max.x&&e.max.x>=t.min.x&&e.max.y>=t.min.y&&e.min.y<=t.max.y},o.translate=function(e,t){e.min.x+=t.x,e.max.x+=t.x,e.min.y+=t.y,e.max.y+=t.y},o.shift=function(e,t){var n=e.max.x-e.min.x,o=e.max.y-e.min.y;e.min.x=t.x,e.max.x=t.x+n,e.min.y=t.y,e.max.y=t.y+o}}()},{}], +26:[function(e,t,n){var o={};t.exports=o;var i=(e("../geometry/Bounds"),e("../core/Common"));!function(){o.pathToVertices=function(e,t){"undefined"==typeof window||"SVGPathSeg"in window||i.warn("Svg.pathToVertices: SVGPathSeg not defined, a polyfill is required.");var n,r,s,a,l,c,u,d,p,f,m,v,y=[],g=0,x=0,h=0;t=t||15;var b=function(e,t,n){var o=n%2==1&&n>1;if(!p||e!=p.x||t!=p.y){p&&o?(m=p.x,v=p.y):(m=0,v=0);var i={x:m+e,y:v+t};!o&&p||(p=i),y.push(i),x=m+e,h=v+t}},w=function(e){var t=e.pathSegTypeAsLetter.toUpperCase();if("Z"!==t){switch(t){case"M":case"L":case"T":case"C":case"S":case"Q":x=e.x,h=e.y;break;case"H":x=e.x;break;case"V":h=e.y}b(x,h,e.pathSegType)}};for(o._svgPathToAbsolute(e),s=e.getTotalLength(),c=[],n=0;n0)return!1}return!0},o.scale=function(e,t,n,r){if(1===t&&1===n)return e;r=r||o.centre(e);for(var s,a,l=0;l=0?l-1:e.length-1],u=e[l],d=e[(l+1)%e.length],p=t[l0&&(r|=2),3===r)return!1;return 0!==r||null},o.hull=function(e){var t,n,o=[],r=[];for(e=e.slice(0),e.sort(function(e,t){var n=e.x-t.x;return 0!==n?n:e.y-t.y}),n=0;n=2&&i.cross3(r[r.length-2],r[r.length-1],t)<=0;)r.pop();r.push(t)}for(n=e.length-1;n>=0;n-=1){for(t=e[n];o.length>=2&&i.cross3(o[o.length-2],o[o.length-1],t)<=0;)o.pop();o.push(t)}return o.pop(),r.pop(),o.concat(r)}}()},{"../core/Common":13,"../geometry/Vector":27}],29:[function(e,t,n){var o=t.exports=e("../core/Matter");o.Body=e("../body/Body"),o.Composite=e("../body/Composite"),o.World=e("../body/World"),o.Detector=e("../collision/Detector"),o.Grid=e("../collision/Grid"),o.Pairs=e("../collision/Pairs"),o.Pair=e("../collision/Pair"),o.Query=e("../collision/Query"),o.Resolver=e("../collision/Resolver"), +o.SAT=e("../collision/SAT"),o.Constraint=e("../constraint/Constraint"),o.MouseConstraint=e("../constraint/MouseConstraint"),o.Common=e("../core/Common"),o.Engine=e("../core/Engine"),o.Events=e("../core/Events"),o.Mouse=e("../core/Mouse"),o.Runner=e("../core/Runner"),o.Sleeping=e("../core/Sleeping"),o.Plugin=e("../core/Plugin"),o.Bodies=e("../factory/Bodies"),o.Composites=e("../factory/Composites"),o.Axes=e("../geometry/Axes"),o.Bounds=e("../geometry/Bounds"),o.Svg=e("../geometry/Svg"),o.Vector=e("../geometry/Vector"),o.Vertices=e("../geometry/Vertices"),o.Render=e("../render/Render"),o.RenderPixi=e("../render/RenderPixi"),o.World.add=o.Composite.add,o.World.remove=o.Composite.remove,o.World.addComposite=o.Composite.addComposite,o.World.addBody=o.Composite.addBody,o.World.addConstraint=o.Composite.addConstraint,o.World.clear=o.Composite.clear,o.Engine.run=o.Runner.run},{"../body/Body":1,"../body/Composite":2,"../body/World":3,"../collision/Detector":4,"../collision/Grid":5, +"../collision/Pair":6,"../collision/Pairs":7,"../collision/Query":8,"../collision/Resolver":9,"../collision/SAT":10,"../constraint/Constraint":11,"../constraint/MouseConstraint":12,"../core/Common":13,"../core/Engine":14,"../core/Events":15,"../core/Matter":16,"../core/Metrics":17,"../core/Mouse":18,"../core/Plugin":19,"../core/Runner":20,"../core/Sleeping":21,"../factory/Bodies":22,"../factory/Composites":23,"../geometry/Axes":24,"../geometry/Bounds":25,"../geometry/Svg":26,"../geometry/Vector":27,"../geometry/Vertices":28,"../render/Render":30,"../render/RenderPixi":31}],30:[function(e,t,n){var o={};t.exports=o;var i=e("../core/Common"),r=e("../body/Composite"),s=e("../geometry/Bounds"),a=e("../core/Events"),l=e("../collision/Grid"),c=e("../geometry/Vector"),u=e("../core/Mouse");!function(){var e,t;"undefined"!=typeof window&&(e=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.msRequestAnimationFrame||function(e){ +window.setTimeout(function(){e(i.now())},1e3/60)},t=window.cancelAnimationFrame||window.mozCancelAnimationFrame||window.webkitCancelAnimationFrame||window.msCancelAnimationFrame),o.create=function(e){var t={controller:o,engine:null,element:null,canvas:null,mouse:null,frameRequestId:null,options:{width:800,height:600,pixelRatio:1,background:"#18181d",wireframeBackground:"#0f0f13",hasBounds:!!e.bounds,enabled:!0,wireframes:!0,showSleeping:!0,showDebug:!1,showBroadphase:!1,showBounds:!1,showVelocity:!1,showCollisions:!1,showSeparations:!1,showAxes:!1,showPositions:!1,showAngleIndicator:!1,showIds:!1,showShadows:!1,showVertexNumbers:!1,showConvexHulls:!1,showInternalEdges:!1,showMousePosition:!1}},r=i.extend(t,e);return r.canvas&&(r.canvas.width=r.options.width||r.canvas.width,r.canvas.height=r.options.height||r.canvas.height),r.mouse=e.mouse,r.engine=e.engine,r.canvas=r.canvas||n(r.options.width,r.options.height),r.context=r.canvas.getContext("2d"),r.textures={},r.bounds=r.bounds||{min:{ +x:0,y:0},max:{x:r.canvas.width,y:r.canvas.height}},1!==r.options.pixelRatio&&o.setPixelRatio(r,r.options.pixelRatio),i.isElement(r.element)?r.element.appendChild(r.canvas):r.canvas.parentNode||i.log("Render.create: options.element was undefined, render.canvas was created but not appended","warn"),r},o.run=function(t){!function n(i){t.frameRequestId=e(n),o.world(t)}()},o.stop=function(e){t(e.frameRequestId)},o.setPixelRatio=function(e,t){var n=e.options,o=e.canvas;"auto"===t&&(t=d(o)),n.pixelRatio=t,o.setAttribute("data-pixel-ratio",t),o.width=n.width*t,o.height=n.height*t,o.style.width=n.width+"px",o.style.height=n.height+"px"},o.lookAt=function(e,t,n,o){o=void 0===o||o,t=i.isArray(t)?t:[t],n=n||{x:0,y:0};for(var r={min:{x:1/0,y:1/0},max:{x:-1/0,y:-1/0}},s=0;sr.max.x&&(r.max.x=c.x),l.yr.max.y&&(r.max.y=c.y))}var d=r.max.x-r.min.x+2*n.x,p=r.max.y-r.min.y+2*n.y,f=e.canvas.height,m=e.canvas.width,v=m/f,y=d/p,g=1,x=1;y>v?x=y/v:g=v/y,e.options.hasBounds=!0,e.bounds.min.x=r.min.x,e.bounds.max.x=r.min.x+d*g,e.bounds.min.y=r.min.y,e.bounds.max.y=r.min.y+p*x,o&&(e.bounds.min.x+=.5*d-d*g*.5,e.bounds.max.x+=.5*d-d*g*.5,e.bounds.min.y+=.5*p-p*x*.5,e.bounds.max.y+=.5*p-p*x*.5),e.bounds.min.x-=n.x,e.bounds.max.x-=n.x,e.bounds.min.y-=n.y,e.bounds.max.y-=n.y,e.mouse&&(u.setScale(e.mouse,{x:(e.bounds.max.x-e.bounds.min.x)/e.canvas.width,y:(e.bounds.max.y-e.bounds.min.y)/e.canvas.height}),u.setOffset(e.mouse,e.bounds.min))},o.startViewTransform=function(e){var t=e.bounds.max.x-e.bounds.min.x,n=e.bounds.max.y-e.bounds.min.y,o=t/e.options.width,i=n/e.options.height;e.context.setTransform(e.options.pixelRatio/o,0,0,e.options.pixelRatio/i,0,0),e.context.translate(-e.bounds.min.x,-e.bounds.min.y)},o.endViewTransform=function(e){ +e.context.setTransform(e.options.pixelRatio,0,0,e.options.pixelRatio,0,0)},o.world=function(e){var t,n=e.engine,i=n.world,d=e.canvas,p=e.context,m=e.options,v=r.allBodies(i),y=r.allConstraints(i),g=m.wireframes?m.wireframeBackground:m.background,x=[],h=[],b={timestamp:n.timing.timestamp};if(a.trigger(e,"beforeRender",b),e.currentBackground!==g&&f(e,g),p.globalCompositeOperation="source-in",p.fillStyle="transparent",p.fillRect(0,0,d.width,d.height),p.globalCompositeOperation="source-over",m.hasBounds){for(t=0;t=500){var l="" +;s.timing&&(l+="fps: "+Math.round(s.timing.fps)+" "),e.debugString=l,e.debugTimestamp=o.timing.timestamp}if(e.debugString){n.font="12px Arial",a.wireframes?n.fillStyle="rgba(255,255,255,0.5)":n.fillStyle="rgba(0,0,0,0.5)";for(var c=e.debugString.split("\n"),u=0;u1?1:0;s1?1:0;a1?1:0;r1?1:0;a1?1:0;r1?1:0;r1?1:0;i0)){var d=o.activeContacts[0].vertex.x,p=o.activeContacts[0].vertex.y;2===o.activeContacts.length&&(d=(o.activeContacts[0].vertex.x+o.activeContacts[1].vertex.x)/2,p=(o.activeContacts[0].vertex.y+o.activeContacts[1].vertex.y)/2),i.bodyB===i.supports[0].body||!0===i.bodyA.isStatic?a.moveTo(d-8*i.normal.x,p-8*i.normal.y):a.moveTo(d+8*i.normal.x,p+8*i.normal.y),a.lineTo(d,p)}l.wireframes?a.strokeStyle="rgba(255,165,0,0.7)":a.strokeStyle="orange",a.lineWidth=1,a.stroke()}, +o.separations=function(e,t,n){var o,i,r,s,a,l=n,c=e.options;for(l.beginPath(),a=0;a1?1:0;p