- commit
- 320e55fa9b91bc4e4411236a803b729090500bc5
- parent
- 7ca90b565ce787f12fdadc85b58476e0ec77c485
- Author
- Tobias Bengfort <tobias.bengfort@posteo.de>
- Date
- 2018-09-16 08:50
build
Diffstat
| A | docs/build.js | 10516 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | docs/index.html | 16 | ++++++++++++++++ |
2 files changed, 10532 insertions, 0 deletions
diff --git a/docs/build.js b/docs/build.js
@@ -0,0 +1,10516 @@
-1 1 (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
-1 2 (function (global){
-1 3 /**
-1 4 * matter-js 0.14.2 by @liabru 2018-06-11
-1 5 * http://brm.io/matter-js/
-1 6 * License MIT
-1 7 */
-1 8
-1 9 /**
-1 10 * The MIT License (MIT)
-1 11 *
-1 12 * Copyright (c) Liam Brummitt and contributors.
-1 13 *
-1 14 * Permission is hereby granted, free of charge, to any person obtaining a copy
-1 15 * of this software and associated documentation files (the "Software"), to deal
-1 16 * in the Software without restriction, including without limitation the rights
-1 17 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-1 18 * copies of the Software, and to permit persons to whom the Software is
-1 19 * furnished to do so, subject to the following conditions:
-1 20 *
-1 21 * The above copyright notice and this permission notice shall be included in
-1 22 * all copies or substantial portions of the Software.
-1 23 *
-1 24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-1 25 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-1 26 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-1 27 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-1 28 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-1 29 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-1 30 * THE SOFTWARE.
-1 31 */
-1 32
-1 33 (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Matter = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(_dereq_,module,exports){
-1 34 /**
-1 35 * The `Matter.Body` module contains methods for creating and manipulating body models.
-1 36 * A `Matter.Body` is a rigid body that can be simulated by a `Matter.Engine`.
-1 37 * Factories for commonly used body configurations (such as rectangles, circles and other polygons) can be found in the module `Matter.Bodies`.
-1 38 *
-1 39 * See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples).
-1 40
-1 41 * @class Body
-1 42 */
-1 43
-1 44 var Body = {};
-1 45
-1 46 module.exports = Body;
-1 47
-1 48 var Vertices = _dereq_('../geometry/Vertices');
-1 49 var Vector = _dereq_('../geometry/Vector');
-1 50 var Sleeping = _dereq_('../core/Sleeping');
-1 51 var Render = _dereq_('../render/Render');
-1 52 var Common = _dereq_('../core/Common');
-1 53 var Bounds = _dereq_('../geometry/Bounds');
-1 54 var Axes = _dereq_('../geometry/Axes');
-1 55
-1 56 (function() {
-1 57
-1 58 Body._inertiaScale = 4;
-1 59 Body._nextCollidingGroupId = 1;
-1 60 Body._nextNonCollidingGroupId = -1;
-1 61 Body._nextCategory = 0x0001;
-1 62
-1 63 /**
-1 64 * Creates a new rigid body model. The options parameter is an object that specifies any properties you wish to override the defaults.
-1 65 * All properties have default values, and many are pre-calculated automatically based on other properties.
-1 66 * Vertices must be specified in clockwise order.
-1 67 * See the properties section below for detailed information on what you can pass via the `options` object.
-1 68 * @method create
-1 69 * @param {} options
-1 70 * @return {body} body
-1 71 */
-1 72 Body.create = function(options) {
-1 73 var defaults = {
-1 74 id: Common.nextId(),
-1 75 type: 'body',
-1 76 label: 'Body',
-1 77 parts: [],
-1 78 plugin: {},
-1 79 angle: 0,
-1 80 vertices: Vertices.fromPath('L 0 0 L 40 0 L 40 40 L 0 40'),
-1 81 position: { x: 0, y: 0 },
-1 82 force: { x: 0, y: 0 },
-1 83 torque: 0,
-1 84 positionImpulse: { x: 0, y: 0 },
-1 85 constraintImpulse: { x: 0, y: 0, angle: 0 },
-1 86 totalContacts: 0,
-1 87 speed: 0,
-1 88 angularSpeed: 0,
-1 89 velocity: { x: 0, y: 0 },
-1 90 angularVelocity: 0,
-1 91 isSensor: false,
-1 92 isStatic: false,
-1 93 isSleeping: false,
-1 94 motion: 0,
-1 95 sleepThreshold: 60,
-1 96 density: 0.001,
-1 97 restitution: 0,
-1 98 friction: 0.1,
-1 99 frictionStatic: 0.5,
-1 100 frictionAir: 0.01,
-1 101 collisionFilter: {
-1 102 category: 0x0001,
-1 103 mask: 0xFFFFFFFF,
-1 104 group: 0
-1 105 },
-1 106 slop: 0.05,
-1 107 timeScale: 1,
-1 108 render: {
-1 109 visible: true,
-1 110 opacity: 1,
-1 111 sprite: {
-1 112 xScale: 1,
-1 113 yScale: 1,
-1 114 xOffset: 0,
-1 115 yOffset: 0
-1 116 },
-1 117 lineWidth: 0
-1 118 }
-1 119 };
-1 120
-1 121 var body = Common.extend(defaults, options);
-1 122
-1 123 _initProperties(body, options);
-1 124
-1 125 return body;
-1 126 };
-1 127
-1 128 /**
-1 129 * Returns the next unique group index for which bodies will collide.
-1 130 * If `isNonColliding` is `true`, returns the next unique group index for which bodies will _not_ collide.
-1 131 * See `body.collisionFilter` for more information.
-1 132 * @method nextGroup
-1 133 * @param {bool} [isNonColliding=false]
-1 134 * @return {Number} Unique group index
-1 135 */
-1 136 Body.nextGroup = function(isNonColliding) {
-1 137 if (isNonColliding)
-1 138 return Body._nextNonCollidingGroupId--;
-1 139
-1 140 return Body._nextCollidingGroupId++;
-1 141 };
-1 142
-1 143 /**
-1 144 * Returns the next unique category bitfield (starting after the initial default category `0x0001`).
-1 145 * There are 32 available. See `body.collisionFilter` for more information.
-1 146 * @method nextCategory
-1 147 * @return {Number} Unique category bitfield
-1 148 */
-1 149 Body.nextCategory = function() {
-1 150 Body._nextCategory = Body._nextCategory << 1;
-1 151 return Body._nextCategory;
-1 152 };
-1 153
-1 154 /**
-1 155 * Initialises body properties.
-1 156 * @method _initProperties
-1 157 * @private
-1 158 * @param {body} body
-1 159 * @param {} [options]
-1 160 */
-1 161 var _initProperties = function(body, options) {
-1 162 options = options || {};
-1 163
-1 164 // init required properties (order is important)
-1 165 Body.set(body, {
-1 166 bounds: body.bounds || Bounds.create(body.vertices),
-1 167 positionPrev: body.positionPrev || Vector.clone(body.position),
-1 168 anglePrev: body.anglePrev || body.angle,
-1 169 vertices: body.vertices,
-1 170 parts: body.parts || [body],
-1 171 isStatic: body.isStatic,
-1 172 isSleeping: body.isSleeping,
-1 173 parent: body.parent || body
-1 174 });
-1 175
-1 176 Vertices.rotate(body.vertices, body.angle, body.position);
-1 177 Axes.rotate(body.axes, body.angle);
-1 178 Bounds.update(body.bounds, body.vertices, body.velocity);
-1 179
-1 180 // allow options to override the automatically calculated properties
-1 181 Body.set(body, {
-1 182 axes: options.axes || body.axes,
-1 183 area: options.area || body.area,
-1 184 mass: options.mass || body.mass,
-1 185 inertia: options.inertia || body.inertia
-1 186 });
-1 187
-1 188 // render properties
-1 189 var defaultFillStyle = (body.isStatic ? '#2e2b44' : Common.choose(['#006BA6', '#0496FF', '#FFBC42', '#D81159', '#8F2D56'])),
-1 190 defaultStrokeStyle = '#000';
-1 191 body.render.fillStyle = body.render.fillStyle || defaultFillStyle;
-1 192 body.render.strokeStyle = body.render.strokeStyle || defaultStrokeStyle;
-1 193 body.render.sprite.xOffset += -(body.bounds.min.x - body.position.x) / (body.bounds.max.x - body.bounds.min.x);
-1 194 body.render.sprite.yOffset += -(body.bounds.min.y - body.position.y) / (body.bounds.max.y - body.bounds.min.y);
-1 195 };
-1 196
-1 197 /**
-1 198 * Given a property and a value (or map of), sets the property(s) on the body, using the appropriate setter functions if they exist.
-1 199 * Prefer to use the actual setter functions in performance critical situations.
-1 200 * @method set
-1 201 * @param {body} body
-1 202 * @param {} settings A property name (or map of properties and values) to set on the body.
-1 203 * @param {} value The value to set if `settings` is a single property name.
-1 204 */
-1 205 Body.set = function(body, settings, value) {
-1 206 var property;
-1 207
-1 208 if (typeof settings === 'string') {
-1 209 property = settings;
-1 210 settings = {};
-1 211 settings[property] = value;
-1 212 }
-1 213
-1 214 for (property in settings) {
-1 215 value = settings[property];
-1 216
-1 217 if (!settings.hasOwnProperty(property))
-1 218 continue;
-1 219
-1 220 switch (property) {
-1 221
-1 222 case 'isStatic':
-1 223 Body.setStatic(body, value);
-1 224 break;
-1 225 case 'isSleeping':
-1 226 Sleeping.set(body, value);
-1 227 break;
-1 228 case 'mass':
-1 229 Body.setMass(body, value);
-1 230 break;
-1 231 case 'density':
-1 232 Body.setDensity(body, value);
-1 233 break;
-1 234 case 'inertia':
-1 235 Body.setInertia(body, value);
-1 236 break;
-1 237 case 'vertices':
-1 238 Body.setVertices(body, value);
-1 239 break;
-1 240 case 'position':
-1 241 Body.setPosition(body, value);
-1 242 break;
-1 243 case 'angle':
-1 244 Body.setAngle(body, value);
-1 245 break;
-1 246 case 'velocity':
-1 247 Body.setVelocity(body, value);
-1 248 break;
-1 249 case 'angularVelocity':
-1 250 Body.setAngularVelocity(body, value);
-1 251 break;
-1 252 case 'parts':
-1 253 Body.setParts(body, value);
-1 254 break;
-1 255 default:
-1 256 body[property] = value;
-1 257
-1 258 }
-1 259 }
-1 260 };
-1 261
-1 262 /**
-1 263 * Sets the body as static, including isStatic flag and setting mass and inertia to Infinity.
-1 264 * @method setStatic
-1 265 * @param {body} body
-1 266 * @param {bool} isStatic
-1 267 */
-1 268 Body.setStatic = function(body, isStatic) {
-1 269 for (var i = 0; i < body.parts.length; i++) {
-1 270 var part = body.parts[i];
-1 271 part.isStatic = isStatic;
-1 272
-1 273 if (isStatic) {
-1 274 part._original = {
-1 275 restitution: part.restitution,
-1 276 friction: part.friction,
-1 277 mass: part.mass,
-1 278 inertia: part.inertia,
-1 279 density: part.density,
-1 280 inverseMass: part.inverseMass,
-1 281 inverseInertia: part.inverseInertia
-1 282 };
-1 283
-1 284 part.restitution = 0;
-1 285 part.friction = 1;
-1 286 part.mass = part.inertia = part.density = Infinity;
-1 287 part.inverseMass = part.inverseInertia = 0;
-1 288
-1 289 part.positionPrev.x = part.position.x;
-1 290 part.positionPrev.y = part.position.y;
-1 291 part.anglePrev = part.angle;
-1 292 part.angularVelocity = 0;
-1 293 part.speed = 0;
-1 294 part.angularSpeed = 0;
-1 295 part.motion = 0;
-1 296 } else if (part._original) {
-1 297 part.restitution = part._original.restitution;
-1 298 part.friction = part._original.friction;
-1 299 part.mass = part._original.mass;
-1 300 part.inertia = part._original.inertia;
-1 301 part.density = part._original.density;
-1 302 part.inverseMass = part._original.inverseMass;
-1 303 part.inverseInertia = part._original.inverseInertia;
-1 304
-1 305 delete part._original;
-1 306 }
-1 307 }
-1 308 };
-1 309
-1 310 /**
-1 311 * Sets the mass of the body. Inverse mass, density and inertia are automatically updated to reflect the change.
-1 312 * @method setMass
-1 313 * @param {body} body
-1 314 * @param {number} mass
-1 315 */
-1 316 Body.setMass = function(body, mass) {
-1 317 var moment = body.inertia / (body.mass / 6);
-1 318 body.inertia = moment * (mass / 6);
-1 319 body.inverseInertia = 1 / body.inertia;
-1 320
-1 321 body.mass = mass;
-1 322 body.inverseMass = 1 / body.mass;
-1 323 body.density = body.mass / body.area;
-1 324 };
-1 325
-1 326 /**
-1 327 * Sets the density of the body. Mass and inertia are automatically updated to reflect the change.
-1 328 * @method setDensity
-1 329 * @param {body} body
-1 330 * @param {number} density
-1 331 */
-1 332 Body.setDensity = function(body, density) {
-1 333 Body.setMass(body, density * body.area);
-1 334 body.density = density;
-1 335 };
-1 336
-1 337 /**
-1 338 * Sets the moment of inertia (i.e. second moment of area) of the body of the body.
-1 339 * Inverse inertia is automatically updated to reflect the change. Mass is not changed.
-1 340 * @method setInertia
-1 341 * @param {body} body
-1 342 * @param {number} inertia
-1 343 */
-1 344 Body.setInertia = function(body, inertia) {
-1 345 body.inertia = inertia;
-1 346 body.inverseInertia = 1 / body.inertia;
-1 347 };
-1 348
-1 349 /**
-1 350 * Sets the body's vertices and updates body properties accordingly, including inertia, area and mass (with respect to `body.density`).
-1 351 * Vertices will be automatically transformed to be orientated around their centre of mass as the origin.
-1 352 * They are then automatically translated to world space based on `body.position`.
-1 353 *
-1 354 * The `vertices` argument should be passed as an array of `Matter.Vector` points (or a `Matter.Vertices` array).
-1 355 * Vertices must form a convex hull, concave hulls are not supported.
-1 356 *
-1 357 * @method setVertices
-1 358 * @param {body} body
-1 359 * @param {vector[]} vertices
-1 360 */
-1 361 Body.setVertices = function(body, vertices) {
-1 362 // change vertices
-1 363 if (vertices[0].body === body) {
-1 364 body.vertices = vertices;
-1 365 } else {
-1 366 body.vertices = Vertices.create(vertices, body);
-1 367 }
-1 368
-1 369 // update properties
-1 370 body.axes = Axes.fromVertices(body.vertices);
-1 371 body.area = Vertices.area(body.vertices);
-1 372 Body.setMass(body, body.density * body.area);
-1 373
-1 374 // orient vertices around the centre of mass at origin (0, 0)
-1 375 var centre = Vertices.centre(body.vertices);
-1 376 Vertices.translate(body.vertices, centre, -1);
-1 377
-1 378 // update inertia while vertices are at origin (0, 0)
-1 379 Body.setInertia(body, Body._inertiaScale * Vertices.inertia(body.vertices, body.mass));
-1 380
-1 381 // update geometry
-1 382 Vertices.translate(body.vertices, body.position);
-1 383 Bounds.update(body.bounds, body.vertices, body.velocity);
-1 384 };
-1 385
-1 386 /**
-1 387 * Sets the parts of the `body` and updates mass, inertia and centroid.
-1 388 * Each part will have its parent set to `body`.
-1 389 * By default the convex hull will be automatically computed and set on `body`, unless `autoHull` is set to `false.`
-1 390 * Note that this method will ensure that the first part in `body.parts` will always be the `body`.
-1 391 * @method setParts
-1 392 * @param {body} body
-1 393 * @param [body] parts
-1 394 * @param {bool} [autoHull=true]
-1 395 */
-1 396 Body.setParts = function(body, parts, autoHull) {
-1 397 var i;
-1 398
-1 399 // add all the parts, ensuring that the first part is always the parent body
-1 400 parts = parts.slice(0);
-1 401 body.parts.length = 0;
-1 402 body.parts.push(body);
-1 403 body.parent = body;
-1 404
-1 405 for (i = 0; i < parts.length; i++) {
-1 406 var part = parts[i];
-1 407 if (part !== body) {
-1 408 part.parent = body;
-1 409 body.parts.push(part);
-1 410 }
-1 411 }
-1 412
-1 413 if (body.parts.length === 1)
-1 414 return;
-1 415
-1 416 autoHull = typeof autoHull !== 'undefined' ? autoHull : true;
-1 417
-1 418 // find the convex hull of all parts to set on the parent body
-1 419 if (autoHull) {
-1 420 var vertices = [];
-1 421 for (i = 0; i < parts.length; i++) {
-1 422 vertices = vertices.concat(parts[i].vertices);
-1 423 }
-1 424
-1 425 Vertices.clockwiseSort(vertices);
-1 426
-1 427 var hull = Vertices.hull(vertices),
-1 428 hullCentre = Vertices.centre(hull);
-1 429
-1 430 Body.setVertices(body, hull);
-1 431 Vertices.translate(body.vertices, hullCentre);
-1 432 }
-1 433
-1 434 // sum the properties of all compound parts of the parent body
-1 435 var total = Body._totalProperties(body);
-1 436
-1 437 body.area = total.area;
-1 438 body.parent = body;
-1 439 body.position.x = total.centre.x;
-1 440 body.position.y = total.centre.y;
-1 441 body.positionPrev.x = total.centre.x;
-1 442 body.positionPrev.y = total.centre.y;
-1 443
-1 444 Body.setMass(body, total.mass);
-1 445 Body.setInertia(body, total.inertia);
-1 446 Body.setPosition(body, total.centre);
-1 447 };
-1 448
-1 449 /**
-1 450 * Sets the position of the body instantly. Velocity, angle, force etc. are unchanged.
-1 451 * @method setPosition
-1 452 * @param {body} body
-1 453 * @param {vector} position
-1 454 */
-1 455 Body.setPosition = function(body, position) {
-1 456 var delta = Vector.sub(position, body.position);
-1 457 body.positionPrev.x += delta.x;
-1 458 body.positionPrev.y += delta.y;
-1 459
-1 460 for (var i = 0; i < body.parts.length; i++) {
-1 461 var part = body.parts[i];
-1 462 part.position.x += delta.x;
-1 463 part.position.y += delta.y;
-1 464 Vertices.translate(part.vertices, delta);
-1 465 Bounds.update(part.bounds, part.vertices, body.velocity);
-1 466 }
-1 467 };
-1 468
-1 469 /**
-1 470 * Sets the angle of the body instantly. Angular velocity, position, force etc. are unchanged.
-1 471 * @method setAngle
-1 472 * @param {body} body
-1 473 * @param {number} angle
-1 474 */
-1 475 Body.setAngle = function(body, angle) {
-1 476 var delta = angle - body.angle;
-1 477 body.anglePrev += delta;
-1 478
-1 479 for (var i = 0; i < body.parts.length; i++) {
-1 480 var part = body.parts[i];
-1 481 part.angle += delta;
-1 482 Vertices.rotate(part.vertices, delta, body.position);
-1 483 Axes.rotate(part.axes, delta);
-1 484 Bounds.update(part.bounds, part.vertices, body.velocity);
-1 485 if (i > 0) {
-1 486 Vector.rotateAbout(part.position, delta, body.position, part.position);
-1 487 }
-1 488 }
-1 489 };
-1 490
-1 491 /**
-1 492 * Sets the linear velocity of the body instantly. Position, angle, force etc. are unchanged. See also `Body.applyForce`.
-1 493 * @method setVelocity
-1 494 * @param {body} body
-1 495 * @param {vector} velocity
-1 496 */
-1 497 Body.setVelocity = function(body, velocity) {
-1 498 body.positionPrev.x = body.position.x - velocity.x;
-1 499 body.positionPrev.y = body.position.y - velocity.y;
-1 500 body.velocity.x = velocity.x;
-1 501 body.velocity.y = velocity.y;
-1 502 body.speed = Vector.magnitude(body.velocity);
-1 503 };
-1 504
-1 505 /**
-1 506 * Sets the angular velocity of the body instantly. Position, angle, force etc. are unchanged. See also `Body.applyForce`.
-1 507 * @method setAngularVelocity
-1 508 * @param {body} body
-1 509 * @param {number} velocity
-1 510 */
-1 511 Body.setAngularVelocity = function(body, velocity) {
-1 512 body.anglePrev = body.angle - velocity;
-1 513 body.angularVelocity = velocity;
-1 514 body.angularSpeed = Math.abs(body.angularVelocity);
-1 515 };
-1 516
-1 517 /**
-1 518 * Moves a body by a given vector relative to its current position, without imparting any velocity.
-1 519 * @method translate
-1 520 * @param {body} body
-1 521 * @param {vector} translation
-1 522 */
-1 523 Body.translate = function(body, translation) {
-1 524 Body.setPosition(body, Vector.add(body.position, translation));
-1 525 };
-1 526
-1 527 /**
-1 528 * Rotates a body by a given angle relative to its current angle, without imparting any angular velocity.
-1 529 * @method rotate
-1 530 * @param {body} body
-1 531 * @param {number} rotation
-1 532 * @param {vector} [point]
-1 533 */
-1 534 Body.rotate = function(body, rotation, point) {
-1 535 if (!point) {
-1 536 Body.setAngle(body, body.angle + rotation);
-1 537 } else {
-1 538 var cos = Math.cos(rotation),
-1 539 sin = Math.sin(rotation),
-1 540 dx = body.position.x - point.x,
-1 541 dy = body.position.y - point.y;
-1 542
-1 543 Body.setPosition(body, {
-1 544 x: point.x + (dx * cos - dy * sin),
-1 545 y: point.y + (dx * sin + dy * cos)
-1 546 });
-1 547
-1 548 Body.setAngle(body, body.angle + rotation);
-1 549 }
-1 550 };
-1 551
-1 552 /**
-1 553 * Scales the body, including updating physical properties (mass, area, axes, inertia), from a world-space point (default is body centre).
-1 554 * @method scale
-1 555 * @param {body} body
-1 556 * @param {number} scaleX
-1 557 * @param {number} scaleY
-1 558 * @param {vector} [point]
-1 559 */
-1 560 Body.scale = function(body, scaleX, scaleY, point) {
-1 561 var totalArea = 0,
-1 562 totalInertia = 0;
-1 563
-1 564 point = point || body.position;
-1 565
-1 566 for (var i = 0; i < body.parts.length; i++) {
-1 567 var part = body.parts[i];
-1 568
-1 569 // scale vertices
-1 570 Vertices.scale(part.vertices, scaleX, scaleY, point);
-1 571
-1 572 // update properties
-1 573 part.axes = Axes.fromVertices(part.vertices);
-1 574 part.area = Vertices.area(part.vertices);
-1 575 Body.setMass(part, body.density * part.area);
-1 576
-1 577 // update inertia (requires vertices to be at origin)
-1 578 Vertices.translate(part.vertices, { x: -part.position.x, y: -part.position.y });
-1 579 Body.setInertia(part, Body._inertiaScale * Vertices.inertia(part.vertices, part.mass));
-1 580 Vertices.translate(part.vertices, { x: part.position.x, y: part.position.y });
-1 581
-1 582 if (i > 0) {
-1 583 totalArea += part.area;
-1 584 totalInertia += part.inertia;
-1 585 }
-1 586
-1 587 // scale position
-1 588 part.position.x = point.x + (part.position.x - point.x) * scaleX;
-1 589 part.position.y = point.y + (part.position.y - point.y) * scaleY;
-1 590
-1 591 // update bounds
-1 592 Bounds.update(part.bounds, part.vertices, body.velocity);
-1 593 }
-1 594
-1 595 // handle parent body
-1 596 if (body.parts.length > 1) {
-1 597 body.area = totalArea;
-1 598
-1 599 if (!body.isStatic) {
-1 600 Body.setMass(body, body.density * totalArea);
-1 601 Body.setInertia(body, totalInertia);
-1 602 }
-1 603 }
-1 604
-1 605 // handle circles
-1 606 if (body.circleRadius) {
-1 607 if (scaleX === scaleY) {
-1 608 body.circleRadius *= scaleX;
-1 609 } else {
-1 610 // body is no longer a circle
-1 611 body.circleRadius = null;
-1 612 }
-1 613 }
-1 614 };
-1 615
-1 616 /**
-1 617 * Performs a simulation step for the given `body`, including updating position and angle using Verlet integration.
-1 618 * @method update
-1 619 * @param {body} body
-1 620 * @param {number} deltaTime
-1 621 * @param {number} timeScale
-1 622 * @param {number} correction
-1 623 */
-1 624 Body.update = function(body, deltaTime, timeScale, correction) {
-1 625 var deltaTimeSquared = Math.pow(deltaTime * timeScale * body.timeScale, 2);
-1 626
-1 627 // from the previous step
-1 628 var frictionAir = 1 - body.frictionAir * timeScale * body.timeScale,
-1 629 velocityPrevX = body.position.x - body.positionPrev.x,
-1 630 velocityPrevY = body.position.y - body.positionPrev.y;
-1 631
-1 632 // update velocity with Verlet integration
-1 633 body.velocity.x = (velocityPrevX * frictionAir * correction) + (body.force.x / body.mass) * deltaTimeSquared;
-1 634 body.velocity.y = (velocityPrevY * frictionAir * correction) + (body.force.y / body.mass) * deltaTimeSquared;
-1 635
-1 636 body.positionPrev.x = body.position.x;
-1 637 body.positionPrev.y = body.position.y;
-1 638 body.position.x += body.velocity.x;
-1 639 body.position.y += body.velocity.y;
-1 640
-1 641 // update angular velocity with Verlet integration
-1 642 body.angularVelocity = ((body.angle - body.anglePrev) * frictionAir * correction) + (body.torque / body.inertia) * deltaTimeSquared;
-1 643 body.anglePrev = body.angle;
-1 644 body.angle += body.angularVelocity;
-1 645
-1 646 // track speed and acceleration
-1 647 body.speed = Vector.magnitude(body.velocity);
-1 648 body.angularSpeed = Math.abs(body.angularVelocity);
-1 649
-1 650 // transform the body geometry
-1 651 for (var i = 0; i < body.parts.length; i++) {
-1 652 var part = body.parts[i];
-1 653
-1 654 Vertices.translate(part.vertices, body.velocity);
-1 655
-1 656 if (i > 0) {
-1 657 part.position.x += body.velocity.x;
-1 658 part.position.y += body.velocity.y;
-1 659 }
-1 660
-1 661 if (body.angularVelocity !== 0) {
-1 662 Vertices.rotate(part.vertices, body.angularVelocity, body.position);
-1 663 Axes.rotate(part.axes, body.angularVelocity);
-1 664 if (i > 0) {
-1 665 Vector.rotateAbout(part.position, body.angularVelocity, body.position, part.position);
-1 666 }
-1 667 }
-1 668
-1 669 Bounds.update(part.bounds, part.vertices, body.velocity);
-1 670 }
-1 671 };
-1 672
-1 673 /**
-1 674 * Applies a force to a body from a given world-space position, including resulting torque.
-1 675 * @method applyForce
-1 676 * @param {body} body
-1 677 * @param {vector} position
-1 678 * @param {vector} force
-1 679 */
-1 680 Body.applyForce = function(body, position, force) {
-1 681 body.force.x += force.x;
-1 682 body.force.y += force.y;
-1 683 var offset = { x: position.x - body.position.x, y: position.y - body.position.y };
-1 684 body.torque += offset.x * force.y - offset.y * force.x;
-1 685 };
-1 686
-1 687 /**
-1 688 * Returns the sums of the properties of all compound parts of the parent body.
-1 689 * @method _totalProperties
-1 690 * @private
-1 691 * @param {body} body
-1 692 * @return {}
-1 693 */
-1 694 Body._totalProperties = function(body) {
-1 695 // from equations at:
-1 696 // https://ecourses.ou.edu/cgi-bin/ebook.cgi?doc=&topic=st&chap_sec=07.2&page=theory
-1 697 // http://output.to/sideway/default.asp?qno=121100087
-1 698
-1 699 var properties = {
-1 700 mass: 0,
-1 701 area: 0,
-1 702 inertia: 0,
-1 703 centre: { x: 0, y: 0 }
-1 704 };
-1 705
-1 706 // sum the properties of all compound parts of the parent body
-1 707 for (var i = body.parts.length === 1 ? 0 : 1; i < body.parts.length; i++) {
-1 708 var part = body.parts[i],
-1 709 mass = part.mass !== Infinity ? part.mass : 1;
-1 710
-1 711 properties.mass += mass;
-1 712 properties.area += part.area;
-1 713 properties.inertia += part.inertia;
-1 714 properties.centre = Vector.add(properties.centre, Vector.mult(part.position, mass));
-1 715 }
-1 716
-1 717 properties.centre = Vector.div(properties.centre, properties.mass);
-1 718
-1 719 return properties;
-1 720 };
-1 721
-1 722 /*
-1 723 *
-1 724 * Events Documentation
-1 725 *
-1 726 */
-1 727
-1 728 /**
-1 729 * Fired when a body starts sleeping (where `this` is the body).
-1 730 *
-1 731 * @event sleepStart
-1 732 * @this {body} The body that has started sleeping
-1 733 * @param {} event An event object
-1 734 * @param {} event.source The source object of the event
-1 735 * @param {} event.name The name of the event
-1 736 */
-1 737
-1 738 /**
-1 739 * Fired when a body ends sleeping (where `this` is the body).
-1 740 *
-1 741 * @event sleepEnd
-1 742 * @this {body} The body that has ended sleeping
-1 743 * @param {} event An event object
-1 744 * @param {} event.source The source object of the event
-1 745 * @param {} event.name The name of the event
-1 746 */
-1 747
-1 748 /*
-1 749 *
-1 750 * Properties Documentation
-1 751 *
-1 752 */
-1 753
-1 754 /**
-1 755 * An integer `Number` uniquely identifying number generated in `Body.create` by `Common.nextId`.
-1 756 *
-1 757 * @property id
-1 758 * @type number
-1 759 */
-1 760
-1 761 /**
-1 762 * A `String` denoting the type of object.
-1 763 *
-1 764 * @property type
-1 765 * @type string
-1 766 * @default "body"
-1 767 * @readOnly
-1 768 */
-1 769
-1 770 /**
-1 771 * An arbitrary `String` name to help the user identify and manage bodies.
-1 772 *
-1 773 * @property label
-1 774 * @type string
-1 775 * @default "Body"
-1 776 */
-1 777
-1 778 /**
-1 779 * An array of bodies that make up this body.
-1 780 * The first body in the array must always be a self reference to the current body instance.
-1 781 * All bodies in the `parts` array together form a single rigid compound body.
-1 782 * Parts are allowed to overlap, have gaps or holes or even form concave bodies.
-1 783 * Parts themselves should never be added to a `World`, only the parent body should be.
-1 784 * Use `Body.setParts` when setting parts to ensure correct updates of all properties.
-1 785 *
-1 786 * @property parts
-1 787 * @type body[]
-1 788 */
-1 789
-1 790 /**
-1 791 * An object reserved for storing plugin-specific properties.
-1 792 *
-1 793 * @property plugin
-1 794 * @type {}
-1 795 */
-1 796
-1 797 /**
-1 798 * A self reference if the body is _not_ a part of another body.
-1 799 * Otherwise this is a reference to the body that this is a part of.
-1 800 * See `body.parts`.
-1 801 *
-1 802 * @property parent
-1 803 * @type body
-1 804 */
-1 805
-1 806 /**
-1 807 * A `Number` specifying the angle of the body, in radians.
-1 808 *
-1 809 * @property angle
-1 810 * @type number
-1 811 * @default 0
-1 812 */
-1 813
-1 814 /**
-1 815 * An array of `Vector` objects that specify the convex hull of the rigid body.
-1 816 * These should be provided about the origin `(0, 0)`. E.g.
-1 817 *
-1 818 * [{ x: 0, y: 0 }, { x: 25, y: 50 }, { x: 50, y: 0 }]
-1 819 *
-1 820 * When passed via `Body.create`, the vertices are translated relative to `body.position` (i.e. world-space, and constantly updated by `Body.update` during simulation).
-1 821 * The `Vector` objects are also augmented with additional properties required for efficient collision detection.
-1 822 *
-1 823 * Other properties such as `inertia` and `bounds` are automatically calculated from the passed vertices (unless provided via `options`).
-1 824 * Concave hulls are not currently supported. The module `Matter.Vertices` contains useful methods for working with vertices.
-1 825 *
-1 826 * @property vertices
-1 827 * @type vector[]
-1 828 */
-1 829
-1 830 /**
-1 831 * A `Vector` that specifies the current world-space position of the body.
-1 832 *
-1 833 * @property position
-1 834 * @type vector
-1 835 * @default { x: 0, y: 0 }
-1 836 */
-1 837
-1 838 /**
-1 839 * A `Vector` that specifies the force to apply in the current step. It is zeroed after every `Body.update`. See also `Body.applyForce`.
-1 840 *
-1 841 * @property force
-1 842 * @type vector
-1 843 * @default { x: 0, y: 0 }
-1 844 */
-1 845
-1 846 /**
-1 847 * A `Number` that specifies the torque (turning force) to apply in the current step. It is zeroed after every `Body.update`.
-1 848 *
-1 849 * @property torque
-1 850 * @type number
-1 851 * @default 0
-1 852 */
-1 853
-1 854 /**
-1 855 * 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`).
-1 856 *
-1 857 * @readOnly
-1 858 * @property speed
-1 859 * @type number
-1 860 * @default 0
-1 861 */
-1 862
-1 863 /**
-1 864 * 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`).
-1 865 *
-1 866 * @readOnly
-1 867 * @property angularSpeed
-1 868 * @type number
-1 869 * @default 0
-1 870 */
-1 871
-1 872 /**
-1 873 * A `Vector` that _measures_ the current velocity of the body after the last `Body.update`. It is read-only.
-1 874 * 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).
-1 875 *
-1 876 * @readOnly
-1 877 * @property velocity
-1 878 * @type vector
-1 879 * @default { x: 0, y: 0 }
-1 880 */
-1 881
-1 882 /**
-1 883 * A `Number` that _measures_ the current angular velocity of the body after the last `Body.update`. It is read-only.
-1 884 * 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).
-1 885 *
-1 886 * @readOnly
-1 887 * @property angularVelocity
-1 888 * @type number
-1 889 * @default 0
-1 890 */
-1 891
-1 892 /**
-1 893 * A flag that indicates whether a body is considered static. A static body can never change position or angle and is completely fixed.
-1 894 * If you need to set a body as static after its creation, you should use `Body.setStatic` as this requires more than just setting this flag.
-1 895 *
-1 896 * @property isStatic
-1 897 * @type boolean
-1 898 * @default false
-1 899 */
-1 900
-1 901 /**
-1 902 * A flag that indicates whether a body is a sensor. Sensor triggers collision events, but doesn't react with colliding body physically.
-1 903 *
-1 904 * @property isSensor
-1 905 * @type boolean
-1 906 * @default false
-1 907 */
-1 908
-1 909 /**
-1 910 * A flag that indicates whether the body is considered sleeping. A sleeping body acts similar to a static body, except it is only temporary and can be awoken.
-1 911 * If you need to set a body as sleeping, you should use `Sleeping.set` as this requires more than just setting this flag.
-1 912 *
-1 913 * @property isSleeping
-1 914 * @type boolean
-1 915 * @default false
-1 916 */
-1 917
-1 918 /**
-1 919 * A `Number` that _measures_ the amount of movement a body currently has (a combination of `speed` and `angularSpeed`). It is read-only and always positive.
-1 920 * It is used and updated by the `Matter.Sleeping` module during simulation to decide if a body has come to rest.
-1 921 *
-1 922 * @readOnly
-1 923 * @property motion
-1 924 * @type number
-1 925 * @default 0
-1 926 */
-1 927
-1 928 /**
-1 929 * A `Number` that defines the number of updates in which this body must have near-zero velocity before it is set as sleeping by the `Matter.Sleeping` module (if sleeping is enabled by the engine).
-1 930 *
-1 931 * @property sleepThreshold
-1 932 * @type number
-1 933 * @default 60
-1 934 */
-1 935
-1 936 /**
-1 937 * A `Number` that defines the density of the body, that is its mass per unit area.
-1 938 * If you pass the density via `Body.create` the `mass` property is automatically calculated for you based on the size (area) of the object.
-1 939 * This is generally preferable to simply setting mass and allows for more intuitive definition of materials (e.g. rock has a higher density than wood).
-1 940 *
-1 941 * @property density
-1 942 * @type number
-1 943 * @default 0.001
-1 944 */
-1 945
-1 946 /**
-1 947 * A `Number` that defines the mass of the body, although it may be more appropriate to specify the `density` property instead.
-1 948 * If you modify this value, you must also modify the `body.inverseMass` property (`1 / mass`).
-1 949 *
-1 950 * @property mass
-1 951 * @type number
-1 952 */
-1 953
-1 954 /**
-1 955 * A `Number` that defines the inverse mass of the body (`1 / mass`).
-1 956 * If you modify this value, you must also modify the `body.mass` property.
-1 957 *
-1 958 * @property inverseMass
-1 959 * @type number
-1 960 */
-1 961
-1 962 /**
-1 963 * A `Number` that defines the moment of inertia (i.e. second moment of area) of the body.
-1 964 * It is automatically calculated from the given convex hull (`vertices` array) and density in `Body.create`.
-1 965 * If you modify this value, you must also modify the `body.inverseInertia` property (`1 / inertia`).
-1 966 *
-1 967 * @property inertia
-1 968 * @type number
-1 969 */
-1 970
-1 971 /**
-1 972 * A `Number` that defines the inverse moment of inertia of the body (`1 / inertia`).
-1 973 * If you modify this value, you must also modify the `body.inertia` property.
-1 974 *
-1 975 * @property inverseInertia
-1 976 * @type number
-1 977 */
-1 978
-1 979 /**
-1 980 * A `Number` that defines the restitution (elasticity) of the body. The value is always positive and is in the range `(0, 1)`.
-1 981 * A value of `0` means collisions may be perfectly inelastic and no bouncing may occur.
-1 982 * A value of `0.8` means the body may bounce back with approximately 80% of its kinetic energy.
-1 983 * Note that collision response is based on _pairs_ of bodies, and that `restitution` values are _combined_ with the following formula:
-1 984 *
-1 985 * Math.max(bodyA.restitution, bodyB.restitution)
-1 986 *
-1 987 * @property restitution
-1 988 * @type number
-1 989 * @default 0
-1 990 */
-1 991
-1 992 /**
-1 993 * A `Number` that defines the friction of the body. The value is always positive and is in the range `(0, 1)`.
-1 994 * A value of `0` means that the body may slide indefinitely.
-1 995 * A value of `1` means the body may come to a stop almost instantly after a force is applied.
-1 996 *
-1 997 * The effects of the value may be non-linear.
-1 998 * High values may be unstable depending on the body.
-1 999 * The engine uses a Coulomb friction model including static and kinetic friction.
-1 1000 * Note that collision response is based on _pairs_ of bodies, and that `friction` values are _combined_ with the following formula:
-1 1001 *
-1 1002 * Math.min(bodyA.friction, bodyB.friction)
-1 1003 *
-1 1004 * @property friction
-1 1005 * @type number
-1 1006 * @default 0.1
-1 1007 */
-1 1008
-1 1009 /**
-1 1010 * A `Number` that defines the static friction of the body (in the Coulomb friction model).
-1 1011 * A value of `0` means the body will never 'stick' when it is nearly stationary and only dynamic `friction` is used.
-1 1012 * The higher the value (e.g. `10`), the more force it will take to initially get the body moving when nearly stationary.
-1 1013 * This value is multiplied with the `friction` property to make it easier to change `friction` and maintain an appropriate amount of static friction.
-1 1014 *
-1 1015 * @property frictionStatic
-1 1016 * @type number
-1 1017 * @default 0.5
-1 1018 */
-1 1019
-1 1020 /**
-1 1021 * A `Number` that defines the air friction of the body (air resistance).
-1 1022 * A value of `0` means the body will never slow as it moves through space.
-1 1023 * The higher the value, the faster a body slows when moving through space.
-1 1024 * The effects of the value are non-linear.
-1 1025 *
-1 1026 * @property frictionAir
-1 1027 * @type number
-1 1028 * @default 0.01
-1 1029 */
-1 1030
-1 1031 /**
-1 1032 * An `Object` that specifies the collision filtering properties of this body.
-1 1033 *
-1 1034 * Collisions between two bodies will obey the following rules:
-1 1035 * - If the two bodies have the same non-zero value of `collisionFilter.group`,
-1 1036 * they will always collide if the value is positive, and they will never collide
-1 1037 * if the value is negative.
-1 1038 * - If the two bodies have different values of `collisionFilter.group` or if one
-1 1039 * (or both) of the bodies has a value of 0, then the category/mask rules apply as follows:
-1 1040 *
-1 1041 * Each body belongs to a collision category, given by `collisionFilter.category`. This
-1 1042 * value is used as a bit field and the category should have only one bit set, meaning that
-1 1043 * the value of this property is a power of two in the range [1, 2^31]. Thus, there are 32
-1 1044 * different collision categories available.
-1 1045 *
-1 1046 * Each body also defines a collision bitmask, given by `collisionFilter.mask` which specifies
-1 1047 * the categories it collides with (the value is the bitwise AND value of all these categories).
-1 1048 *
-1 1049 * Using the category/mask rules, two bodies `A` and `B` collide if each includes the other's
-1 1050 * category in its mask, i.e. `(categoryA & maskB) !== 0` and `(categoryB & maskA) !== 0`
-1 1051 * are both true.
-1 1052 *
-1 1053 * @property collisionFilter
-1 1054 * @type object
-1 1055 */
-1 1056
-1 1057 /**
-1 1058 * An Integer `Number`, that specifies the collision group this body belongs to.
-1 1059 * See `body.collisionFilter` for more information.
-1 1060 *
-1 1061 * @property collisionFilter.group
-1 1062 * @type object
-1 1063 * @default 0
-1 1064 */
-1 1065
-1 1066 /**
-1 1067 * A bit field that specifies the collision category this body belongs to.
-1 1068 * The category value should have only one bit set, for example `0x0001`.
-1 1069 * This means there are up to 32 unique collision categories available.
-1 1070 * See `body.collisionFilter` for more information.
-1 1071 *
-1 1072 * @property collisionFilter.category
-1 1073 * @type object
-1 1074 * @default 1
-1 1075 */
-1 1076
-1 1077 /**
-1 1078 * A bit mask that specifies the collision categories this body may collide with.
-1 1079 * See `body.collisionFilter` for more information.
-1 1080 *
-1 1081 * @property collisionFilter.mask
-1 1082 * @type object
-1 1083 * @default -1
-1 1084 */
-1 1085
-1 1086 /**
-1 1087 * A `Number` that specifies a tolerance on how far a body is allowed to 'sink' or rotate into other bodies.
-1 1088 * Avoid changing this value unless you understand the purpose of `slop` in physics engines.
-1 1089 * The default should generally suffice, although very large bodies may require larger values for stable stacking.
-1 1090 *
-1 1091 * @property slop
-1 1092 * @type number
-1 1093 * @default 0.05
-1 1094 */
-1 1095
-1 1096 /**
-1 1097 * A `Number` that allows per-body time scaling, e.g. a force-field where bodies inside are in slow-motion, while others are at full speed.
-1 1098 *
-1 1099 * @property timeScale
-1 1100 * @type number
-1 1101 * @default 1
-1 1102 */
-1 1103
-1 1104 /**
-1 1105 * An `Object` that defines the rendering properties to be consumed by the module `Matter.Render`.
-1 1106 *
-1 1107 * @property render
-1 1108 * @type object
-1 1109 */
-1 1110
-1 1111 /**
-1 1112 * A flag that indicates if the body should be rendered.
-1 1113 *
-1 1114 * @property render.visible
-1 1115 * @type boolean
-1 1116 * @default true
-1 1117 */
-1 1118
-1 1119 /**
-1 1120 * Sets the opacity to use when rendering.
-1 1121 *
-1 1122 * @property render.opacity
-1 1123 * @type number
-1 1124 * @default 1
-1 1125 */
-1 1126
-1 1127 /**
-1 1128 * An `Object` that defines the sprite properties to use when rendering, if any.
-1 1129 *
-1 1130 * @property render.sprite
-1 1131 * @type object
-1 1132 */
-1 1133
-1 1134 /**
-1 1135 * An `String` that defines the path to the image to use as the sprite texture, if any.
-1 1136 *
-1 1137 * @property render.sprite.texture
-1 1138 * @type string
-1 1139 */
-1 1140
-1 1141 /**
-1 1142 * A `Number` that defines the scaling in the x-axis for the sprite, if any.
-1 1143 *
-1 1144 * @property render.sprite.xScale
-1 1145 * @type number
-1 1146 * @default 1
-1 1147 */
-1 1148
-1 1149 /**
-1 1150 * A `Number` that defines the scaling in the y-axis for the sprite, if any.
-1 1151 *
-1 1152 * @property render.sprite.yScale
-1 1153 * @type number
-1 1154 * @default 1
-1 1155 */
-1 1156
-1 1157 /**
-1 1158 * A `Number` that defines the offset in the x-axis for the sprite (normalised by texture width).
-1 1159 *
-1 1160 * @property render.sprite.xOffset
-1 1161 * @type number
-1 1162 * @default 0
-1 1163 */
-1 1164
-1 1165 /**
-1 1166 * A `Number` that defines the offset in the y-axis for the sprite (normalised by texture height).
-1 1167 *
-1 1168 * @property render.sprite.yOffset
-1 1169 * @type number
-1 1170 * @default 0
-1 1171 */
-1 1172
-1 1173 /**
-1 1174 * A `Number` that defines the line width to use when rendering the body outline (if a sprite is not defined).
-1 1175 * A value of `0` means no outline will be rendered.
-1 1176 *
-1 1177 * @property render.lineWidth
-1 1178 * @type number
-1 1179 * @default 0
-1 1180 */
-1 1181
-1 1182 /**
-1 1183 * A `String` that defines the fill style to use when rendering the body (if a sprite is not defined).
-1 1184 * It is the same as when using a canvas, so it accepts CSS style property values.
-1 1185 *
-1 1186 * @property render.fillStyle
-1 1187 * @type string
-1 1188 * @default a random colour
-1 1189 */
-1 1190
-1 1191 /**
-1 1192 * A `String` that defines the stroke style to use when rendering the body outline (if a sprite is not defined).
-1 1193 * It is the same as when using a canvas, so it accepts CSS style property values.
-1 1194 *
-1 1195 * @property render.strokeStyle
-1 1196 * @type string
-1 1197 * @default a random colour
-1 1198 */
-1 1199
-1 1200 /**
-1 1201 * An array of unique axis vectors (edge normals) used for collision detection.
-1 1202 * These are automatically calculated from the given convex hull (`vertices` array) in `Body.create`.
-1 1203 * They are constantly updated by `Body.update` during the simulation.
-1 1204 *
-1 1205 * @property axes
-1 1206 * @type vector[]
-1 1207 */
-1 1208
-1 1209 /**
-1 1210 * A `Number` that _measures_ the area of the body's convex hull, calculated at creation by `Body.create`.
-1 1211 *
-1 1212 * @property area
-1 1213 * @type string
-1 1214 * @default
-1 1215 */
-1 1216
-1 1217 /**
-1 1218 * A `Bounds` object that defines the AABB region for the body.
-1 1219 * It is automatically calculated from the given convex hull (`vertices` array) in `Body.create` and constantly updated by `Body.update` during simulation.
-1 1220 *
-1 1221 * @property bounds
-1 1222 * @type bounds
-1 1223 */
-1 1224
-1 1225 })();
-1 1226
-1 1227 },{"../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){
-1 1228 /**
-1 1229 * The `Matter.Composite` module contains methods for creating and manipulating composite bodies.
-1 1230 * A composite body is a collection of `Matter.Body`, `Matter.Constraint` and other `Matter.Composite`, therefore composites form a tree structure.
-1 1231 * It is important to use the functions in this module to modify composites, rather than directly modifying their properties.
-1 1232 * Note that the `Matter.World` object is also a type of `Matter.Composite` and as such all composite methods here can also operate on a `Matter.World`.
-1 1233 *
-1 1234 * See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples).
-1 1235 *
-1 1236 * @class Composite
-1 1237 */
-1 1238
-1 1239 var Composite = {};
-1 1240
-1 1241 module.exports = Composite;
-1 1242
-1 1243 var Events = _dereq_('../core/Events');
-1 1244 var Common = _dereq_('../core/Common');
-1 1245 var Bounds = _dereq_('../geometry/Bounds');
-1 1246 var Body = _dereq_('./Body');
-1 1247
-1 1248 (function() {
-1 1249
-1 1250 /**
-1 1251 * Creates a new composite. The options parameter is an object that specifies any properties you wish to override the defaults.
-1 1252 * See the properites section below for detailed information on what you can pass via the `options` object.
-1 1253 * @method create
-1 1254 * @param {} [options]
-1 1255 * @return {composite} A new composite
-1 1256 */
-1 1257 Composite.create = function(options) {
-1 1258 return Common.extend({
-1 1259 id: Common.nextId(),
-1 1260 type: 'composite',
-1 1261 parent: null,
-1 1262 isModified: false,
-1 1263 bodies: [],
-1 1264 constraints: [],
-1 1265 composites: [],
-1 1266 label: 'Composite',
-1 1267 plugin: {}
-1 1268 }, options);
-1 1269 };
-1 1270
-1 1271 /**
-1 1272 * Sets the composite's `isModified` flag.
-1 1273 * If `updateParents` is true, all parents will be set (default: false).
-1 1274 * If `updateChildren` is true, all children will be set (default: false).
-1 1275 * @method setModified
-1 1276 * @param {composite} composite
-1 1277 * @param {boolean} isModified
-1 1278 * @param {boolean} [updateParents=false]
-1 1279 * @param {boolean} [updateChildren=false]
-1 1280 */
-1 1281 Composite.setModified = function(composite, isModified, updateParents, updateChildren) {
-1 1282 composite.isModified = isModified;
-1 1283
-1 1284 if (updateParents && composite.parent) {
-1 1285 Composite.setModified(composite.parent, isModified, updateParents, updateChildren);
-1 1286 }
-1 1287
-1 1288 if (updateChildren) {
-1 1289 for(var i = 0; i < composite.composites.length; i++) {
-1 1290 var childComposite = composite.composites[i];
-1 1291 Composite.setModified(childComposite, isModified, updateParents, updateChildren);
-1 1292 }
-1 1293 }
-1 1294 };
-1 1295
-1 1296 /**
-1 1297 * Generic add function. Adds one or many body(s), constraint(s) or a composite(s) to the given composite.
-1 1298 * Triggers `beforeAdd` and `afterAdd` events on the `composite`.
-1 1299 * @method add
-1 1300 * @param {composite} composite
-1 1301 * @param {} object
-1 1302 * @return {composite} The original composite with the objects added
-1 1303 */
-1 1304 Composite.add = function(composite, object) {
-1 1305 var objects = [].concat(object);
-1 1306
-1 1307 Events.trigger(composite, 'beforeAdd', { object: object });
-1 1308
-1 1309 for (var i = 0; i < objects.length; i++) {
-1 1310 var obj = objects[i];
-1 1311
-1 1312 switch (obj.type) {
-1 1313
-1 1314 case 'body':
-1 1315 // skip adding compound parts
-1 1316 if (obj.parent !== obj) {
-1 1317 Common.warn('Composite.add: skipped adding a compound body part (you must add its parent instead)');
-1 1318 break;
-1 1319 }
-1 1320
-1 1321 Composite.addBody(composite, obj);
-1 1322 break;
-1 1323 case 'constraint':
-1 1324 Composite.addConstraint(composite, obj);
-1 1325 break;
-1 1326 case 'composite':
-1 1327 Composite.addComposite(composite, obj);
-1 1328 break;
-1 1329 case 'mouseConstraint':
-1 1330 Composite.addConstraint(composite, obj.constraint);
-1 1331 break;
-1 1332
-1 1333 }
-1 1334 }
-1 1335
-1 1336 Events.trigger(composite, 'afterAdd', { object: object });
-1 1337
-1 1338 return composite;
-1 1339 };
-1 1340
-1 1341 /**
-1 1342 * Generic remove function. Removes one or many body(s), constraint(s) or a composite(s) to the given composite.
-1 1343 * Optionally searching its children recursively.
-1 1344 * Triggers `beforeRemove` and `afterRemove` events on the `composite`.
-1 1345 * @method remove
-1 1346 * @param {composite} composite
-1 1347 * @param {} object
-1 1348 * @param {boolean} [deep=false]
-1 1349 * @return {composite} The original composite with the objects removed
-1 1350 */
-1 1351 Composite.remove = function(composite, object, deep) {
-1 1352 var objects = [].concat(object);
-1 1353
-1 1354 Events.trigger(composite, 'beforeRemove', { object: object });
-1 1355
-1 1356 for (var i = 0; i < objects.length; i++) {
-1 1357 var obj = objects[i];
-1 1358
-1 1359 switch (obj.type) {
-1 1360
-1 1361 case 'body':
-1 1362 Composite.removeBody(composite, obj, deep);
-1 1363 break;
-1 1364 case 'constraint':
-1 1365 Composite.removeConstraint(composite, obj, deep);
-1 1366 break;
-1 1367 case 'composite':
-1 1368 Composite.removeComposite(composite, obj, deep);
-1 1369 break;
-1 1370 case 'mouseConstraint':
-1 1371 Composite.removeConstraint(composite, obj.constraint);
-1 1372 break;
-1 1373
-1 1374 }
-1 1375 }
-1 1376
-1 1377 Events.trigger(composite, 'afterRemove', { object: object });
-1 1378
-1 1379 return composite;
-1 1380 };
-1 1381
-1 1382 /**
-1 1383 * Adds a composite to the given composite.
-1 1384 * @private
-1 1385 * @method addComposite
-1 1386 * @param {composite} compositeA
-1 1387 * @param {composite} compositeB
-1 1388 * @return {composite} The original compositeA with the objects from compositeB added
-1 1389 */
-1 1390 Composite.addComposite = function(compositeA, compositeB) {
-1 1391 compositeA.composites.push(compositeB);
-1 1392 compositeB.parent = compositeA;
-1 1393 Composite.setModified(compositeA, true, true, false);
-1 1394 return compositeA;
-1 1395 };
-1 1396
-1 1397 /**
-1 1398 * Removes a composite from the given composite, and optionally searching its children recursively.
-1 1399 * @private
-1 1400 * @method removeComposite
-1 1401 * @param {composite} compositeA
-1 1402 * @param {composite} compositeB
-1 1403 * @param {boolean} [deep=false]
-1 1404 * @return {composite} The original compositeA with the composite removed
-1 1405 */
-1 1406 Composite.removeComposite = function(compositeA, compositeB, deep) {
-1 1407 var position = Common.indexOf(compositeA.composites, compositeB);
-1 1408 if (position !== -1) {
-1 1409 Composite.removeCompositeAt(compositeA, position);
-1 1410 Composite.setModified(compositeA, true, true, false);
-1 1411 }
-1 1412
-1 1413 if (deep) {
-1 1414 for (var i = 0; i < compositeA.composites.length; i++){
-1 1415 Composite.removeComposite(compositeA.composites[i], compositeB, true);
-1 1416 }
-1 1417 }
-1 1418
-1 1419 return compositeA;
-1 1420 };
-1 1421
-1 1422 /**
-1 1423 * Removes a composite from the given composite.
-1 1424 * @private
-1 1425 * @method removeCompositeAt
-1 1426 * @param {composite} composite
-1 1427 * @param {number} position
-1 1428 * @return {composite} The original composite with the composite removed
-1 1429 */
-1 1430 Composite.removeCompositeAt = function(composite, position) {
-1 1431 composite.composites.splice(position, 1);
-1 1432 Composite.setModified(composite, true, true, false);
-1 1433 return composite;
-1 1434 };
-1 1435
-1 1436 /**
-1 1437 * Adds a body to the given composite.
-1 1438 * @private
-1 1439 * @method addBody
-1 1440 * @param {composite} composite
-1 1441 * @param {body} body
-1 1442 * @return {composite} The original composite with the body added
-1 1443 */
-1 1444 Composite.addBody = function(composite, body) {
-1 1445 composite.bodies.push(body);
-1 1446 Composite.setModified(composite, true, true, false);
-1 1447 return composite;
-1 1448 };
-1 1449
-1 1450 /**
-1 1451 * Removes a body from the given composite, and optionally searching its children recursively.
-1 1452 * @private
-1 1453 * @method removeBody
-1 1454 * @param {composite} composite
-1 1455 * @param {body} body
-1 1456 * @param {boolean} [deep=false]
-1 1457 * @return {composite} The original composite with the body removed
-1 1458 */
-1 1459 Composite.removeBody = function(composite, body, deep) {
-1 1460 var position = Common.indexOf(composite.bodies, body);
-1 1461 if (position !== -1) {
-1 1462 Composite.removeBodyAt(composite, position);
-1 1463 Composite.setModified(composite, true, true, false);
-1 1464 }
-1 1465
-1 1466 if (deep) {
-1 1467 for (var i = 0; i < composite.composites.length; i++){
-1 1468 Composite.removeBody(composite.composites[i], body, true);
-1 1469 }
-1 1470 }
-1 1471
-1 1472 return composite;
-1 1473 };
-1 1474
-1 1475 /**
-1 1476 * Removes a body from the given composite.
-1 1477 * @private
-1 1478 * @method removeBodyAt
-1 1479 * @param {composite} composite
-1 1480 * @param {number} position
-1 1481 * @return {composite} The original composite with the body removed
-1 1482 */
-1 1483 Composite.removeBodyAt = function(composite, position) {
-1 1484 composite.bodies.splice(position, 1);
-1 1485 Composite.setModified(composite, true, true, false);
-1 1486 return composite;
-1 1487 };
-1 1488
-1 1489 /**
-1 1490 * Adds a constraint to the given composite.
-1 1491 * @private
-1 1492 * @method addConstraint
-1 1493 * @param {composite} composite
-1 1494 * @param {constraint} constraint
-1 1495 * @return {composite} The original composite with the constraint added
-1 1496 */
-1 1497 Composite.addConstraint = function(composite, constraint) {
-1 1498 composite.constraints.push(constraint);
-1 1499 Composite.setModified(composite, true, true, false);
-1 1500 return composite;
-1 1501 };
-1 1502
-1 1503 /**
-1 1504 * Removes a constraint from the given composite, and optionally searching its children recursively.
-1 1505 * @private
-1 1506 * @method removeConstraint
-1 1507 * @param {composite} composite
-1 1508 * @param {constraint} constraint
-1 1509 * @param {boolean} [deep=false]
-1 1510 * @return {composite} The original composite with the constraint removed
-1 1511 */
-1 1512 Composite.removeConstraint = function(composite, constraint, deep) {
-1 1513 var position = Common.indexOf(composite.constraints, constraint);
-1 1514 if (position !== -1) {
-1 1515 Composite.removeConstraintAt(composite, position);
-1 1516 }
-1 1517
-1 1518 if (deep) {
-1 1519 for (var i = 0; i < composite.composites.length; i++){
-1 1520 Composite.removeConstraint(composite.composites[i], constraint, true);
-1 1521 }
-1 1522 }
-1 1523
-1 1524 return composite;
-1 1525 };
-1 1526
-1 1527 /**
-1 1528 * Removes a body from the given composite.
-1 1529 * @private
-1 1530 * @method removeConstraintAt
-1 1531 * @param {composite} composite
-1 1532 * @param {number} position
-1 1533 * @return {composite} The original composite with the constraint removed
-1 1534 */
-1 1535 Composite.removeConstraintAt = function(composite, position) {
-1 1536 composite.constraints.splice(position, 1);
-1 1537 Composite.setModified(composite, true, true, false);
-1 1538 return composite;
-1 1539 };
-1 1540
-1 1541 /**
-1 1542 * Removes all bodies, constraints and composites from the given composite.
-1 1543 * Optionally clearing its children recursively.
-1 1544 * @method clear
-1 1545 * @param {composite} composite
-1 1546 * @param {boolean} keepStatic
-1 1547 * @param {boolean} [deep=false]
-1 1548 */
-1 1549 Composite.clear = function(composite, keepStatic, deep) {
-1 1550 if (deep) {
-1 1551 for (var i = 0; i < composite.composites.length; i++){
-1 1552 Composite.clear(composite.composites[i], keepStatic, true);
-1 1553 }
-1 1554 }
-1 1555
-1 1556 if (keepStatic) {
-1 1557 composite.bodies = composite.bodies.filter(function(body) { return body.isStatic; });
-1 1558 } else {
-1 1559 composite.bodies.length = 0;
-1 1560 }
-1 1561
-1 1562 composite.constraints.length = 0;
-1 1563 composite.composites.length = 0;
-1 1564 Composite.setModified(composite, true, true, false);
-1 1565
-1 1566 return composite;
-1 1567 };
-1 1568
-1 1569 /**
-1 1570 * Returns all bodies in the given composite, including all bodies in its children, recursively.
-1 1571 * @method allBodies
-1 1572 * @param {composite} composite
-1 1573 * @return {body[]} All the bodies
-1 1574 */
-1 1575 Composite.allBodies = function(composite) {
-1 1576 var bodies = [].concat(composite.bodies);
-1 1577
-1 1578 for (var i = 0; i < composite.composites.length; i++)
-1 1579 bodies = bodies.concat(Composite.allBodies(composite.composites[i]));
-1 1580
-1 1581 return bodies;
-1 1582 };
-1 1583
-1 1584 /**
-1 1585 * Returns all constraints in the given composite, including all constraints in its children, recursively.
-1 1586 * @method allConstraints
-1 1587 * @param {composite} composite
-1 1588 * @return {constraint[]} All the constraints
-1 1589 */
-1 1590 Composite.allConstraints = function(composite) {
-1 1591 var constraints = [].concat(composite.constraints);
-1 1592
-1 1593 for (var i = 0; i < composite.composites.length; i++)
-1 1594 constraints = constraints.concat(Composite.allConstraints(composite.composites[i]));
-1 1595
-1 1596 return constraints;
-1 1597 };
-1 1598
-1 1599 /**
-1 1600 * Returns all composites in the given composite, including all composites in its children, recursively.
-1 1601 * @method allComposites
-1 1602 * @param {composite} composite
-1 1603 * @return {composite[]} All the composites
-1 1604 */
-1 1605 Composite.allComposites = function(composite) {
-1 1606 var composites = [].concat(composite.composites);
-1 1607
-1 1608 for (var i = 0; i < composite.composites.length; i++)
-1 1609 composites = composites.concat(Composite.allComposites(composite.composites[i]));
-1 1610
-1 1611 return composites;
-1 1612 };
-1 1613
-1 1614 /**
-1 1615 * Searches the composite recursively for an object matching the type and id supplied, null if not found.
-1 1616 * @method get
-1 1617 * @param {composite} composite
-1 1618 * @param {number} id
-1 1619 * @param {string} type
-1 1620 * @return {object} The requested object, if found
-1 1621 */
-1 1622 Composite.get = function(composite, id, type) {
-1 1623 var objects,
-1 1624 object;
-1 1625
-1 1626 switch (type) {
-1 1627 case 'body':
-1 1628 objects = Composite.allBodies(composite);
-1 1629 break;
-1 1630 case 'constraint':
-1 1631 objects = Composite.allConstraints(composite);
-1 1632 break;
-1 1633 case 'composite':
-1 1634 objects = Composite.allComposites(composite).concat(composite);
-1 1635 break;
-1 1636 }
-1 1637
-1 1638 if (!objects)
-1 1639 return null;
-1 1640
-1 1641 object = objects.filter(function(object) {
-1 1642 return object.id.toString() === id.toString();
-1 1643 });
-1 1644
-1 1645 return object.length === 0 ? null : object[0];
-1 1646 };
-1 1647
-1 1648 /**
-1 1649 * Moves the given object(s) from compositeA to compositeB (equal to a remove followed by an add).
-1 1650 * @method move
-1 1651 * @param {compositeA} compositeA
-1 1652 * @param {object[]} objects
-1 1653 * @param {compositeB} compositeB
-1 1654 * @return {composite} Returns compositeA
-1 1655 */
-1 1656 Composite.move = function(compositeA, objects, compositeB) {
-1 1657 Composite.remove(compositeA, objects);
-1 1658 Composite.add(compositeB, objects);
-1 1659 return compositeA;
-1 1660 };
-1 1661
-1 1662 /**
-1 1663 * Assigns new ids for all objects in the composite, recursively.
-1 1664 * @method rebase
-1 1665 * @param {composite} composite
-1 1666 * @return {composite} Returns composite
-1 1667 */
-1 1668 Composite.rebase = function(composite) {
-1 1669 var objects = Composite.allBodies(composite)
-1 1670 .concat(Composite.allConstraints(composite))
-1 1671 .concat(Composite.allComposites(composite));
-1 1672
-1 1673 for (var i = 0; i < objects.length; i++) {
-1 1674 objects[i].id = Common.nextId();
-1 1675 }
-1 1676
-1 1677 Composite.setModified(composite, true, true, false);
-1 1678
-1 1679 return composite;
-1 1680 };
-1 1681
-1 1682 /**
-1 1683 * Translates all children in the composite by a given vector relative to their current positions,
-1 1684 * without imparting any velocity.
-1 1685 * @method translate
-1 1686 * @param {composite} composite
-1 1687 * @param {vector} translation
-1 1688 * @param {bool} [recursive=true]
-1 1689 */
-1 1690 Composite.translate = function(composite, translation, recursive) {
-1 1691 var bodies = recursive ? Composite.allBodies(composite) : composite.bodies;
-1 1692
-1 1693 for (var i = 0; i < bodies.length; i++) {
-1 1694 Body.translate(bodies[i], translation);
-1 1695 }
-1 1696
-1 1697 Composite.setModified(composite, true, true, false);
-1 1698
-1 1699 return composite;
-1 1700 };
-1 1701
-1 1702 /**
-1 1703 * Rotates all children in the composite by a given angle about the given point, without imparting any angular velocity.
-1 1704 * @method rotate
-1 1705 * @param {composite} composite
-1 1706 * @param {number} rotation
-1 1707 * @param {vector} point
-1 1708 * @param {bool} [recursive=true]
-1 1709 */
-1 1710 Composite.rotate = function(composite, rotation, point, recursive) {
-1 1711 var cos = Math.cos(rotation),
-1 1712 sin = Math.sin(rotation),
-1 1713 bodies = recursive ? Composite.allBodies(composite) : composite.bodies;
-1 1714
-1 1715 for (var i = 0; i < bodies.length; i++) {
-1 1716 var body = bodies[i],
-1 1717 dx = body.position.x - point.x,
-1 1718 dy = body.position.y - point.y;
-1 1719
-1 1720 Body.setPosition(body, {
-1 1721 x: point.x + (dx * cos - dy * sin),
-1 1722 y: point.y + (dx * sin + dy * cos)
-1 1723 });
-1 1724
-1 1725 Body.rotate(body, rotation);
-1 1726 }
-1 1727
-1 1728 Composite.setModified(composite, true, true, false);
-1 1729
-1 1730 return composite;
-1 1731 };
-1 1732
-1 1733 /**
-1 1734 * Scales all children in the composite, including updating physical properties (mass, area, axes, inertia), from a world-space point.
-1 1735 * @method scale
-1 1736 * @param {composite} composite
-1 1737 * @param {number} scaleX
-1 1738 * @param {number} scaleY
-1 1739 * @param {vector} point
-1 1740 * @param {bool} [recursive=true]
-1 1741 */
-1 1742 Composite.scale = function(composite, scaleX, scaleY, point, recursive) {
-1 1743 var bodies = recursive ? Composite.allBodies(composite) : composite.bodies;
-1 1744
-1 1745 for (var i = 0; i < bodies.length; i++) {
-1 1746 var body = bodies[i],
-1 1747 dx = body.position.x - point.x,
-1 1748 dy = body.position.y - point.y;
-1 1749
-1 1750 Body.setPosition(body, {
-1 1751 x: point.x + dx * scaleX,
-1 1752 y: point.y + dy * scaleY
-1 1753 });
-1 1754
-1 1755 Body.scale(body, scaleX, scaleY);
-1 1756 }
-1 1757
-1 1758 Composite.setModified(composite, true, true, false);
-1 1759
-1 1760 return composite;
-1 1761 };
-1 1762
-1 1763 /**
-1 1764 * Returns the union of the bounds of all of the composite's bodies.
-1 1765 * @method bounds
-1 1766 * @param {composite} composite The composite.
-1 1767 * @returns {bounds} The composite bounds.
-1 1768 */
-1 1769 Composite.bounds = function(composite) {
-1 1770 var bodies = Composite.allBodies(composite),
-1 1771 vertices = [];
-1 1772
-1 1773 for (var i = 0; i < bodies.length; i += 1) {
-1 1774 var body = bodies[i];
-1 1775 vertices.push(body.bounds.min, body.bounds.max);
-1 1776 }
-1 1777
-1 1778 return Bounds.create(vertices);
-1 1779 };
-1 1780
-1 1781 /*
-1 1782 *
-1 1783 * Events Documentation
-1 1784 *
-1 1785 */
-1 1786
-1 1787 /**
-1 1788 * Fired when a call to `Composite.add` is made, before objects have been added.
-1 1789 *
-1 1790 * @event beforeAdd
-1 1791 * @param {} event An event object
-1 1792 * @param {} event.object The object(s) to be added (may be a single body, constraint, composite or a mixed array of these)
-1 1793 * @param {} event.source The source object of the event
-1 1794 * @param {} event.name The name of the event
-1 1795 */
-1 1796
-1 1797 /**
-1 1798 * Fired when a call to `Composite.add` is made, after objects have been added.
-1 1799 *
-1 1800 * @event afterAdd
-1 1801 * @param {} event An event object
-1 1802 * @param {} event.object The object(s) that have been added (may be a single body, constraint, composite or a mixed array of these)
-1 1803 * @param {} event.source The source object of the event
-1 1804 * @param {} event.name The name of the event
-1 1805 */
-1 1806
-1 1807 /**
-1 1808 * Fired when a call to `Composite.remove` is made, before objects have been removed.
-1 1809 *
-1 1810 * @event beforeRemove
-1 1811 * @param {} event An event object
-1 1812 * @param {} event.object The object(s) to be removed (may be a single body, constraint, composite or a mixed array of these)
-1 1813 * @param {} event.source The source object of the event
-1 1814 * @param {} event.name The name of the event
-1 1815 */
-1 1816
-1 1817 /**
-1 1818 * Fired when a call to `Composite.remove` is made, after objects have been removed.
-1 1819 *
-1 1820 * @event afterRemove
-1 1821 * @param {} event An event object
-1 1822 * @param {} event.object The object(s) that have been removed (may be a single body, constraint, composite or a mixed array of these)
-1 1823 * @param {} event.source The source object of the event
-1 1824 * @param {} event.name The name of the event
-1 1825 */
-1 1826
-1 1827 /*
-1 1828 *
-1 1829 * Properties Documentation
-1 1830 *
-1 1831 */
-1 1832
-1 1833 /**
-1 1834 * An integer `Number` uniquely identifying number generated in `Composite.create` by `Common.nextId`.
-1 1835 *
-1 1836 * @property id
-1 1837 * @type number
-1 1838 */
-1 1839
-1 1840 /**
-1 1841 * A `String` denoting the type of object.
-1 1842 *
-1 1843 * @property type
-1 1844 * @type string
-1 1845 * @default "composite"
-1 1846 * @readOnly
-1 1847 */
-1 1848
-1 1849 /**
-1 1850 * An arbitrary `String` name to help the user identify and manage composites.
-1 1851 *
-1 1852 * @property label
-1 1853 * @type string
-1 1854 * @default "Composite"
-1 1855 */
-1 1856
-1 1857 /**
-1 1858 * A flag that specifies whether the composite has been modified during the current step.
-1 1859 * Most `Matter.Composite` methods will automatically set this flag to `true` to inform the engine of changes to be handled.
-1 1860 * If you need to change it manually, you should use the `Composite.setModified` method.
-1 1861 *
-1 1862 * @property isModified
-1 1863 * @type boolean
-1 1864 * @default false
-1 1865 */
-1 1866
-1 1867 /**
-1 1868 * The `Composite` that is the parent of this composite. It is automatically managed by the `Matter.Composite` methods.
-1 1869 *
-1 1870 * @property parent
-1 1871 * @type composite
-1 1872 * @default null
-1 1873 */
-1 1874
-1 1875 /**
-1 1876 * An array of `Body` that are _direct_ children of this composite.
-1 1877 * To add or remove bodies you should use `Composite.add` and `Composite.remove` methods rather than directly modifying this property.
-1 1878 * If you wish to recursively find all descendants, you should use the `Composite.allBodies` method.
-1 1879 *
-1 1880 * @property bodies
-1 1881 * @type body[]
-1 1882 * @default []
-1 1883 */
-1 1884
-1 1885 /**
-1 1886 * An array of `Constraint` that are _direct_ children of this composite.
-1 1887 * To add or remove constraints you should use `Composite.add` and `Composite.remove` methods rather than directly modifying this property.
-1 1888 * If you wish to recursively find all descendants, you should use the `Composite.allConstraints` method.
-1 1889 *
-1 1890 * @property constraints
-1 1891 * @type constraint[]
-1 1892 * @default []
-1 1893 */
-1 1894
-1 1895 /**
-1 1896 * An array of `Composite` that are _direct_ children of this composite.
-1 1897 * To add or remove composites you should use `Composite.add` and `Composite.remove` methods rather than directly modifying this property.
-1 1898 * If you wish to recursively find all descendants, you should use the `Composite.allComposites` method.
-1 1899 *
-1 1900 * @property composites
-1 1901 * @type composite[]
-1 1902 * @default []
-1 1903 */
-1 1904
-1 1905 /**
-1 1906 * An object reserved for storing plugin-specific properties.
-1 1907 *
-1 1908 * @property plugin
-1 1909 * @type {}
-1 1910 */
-1 1911
-1 1912 })();
-1 1913
-1 1914 },{"../core/Common":14,"../core/Events":16,"../geometry/Bounds":26,"./Body":1}],3:[function(_dereq_,module,exports){
-1 1915 /**
-1 1916 * The `Matter.World` module contains methods for creating and manipulating the world composite.
-1 1917 * A `Matter.World` is a `Matter.Composite` body, which is a collection of `Matter.Body`, `Matter.Constraint` and other `Matter.Composite`.
-1 1918 * A `Matter.World` has a few additional properties including `gravity` and `bounds`.
-1 1919 * It is important to use the functions in the `Matter.Composite` module to modify the world composite, rather than directly modifying its properties.
-1 1920 * There are also a few methods here that alias those in `Matter.Composite` for easier readability.
-1 1921 *
-1 1922 * See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples).
-1 1923 *
-1 1924 * @class World
-1 1925 * @extends Composite
-1 1926 */
-1 1927
-1 1928 var World = {};
-1 1929
-1 1930 module.exports = World;
-1 1931
-1 1932 var Composite = _dereq_('./Composite');
-1 1933 var Constraint = _dereq_('../constraint/Constraint');
-1 1934 var Common = _dereq_('../core/Common');
-1 1935
-1 1936 (function() {
-1 1937
-1 1938 /**
-1 1939 * Creates a new world composite. The options parameter is an object that specifies any properties you wish to override the defaults.
-1 1940 * See the properties section below for detailed information on what you can pass via the `options` object.
-1 1941 * @method create
-1 1942 * @constructor
-1 1943 * @param {} options
-1 1944 * @return {world} A new world
-1 1945 */
-1 1946 World.create = function(options) {
-1 1947 var composite = Composite.create();
-1 1948
-1 1949 var defaults = {
-1 1950 label: 'World',
-1 1951 gravity: {
-1 1952 x: 0,
-1 1953 y: 1,
-1 1954 scale: 0.001
-1 1955 },
-1 1956 bounds: {
-1 1957 min: { x: -Infinity, y: -Infinity },
-1 1958 max: { x: Infinity, y: Infinity }
-1 1959 }
-1 1960 };
-1 1961
-1 1962 return Common.extend(composite, defaults, options);
-1 1963 };
-1 1964
-1 1965 /*
-1 1966 *
-1 1967 * Properties Documentation
-1 1968 *
-1 1969 */
-1 1970
-1 1971 /**
-1 1972 * The gravity to apply on the world.
-1 1973 *
-1 1974 * @property gravity
-1 1975 * @type object
-1 1976 */
-1 1977
-1 1978 /**
-1 1979 * The gravity x component.
-1 1980 *
-1 1981 * @property gravity.x
-1 1982 * @type object
-1 1983 * @default 0
-1 1984 */
-1 1985
-1 1986 /**
-1 1987 * The gravity y component.
-1 1988 *
-1 1989 * @property gravity.y
-1 1990 * @type object
-1 1991 * @default 1
-1 1992 */
-1 1993
-1 1994 /**
-1 1995 * The gravity scale factor.
-1 1996 *
-1 1997 * @property gravity.scale
-1 1998 * @type object
-1 1999 * @default 0.001
-1 2000 */
-1 2001
-1 2002 /**
-1 2003 * A `Bounds` object that defines the world bounds for collision detection.
-1 2004 *
-1 2005 * @property bounds
-1 2006 * @type bounds
-1 2007 * @default { min: { x: -Infinity, y: -Infinity }, max: { x: Infinity, y: Infinity } }
-1 2008 */
-1 2009
-1 2010 // World is a Composite body
-1 2011 // see src/module/Outro.js for these aliases:
-1 2012
-1 2013 /**
-1 2014 * An alias for Composite.add
-1 2015 * @method add
-1 2016 * @param {world} world
-1 2017 * @param {} object
-1 2018 * @return {composite} The original world with the objects added
-1 2019 */
-1 2020
-1 2021 /**
-1 2022 * An alias for Composite.remove
-1 2023 * @method remove
-1 2024 * @param {world} world
-1 2025 * @param {} object
-1 2026 * @param {boolean} [deep=false]
-1 2027 * @return {composite} The original world with the objects removed
-1 2028 */
-1 2029
-1 2030 /**
-1 2031 * An alias for Composite.clear
-1 2032 * @method clear
-1 2033 * @param {world} world
-1 2034 * @param {boolean} keepStatic
-1 2035 */
-1 2036
-1 2037 /**
-1 2038 * An alias for Composite.addComposite
-1 2039 * @method addComposite
-1 2040 * @param {world} world
-1 2041 * @param {composite} composite
-1 2042 * @return {world} The original world with the objects from composite added
-1 2043 */
-1 2044
-1 2045 /**
-1 2046 * An alias for Composite.addBody
-1 2047 * @method addBody
-1 2048 * @param {world} world
-1 2049 * @param {body} body
-1 2050 * @return {world} The original world with the body added
-1 2051 */
-1 2052
-1 2053 /**
-1 2054 * An alias for Composite.addConstraint
-1 2055 * @method addConstraint
-1 2056 * @param {world} world
-1 2057 * @param {constraint} constraint
-1 2058 * @return {world} The original world with the constraint added
-1 2059 */
-1 2060
-1 2061 })();
-1 2062
-1 2063 },{"../constraint/Constraint":12,"../core/Common":14,"./Composite":2}],4:[function(_dereq_,module,exports){
-1 2064 /**
-1 2065 * The `Matter.Contact` module contains methods for creating and manipulating collision contacts.
-1 2066 *
-1 2067 * @class Contact
-1 2068 */
-1 2069
-1 2070 var Contact = {};
-1 2071
-1 2072 module.exports = Contact;
-1 2073
-1 2074 (function() {
-1 2075
-1 2076 /**
-1 2077 * Creates a new contact.
-1 2078 * @method create
-1 2079 * @param {vertex} vertex
-1 2080 * @return {contact} A new contact
-1 2081 */
-1 2082 Contact.create = function(vertex) {
-1 2083 return {
-1 2084 id: Contact.id(vertex),
-1 2085 vertex: vertex,
-1 2086 normalImpulse: 0,
-1 2087 tangentImpulse: 0
-1 2088 };
-1 2089 };
-1 2090
-1 2091 /**
-1 2092 * Generates a contact id.
-1 2093 * @method id
-1 2094 * @param {vertex} vertex
-1 2095 * @return {string} Unique contactID
-1 2096 */
-1 2097 Contact.id = function(vertex) {
-1 2098 return vertex.body.id + '_' + vertex.index;
-1 2099 };
-1 2100
-1 2101 })();
-1 2102
-1 2103 },{}],5:[function(_dereq_,module,exports){
-1 2104 /**
-1 2105 * The `Matter.Detector` module contains methods for detecting collisions given a set of pairs.
-1 2106 *
-1 2107 * @class Detector
-1 2108 */
-1 2109
-1 2110 // TODO: speculative contacts
-1 2111
-1 2112 var Detector = {};
-1 2113
-1 2114 module.exports = Detector;
-1 2115
-1 2116 var SAT = _dereq_('./SAT');
-1 2117 var Pair = _dereq_('./Pair');
-1 2118 var Bounds = _dereq_('../geometry/Bounds');
-1 2119
-1 2120 (function() {
-1 2121
-1 2122 /**
-1 2123 * Finds all collisions given a list of pairs.
-1 2124 * @method collisions
-1 2125 * @param {pair[]} broadphasePairs
-1 2126 * @param {engine} engine
-1 2127 * @return {array} collisions
-1 2128 */
-1 2129 Detector.collisions = function(broadphasePairs, engine) {
-1 2130 var collisions = [],
-1 2131 pairsTable = engine.pairs.table;
-1 2132
-1 2133
-1 2134 for (var i = 0; i < broadphasePairs.length; i++) {
-1 2135 var bodyA = broadphasePairs[i][0],
-1 2136 bodyB = broadphasePairs[i][1];
-1 2137
-1 2138 if ((bodyA.isStatic || bodyA.isSleeping) && (bodyB.isStatic || bodyB.isSleeping))
-1 2139 continue;
-1 2140
-1 2141 if (!Detector.canCollide(bodyA.collisionFilter, bodyB.collisionFilter))
-1 2142 continue;
-1 2143
-1 2144
-1 2145 // mid phase
-1 2146 if (Bounds.overlaps(bodyA.bounds, bodyB.bounds)) {
-1 2147 for (var j = bodyA.parts.length > 1 ? 1 : 0; j < bodyA.parts.length; j++) {
-1 2148 var partA = bodyA.parts[j];
-1 2149
-1 2150 for (var k = bodyB.parts.length > 1 ? 1 : 0; k < bodyB.parts.length; k++) {
-1 2151 var partB = bodyB.parts[k];
-1 2152
-1 2153 if ((partA === bodyA && partB === bodyB) || Bounds.overlaps(partA.bounds, partB.bounds)) {
-1 2154 // find a previous collision we could reuse
-1 2155 var pairId = Pair.id(partA, partB),
-1 2156 pair = pairsTable[pairId],
-1 2157 previousCollision;
-1 2158
-1 2159 if (pair && pair.isActive) {
-1 2160 previousCollision = pair.collision;
-1 2161 } else {
-1 2162 previousCollision = null;
-1 2163 }
-1 2164
-1 2165 // narrow phase
-1 2166 var collision = SAT.collides(partA, partB, previousCollision);
-1 2167
-1 2168
-1 2169 if (collision.collided) {
-1 2170 collisions.push(collision);
-1 2171 }
-1 2172 }
-1 2173 }
-1 2174 }
-1 2175 }
-1 2176 }
-1 2177
-1 2178 return collisions;
-1 2179 };
-1 2180
-1 2181 /**
-1 2182 * Returns `true` if both supplied collision filters will allow a collision to occur.
-1 2183 * See `body.collisionFilter` for more information.
-1 2184 * @method canCollide
-1 2185 * @param {} filterA
-1 2186 * @param {} filterB
-1 2187 * @return {bool} `true` if collision can occur
-1 2188 */
-1 2189 Detector.canCollide = function(filterA, filterB) {
-1 2190 if (filterA.group === filterB.group && filterA.group !== 0)
-1 2191 return filterA.group > 0;
-1 2192
-1 2193 return (filterA.mask & filterB.category) !== 0 && (filterB.mask & filterA.category) !== 0;
-1 2194 };
-1 2195
-1 2196 })();
-1 2197
-1 2198 },{"../geometry/Bounds":26,"./Pair":7,"./SAT":11}],6:[function(_dereq_,module,exports){
-1 2199 /**
-1 2200 * The `Matter.Grid` module contains methods for creating and manipulating collision broadphase grid structures.
-1 2201 *
-1 2202 * @class Grid
-1 2203 */
-1 2204
-1 2205 var Grid = {};
-1 2206
-1 2207 module.exports = Grid;
-1 2208
-1 2209 var Pair = _dereq_('./Pair');
-1 2210 var Detector = _dereq_('./Detector');
-1 2211 var Common = _dereq_('../core/Common');
-1 2212
-1 2213 (function() {
-1 2214
-1 2215 /**
-1 2216 * Creates a new grid.
-1 2217 * @method create
-1 2218 * @param {} options
-1 2219 * @return {grid} A new grid
-1 2220 */
-1 2221 Grid.create = function(options) {
-1 2222 var defaults = {
-1 2223 controller: Grid,
-1 2224 detector: Detector.collisions,
-1 2225 buckets: {},
-1 2226 pairs: {},
-1 2227 pairsList: [],
-1 2228 bucketWidth: 48,
-1 2229 bucketHeight: 48
-1 2230 };
-1 2231
-1 2232 return Common.extend(defaults, options);
-1 2233 };
-1 2234
-1 2235 /**
-1 2236 * The width of a single grid bucket.
-1 2237 *
-1 2238 * @property bucketWidth
-1 2239 * @type number
-1 2240 * @default 48
-1 2241 */
-1 2242
-1 2243 /**
-1 2244 * The height of a single grid bucket.
-1 2245 *
-1 2246 * @property bucketHeight
-1 2247 * @type number
-1 2248 * @default 48
-1 2249 */
-1 2250
-1 2251 /**
-1 2252 * Updates the grid.
-1 2253 * @method update
-1 2254 * @param {grid} grid
-1 2255 * @param {body[]} bodies
-1 2256 * @param {engine} engine
-1 2257 * @param {boolean} forceUpdate
-1 2258 */
-1 2259 Grid.update = function(grid, bodies, engine, forceUpdate) {
-1 2260 var i, col, row,
-1 2261 world = engine.world,
-1 2262 buckets = grid.buckets,
-1 2263 bucket,
-1 2264 bucketId,
-1 2265 gridChanged = false;
-1 2266
-1 2267
-1 2268 for (i = 0; i < bodies.length; i++) {
-1 2269 var body = bodies[i];
-1 2270
-1 2271 if (body.isSleeping && !forceUpdate)
-1 2272 continue;
-1 2273
-1 2274 // don't update out of world bodies
-1 2275 if (body.bounds.max.x < world.bounds.min.x || body.bounds.min.x > world.bounds.max.x
-1 2276 || body.bounds.max.y < world.bounds.min.y || body.bounds.min.y > world.bounds.max.y)
-1 2277 continue;
-1 2278
-1 2279 var newRegion = Grid._getRegion(grid, body);
-1 2280
-1 2281 // if the body has changed grid region
-1 2282 if (!body.region || newRegion.id !== body.region.id || forceUpdate) {
-1 2283
-1 2284
-1 2285 if (!body.region || forceUpdate)
-1 2286 body.region = newRegion;
-1 2287
-1 2288 var union = Grid._regionUnion(newRegion, body.region);
-1 2289
-1 2290 // update grid buckets affected by region change
-1 2291 // iterate over the union of both regions
-1 2292 for (col = union.startCol; col <= union.endCol; col++) {
-1 2293 for (row = union.startRow; row <= union.endRow; row++) {
-1 2294 bucketId = Grid._getBucketId(col, row);
-1 2295 bucket = buckets[bucketId];
-1 2296
-1 2297 var isInsideNewRegion = (col >= newRegion.startCol && col <= newRegion.endCol
-1 2298 && row >= newRegion.startRow && row <= newRegion.endRow);
-1 2299
-1 2300 var isInsideOldRegion = (col >= body.region.startCol && col <= body.region.endCol
-1 2301 && row >= body.region.startRow && row <= body.region.endRow);
-1 2302
-1 2303 // remove from old region buckets
-1 2304 if (!isInsideNewRegion && isInsideOldRegion) {
-1 2305 if (isInsideOldRegion) {
-1 2306 if (bucket)
-1 2307 Grid._bucketRemoveBody(grid, bucket, body);
-1 2308 }
-1 2309 }
-1 2310
-1 2311 // add to new region buckets
-1 2312 if (body.region === newRegion || (isInsideNewRegion && !isInsideOldRegion) || forceUpdate) {
-1 2313 if (!bucket)
-1 2314 bucket = Grid._createBucket(buckets, bucketId);
-1 2315 Grid._bucketAddBody(grid, bucket, body);
-1 2316 }
-1 2317 }
-1 2318 }
-1 2319
-1 2320 // set the new region
-1 2321 body.region = newRegion;
-1 2322
-1 2323 // flag changes so we can update pairs
-1 2324 gridChanged = true;
-1 2325 }
-1 2326 }
-1 2327
-1 2328 // update pairs list only if pairs changed (i.e. a body changed region)
-1 2329 if (gridChanged)
-1 2330 grid.pairsList = Grid._createActivePairsList(grid);
-1 2331 };
-1 2332
-1 2333 /**
-1 2334 * Clears the grid.
-1 2335 * @method clear
-1 2336 * @param {grid} grid
-1 2337 */
-1 2338 Grid.clear = function(grid) {
-1 2339 grid.buckets = {};
-1 2340 grid.pairs = {};
-1 2341 grid.pairsList = [];
-1 2342 };
-1 2343
-1 2344 /**
-1 2345 * Finds the union of two regions.
-1 2346 * @method _regionUnion
-1 2347 * @private
-1 2348 * @param {} regionA
-1 2349 * @param {} regionB
-1 2350 * @return {} region
-1 2351 */
-1 2352 Grid._regionUnion = function(regionA, regionB) {
-1 2353 var startCol = Math.min(regionA.startCol, regionB.startCol),
-1 2354 endCol = Math.max(regionA.endCol, regionB.endCol),
-1 2355 startRow = Math.min(regionA.startRow, regionB.startRow),
-1 2356 endRow = Math.max(regionA.endRow, regionB.endRow);
-1 2357
-1 2358 return Grid._createRegion(startCol, endCol, startRow, endRow);
-1 2359 };
-1 2360
-1 2361 /**
-1 2362 * Gets the region a given body falls in for a given grid.
-1 2363 * @method _getRegion
-1 2364 * @private
-1 2365 * @param {} grid
-1 2366 * @param {} body
-1 2367 * @return {} region
-1 2368 */
-1 2369 Grid._getRegion = function(grid, body) {
-1 2370 var bounds = body.bounds,
-1 2371 startCol = Math.floor(bounds.min.x / grid.bucketWidth),
-1 2372 endCol = Math.floor(bounds.max.x / grid.bucketWidth),
-1 2373 startRow = Math.floor(bounds.min.y / grid.bucketHeight),
-1 2374 endRow = Math.floor(bounds.max.y / grid.bucketHeight);
-1 2375
-1 2376 return Grid._createRegion(startCol, endCol, startRow, endRow);
-1 2377 };
-1 2378
-1 2379 /**
-1 2380 * Creates a region.
-1 2381 * @method _createRegion
-1 2382 * @private
-1 2383 * @param {} startCol
-1 2384 * @param {} endCol
-1 2385 * @param {} startRow
-1 2386 * @param {} endRow
-1 2387 * @return {} region
-1 2388 */
-1 2389 Grid._createRegion = function(startCol, endCol, startRow, endRow) {
-1 2390 return {
-1 2391 id: startCol + ',' + endCol + ',' + startRow + ',' + endRow,
-1 2392 startCol: startCol,
-1 2393 endCol: endCol,
-1 2394 startRow: startRow,
-1 2395 endRow: endRow
-1 2396 };
-1 2397 };
-1 2398
-1 2399 /**
-1 2400 * Gets the bucket id at the given position.
-1 2401 * @method _getBucketId
-1 2402 * @private
-1 2403 * @param {} column
-1 2404 * @param {} row
-1 2405 * @return {string} bucket id
-1 2406 */
-1 2407 Grid._getBucketId = function(column, row) {
-1 2408 return 'C' + column + 'R' + row;
-1 2409 };
-1 2410
-1 2411 /**
-1 2412 * Creates a bucket.
-1 2413 * @method _createBucket
-1 2414 * @private
-1 2415 * @param {} buckets
-1 2416 * @param {} bucketId
-1 2417 * @return {} bucket
-1 2418 */
-1 2419 Grid._createBucket = function(buckets, bucketId) {
-1 2420 var bucket = buckets[bucketId] = [];
-1 2421 return bucket;
-1 2422 };
-1 2423
-1 2424 /**
-1 2425 * Adds a body to a bucket.
-1 2426 * @method _bucketAddBody
-1 2427 * @private
-1 2428 * @param {} grid
-1 2429 * @param {} bucket
-1 2430 * @param {} body
-1 2431 */
-1 2432 Grid._bucketAddBody = function(grid, bucket, body) {
-1 2433 // add new pairs
-1 2434 for (var i = 0; i < bucket.length; i++) {
-1 2435 var bodyB = bucket[i];
-1 2436
-1 2437 if (body.id === bodyB.id || (body.isStatic && bodyB.isStatic))
-1 2438 continue;
-1 2439
-1 2440 // keep track of the number of buckets the pair exists in
-1 2441 // important for Grid.update to work
-1 2442 var pairId = Pair.id(body, bodyB),
-1 2443 pair = grid.pairs[pairId];
-1 2444
-1 2445 if (pair) {
-1 2446 pair[2] += 1;
-1 2447 } else {
-1 2448 grid.pairs[pairId] = [body, bodyB, 1];
-1 2449 }
-1 2450 }
-1 2451
-1 2452 // add to bodies (after pairs, otherwise pairs with self)
-1 2453 bucket.push(body);
-1 2454 };
-1 2455
-1 2456 /**
-1 2457 * Removes a body from a bucket.
-1 2458 * @method _bucketRemoveBody
-1 2459 * @private
-1 2460 * @param {} grid
-1 2461 * @param {} bucket
-1 2462 * @param {} body
-1 2463 */
-1 2464 Grid._bucketRemoveBody = function(grid, bucket, body) {
-1 2465 // remove from bucket
-1 2466 bucket.splice(Common.indexOf(bucket, body), 1);
-1 2467
-1 2468 // update pair counts
-1 2469 for (var i = 0; i < bucket.length; i++) {
-1 2470 // keep track of the number of buckets the pair exists in
-1 2471 // important for _createActivePairsList to work
-1 2472 var bodyB = bucket[i],
-1 2473 pairId = Pair.id(body, bodyB),
-1 2474 pair = grid.pairs[pairId];
-1 2475
-1 2476 if (pair)
-1 2477 pair[2] -= 1;
-1 2478 }
-1 2479 };
-1 2480
-1 2481 /**
-1 2482 * Generates a list of the active pairs in the grid.
-1 2483 * @method _createActivePairsList
-1 2484 * @private
-1 2485 * @param {} grid
-1 2486 * @return [] pairs
-1 2487 */
-1 2488 Grid._createActivePairsList = function(grid) {
-1 2489 var pairKeys,
-1 2490 pair,
-1 2491 pairs = [];
-1 2492
-1 2493 // grid.pairs is used as a hashmap
-1 2494 pairKeys = Common.keys(grid.pairs);
-1 2495
-1 2496 // iterate over grid.pairs
-1 2497 for (var k = 0; k < pairKeys.length; k++) {
-1 2498 pair = grid.pairs[pairKeys[k]];
-1 2499
-1 2500 // if pair exists in at least one bucket
-1 2501 // it is a pair that needs further collision testing so push it
-1 2502 if (pair[2] > 0) {
-1 2503 pairs.push(pair);
-1 2504 } else {
-1 2505 delete grid.pairs[pairKeys[k]];
-1 2506 }
-1 2507 }
-1 2508
-1 2509 return pairs;
-1 2510 };
-1 2511
-1 2512 })();
-1 2513
-1 2514 },{"../core/Common":14,"./Detector":5,"./Pair":7}],7:[function(_dereq_,module,exports){
-1 2515 /**
-1 2516 * The `Matter.Pair` module contains methods for creating and manipulating collision pairs.
-1 2517 *
-1 2518 * @class Pair
-1 2519 */
-1 2520
-1 2521 var Pair = {};
-1 2522
-1 2523 module.exports = Pair;
-1 2524
-1 2525 var Contact = _dereq_('./Contact');
-1 2526
-1 2527 (function() {
-1 2528
-1 2529 /**
-1 2530 * Creates a pair.
-1 2531 * @method create
-1 2532 * @param {collision} collision
-1 2533 * @param {number} timestamp
-1 2534 * @return {pair} A new pair
-1 2535 */
-1 2536 Pair.create = function(collision, timestamp) {
-1 2537 var bodyA = collision.bodyA,
-1 2538 bodyB = collision.bodyB,
-1 2539 parentA = collision.parentA,
-1 2540 parentB = collision.parentB;
-1 2541
-1 2542 var pair = {
-1 2543 id: Pair.id(bodyA, bodyB),
-1 2544 bodyA: bodyA,
-1 2545 bodyB: bodyB,
-1 2546 contacts: {},
-1 2547 activeContacts: [],
-1 2548 separation: 0,
-1 2549 isActive: true,
-1 2550 isSensor: bodyA.isSensor || bodyB.isSensor,
-1 2551 timeCreated: timestamp,
-1 2552 timeUpdated: timestamp,
-1 2553 inverseMass: parentA.inverseMass + parentB.inverseMass,
-1 2554 friction: Math.min(parentA.friction, parentB.friction),
-1 2555 frictionStatic: Math.max(parentA.frictionStatic, parentB.frictionStatic),
-1 2556 restitution: Math.max(parentA.restitution, parentB.restitution),
-1 2557 slop: Math.max(parentA.slop, parentB.slop)
-1 2558 };
-1 2559
-1 2560 Pair.update(pair, collision, timestamp);
-1 2561
-1 2562 return pair;
-1 2563 };
-1 2564
-1 2565 /**
-1 2566 * Updates a pair given a collision.
-1 2567 * @method update
-1 2568 * @param {pair} pair
-1 2569 * @param {collision} collision
-1 2570 * @param {number} timestamp
-1 2571 */
-1 2572 Pair.update = function(pair, collision, timestamp) {
-1 2573 var contacts = pair.contacts,
-1 2574 supports = collision.supports,
-1 2575 activeContacts = pair.activeContacts,
-1 2576 parentA = collision.parentA,
-1 2577 parentB = collision.parentB;
-1 2578
-1 2579 pair.collision = collision;
-1 2580 pair.inverseMass = parentA.inverseMass + parentB.inverseMass;
-1 2581 pair.friction = Math.min(parentA.friction, parentB.friction);
-1 2582 pair.frictionStatic = Math.max(parentA.frictionStatic, parentB.frictionStatic);
-1 2583 pair.restitution = Math.max(parentA.restitution, parentB.restitution);
-1 2584 pair.slop = Math.max(parentA.slop, parentB.slop);
-1 2585 activeContacts.length = 0;
-1 2586
-1 2587 if (collision.collided) {
-1 2588 for (var i = 0; i < supports.length; i++) {
-1 2589 var support = supports[i],
-1 2590 contactId = Contact.id(support),
-1 2591 contact = contacts[contactId];
-1 2592
-1 2593 if (contact) {
-1 2594 activeContacts.push(contact);
-1 2595 } else {
-1 2596 activeContacts.push(contacts[contactId] = Contact.create(support));
-1 2597 }
-1 2598 }
-1 2599
-1 2600 pair.separation = collision.depth;
-1 2601 Pair.setActive(pair, true, timestamp);
-1 2602 } else {
-1 2603 if (pair.isActive === true)
-1 2604 Pair.setActive(pair, false, timestamp);
-1 2605 }
-1 2606 };
-1 2607
-1 2608 /**
-1 2609 * Set a pair as active or inactive.
-1 2610 * @method setActive
-1 2611 * @param {pair} pair
-1 2612 * @param {bool} isActive
-1 2613 * @param {number} timestamp
-1 2614 */
-1 2615 Pair.setActive = function(pair, isActive, timestamp) {
-1 2616 if (isActive) {
-1 2617 pair.isActive = true;
-1 2618 pair.timeUpdated = timestamp;
-1 2619 } else {
-1 2620 pair.isActive = false;
-1 2621 pair.activeContacts.length = 0;
-1 2622 }
-1 2623 };
-1 2624
-1 2625 /**
-1 2626 * Get the id for the given pair.
-1 2627 * @method id
-1 2628 * @param {body} bodyA
-1 2629 * @param {body} bodyB
-1 2630 * @return {string} Unique pairId
-1 2631 */
-1 2632 Pair.id = function(bodyA, bodyB) {
-1 2633 if (bodyA.id < bodyB.id) {
-1 2634 return 'A' + bodyA.id + 'B' + bodyB.id;
-1 2635 } else {
-1 2636 return 'A' + bodyB.id + 'B' + bodyA.id;
-1 2637 }
-1 2638 };
-1 2639
-1 2640 })();
-1 2641
-1 2642 },{"./Contact":4}],8:[function(_dereq_,module,exports){
-1 2643 /**
-1 2644 * The `Matter.Pairs` module contains methods for creating and manipulating collision pair sets.
-1 2645 *
-1 2646 * @class Pairs
-1 2647 */
-1 2648
-1 2649 var Pairs = {};
-1 2650
-1 2651 module.exports = Pairs;
-1 2652
-1 2653 var Pair = _dereq_('./Pair');
-1 2654 var Common = _dereq_('../core/Common');
-1 2655
-1 2656 (function() {
-1 2657
-1 2658 Pairs._pairMaxIdleLife = 1000;
-1 2659
-1 2660 /**
-1 2661 * Creates a new pairs structure.
-1 2662 * @method create
-1 2663 * @param {object} options
-1 2664 * @return {pairs} A new pairs structure
-1 2665 */
-1 2666 Pairs.create = function(options) {
-1 2667 return Common.extend({
-1 2668 table: {},
-1 2669 list: [],
-1 2670 collisionStart: [],
-1 2671 collisionActive: [],
-1 2672 collisionEnd: []
-1 2673 }, options);
-1 2674 };
-1 2675
-1 2676 /**
-1 2677 * Updates pairs given a list of collisions.
-1 2678 * @method update
-1 2679 * @param {object} pairs
-1 2680 * @param {collision[]} collisions
-1 2681 * @param {number} timestamp
-1 2682 */
-1 2683 Pairs.update = function(pairs, collisions, timestamp) {
-1 2684 var pairsList = pairs.list,
-1 2685 pairsTable = pairs.table,
-1 2686 collisionStart = pairs.collisionStart,
-1 2687 collisionEnd = pairs.collisionEnd,
-1 2688 collisionActive = pairs.collisionActive,
-1 2689 activePairIds = [],
-1 2690 collision,
-1 2691 pairId,
-1 2692 pair,
-1 2693 i;
-1 2694
-1 2695 // clear collision state arrays, but maintain old reference
-1 2696 collisionStart.length = 0;
-1 2697 collisionEnd.length = 0;
-1 2698 collisionActive.length = 0;
-1 2699
-1 2700 for (i = 0; i < collisions.length; i++) {
-1 2701 collision = collisions[i];
-1 2702
-1 2703 if (collision.collided) {
-1 2704 pairId = Pair.id(collision.bodyA, collision.bodyB);
-1 2705 activePairIds.push(pairId);
-1 2706
-1 2707 pair = pairsTable[pairId];
-1 2708
-1 2709 if (pair) {
-1 2710 // pair already exists (but may or may not be active)
-1 2711 if (pair.isActive) {
-1 2712 // pair exists and is active
-1 2713 collisionActive.push(pair);
-1 2714 } else {
-1 2715 // pair exists but was inactive, so a collision has just started again
-1 2716 collisionStart.push(pair);
-1 2717 }
-1 2718
-1 2719 // update the pair
-1 2720 Pair.update(pair, collision, timestamp);
-1 2721 } else {
-1 2722 // pair did not exist, create a new pair
-1 2723 pair = Pair.create(collision, timestamp);
-1 2724 pairsTable[pairId] = pair;
-1 2725
-1 2726 // push the new pair
-1 2727 collisionStart.push(pair);
-1 2728 pairsList.push(pair);
-1 2729 }
-1 2730 }
-1 2731 }
-1 2732
-1 2733 // deactivate previously active pairs that are now inactive
-1 2734 for (i = 0; i < pairsList.length; i++) {
-1 2735 pair = pairsList[i];
-1 2736 if (pair.isActive && Common.indexOf(activePairIds, pair.id) === -1) {
-1 2737 Pair.setActive(pair, false, timestamp);
-1 2738 collisionEnd.push(pair);
-1 2739 }
-1 2740 }
-1 2741 };
-1 2742
-1 2743 /**
-1 2744 * Finds and removes pairs that have been inactive for a set amount of time.
-1 2745 * @method removeOld
-1 2746 * @param {object} pairs
-1 2747 * @param {number} timestamp
-1 2748 */
-1 2749 Pairs.removeOld = function(pairs, timestamp) {
-1 2750 var pairsList = pairs.list,
-1 2751 pairsTable = pairs.table,
-1 2752 indexesToRemove = [],
-1 2753 pair,
-1 2754 collision,
-1 2755 pairIndex,
-1 2756 i;
-1 2757
-1 2758 for (i = 0; i < pairsList.length; i++) {
-1 2759 pair = pairsList[i];
-1 2760 collision = pair.collision;
-1 2761
-1 2762 // never remove sleeping pairs
-1 2763 if (collision.bodyA.isSleeping || collision.bodyB.isSleeping) {
-1 2764 pair.timeUpdated = timestamp;
-1 2765 continue;
-1 2766 }
-1 2767
-1 2768 // if pair is inactive for too long, mark it to be removed
-1 2769 if (timestamp - pair.timeUpdated > Pairs._pairMaxIdleLife) {
-1 2770 indexesToRemove.push(i);
-1 2771 }
-1 2772 }
-1 2773
-1 2774 // remove marked pairs
-1 2775 for (i = 0; i < indexesToRemove.length; i++) {
-1 2776 pairIndex = indexesToRemove[i] - i;
-1 2777 pair = pairsList[pairIndex];
-1 2778 delete pairsTable[pair.id];
-1 2779 pairsList.splice(pairIndex, 1);
-1 2780 }
-1 2781 };
-1 2782
-1 2783 /**
-1 2784 * Clears the given pairs structure.
-1 2785 * @method clear
-1 2786 * @param {pairs} pairs
-1 2787 * @return {pairs} pairs
-1 2788 */
-1 2789 Pairs.clear = function(pairs) {
-1 2790 pairs.table = {};
-1 2791 pairs.list.length = 0;
-1 2792 pairs.collisionStart.length = 0;
-1 2793 pairs.collisionActive.length = 0;
-1 2794 pairs.collisionEnd.length = 0;
-1 2795 return pairs;
-1 2796 };
-1 2797
-1 2798 })();
-1 2799
-1 2800 },{"../core/Common":14,"./Pair":7}],9:[function(_dereq_,module,exports){
-1 2801 /**
-1 2802 * The `Matter.Query` module contains methods for performing collision queries.
-1 2803 *
-1 2804 * See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples).
-1 2805 *
-1 2806 * @class Query
-1 2807 */
-1 2808
-1 2809 var Query = {};
-1 2810
-1 2811 module.exports = Query;
-1 2812
-1 2813 var Vector = _dereq_('../geometry/Vector');
-1 2814 var SAT = _dereq_('./SAT');
-1 2815 var Bounds = _dereq_('../geometry/Bounds');
-1 2816 var Bodies = _dereq_('../factory/Bodies');
-1 2817 var Vertices = _dereq_('../geometry/Vertices');
-1 2818
-1 2819 (function() {
-1 2820
-1 2821 /**
-1 2822 * Returns a list of collisions between `body` and `bodies`.
-1 2823 * @method collides
-1 2824 * @param {body} body
-1 2825 * @param {body[]} bodies
-1 2826 * @return {object[]} Collisions
-1 2827 */
-1 2828 Query.collides = function(body, bodies) {
-1 2829 var collisions = [];
-1 2830
-1 2831 for (var i = 0; i < bodies.length; i++) {
-1 2832 var bodyA = bodies[i];
-1 2833
-1 2834 if (Bounds.overlaps(bodyA.bounds, body.bounds)) {
-1 2835 for (var j = bodyA.parts.length === 1 ? 0 : 1; j < bodyA.parts.length; j++) {
-1 2836 var part = bodyA.parts[j];
-1 2837
-1 2838 if (Bounds.overlaps(part.bounds, body.bounds)) {
-1 2839 var collision = SAT.collides(part, body);
-1 2840
-1 2841 if (collision.collided) {
-1 2842 collisions.push(collision);
-1 2843 break;
-1 2844 }
-1 2845 }
-1 2846 }
-1 2847 }
-1 2848 }
-1 2849
-1 2850 return collisions;
-1 2851 };
-1 2852
-1 2853 /**
-1 2854 * Casts a ray segment against a set of bodies and returns all collisions, ray width is optional. Intersection points are not provided.
-1 2855 * @method ray
-1 2856 * @param {body[]} bodies
-1 2857 * @param {vector} startPoint
-1 2858 * @param {vector} endPoint
-1 2859 * @param {number} [rayWidth]
-1 2860 * @return {object[]} Collisions
-1 2861 */
-1 2862 Query.ray = function(bodies, startPoint, endPoint, rayWidth) {
-1 2863 rayWidth = rayWidth || 1e-100;
-1 2864
-1 2865 var rayAngle = Vector.angle(startPoint, endPoint),
-1 2866 rayLength = Vector.magnitude(Vector.sub(startPoint, endPoint)),
-1 2867 rayX = (endPoint.x + startPoint.x) * 0.5,
-1 2868 rayY = (endPoint.y + startPoint.y) * 0.5,
-1 2869 ray = Bodies.rectangle(rayX, rayY, rayLength, rayWidth, { angle: rayAngle }),
-1 2870 collisions = Query.collides(ray, bodies);
-1 2871
-1 2872 for (var i = 0; i < collisions.length; i += 1) {
-1 2873 var collision = collisions[i];
-1 2874 collision.body = collision.bodyB = collision.bodyA;
-1 2875 }
-1 2876
-1 2877 return collisions;
-1 2878 };
-1 2879
-1 2880 /**
-1 2881 * Returns all bodies whose bounds are inside (or outside if set) the given set of bounds, from the given set of bodies.
-1 2882 * @method region
-1 2883 * @param {body[]} bodies
-1 2884 * @param {bounds} bounds
-1 2885 * @param {bool} [outside=false]
-1 2886 * @return {body[]} The bodies matching the query
-1 2887 */
-1 2888 Query.region = function(bodies, bounds, outside) {
-1 2889 var result = [];
-1 2890
-1 2891 for (var i = 0; i < bodies.length; i++) {
-1 2892 var body = bodies[i],
-1 2893 overlaps = Bounds.overlaps(body.bounds, bounds);
-1 2894 if ((overlaps && !outside) || (!overlaps && outside))
-1 2895 result.push(body);
-1 2896 }
-1 2897
-1 2898 return result;
-1 2899 };
-1 2900
-1 2901 /**
-1 2902 * Returns all bodies whose vertices contain the given point, from the given set of bodies.
-1 2903 * @method point
-1 2904 * @param {body[]} bodies
-1 2905 * @param {vector} point
-1 2906 * @return {body[]} The bodies matching the query
-1 2907 */
-1 2908 Query.point = function(bodies, point) {
-1 2909 var result = [];
-1 2910
-1 2911 for (var i = 0; i < bodies.length; i++) {
-1 2912 var body = bodies[i];
-1 2913
-1 2914 if (Bounds.contains(body.bounds, point)) {
-1 2915 for (var j = body.parts.length === 1 ? 0 : 1; j < body.parts.length; j++) {
-1 2916 var part = body.parts[j];
-1 2917
-1 2918 if (Bounds.contains(part.bounds, point)
-1 2919 && Vertices.contains(part.vertices, point)) {
-1 2920 result.push(body);
-1 2921 break;
-1 2922 }
-1 2923 }
-1 2924 }
-1 2925 }
-1 2926
-1 2927 return result;
-1 2928 };
-1 2929
-1 2930 })();
-1 2931
-1 2932 },{"../factory/Bodies":23,"../geometry/Bounds":26,"../geometry/Vector":28,"../geometry/Vertices":29,"./SAT":11}],10:[function(_dereq_,module,exports){
-1 2933 /**
-1 2934 * The `Matter.Resolver` module contains methods for resolving collision pairs.
-1 2935 *
-1 2936 * @class Resolver
-1 2937 */
-1 2938
-1 2939 var Resolver = {};
-1 2940
-1 2941 module.exports = Resolver;
-1 2942
-1 2943 var Vertices = _dereq_('../geometry/Vertices');
-1 2944 var Vector = _dereq_('../geometry/Vector');
-1 2945 var Common = _dereq_('../core/Common');
-1 2946 var Bounds = _dereq_('../geometry/Bounds');
-1 2947
-1 2948 (function() {
-1 2949
-1 2950 Resolver._restingThresh = 4;
-1 2951 Resolver._restingThreshTangent = 6;
-1 2952 Resolver._positionDampen = 0.9;
-1 2953 Resolver._positionWarming = 0.8;
-1 2954 Resolver._frictionNormalMultiplier = 5;
-1 2955
-1 2956 /**
-1 2957 * Prepare pairs for position solving.
-1 2958 * @method preSolvePosition
-1 2959 * @param {pair[]} pairs
-1 2960 */
-1 2961 Resolver.preSolvePosition = function(pairs) {
-1 2962 var i,
-1 2963 pair,
-1 2964 activeCount;
-1 2965
-1 2966 // find total contacts on each body
-1 2967 for (i = 0; i < pairs.length; i++) {
-1 2968 pair = pairs[i];
-1 2969
-1 2970 if (!pair.isActive)
-1 2971 continue;
-1 2972
-1 2973 activeCount = pair.activeContacts.length;
-1 2974 pair.collision.parentA.totalContacts += activeCount;
-1 2975 pair.collision.parentB.totalContacts += activeCount;
-1 2976 }
-1 2977 };
-1 2978
-1 2979 /**
-1 2980 * Find a solution for pair positions.
-1 2981 * @method solvePosition
-1 2982 * @param {pair[]} pairs
-1 2983 * @param {number} timeScale
-1 2984 */
-1 2985 Resolver.solvePosition = function(pairs, timeScale) {
-1 2986 var i,
-1 2987 pair,
-1 2988 collision,
-1 2989 bodyA,
-1 2990 bodyB,
-1 2991 normal,
-1 2992 bodyBtoA,
-1 2993 contactShare,
-1 2994 positionImpulse,
-1 2995 contactCount = {},
-1 2996 tempA = Vector._temp[0],
-1 2997 tempB = Vector._temp[1],
-1 2998 tempC = Vector._temp[2],
-1 2999 tempD = Vector._temp[3];
-1 3000
-1 3001 // find impulses required to resolve penetration
-1 3002 for (i = 0; i < pairs.length; i++) {
-1 3003 pair = pairs[i];
-1 3004
-1 3005 if (!pair.isActive || pair.isSensor)
-1 3006 continue;
-1 3007
-1 3008 collision = pair.collision;
-1 3009 bodyA = collision.parentA;
-1 3010 bodyB = collision.parentB;
-1 3011 normal = collision.normal;
-1 3012
-1 3013 // get current separation between body edges involved in collision
-1 3014 bodyBtoA = Vector.sub(Vector.add(bodyB.positionImpulse, bodyB.position, tempA),
-1 3015 Vector.add(bodyA.positionImpulse,
-1 3016 Vector.sub(bodyB.position, collision.penetration, tempB), tempC), tempD);
-1 3017
-1 3018 pair.separation = Vector.dot(normal, bodyBtoA);
-1 3019 }
-1 3020
-1 3021 for (i = 0; i < pairs.length; i++) {
-1 3022 pair = pairs[i];
-1 3023
-1 3024 if (!pair.isActive || pair.isSensor)
-1 3025 continue;
-1 3026
-1 3027 collision = pair.collision;
-1 3028 bodyA = collision.parentA;
-1 3029 bodyB = collision.parentB;
-1 3030 normal = collision.normal;
-1 3031 positionImpulse = (pair.separation - pair.slop) * timeScale;
-1 3032
-1 3033 if (bodyA.isStatic || bodyB.isStatic)
-1 3034 positionImpulse *= 2;
-1 3035
-1 3036 if (!(bodyA.isStatic || bodyA.isSleeping)) {
-1 3037 contactShare = Resolver._positionDampen / bodyA.totalContacts;
-1 3038 bodyA.positionImpulse.x += normal.x * positionImpulse * contactShare;
-1 3039 bodyA.positionImpulse.y += normal.y * positionImpulse * contactShare;
-1 3040 }
-1 3041
-1 3042 if (!(bodyB.isStatic || bodyB.isSleeping)) {
-1 3043 contactShare = Resolver._positionDampen / bodyB.totalContacts;
-1 3044 bodyB.positionImpulse.x -= normal.x * positionImpulse * contactShare;
-1 3045 bodyB.positionImpulse.y -= normal.y * positionImpulse * contactShare;
-1 3046 }
-1 3047 }
-1 3048 };
-1 3049
-1 3050 /**
-1 3051 * Apply position resolution.
-1 3052 * @method postSolvePosition
-1 3053 * @param {body[]} bodies
-1 3054 */
-1 3055 Resolver.postSolvePosition = function(bodies) {
-1 3056 for (var i = 0; i < bodies.length; i++) {
-1 3057 var body = bodies[i];
-1 3058
-1 3059 // reset contact count
-1 3060 body.totalContacts = 0;
-1 3061
-1 3062 if (body.positionImpulse.x !== 0 || body.positionImpulse.y !== 0) {
-1 3063 // update body geometry
-1 3064 for (var j = 0; j < body.parts.length; j++) {
-1 3065 var part = body.parts[j];
-1 3066 Vertices.translate(part.vertices, body.positionImpulse);
-1 3067 Bounds.update(part.bounds, part.vertices, body.velocity);
-1 3068 part.position.x += body.positionImpulse.x;
-1 3069 part.position.y += body.positionImpulse.y;
-1 3070 }
-1 3071
-1 3072 // move the body without changing velocity
-1 3073 body.positionPrev.x += body.positionImpulse.x;
-1 3074 body.positionPrev.y += body.positionImpulse.y;
-1 3075
-1 3076 if (Vector.dot(body.positionImpulse, body.velocity) < 0) {
-1 3077 // reset cached impulse if the body has velocity along it
-1 3078 body.positionImpulse.x = 0;
-1 3079 body.positionImpulse.y = 0;
-1 3080 } else {
-1 3081 // warm the next iteration
-1 3082 body.positionImpulse.x *= Resolver._positionWarming;
-1 3083 body.positionImpulse.y *= Resolver._positionWarming;
-1 3084 }
-1 3085 }
-1 3086 }
-1 3087 };
-1 3088
-1 3089 /**
-1 3090 * Prepare pairs for velocity solving.
-1 3091 * @method preSolveVelocity
-1 3092 * @param {pair[]} pairs
-1 3093 */
-1 3094 Resolver.preSolveVelocity = function(pairs) {
-1 3095 var i,
-1 3096 j,
-1 3097 pair,
-1 3098 contacts,
-1 3099 collision,
-1 3100 bodyA,
-1 3101 bodyB,
-1 3102 normal,
-1 3103 tangent,
-1 3104 contact,
-1 3105 contactVertex,
-1 3106 normalImpulse,
-1 3107 tangentImpulse,
-1 3108 offset,
-1 3109 impulse = Vector._temp[0],
-1 3110 tempA = Vector._temp[1];
-1 3111
-1 3112 for (i = 0; i < pairs.length; i++) {
-1 3113 pair = pairs[i];
-1 3114
-1 3115 if (!pair.isActive || pair.isSensor)
-1 3116 continue;
-1 3117
-1 3118 contacts = pair.activeContacts;
-1 3119 collision = pair.collision;
-1 3120 bodyA = collision.parentA;
-1 3121 bodyB = collision.parentB;
-1 3122 normal = collision.normal;
-1 3123 tangent = collision.tangent;
-1 3124
-1 3125 // resolve each contact
-1 3126 for (j = 0; j < contacts.length; j++) {
-1 3127 contact = contacts[j];
-1 3128 contactVertex = contact.vertex;
-1 3129 normalImpulse = contact.normalImpulse;
-1 3130 tangentImpulse = contact.tangentImpulse;
-1 3131
-1 3132 if (normalImpulse !== 0 || tangentImpulse !== 0) {
-1 3133 // total impulse from contact
-1 3134 impulse.x = (normal.x * normalImpulse) + (tangent.x * tangentImpulse);
-1 3135 impulse.y = (normal.y * normalImpulse) + (tangent.y * tangentImpulse);
-1 3136
-1 3137 // apply impulse from contact
-1 3138 if (!(bodyA.isStatic || bodyA.isSleeping)) {
-1 3139 offset = Vector.sub(contactVertex, bodyA.position, tempA);
-1 3140 bodyA.positionPrev.x += impulse.x * bodyA.inverseMass;
-1 3141 bodyA.positionPrev.y += impulse.y * bodyA.inverseMass;
-1 3142 bodyA.anglePrev += Vector.cross(offset, impulse) * bodyA.inverseInertia;
-1 3143 }
-1 3144
-1 3145 if (!(bodyB.isStatic || bodyB.isSleeping)) {
-1 3146 offset = Vector.sub(contactVertex, bodyB.position, tempA);
-1 3147 bodyB.positionPrev.x -= impulse.x * bodyB.inverseMass;
-1 3148 bodyB.positionPrev.y -= impulse.y * bodyB.inverseMass;
-1 3149 bodyB.anglePrev -= Vector.cross(offset, impulse) * bodyB.inverseInertia;
-1 3150 }
-1 3151 }
-1 3152 }
-1 3153 }
-1 3154 };
-1 3155
-1 3156 /**
-1 3157 * Find a solution for pair velocities.
-1 3158 * @method solveVelocity
-1 3159 * @param {pair[]} pairs
-1 3160 * @param {number} timeScale
-1 3161 */
-1 3162 Resolver.solveVelocity = function(pairs, timeScale) {
-1 3163 var timeScaleSquared = timeScale * timeScale,
-1 3164 impulse = Vector._temp[0],
-1 3165 tempA = Vector._temp[1],
-1 3166 tempB = Vector._temp[2],
-1 3167 tempC = Vector._temp[3],
-1 3168 tempD = Vector._temp[4],
-1 3169 tempE = Vector._temp[5];
-1 3170
-1 3171 for (var i = 0; i < pairs.length; i++) {
-1 3172 var pair = pairs[i];
-1 3173
-1 3174 if (!pair.isActive || pair.isSensor)
-1 3175 continue;
-1 3176
-1 3177 var collision = pair.collision,
-1 3178 bodyA = collision.parentA,
-1 3179 bodyB = collision.parentB,
-1 3180 normal = collision.normal,
-1 3181 tangent = collision.tangent,
-1 3182 contacts = pair.activeContacts,
-1 3183 contactShare = 1 / contacts.length;
-1 3184
-1 3185 // update body velocities
-1 3186 bodyA.velocity.x = bodyA.position.x - bodyA.positionPrev.x;
-1 3187 bodyA.velocity.y = bodyA.position.y - bodyA.positionPrev.y;
-1 3188 bodyB.velocity.x = bodyB.position.x - bodyB.positionPrev.x;
-1 3189 bodyB.velocity.y = bodyB.position.y - bodyB.positionPrev.y;
-1 3190 bodyA.angularVelocity = bodyA.angle - bodyA.anglePrev;
-1 3191 bodyB.angularVelocity = bodyB.angle - bodyB.anglePrev;
-1 3192
-1 3193 // resolve each contact
-1 3194 for (var j = 0; j < contacts.length; j++) {
-1 3195 var contact = contacts[j],
-1 3196 contactVertex = contact.vertex,
-1 3197 offsetA = Vector.sub(contactVertex, bodyA.position, tempA),
-1 3198 offsetB = Vector.sub(contactVertex, bodyB.position, tempB),
-1 3199 velocityPointA = Vector.add(bodyA.velocity, Vector.mult(Vector.perp(offsetA), bodyA.angularVelocity), tempC),
-1 3200 velocityPointB = Vector.add(bodyB.velocity, Vector.mult(Vector.perp(offsetB), bodyB.angularVelocity), tempD),
-1 3201 relativeVelocity = Vector.sub(velocityPointA, velocityPointB, tempE),
-1 3202 normalVelocity = Vector.dot(normal, relativeVelocity);
-1 3203
-1 3204 var tangentVelocity = Vector.dot(tangent, relativeVelocity),
-1 3205 tangentSpeed = Math.abs(tangentVelocity),
-1 3206 tangentVelocityDirection = Common.sign(tangentVelocity);
-1 3207
-1 3208 // raw impulses
-1 3209 var normalImpulse = (1 + pair.restitution) * normalVelocity,
-1 3210 normalForce = Common.clamp(pair.separation + normalVelocity, 0, 1) * Resolver._frictionNormalMultiplier;
-1 3211
-1 3212 // coulomb friction
-1 3213 var tangentImpulse = tangentVelocity,
-1 3214 maxFriction = Infinity;
-1 3215
-1 3216 if (tangentSpeed > pair.friction * pair.frictionStatic * normalForce * timeScaleSquared) {
-1 3217 maxFriction = tangentSpeed;
-1 3218 tangentImpulse = Common.clamp(
-1 3219 pair.friction * tangentVelocityDirection * timeScaleSquared,
-1 3220 -maxFriction, maxFriction
-1 3221 );
-1 3222 }
-1 3223
-1 3224 // modify impulses accounting for mass, inertia and offset
-1 3225 var oAcN = Vector.cross(offsetA, normal),
-1 3226 oBcN = Vector.cross(offsetB, normal),
-1 3227 share = contactShare / (bodyA.inverseMass + bodyB.inverseMass + bodyA.inverseInertia * oAcN * oAcN + bodyB.inverseInertia * oBcN * oBcN);
-1 3228
-1 3229 normalImpulse *= share;
-1 3230 tangentImpulse *= share;
-1 3231
-1 3232 // handle high velocity and resting collisions separately
-1 3233 if (normalVelocity < 0 && normalVelocity * normalVelocity > Resolver._restingThresh * timeScaleSquared) {
-1 3234 // high normal velocity so clear cached contact normal impulse
-1 3235 contact.normalImpulse = 0;
-1 3236 } else {
-1 3237 // solve resting collision constraints using Erin Catto's method (GDC08)
-1 3238 // impulse constraint tends to 0
-1 3239 var contactNormalImpulse = contact.normalImpulse;
-1 3240 contact.normalImpulse = Math.min(contact.normalImpulse + normalImpulse, 0);
-1 3241 normalImpulse = contact.normalImpulse - contactNormalImpulse;
-1 3242 }
-1 3243
-1 3244 // handle high velocity and resting collisions separately
-1 3245 if (tangentVelocity * tangentVelocity > Resolver._restingThreshTangent * timeScaleSquared) {
-1 3246 // high tangent velocity so clear cached contact tangent impulse
-1 3247 contact.tangentImpulse = 0;
-1 3248 } else {
-1 3249 // solve resting collision constraints using Erin Catto's method (GDC08)
-1 3250 // tangent impulse tends to -tangentSpeed or +tangentSpeed
-1 3251 var contactTangentImpulse = contact.tangentImpulse;
-1 3252 contact.tangentImpulse = Common.clamp(contact.tangentImpulse + tangentImpulse, -maxFriction, maxFriction);
-1 3253 tangentImpulse = contact.tangentImpulse - contactTangentImpulse;
-1 3254 }
-1 3255
-1 3256 // total impulse from contact
-1 3257 impulse.x = (normal.x * normalImpulse) + (tangent.x * tangentImpulse);
-1 3258 impulse.y = (normal.y * normalImpulse) + (tangent.y * tangentImpulse);
-1 3259
-1 3260 // apply impulse from contact
-1 3261 if (!(bodyA.isStatic || bodyA.isSleeping)) {
-1 3262 bodyA.positionPrev.x += impulse.x * bodyA.inverseMass;
-1 3263 bodyA.positionPrev.y += impulse.y * bodyA.inverseMass;
-1 3264 bodyA.anglePrev += Vector.cross(offsetA, impulse) * bodyA.inverseInertia;
-1 3265 }
-1 3266
-1 3267 if (!(bodyB.isStatic || bodyB.isSleeping)) {
-1 3268 bodyB.positionPrev.x -= impulse.x * bodyB.inverseMass;
-1 3269 bodyB.positionPrev.y -= impulse.y * bodyB.inverseMass;
-1 3270 bodyB.anglePrev -= Vector.cross(offsetB, impulse) * bodyB.inverseInertia;
-1 3271 }
-1 3272 }
-1 3273 }
-1 3274 };
-1 3275
-1 3276 })();
-1 3277
-1 3278 },{"../core/Common":14,"../geometry/Bounds":26,"../geometry/Vector":28,"../geometry/Vertices":29}],11:[function(_dereq_,module,exports){
-1 3279 /**
-1 3280 * The `Matter.SAT` module contains methods for detecting collisions using the Separating Axis Theorem.
-1 3281 *
-1 3282 * @class SAT
-1 3283 */
-1 3284
-1 3285 // TODO: true circles and curves
-1 3286
-1 3287 var SAT = {};
-1 3288
-1 3289 module.exports = SAT;
-1 3290
-1 3291 var Vertices = _dereq_('../geometry/Vertices');
-1 3292 var Vector = _dereq_('../geometry/Vector');
-1 3293
-1 3294 (function() {
-1 3295
-1 3296 /**
-1 3297 * Detect collision between two bodies using the Separating Axis Theorem.
-1 3298 * @method collides
-1 3299 * @param {body} bodyA
-1 3300 * @param {body} bodyB
-1 3301 * @param {collision} previousCollision
-1 3302 * @return {collision} collision
-1 3303 */
-1 3304 SAT.collides = function(bodyA, bodyB, previousCollision) {
-1 3305 var overlapAB,
-1 3306 overlapBA,
-1 3307 minOverlap,
-1 3308 collision,
-1 3309 canReusePrevCol = false;
-1 3310
-1 3311 if (previousCollision) {
-1 3312 // estimate total motion
-1 3313 var parentA = bodyA.parent,
-1 3314 parentB = bodyB.parent,
-1 3315 motion = parentA.speed * parentA.speed + parentA.angularSpeed * parentA.angularSpeed
-1 3316 + parentB.speed * parentB.speed + parentB.angularSpeed * parentB.angularSpeed;
-1 3317
-1 3318 // we may be able to (partially) reuse collision result
-1 3319 // but only safe if collision was resting
-1 3320 canReusePrevCol = previousCollision && previousCollision.collided && motion < 0.2;
-1 3321
-1 3322 // reuse collision object
-1 3323 collision = previousCollision;
-1 3324 } else {
-1 3325 collision = { collided: false, bodyA: bodyA, bodyB: bodyB };
-1 3326 }
-1 3327
-1 3328 if (previousCollision && canReusePrevCol) {
-1 3329 // if we can reuse the collision result
-1 3330 // we only need to test the previously found axis
-1 3331 var axisBodyA = collision.axisBody,
-1 3332 axisBodyB = axisBodyA === bodyA ? bodyB : bodyA,
-1 3333 axes = [axisBodyA.axes[previousCollision.axisNumber]];
-1 3334
-1 3335 minOverlap = SAT._overlapAxes(axisBodyA.vertices, axisBodyB.vertices, axes);
-1 3336 collision.reused = true;
-1 3337
-1 3338 if (minOverlap.overlap <= 0) {
-1 3339 collision.collided = false;
-1 3340 return collision;
-1 3341 }
-1 3342 } else {
-1 3343 // if we can't reuse a result, perform a full SAT test
-1 3344
-1 3345 overlapAB = SAT._overlapAxes(bodyA.vertices, bodyB.vertices, bodyA.axes);
-1 3346
-1 3347 if (overlapAB.overlap <= 0) {
-1 3348 collision.collided = false;
-1 3349 return collision;
-1 3350 }
-1 3351
-1 3352 overlapBA = SAT._overlapAxes(bodyB.vertices, bodyA.vertices, bodyB.axes);
-1 3353
-1 3354 if (overlapBA.overlap <= 0) {
-1 3355 collision.collided = false;
-1 3356 return collision;
-1 3357 }
-1 3358
-1 3359 if (overlapAB.overlap < overlapBA.overlap) {
-1 3360 minOverlap = overlapAB;
-1 3361 collision.axisBody = bodyA;
-1 3362 } else {
-1 3363 minOverlap = overlapBA;
-1 3364 collision.axisBody = bodyB;
-1 3365 }
-1 3366
-1 3367 // important for reuse later
-1 3368 collision.axisNumber = minOverlap.axisNumber;
-1 3369 }
-1 3370
-1 3371 collision.bodyA = bodyA.id < bodyB.id ? bodyA : bodyB;
-1 3372 collision.bodyB = bodyA.id < bodyB.id ? bodyB : bodyA;
-1 3373 collision.collided = true;
-1 3374 collision.depth = minOverlap.overlap;
-1 3375 collision.parentA = collision.bodyA.parent;
-1 3376 collision.parentB = collision.bodyB.parent;
-1 3377
-1 3378 bodyA = collision.bodyA;
-1 3379 bodyB = collision.bodyB;
-1 3380
-1 3381 // ensure normal is facing away from bodyA
-1 3382 if (Vector.dot(minOverlap.axis, Vector.sub(bodyB.position, bodyA.position)) < 0) {
-1 3383 collision.normal = {
-1 3384 x: minOverlap.axis.x,
-1 3385 y: minOverlap.axis.y
-1 3386 };
-1 3387 } else {
-1 3388 collision.normal = {
-1 3389 x: -minOverlap.axis.x,
-1 3390 y: -minOverlap.axis.y
-1 3391 };
-1 3392 }
-1 3393
-1 3394 collision.tangent = Vector.perp(collision.normal);
-1 3395
-1 3396 collision.penetration = collision.penetration || {};
-1 3397 collision.penetration.x = collision.normal.x * collision.depth;
-1 3398 collision.penetration.y = collision.normal.y * collision.depth;
-1 3399
-1 3400 // find support points, there is always either exactly one or two
-1 3401 var verticesB = SAT._findSupports(bodyA, bodyB, collision.normal),
-1 3402 supports = [];
-1 3403
-1 3404 // find the supports from bodyB that are inside bodyA
-1 3405 if (Vertices.contains(bodyA.vertices, verticesB[0]))
-1 3406 supports.push(verticesB[0]);
-1 3407
-1 3408 if (Vertices.contains(bodyA.vertices, verticesB[1]))
-1 3409 supports.push(verticesB[1]);
-1 3410
-1 3411 // find the supports from bodyA that are inside bodyB
-1 3412 if (supports.length < 2) {
-1 3413 var verticesA = SAT._findSupports(bodyB, bodyA, Vector.neg(collision.normal));
-1 3414
-1 3415 if (Vertices.contains(bodyB.vertices, verticesA[0]))
-1 3416 supports.push(verticesA[0]);
-1 3417
-1 3418 if (supports.length < 2 && Vertices.contains(bodyB.vertices, verticesA[1]))
-1 3419 supports.push(verticesA[1]);
-1 3420 }
-1 3421
-1 3422 // account for the edge case of overlapping but no vertex containment
-1 3423 if (supports.length < 1)
-1 3424 supports = [verticesB[0]];
-1 3425
-1 3426 collision.supports = supports;
-1 3427
-1 3428 return collision;
-1 3429 };
-1 3430
-1 3431 /**
-1 3432 * Find the overlap between two sets of vertices.
-1 3433 * @method _overlapAxes
-1 3434 * @private
-1 3435 * @param {} verticesA
-1 3436 * @param {} verticesB
-1 3437 * @param {} axes
-1 3438 * @return result
-1 3439 */
-1 3440 SAT._overlapAxes = function(verticesA, verticesB, axes) {
-1 3441 var projectionA = Vector._temp[0],
-1 3442 projectionB = Vector._temp[1],
-1 3443 result = { overlap: Number.MAX_VALUE },
-1 3444 overlap,
-1 3445 axis;
-1 3446
-1 3447 for (var i = 0; i < axes.length; i++) {
-1 3448 axis = axes[i];
-1 3449
-1 3450 SAT._projectToAxis(projectionA, verticesA, axis);
-1 3451 SAT._projectToAxis(projectionB, verticesB, axis);
-1 3452
-1 3453 overlap = Math.min(projectionA.max - projectionB.min, projectionB.max - projectionA.min);
-1 3454
-1 3455 if (overlap <= 0) {
-1 3456 result.overlap = overlap;
-1 3457 return result;
-1 3458 }
-1 3459
-1 3460 if (overlap < result.overlap) {
-1 3461 result.overlap = overlap;
-1 3462 result.axis = axis;
-1 3463 result.axisNumber = i;
-1 3464 }
-1 3465 }
-1 3466
-1 3467 return result;
-1 3468 };
-1 3469
-1 3470 /**
-1 3471 * Projects vertices on an axis and returns an interval.
-1 3472 * @method _projectToAxis
-1 3473 * @private
-1 3474 * @param {} projection
-1 3475 * @param {} vertices
-1 3476 * @param {} axis
-1 3477 */
-1 3478 SAT._projectToAxis = function(projection, vertices, axis) {
-1 3479 var min = Vector.dot(vertices[0], axis),
-1 3480 max = min;
-1 3481
-1 3482 for (var i = 1; i < vertices.length; i += 1) {
-1 3483 var dot = Vector.dot(vertices[i], axis);
-1 3484
-1 3485 if (dot > max) {
-1 3486 max = dot;
-1 3487 } else if (dot < min) {
-1 3488 min = dot;
-1 3489 }
-1 3490 }
-1 3491
-1 3492 projection.min = min;
-1 3493 projection.max = max;
-1 3494 };
-1 3495
-1 3496 /**
-1 3497 * Finds supporting vertices given two bodies along a given direction using hill-climbing.
-1 3498 * @method _findSupports
-1 3499 * @private
-1 3500 * @param {} bodyA
-1 3501 * @param {} bodyB
-1 3502 * @param {} normal
-1 3503 * @return [vector]
-1 3504 */
-1 3505 SAT._findSupports = function(bodyA, bodyB, normal) {
-1 3506 var nearestDistance = Number.MAX_VALUE,
-1 3507 vertexToBody = Vector._temp[0],
-1 3508 vertices = bodyB.vertices,
-1 3509 bodyAPosition = bodyA.position,
-1 3510 distance,
-1 3511 vertex,
-1 3512 vertexA,
-1 3513 vertexB;
-1 3514
-1 3515 // find closest vertex on bodyB
-1 3516 for (var i = 0; i < vertices.length; i++) {
-1 3517 vertex = vertices[i];
-1 3518 vertexToBody.x = vertex.x - bodyAPosition.x;
-1 3519 vertexToBody.y = vertex.y - bodyAPosition.y;
-1 3520 distance = -Vector.dot(normal, vertexToBody);
-1 3521
-1 3522 if (distance < nearestDistance) {
-1 3523 nearestDistance = distance;
-1 3524 vertexA = vertex;
-1 3525 }
-1 3526 }
-1 3527
-1 3528 // find next closest vertex using the two connected to it
-1 3529 var prevIndex = vertexA.index - 1 >= 0 ? vertexA.index - 1 : vertices.length - 1;
-1 3530 vertex = vertices[prevIndex];
-1 3531 vertexToBody.x = vertex.x - bodyAPosition.x;
-1 3532 vertexToBody.y = vertex.y - bodyAPosition.y;
-1 3533 nearestDistance = -Vector.dot(normal, vertexToBody);
-1 3534 vertexB = vertex;
-1 3535
-1 3536 var nextIndex = (vertexA.index + 1) % vertices.length;
-1 3537 vertex = vertices[nextIndex];
-1 3538 vertexToBody.x = vertex.x - bodyAPosition.x;
-1 3539 vertexToBody.y = vertex.y - bodyAPosition.y;
-1 3540 distance = -Vector.dot(normal, vertexToBody);
-1 3541 if (distance < nearestDistance) {
-1 3542 vertexB = vertex;
-1 3543 }
-1 3544
-1 3545 return [vertexA, vertexB];
-1 3546 };
-1 3547
-1 3548 })();
-1 3549
-1 3550 },{"../geometry/Vector":28,"../geometry/Vertices":29}],12:[function(_dereq_,module,exports){
-1 3551 /**
-1 3552 * The `Matter.Constraint` module contains methods for creating and manipulating constraints.
-1 3553 * Constraints are used for specifying that a fixed distance must be maintained between two bodies (or a body and a fixed world-space position).
-1 3554 * The stiffness of constraints can be modified to create springs or elastic.
-1 3555 *
-1 3556 * See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples).
-1 3557 *
-1 3558 * @class Constraint
-1 3559 */
-1 3560
-1 3561 var Constraint = {};
-1 3562
-1 3563 module.exports = Constraint;
-1 3564
-1 3565 var Vertices = _dereq_('../geometry/Vertices');
-1 3566 var Vector = _dereq_('../geometry/Vector');
-1 3567 var Sleeping = _dereq_('../core/Sleeping');
-1 3568 var Bounds = _dereq_('../geometry/Bounds');
-1 3569 var Axes = _dereq_('../geometry/Axes');
-1 3570 var Common = _dereq_('../core/Common');
-1 3571
-1 3572 (function() {
-1 3573
-1 3574 Constraint._warming = 0.4;
-1 3575 Constraint._torqueDampen = 1;
-1 3576 Constraint._minLength = 0.000001;
-1 3577
-1 3578 /**
-1 3579 * Creates a new constraint.
-1 3580 * All properties have default values, and many are pre-calculated automatically based on other properties.
-1 3581 * To simulate a revolute constraint (or pin joint) set `length: 0` and a high `stiffness` value (e.g. `0.7` or above).
-1 3582 * If the constraint is unstable, try lowering the `stiffness` value and / or increasing `engine.constraintIterations`.
-1 3583 * For compound bodies, constraints must be applied to the parent body (not one of its parts).
-1 3584 * See the properties section below for detailed information on what you can pass via the `options` object.
-1 3585 * @method create
-1 3586 * @param {} options
-1 3587 * @return {constraint} constraint
-1 3588 */
-1 3589 Constraint.create = function(options) {
-1 3590 var constraint = options;
-1 3591
-1 3592 // if bodies defined but no points, use body centre
-1 3593 if (constraint.bodyA && !constraint.pointA)
-1 3594 constraint.pointA = { x: 0, y: 0 };
-1 3595 if (constraint.bodyB && !constraint.pointB)
-1 3596 constraint.pointB = { x: 0, y: 0 };
-1 3597
-1 3598 // calculate static length using initial world space points
-1 3599 var initialPointA = constraint.bodyA ? Vector.add(constraint.bodyA.position, constraint.pointA) : constraint.pointA,
-1 3600 initialPointB = constraint.bodyB ? Vector.add(constraint.bodyB.position, constraint.pointB) : constraint.pointB,
-1 3601 length = Vector.magnitude(Vector.sub(initialPointA, initialPointB));
-1 3602
-1 3603 constraint.length = typeof constraint.length !== 'undefined' ? constraint.length : length;
-1 3604
-1 3605 // option defaults
-1 3606 constraint.id = constraint.id || Common.nextId();
-1 3607 constraint.label = constraint.label || 'Constraint';
-1 3608 constraint.type = 'constraint';
-1 3609 constraint.stiffness = constraint.stiffness || (constraint.length > 0 ? 1 : 0.7);
-1 3610 constraint.damping = constraint.damping || 0;
-1 3611 constraint.angularStiffness = constraint.angularStiffness || 0;
-1 3612 constraint.angleA = constraint.bodyA ? constraint.bodyA.angle : constraint.angleA;
-1 3613 constraint.angleB = constraint.bodyB ? constraint.bodyB.angle : constraint.angleB;
-1 3614 constraint.plugin = {};
-1 3615
-1 3616 // render
-1 3617 var render = {
-1 3618 visible: true,
-1 3619 lineWidth: 2,
-1 3620 strokeStyle: '#ffffff',
-1 3621 type: 'line',
-1 3622 anchors: true
-1 3623 };
-1 3624
-1 3625 if (constraint.length === 0 && constraint.stiffness > 0.1) {
-1 3626 render.type = 'pin';
-1 3627 render.anchors = false;
-1 3628 } else if (constraint.stiffness < 0.9) {
-1 3629 render.type = 'spring';
-1 3630 }
-1 3631
-1 3632 constraint.render = Common.extend(render, constraint.render);
-1 3633
-1 3634 return constraint;
-1 3635 };
-1 3636
-1 3637 /**
-1 3638 * Prepares for solving by constraint warming.
-1 3639 * @private
-1 3640 * @method preSolveAll
-1 3641 * @param {body[]} bodies
-1 3642 */
-1 3643 Constraint.preSolveAll = function(bodies) {
-1 3644 for (var i = 0; i < bodies.length; i += 1) {
-1 3645 var body = bodies[i],
-1 3646 impulse = body.constraintImpulse;
-1 3647
-1 3648 if (body.isStatic || (impulse.x === 0 && impulse.y === 0 && impulse.angle === 0)) {
-1 3649 continue;
-1 3650 }
-1 3651
-1 3652 body.position.x += impulse.x;
-1 3653 body.position.y += impulse.y;
-1 3654 body.angle += impulse.angle;
-1 3655 }
-1 3656 };
-1 3657
-1 3658 /**
-1 3659 * Solves all constraints in a list of collisions.
-1 3660 * @private
-1 3661 * @method solveAll
-1 3662 * @param {constraint[]} constraints
-1 3663 * @param {number} timeScale
-1 3664 */
-1 3665 Constraint.solveAll = function(constraints, timeScale) {
-1 3666 // Solve fixed constraints first.
-1 3667 for (var i = 0; i < constraints.length; i += 1) {
-1 3668 var constraint = constraints[i],
-1 3669 fixedA = !constraint.bodyA || (constraint.bodyA && constraint.bodyA.isStatic),
-1 3670 fixedB = !constraint.bodyB || (constraint.bodyB && constraint.bodyB.isStatic);
-1 3671
-1 3672 if (fixedA || fixedB) {
-1 3673 Constraint.solve(constraints[i], timeScale);
-1 3674 }
-1 3675 }
-1 3676
-1 3677 // Solve free constraints last.
-1 3678 for (i = 0; i < constraints.length; i += 1) {
-1 3679 constraint = constraints[i];
-1 3680 fixedA = !constraint.bodyA || (constraint.bodyA && constraint.bodyA.isStatic);
-1 3681 fixedB = !constraint.bodyB || (constraint.bodyB && constraint.bodyB.isStatic);
-1 3682
-1 3683 if (!fixedA && !fixedB) {
-1 3684 Constraint.solve(constraints[i], timeScale);
-1 3685 }
-1 3686 }
-1 3687 };
-1 3688
-1 3689 /**
-1 3690 * Solves a distance constraint with Gauss-Siedel method.
-1 3691 * @private
-1 3692 * @method solve
-1 3693 * @param {constraint} constraint
-1 3694 * @param {number} timeScale
-1 3695 */
-1 3696 Constraint.solve = function(constraint, timeScale) {
-1 3697 var bodyA = constraint.bodyA,
-1 3698 bodyB = constraint.bodyB,
-1 3699 pointA = constraint.pointA,
-1 3700 pointB = constraint.pointB;
-1 3701
-1 3702 if (!bodyA && !bodyB)
-1 3703 return;
-1 3704
-1 3705 // update reference angle
-1 3706 if (bodyA && !bodyA.isStatic) {
-1 3707 Vector.rotate(pointA, bodyA.angle - constraint.angleA, pointA);
-1 3708 constraint.angleA = bodyA.angle;
-1 3709 }
-1 3710
-1 3711 // update reference angle
-1 3712 if (bodyB && !bodyB.isStatic) {
-1 3713 Vector.rotate(pointB, bodyB.angle - constraint.angleB, pointB);
-1 3714 constraint.angleB = bodyB.angle;
-1 3715 }
-1 3716
-1 3717 var pointAWorld = pointA,
-1 3718 pointBWorld = pointB;
-1 3719
-1 3720 if (bodyA) pointAWorld = Vector.add(bodyA.position, pointA);
-1 3721 if (bodyB) pointBWorld = Vector.add(bodyB.position, pointB);
-1 3722
-1 3723 if (!pointAWorld || !pointBWorld)
-1 3724 return;
-1 3725
-1 3726 var delta = Vector.sub(pointAWorld, pointBWorld),
-1 3727 currentLength = Vector.magnitude(delta);
-1 3728
-1 3729 // prevent singularity
-1 3730 if (currentLength < Constraint._minLength) {
-1 3731 currentLength = Constraint._minLength;
-1 3732 }
-1 3733
-1 3734 // solve distance constraint with Gauss-Siedel method
-1 3735 var difference = (currentLength - constraint.length) / currentLength,
-1 3736 stiffness = constraint.stiffness < 1 ? constraint.stiffness * timeScale : constraint.stiffness,
-1 3737 force = Vector.mult(delta, difference * stiffness),
-1 3738 massTotal = (bodyA ? bodyA.inverseMass : 0) + (bodyB ? bodyB.inverseMass : 0),
-1 3739 inertiaTotal = (bodyA ? bodyA.inverseInertia : 0) + (bodyB ? bodyB.inverseInertia : 0),
-1 3740 resistanceTotal = massTotal + inertiaTotal,
-1 3741 torque,
-1 3742 share,
-1 3743 normal,
-1 3744 normalVelocity,
-1 3745 relativeVelocity;
-1 3746
-1 3747 if (constraint.damping) {
-1 3748 var zero = Vector.create();
-1 3749 normal = Vector.div(delta, currentLength);
-1 3750
-1 3751 relativeVelocity = Vector.sub(
-1 3752 bodyB && Vector.sub(bodyB.position, bodyB.positionPrev) || zero,
-1 3753 bodyA && Vector.sub(bodyA.position, bodyA.positionPrev) || zero
-1 3754 );
-1 3755
-1 3756 normalVelocity = Vector.dot(normal, relativeVelocity);
-1 3757 }
-1 3758
-1 3759 if (bodyA && !bodyA.isStatic) {
-1 3760 share = bodyA.inverseMass / massTotal;
-1 3761
-1 3762 // keep track of applied impulses for post solving
-1 3763 bodyA.constraintImpulse.x -= force.x * share;
-1 3764 bodyA.constraintImpulse.y -= force.y * share;
-1 3765
-1 3766 // apply forces
-1 3767 bodyA.position.x -= force.x * share;
-1 3768 bodyA.position.y -= force.y * share;
-1 3769
-1 3770 // apply damping
-1 3771 if (constraint.damping) {
-1 3772 bodyA.positionPrev.x -= constraint.damping * normal.x * normalVelocity * share;
-1 3773 bodyA.positionPrev.y -= constraint.damping * normal.y * normalVelocity * share;
-1 3774 }
-1 3775
-1 3776 // apply torque
-1 3777 torque = (Vector.cross(pointA, force) / resistanceTotal) * Constraint._torqueDampen * bodyA.inverseInertia * (1 - constraint.angularStiffness);
-1 3778 bodyA.constraintImpulse.angle -= torque;
-1 3779 bodyA.angle -= torque;
-1 3780 }
-1 3781
-1 3782 if (bodyB && !bodyB.isStatic) {
-1 3783 share = bodyB.inverseMass / massTotal;
-1 3784
-1 3785 // keep track of applied impulses for post solving
-1 3786 bodyB.constraintImpulse.x += force.x * share;
-1 3787 bodyB.constraintImpulse.y += force.y * share;
-1 3788
-1 3789 // apply forces
-1 3790 bodyB.position.x += force.x * share;
-1 3791 bodyB.position.y += force.y * share;
-1 3792
-1 3793 // apply damping
-1 3794 if (constraint.damping) {
-1 3795 bodyB.positionPrev.x += constraint.damping * normal.x * normalVelocity * share;
-1 3796 bodyB.positionPrev.y += constraint.damping * normal.y * normalVelocity * share;
-1 3797 }
-1 3798
-1 3799 // apply torque
-1 3800 torque = (Vector.cross(pointB, force) / resistanceTotal) * Constraint._torqueDampen * bodyB.inverseInertia * (1 - constraint.angularStiffness);
-1 3801 bodyB.constraintImpulse.angle += torque;
-1 3802 bodyB.angle += torque;
-1 3803 }
-1 3804
-1 3805 };
-1 3806
-1 3807 /**
-1 3808 * Performs body updates required after solving constraints.
-1 3809 * @private
-1 3810 * @method postSolveAll
-1 3811 * @param {body[]} bodies
-1 3812 */
-1 3813 Constraint.postSolveAll = function(bodies) {
-1 3814 for (var i = 0; i < bodies.length; i++) {
-1 3815 var body = bodies[i],
-1 3816 impulse = body.constraintImpulse;
-1 3817
-1 3818 if (body.isStatic || (impulse.x === 0 && impulse.y === 0 && impulse.angle === 0)) {
-1 3819 continue;
-1 3820 }
-1 3821
-1 3822 Sleeping.set(body, false);
-1 3823
-1 3824 // update geometry and reset
-1 3825 for (var j = 0; j < body.parts.length; j++) {
-1 3826 var part = body.parts[j];
-1 3827
-1 3828 Vertices.translate(part.vertices, impulse);
-1 3829
-1 3830 if (j > 0) {
-1 3831 part.position.x += impulse.x;
-1 3832 part.position.y += impulse.y;
-1 3833 }
-1 3834
-1 3835 if (impulse.angle !== 0) {
-1 3836 Vertices.rotate(part.vertices, impulse.angle, body.position);
-1 3837 Axes.rotate(part.axes, impulse.angle);
-1 3838 if (j > 0) {
-1 3839 Vector.rotateAbout(part.position, impulse.angle, body.position, part.position);
-1 3840 }
-1 3841 }
-1 3842
-1 3843 Bounds.update(part.bounds, part.vertices, body.velocity);
-1 3844 }
-1 3845
-1 3846 // dampen the cached impulse for warming next step
-1 3847 impulse.angle *= Constraint._warming;
-1 3848 impulse.x *= Constraint._warming;
-1 3849 impulse.y *= Constraint._warming;
-1 3850 }
-1 3851 };
-1 3852
-1 3853 /*
-1 3854 *
-1 3855 * Properties Documentation
-1 3856 *
-1 3857 */
-1 3858
-1 3859 /**
-1 3860 * An integer `Number` uniquely identifying number generated in `Composite.create` by `Common.nextId`.
-1 3861 *
-1 3862 * @property id
-1 3863 * @type number
-1 3864 */
-1 3865
-1 3866 /**
-1 3867 * A `String` denoting the type of object.
-1 3868 *
-1 3869 * @property type
-1 3870 * @type string
-1 3871 * @default "constraint"
-1 3872 * @readOnly
-1 3873 */
-1 3874
-1 3875 /**
-1 3876 * An arbitrary `String` name to help the user identify and manage bodies.
-1 3877 *
-1 3878 * @property label
-1 3879 * @type string
-1 3880 * @default "Constraint"
-1 3881 */
-1 3882
-1 3883 /**
-1 3884 * An `Object` that defines the rendering properties to be consumed by the module `Matter.Render`.
-1 3885 *
-1 3886 * @property render
-1 3887 * @type object
-1 3888 */
-1 3889
-1 3890 /**
-1 3891 * A flag that indicates if the constraint should be rendered.
-1 3892 *
-1 3893 * @property render.visible
-1 3894 * @type boolean
-1 3895 * @default true
-1 3896 */
-1 3897
-1 3898 /**
-1 3899 * A `Number` that defines the line width to use when rendering the constraint outline.
-1 3900 * A value of `0` means no outline will be rendered.
-1 3901 *
-1 3902 * @property render.lineWidth
-1 3903 * @type number
-1 3904 * @default 2
-1 3905 */
-1 3906
-1 3907 /**
-1 3908 * A `String` that defines the stroke style to use when rendering the constraint outline.
-1 3909 * It is the same as when using a canvas, so it accepts CSS style property values.
-1 3910 *
-1 3911 * @property render.strokeStyle
-1 3912 * @type string
-1 3913 * @default a random colour
-1 3914 */
-1 3915
-1 3916 /**
-1 3917 * A `String` that defines the constraint rendering type.
-1 3918 * The possible values are 'line', 'pin', 'spring'.
-1 3919 * An appropriate render type will be automatically chosen unless one is given in options.
-1 3920 *
-1 3921 * @property render.type
-1 3922 * @type string
-1 3923 * @default 'line'
-1 3924 */
-1 3925
-1 3926 /**
-1 3927 * A `Boolean` that defines if the constraint's anchor points should be rendered.
-1 3928 *
-1 3929 * @property render.anchors
-1 3930 * @type boolean
-1 3931 * @default true
-1 3932 */
-1 3933
-1 3934 /**
-1 3935 * The first possible `Body` that this constraint is attached to.
-1 3936 *
-1 3937 * @property bodyA
-1 3938 * @type body
-1 3939 * @default null
-1 3940 */
-1 3941
-1 3942 /**
-1 3943 * The second possible `Body` that this constraint is attached to.
-1 3944 *
-1 3945 * @property bodyB
-1 3946 * @type body
-1 3947 * @default null
-1 3948 */
-1 3949
-1 3950 /**
-1 3951 * A `Vector` that specifies the offset of the constraint from center of the `constraint.bodyA` if defined, otherwise a world-space position.
-1 3952 *
-1 3953 * @property pointA
-1 3954 * @type vector
-1 3955 * @default { x: 0, y: 0 }
-1 3956 */
-1 3957
-1 3958 /**
-1 3959 * A `Vector` that specifies the offset of the constraint from center of the `constraint.bodyB` if defined, otherwise a world-space position.
-1 3960 *
-1 3961 * @property pointB
-1 3962 * @type vector
-1 3963 * @default { x: 0, y: 0 }
-1 3964 */
-1 3965
-1 3966 /**
-1 3967 * A `Number` that specifies the stiffness of the constraint, i.e. the rate at which it returns to its resting `constraint.length`.
-1 3968 * A value of `1` means the constraint should be very stiff.
-1 3969 * A value of `0.2` means the constraint acts like a soft spring.
-1 3970 *
-1 3971 * @property stiffness
-1 3972 * @type number
-1 3973 * @default 1
-1 3974 */
-1 3975
-1 3976 /**
-1 3977 * A `Number` that specifies the damping of the constraint,
-1 3978 * i.e. the amount of resistance applied to each body based on their velocities to limit the amount of oscillation.
-1 3979 * Damping will only be apparent when the constraint also has a very low `stiffness`.
-1 3980 * A value of `0.1` means the constraint will apply heavy damping, resulting in little to no oscillation.
-1 3981 * A value of `0` means the constraint will apply no damping.
-1 3982 *
-1 3983 * @property damping
-1 3984 * @type number
-1 3985 * @default 0
-1 3986 */
-1 3987
-1 3988 /**
-1 3989 * A `Number` that specifies the target resting length of the constraint.
-1 3990 * It is calculated automatically in `Constraint.create` from initial positions of the `constraint.bodyA` and `constraint.bodyB`.
-1 3991 *
-1 3992 * @property length
-1 3993 * @type number
-1 3994 */
-1 3995
-1 3996 /**
-1 3997 * An object reserved for storing plugin-specific properties.
-1 3998 *
-1 3999 * @property plugin
-1 4000 * @type {}
-1 4001 */
-1 4002
-1 4003 })();
-1 4004
-1 4005 },{"../core/Common":14,"../core/Sleeping":22,"../geometry/Axes":25,"../geometry/Bounds":26,"../geometry/Vector":28,"../geometry/Vertices":29}],13:[function(_dereq_,module,exports){
-1 4006 /**
-1 4007 * The `Matter.MouseConstraint` module contains methods for creating mouse constraints.
-1 4008 * Mouse constraints are used for allowing user interaction, providing the ability to move bodies via the mouse or touch.
-1 4009 *
-1 4010 * See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples).
-1 4011 *
-1 4012 * @class MouseConstraint
-1 4013 */
-1 4014
-1 4015 var MouseConstraint = {};
-1 4016
-1 4017 module.exports = MouseConstraint;
-1 4018
-1 4019 var Vertices = _dereq_('../geometry/Vertices');
-1 4020 var Sleeping = _dereq_('../core/Sleeping');
-1 4021 var Mouse = _dereq_('../core/Mouse');
-1 4022 var Events = _dereq_('../core/Events');
-1 4023 var Detector = _dereq_('../collision/Detector');
-1 4024 var Constraint = _dereq_('./Constraint');
-1 4025 var Composite = _dereq_('../body/Composite');
-1 4026 var Common = _dereq_('../core/Common');
-1 4027 var Bounds = _dereq_('../geometry/Bounds');
-1 4028
-1 4029 (function() {
-1 4030
-1 4031 /**
-1 4032 * Creates a new mouse constraint.
-1 4033 * All properties have default values, and many are pre-calculated automatically based on other properties.
-1 4034 * See the properties section below for detailed information on what you can pass via the `options` object.
-1 4035 * @method create
-1 4036 * @param {engine} engine
-1 4037 * @param {} options
-1 4038 * @return {MouseConstraint} A new MouseConstraint
-1 4039 */
-1 4040 MouseConstraint.create = function(engine, options) {
-1 4041 var mouse = (engine ? engine.mouse : null) || (options ? options.mouse : null);
-1 4042
-1 4043 if (!mouse) {
-1 4044 if (engine && engine.render && engine.render.canvas) {
-1 4045 mouse = Mouse.create(engine.render.canvas);
-1 4046 } else if (options && options.element) {
-1 4047 mouse = Mouse.create(options.element);
-1 4048 } else {
-1 4049 mouse = Mouse.create();
-1 4050 Common.warn('MouseConstraint.create: options.mouse was undefined, options.element was undefined, may not function as expected');
-1 4051 }
-1 4052 }
-1 4053
-1 4054 var constraint = Constraint.create({
-1 4055 label: 'Mouse Constraint',
-1 4056 pointA: mouse.position,
-1 4057 pointB: { x: 0, y: 0 },
-1 4058 length: 0.01,
-1 4059 stiffness: 0.1,
-1 4060 angularStiffness: 1,
-1 4061 render: {
-1 4062 strokeStyle: '#90EE90',
-1 4063 lineWidth: 3
-1 4064 }
-1 4065 });
-1 4066
-1 4067 var defaults = {
-1 4068 type: 'mouseConstraint',
-1 4069 mouse: mouse,
-1 4070 element: null,
-1 4071 body: null,
-1 4072 constraint: constraint,
-1 4073 collisionFilter: {
-1 4074 category: 0x0001,
-1 4075 mask: 0xFFFFFFFF,
-1 4076 group: 0
-1 4077 }
-1 4078 };
-1 4079
-1 4080 var mouseConstraint = Common.extend(defaults, options);
-1 4081
-1 4082 Events.on(engine, 'beforeUpdate', function() {
-1 4083 var allBodies = Composite.allBodies(engine.world);
-1 4084 MouseConstraint.update(mouseConstraint, allBodies);
-1 4085 MouseConstraint._triggerEvents(mouseConstraint);
-1 4086 });
-1 4087
-1 4088 return mouseConstraint;
-1 4089 };
-1 4090
-1 4091 /**
-1 4092 * Updates the given mouse constraint.
-1 4093 * @private
-1 4094 * @method update
-1 4095 * @param {MouseConstraint} mouseConstraint
-1 4096 * @param {body[]} bodies
-1 4097 */
-1 4098 MouseConstraint.update = function(mouseConstraint, bodies) {
-1 4099 var mouse = mouseConstraint.mouse,
-1 4100 constraint = mouseConstraint.constraint,
-1 4101 body = mouseConstraint.body;
-1 4102
-1 4103 if (mouse.button === 0) {
-1 4104 if (!constraint.bodyB) {
-1 4105 for (var i = 0; i < bodies.length; i++) {
-1 4106 body = bodies[i];
-1 4107 if (Bounds.contains(body.bounds, mouse.position)
-1 4108 && Detector.canCollide(body.collisionFilter, mouseConstraint.collisionFilter)) {
-1 4109 for (var j = body.parts.length > 1 ? 1 : 0; j < body.parts.length; j++) {
-1 4110 var part = body.parts[j];
-1 4111 if (Vertices.contains(part.vertices, mouse.position)) {
-1 4112 constraint.pointA = mouse.position;
-1 4113 constraint.bodyB = mouseConstraint.body = body;
-1 4114 constraint.pointB = { x: mouse.position.x - body.position.x, y: mouse.position.y - body.position.y };
-1 4115 constraint.angleB = body.angle;
-1 4116
-1 4117 Sleeping.set(body, false);
-1 4118 Events.trigger(mouseConstraint, 'startdrag', { mouse: mouse, body: body });
-1 4119
-1 4120 break;
-1 4121 }
-1 4122 }
-1 4123 }
-1 4124 }
-1 4125 } else {
-1 4126 Sleeping.set(constraint.bodyB, false);
-1 4127 constraint.pointA = mouse.position;
-1 4128 }
-1 4129 } else {
-1 4130 constraint.bodyB = mouseConstraint.body = null;
-1 4131 constraint.pointB = null;
-1 4132
-1 4133 if (body)
-1 4134 Events.trigger(mouseConstraint, 'enddrag', { mouse: mouse, body: body });
-1 4135 }
-1 4136 };
-1 4137
-1 4138 /**
-1 4139 * Triggers mouse constraint events.
-1 4140 * @method _triggerEvents
-1 4141 * @private
-1 4142 * @param {mouse} mouseConstraint
-1 4143 */
-1 4144 MouseConstraint._triggerEvents = function(mouseConstraint) {
-1 4145 var mouse = mouseConstraint.mouse,
-1 4146 mouseEvents = mouse.sourceEvents;
-1 4147
-1 4148 if (mouseEvents.mousemove)
-1 4149 Events.trigger(mouseConstraint, 'mousemove', { mouse: mouse });
-1 4150
-1 4151 if (mouseEvents.mousedown)
-1 4152 Events.trigger(mouseConstraint, 'mousedown', { mouse: mouse });
-1 4153
-1 4154 if (mouseEvents.mouseup)
-1 4155 Events.trigger(mouseConstraint, 'mouseup', { mouse: mouse });
-1 4156
-1 4157 // reset the mouse state ready for the next step
-1 4158 Mouse.clearSourceEvents(mouse);
-1 4159 };
-1 4160
-1 4161 /*
-1 4162 *
-1 4163 * Events Documentation
-1 4164 *
-1 4165 */
-1 4166
-1 4167 /**
-1 4168 * Fired when the mouse has moved (or a touch moves) during the last step
-1 4169 *
-1 4170 * @event mousemove
-1 4171 * @param {} event An event object
-1 4172 * @param {mouse} event.mouse The engine's mouse instance
-1 4173 * @param {} event.source The source object of the event
-1 4174 * @param {} event.name The name of the event
-1 4175 */
-1 4176
-1 4177 /**
-1 4178 * Fired when the mouse is down (or a touch has started) during the last step
-1 4179 *
-1 4180 * @event mousedown
-1 4181 * @param {} event An event object
-1 4182 * @param {mouse} event.mouse The engine's mouse instance
-1 4183 * @param {} event.source The source object of the event
-1 4184 * @param {} event.name The name of the event
-1 4185 */
-1 4186
-1 4187 /**
-1 4188 * Fired when the mouse is up (or a touch has ended) during the last step
-1 4189 *
-1 4190 * @event mouseup
-1 4191 * @param {} event An event object
-1 4192 * @param {mouse} event.mouse The engine's mouse instance
-1 4193 * @param {} event.source The source object of the event
-1 4194 * @param {} event.name The name of the event
-1 4195 */
-1 4196
-1 4197 /**
-1 4198 * Fired when the user starts dragging a body
-1 4199 *
-1 4200 * @event startdrag
-1 4201 * @param {} event An event object
-1 4202 * @param {mouse} event.mouse The engine's mouse instance
-1 4203 * @param {body} event.body The body being dragged
-1 4204 * @param {} event.source The source object of the event
-1 4205 * @param {} event.name The name of the event
-1 4206 */
-1 4207
-1 4208 /**
-1 4209 * Fired when the user ends dragging a body
-1 4210 *
-1 4211 * @event enddrag
-1 4212 * @param {} event An event object
-1 4213 * @param {mouse} event.mouse The engine's mouse instance
-1 4214 * @param {body} event.body The body that has stopped being dragged
-1 4215 * @param {} event.source The source object of the event
-1 4216 * @param {} event.name The name of the event
-1 4217 */
-1 4218
-1 4219 /*
-1 4220 *
-1 4221 * Properties Documentation
-1 4222 *
-1 4223 */
-1 4224
-1 4225 /**
-1 4226 * A `String` denoting the type of object.
-1 4227 *
-1 4228 * @property type
-1 4229 * @type string
-1 4230 * @default "constraint"
-1 4231 * @readOnly
-1 4232 */
-1 4233
-1 4234 /**
-1 4235 * The `Mouse` instance in use. If not supplied in `MouseConstraint.create`, one will be created.
-1 4236 *
-1 4237 * @property mouse
-1 4238 * @type mouse
-1 4239 * @default mouse
-1 4240 */
-1 4241
-1 4242 /**
-1 4243 * The `Body` that is currently being moved by the user, or `null` if no body.
-1 4244 *
-1 4245 * @property body
-1 4246 * @type body
-1 4247 * @default null
-1 4248 */
-1 4249
-1 4250 /**
-1 4251 * The `Constraint` object that is used to move the body during interaction.
-1 4252 *
-1 4253 * @property constraint
-1 4254 * @type constraint
-1 4255 */
-1 4256
-1 4257 /**
-1 4258 * An `Object` that specifies the collision filter properties.
-1 4259 * The collision filter allows the user to define which types of body this mouse constraint can interact with.
-1 4260 * See `body.collisionFilter` for more information.
-1 4261 *
-1 4262 * @property collisionFilter
-1 4263 * @type object
-1 4264 */
-1 4265
-1 4266 })();
-1 4267
-1 4268 },{"../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){
-1 4269 (function (global){
-1 4270 /**
-1 4271 * The `Matter.Common` module contains utility functions that are common to all modules.
-1 4272 *
-1 4273 * @class Common
-1 4274 */
-1 4275
-1 4276 var Common = {};
-1 4277
-1 4278 module.exports = Common;
-1 4279
-1 4280 (function() {
-1 4281
-1 4282 Common._nextId = 0;
-1 4283 Common._seed = 0;
-1 4284 Common._nowStartTime = +(new Date());
-1 4285
-1 4286 /**
-1 4287 * Extends the object in the first argument using the object in the second argument.
-1 4288 * @method extend
-1 4289 * @param {} obj
-1 4290 * @param {boolean} deep
-1 4291 * @return {} obj extended
-1 4292 */
-1 4293 Common.extend = function(obj, deep) {
-1 4294 var argsStart,
-1 4295 args,
-1 4296 deepClone;
-1 4297
-1 4298 if (typeof deep === 'boolean') {
-1 4299 argsStart = 2;
-1 4300 deepClone = deep;
-1 4301 } else {
-1 4302 argsStart = 1;
-1 4303 deepClone = true;
-1 4304 }
-1 4305
-1 4306 for (var i = argsStart; i < arguments.length; i++) {
-1 4307 var source = arguments[i];
-1 4308
-1 4309 if (source) {
-1 4310 for (var prop in source) {
-1 4311 if (deepClone && source[prop] && source[prop].constructor === Object) {
-1 4312 if (!obj[prop] || obj[prop].constructor === Object) {
-1 4313 obj[prop] = obj[prop] || {};
-1 4314 Common.extend(obj[prop], deepClone, source[prop]);
-1 4315 } else {
-1 4316 obj[prop] = source[prop];
-1 4317 }
-1 4318 } else {
-1 4319 obj[prop] = source[prop];
-1 4320 }
-1 4321 }
-1 4322 }
-1 4323 }
-1 4324
-1 4325 return obj;
-1 4326 };
-1 4327
-1 4328 /**
-1 4329 * Creates a new clone of the object, if deep is true references will also be cloned.
-1 4330 * @method clone
-1 4331 * @param {} obj
-1 4332 * @param {bool} deep
-1 4333 * @return {} obj cloned
-1 4334 */
-1 4335 Common.clone = function(obj, deep) {
-1 4336 return Common.extend({}, deep, obj);
-1 4337 };
-1 4338
-1 4339 /**
-1 4340 * Returns the list of keys for the given object.
-1 4341 * @method keys
-1 4342 * @param {} obj
-1 4343 * @return {string[]} keys
-1 4344 */
-1 4345 Common.keys = function(obj) {
-1 4346 if (Object.keys)
-1 4347 return Object.keys(obj);
-1 4348
-1 4349 // avoid hasOwnProperty for performance
-1 4350 var keys = [];
-1 4351 for (var key in obj)
-1 4352 keys.push(key);
-1 4353 return keys;
-1 4354 };
-1 4355
-1 4356 /**
-1 4357 * Returns the list of values for the given object.
-1 4358 * @method values
-1 4359 * @param {} obj
-1 4360 * @return {array} Array of the objects property values
-1 4361 */
-1 4362 Common.values = function(obj) {
-1 4363 var values = [];
-1 4364
-1 4365 if (Object.keys) {
-1 4366 var keys = Object.keys(obj);
-1 4367 for (var i = 0; i < keys.length; i++) {
-1 4368 values.push(obj[keys[i]]);
-1 4369 }
-1 4370 return values;
-1 4371 }
-1 4372
-1 4373 // avoid hasOwnProperty for performance
-1 4374 for (var key in obj)
-1 4375 values.push(obj[key]);
-1 4376 return values;
-1 4377 };
-1 4378
-1 4379 /**
-1 4380 * Gets a value from `base` relative to the `path` string.
-1 4381 * @method get
-1 4382 * @param {} obj The base object
-1 4383 * @param {string} path The path relative to `base`, e.g. 'Foo.Bar.baz'
-1 4384 * @param {number} [begin] Path slice begin
-1 4385 * @param {number} [end] Path slice end
-1 4386 * @return {} The object at the given path
-1 4387 */
-1 4388 Common.get = function(obj, path, begin, end) {
-1 4389 path = path.split('.').slice(begin, end);
-1 4390
-1 4391 for (var i = 0; i < path.length; i += 1) {
-1 4392 obj = obj[path[i]];
-1 4393 }
-1 4394
-1 4395 return obj;
-1 4396 };
-1 4397
-1 4398 /**
-1 4399 * Sets a value on `base` relative to the given `path` string.
-1 4400 * @method set
-1 4401 * @param {} obj The base object
-1 4402 * @param {string} path The path relative to `base`, e.g. 'Foo.Bar.baz'
-1 4403 * @param {} val The value to set
-1 4404 * @param {number} [begin] Path slice begin
-1 4405 * @param {number} [end] Path slice end
-1 4406 * @return {} Pass through `val` for chaining
-1 4407 */
-1 4408 Common.set = function(obj, path, val, begin, end) {
-1 4409 var parts = path.split('.').slice(begin, end);
-1 4410 Common.get(obj, path, 0, -1)[parts[parts.length - 1]] = val;
-1 4411 return val;
-1 4412 };
-1 4413
-1 4414 /**
-1 4415 * Shuffles the given array in-place.
-1 4416 * The function uses a seeded random generator.
-1 4417 * @method shuffle
-1 4418 * @param {array} array
-1 4419 * @return {array} array shuffled randomly
-1 4420 */
-1 4421 Common.shuffle = function(array) {
-1 4422 for (var i = array.length - 1; i > 0; i--) {
-1 4423 var j = Math.floor(Common.random() * (i + 1));
-1 4424 var temp = array[i];
-1 4425 array[i] = array[j];
-1 4426 array[j] = temp;
-1 4427 }
-1 4428 return array;
-1 4429 };
-1 4430
-1 4431 /**
-1 4432 * Randomly chooses a value from a list with equal probability.
-1 4433 * The function uses a seeded random generator.
-1 4434 * @method choose
-1 4435 * @param {array} choices
-1 4436 * @return {object} A random choice object from the array
-1 4437 */
-1 4438 Common.choose = function(choices) {
-1 4439 return choices[Math.floor(Common.random() * choices.length)];
-1 4440 };
-1 4441
-1 4442 /**
-1 4443 * Returns true if the object is a HTMLElement, otherwise false.
-1 4444 * @method isElement
-1 4445 * @param {object} obj
-1 4446 * @return {boolean} True if the object is a HTMLElement, otherwise false
-1 4447 */
-1 4448 Common.isElement = function(obj) {
-1 4449 if (typeof HTMLElement !== 'undefined') {
-1 4450 return obj instanceof HTMLElement;
-1 4451 }
-1 4452
-1 4453 return !!(obj && obj.nodeType && obj.nodeName);
-1 4454 };
-1 4455
-1 4456 /**
-1 4457 * Returns true if the object is an array.
-1 4458 * @method isArray
-1 4459 * @param {object} obj
-1 4460 * @return {boolean} True if the object is an array, otherwise false
-1 4461 */
-1 4462 Common.isArray = function(obj) {
-1 4463 return Object.prototype.toString.call(obj) === '[object Array]';
-1 4464 };
-1 4465
-1 4466 /**
-1 4467 * Returns true if the object is a function.
-1 4468 * @method isFunction
-1 4469 * @param {object} obj
-1 4470 * @return {boolean} True if the object is a function, otherwise false
-1 4471 */
-1 4472 Common.isFunction = function(obj) {
-1 4473 return typeof obj === "function";
-1 4474 };
-1 4475
-1 4476 /**
-1 4477 * Returns true if the object is a plain object.
-1 4478 * @method isPlainObject
-1 4479 * @param {object} obj
-1 4480 * @return {boolean} True if the object is a plain object, otherwise false
-1 4481 */
-1 4482 Common.isPlainObject = function(obj) {
-1 4483 return typeof obj === 'object' && obj.constructor === Object;
-1 4484 };
-1 4485
-1 4486 /**
-1 4487 * Returns true if the object is a string.
-1 4488 * @method isString
-1 4489 * @param {object} obj
-1 4490 * @return {boolean} True if the object is a string, otherwise false
-1 4491 */
-1 4492 Common.isString = function(obj) {
-1 4493 return toString.call(obj) === '[object String]';
-1 4494 };
-1 4495
-1 4496 /**
-1 4497 * Returns the given value clamped between a minimum and maximum value.
-1 4498 * @method clamp
-1 4499 * @param {number} value
-1 4500 * @param {number} min
-1 4501 * @param {number} max
-1 4502 * @return {number} The value clamped between min and max inclusive
-1 4503 */
-1 4504 Common.clamp = function(value, min, max) {
-1 4505 if (value < min)
-1 4506 return min;
-1 4507 if (value > max)
-1 4508 return max;
-1 4509 return value;
-1 4510 };
-1 4511
-1 4512 /**
-1 4513 * Returns the sign of the given value.
-1 4514 * @method sign
-1 4515 * @param {number} value
-1 4516 * @return {number} -1 if negative, +1 if 0 or positive
-1 4517 */
-1 4518 Common.sign = function(value) {
-1 4519 return value < 0 ? -1 : 1;
-1 4520 };
-1 4521
-1 4522 /**
-1 4523 * Returns the current timestamp since the time origin (e.g. from page load).
-1 4524 * The result will be high-resolution including decimal places if available.
-1 4525 * @method now
-1 4526 * @return {number} the current timestamp
-1 4527 */
-1 4528 Common.now = function() {
-1 4529 if (window.performance) {
-1 4530 if (window.performance.now) {
-1 4531 return window.performance.now();
-1 4532 } else if (window.performance.webkitNow) {
-1 4533 return window.performance.webkitNow();
-1 4534 }
-1 4535 }
-1 4536
-1 4537 return (new Date()) - Common._nowStartTime;
-1 4538 };
-1 4539
-1 4540 /**
-1 4541 * Returns a random value between a minimum and a maximum value inclusive.
-1 4542 * The function uses a seeded random generator.
-1 4543 * @method random
-1 4544 * @param {number} min
-1 4545 * @param {number} max
-1 4546 * @return {number} A random number between min and max inclusive
-1 4547 */
-1 4548 Common.random = function(min, max) {
-1 4549 min = (typeof min !== "undefined") ? min : 0;
-1 4550 max = (typeof max !== "undefined") ? max : 1;
-1 4551 return min + _seededRandom() * (max - min);
-1 4552 };
-1 4553
-1 4554 var _seededRandom = function() {
-1 4555 // https://en.wikipedia.org/wiki/Linear_congruential_generator
-1 4556 Common._seed = (Common._seed * 9301 + 49297) % 233280;
-1 4557 return Common._seed / 233280;
-1 4558 };
-1 4559
-1 4560 /**
-1 4561 * Converts a CSS hex colour string into an integer.
-1 4562 * @method colorToNumber
-1 4563 * @param {string} colorString
-1 4564 * @return {number} An integer representing the CSS hex string
-1 4565 */
-1 4566 Common.colorToNumber = function(colorString) {
-1 4567 colorString = colorString.replace('#','');
-1 4568
-1 4569 if (colorString.length == 3) {
-1 4570 colorString = colorString.charAt(0) + colorString.charAt(0)
-1 4571 + colorString.charAt(1) + colorString.charAt(1)
-1 4572 + colorString.charAt(2) + colorString.charAt(2);
-1 4573 }
-1 4574
-1 4575 return parseInt(colorString, 16);
-1 4576 };
-1 4577
-1 4578 /**
-1 4579 * The console logging level to use, where each level includes all levels above and excludes the levels below.
-1 4580 * The default level is 'debug' which shows all console messages.
-1 4581 *
-1 4582 * Possible level values are:
-1 4583 * - 0 = None
-1 4584 * - 1 = Debug
-1 4585 * - 2 = Info
-1 4586 * - 3 = Warn
-1 4587 * - 4 = Error
-1 4588 * @property Common.logLevel
-1 4589 * @type {Number}
-1 4590 * @default 1
-1 4591 */
-1 4592 Common.logLevel = 1;
-1 4593
-1 4594 /**
-1 4595 * Shows a `console.log` message only if the current `Common.logLevel` allows it.
-1 4596 * The message will be prefixed with 'matter-js' to make it easily identifiable.
-1 4597 * @method log
-1 4598 * @param ...objs {} The objects to log.
-1 4599 */
-1 4600 Common.log = function() {
-1 4601 if (console && Common.logLevel > 0 && Common.logLevel <= 3) {
-1 4602 console.log.apply(console, ['matter-js:'].concat(Array.prototype.slice.call(arguments)));
-1 4603 }
-1 4604 };
-1 4605
-1 4606 /**
-1 4607 * Shows a `console.info` message only if the current `Common.logLevel` allows it.
-1 4608 * The message will be prefixed with 'matter-js' to make it easily identifiable.
-1 4609 * @method info
-1 4610 * @param ...objs {} The objects to log.
-1 4611 */
-1 4612 Common.info = function() {
-1 4613 if (console && Common.logLevel > 0 && Common.logLevel <= 2) {
-1 4614 console.info.apply(console, ['matter-js:'].concat(Array.prototype.slice.call(arguments)));
-1 4615 }
-1 4616 };
-1 4617
-1 4618 /**
-1 4619 * Shows a `console.warn` message only if the current `Common.logLevel` allows it.
-1 4620 * The message will be prefixed with 'matter-js' to make it easily identifiable.
-1 4621 * @method warn
-1 4622 * @param ...objs {} The objects to log.
-1 4623 */
-1 4624 Common.warn = function() {
-1 4625 if (console && Common.logLevel > 0 && Common.logLevel <= 3) {
-1 4626 console.warn.apply(console, ['matter-js:'].concat(Array.prototype.slice.call(arguments)));
-1 4627 }
-1 4628 };
-1 4629
-1 4630 /**
-1 4631 * Returns the next unique sequential ID.
-1 4632 * @method nextId
-1 4633 * @return {Number} Unique sequential ID
-1 4634 */
-1 4635 Common.nextId = function() {
-1 4636 return Common._nextId++;
-1 4637 };
-1 4638
-1 4639 /**
-1 4640 * A cross browser compatible indexOf implementation.
-1 4641 * @method indexOf
-1 4642 * @param {array} haystack
-1 4643 * @param {object} needle
-1 4644 * @return {number} The position of needle in haystack, otherwise -1.
-1 4645 */
-1 4646 Common.indexOf = function(haystack, needle) {
-1 4647 if (haystack.indexOf)
-1 4648 return haystack.indexOf(needle);
-1 4649
-1 4650 for (var i = 0; i < haystack.length; i++) {
-1 4651 if (haystack[i] === needle)
-1 4652 return i;
-1 4653 }
-1 4654
-1 4655 return -1;
-1 4656 };
-1 4657
-1 4658 /**
-1 4659 * A cross browser compatible array map implementation.
-1 4660 * @method map
-1 4661 * @param {array} list
-1 4662 * @param {function} func
-1 4663 * @return {array} Values from list transformed by func.
-1 4664 */
-1 4665 Common.map = function(list, func) {
-1 4666 if (list.map) {
-1 4667 return list.map(func);
-1 4668 }
-1 4669
-1 4670 var mapped = [];
-1 4671
-1 4672 for (var i = 0; i < list.length; i += 1) {
-1 4673 mapped.push(func(list[i]));
-1 4674 }
-1 4675
-1 4676 return mapped;
-1 4677 };
-1 4678
-1 4679 /**
-1 4680 * Takes a directed graph and returns the partially ordered set of vertices in topological order.
-1 4681 * Circular dependencies are allowed.
-1 4682 * @method topologicalSort
-1 4683 * @param {object} graph
-1 4684 * @return {array} Partially ordered set of vertices in topological order.
-1 4685 */
-1 4686 Common.topologicalSort = function(graph) {
-1 4687 // https://github.com/mgechev/javascript-algorithms
-1 4688 // Copyright (c) Minko Gechev (MIT license)
-1 4689 // Modifications: tidy formatting and naming
-1 4690 var result = [],
-1 4691 visited = [],
-1 4692 temp = [];
-1 4693
-1 4694 for (var node in graph) {
-1 4695 if (!visited[node] && !temp[node]) {
-1 4696 Common._topologicalSort(node, visited, temp, graph, result);
-1 4697 }
-1 4698 }
-1 4699
-1 4700 return result;
-1 4701 };
-1 4702
-1 4703 Common._topologicalSort = function(node, visited, temp, graph, result) {
-1 4704 var neighbors = graph[node] || [];
-1 4705 temp[node] = true;
-1 4706
-1 4707 for (var i = 0; i < neighbors.length; i += 1) {
-1 4708 var neighbor = neighbors[i];
-1 4709
-1 4710 if (temp[neighbor]) {
-1 4711 // skip circular dependencies
-1 4712 continue;
-1 4713 }
-1 4714
-1 4715 if (!visited[neighbor]) {
-1 4716 Common._topologicalSort(neighbor, visited, temp, graph, result);
-1 4717 }
-1 4718 }
-1 4719
-1 4720 temp[node] = false;
-1 4721 visited[node] = true;
-1 4722
-1 4723 result.push(node);
-1 4724 };
-1 4725
-1 4726 /**
-1 4727 * Takes _n_ functions as arguments and returns a new function that calls them in order.
-1 4728 * The arguments applied when calling the new function will also be applied to every function passed.
-1 4729 * The value of `this` refers to the last value returned in the chain that was not `undefined`.
-1 4730 * Therefore if a passed function does not return a value, the previously returned value is maintained.
-1 4731 * After all passed functions have been called the new function returns the last returned value (if any).
-1 4732 * If any of the passed functions are a chain, then the chain will be flattened.
-1 4733 * @method chain
-1 4734 * @param ...funcs {function} The functions to chain.
-1 4735 * @return {function} A new function that calls the passed functions in order.
-1 4736 */
-1 4737 Common.chain = function() {
-1 4738 var funcs = [];
-1 4739
-1 4740 for (var i = 0; i < arguments.length; i += 1) {
-1 4741 var func = arguments[i];
-1 4742
-1 4743 if (func._chained) {
-1 4744 // flatten already chained functions
-1 4745 funcs.push.apply(funcs, func._chained);
-1 4746 } else {
-1 4747 funcs.push(func);
-1 4748 }
-1 4749 }
-1 4750
-1 4751 var chain = function() {
-1 4752 // https://github.com/GoogleChrome/devtools-docs/issues/53#issuecomment-51941358
-1 4753 var lastResult,
-1 4754 args = new Array(arguments.length);
-1 4755
-1 4756 for (var i = 0, l = arguments.length; i < l; i++) {
-1 4757 args[i] = arguments[i];
-1 4758 }
-1 4759
-1 4760 for (i = 0; i < funcs.length; i += 1) {
-1 4761 var result = funcs[i].apply(lastResult, args);
-1 4762
-1 4763 if (typeof result !== 'undefined') {
-1 4764 lastResult = result;
-1 4765 }
-1 4766 }
-1 4767
-1 4768 return lastResult;
-1 4769 };
-1 4770
-1 4771 chain._chained = funcs;
-1 4772
-1 4773 return chain;
-1 4774 };
-1 4775
-1 4776 /**
-1 4777 * Chains a function to excute before the original function on the given `path` relative to `base`.
-1 4778 * See also docs for `Common.chain`.
-1 4779 * @method chainPathBefore
-1 4780 * @param {} base The base object
-1 4781 * @param {string} path The path relative to `base`
-1 4782 * @param {function} func The function to chain before the original
-1 4783 * @return {function} The chained function that replaced the original
-1 4784 */
-1 4785 Common.chainPathBefore = function(base, path, func) {
-1 4786 return Common.set(base, path, Common.chain(
-1 4787 func,
-1 4788 Common.get(base, path)
-1 4789 ));
-1 4790 };
-1 4791
-1 4792 /**
-1 4793 * Chains a function to excute after the original function on the given `path` relative to `base`.
-1 4794 * See also docs for `Common.chain`.
-1 4795 * @method chainPathAfter
-1 4796 * @param {} base The base object
-1 4797 * @param {string} path The path relative to `base`
-1 4798 * @param {function} func The function to chain after the original
-1 4799 * @return {function} The chained function that replaced the original
-1 4800 */
-1 4801 Common.chainPathAfter = function(base, path, func) {
-1 4802 return Common.set(base, path, Common.chain(
-1 4803 Common.get(base, path),
-1 4804 func
-1 4805 ));
-1 4806 };
-1 4807
-1 4808 /**
-1 4809 * Used to require external libraries outside of the bundle.
-1 4810 * It first looks for the `globalName` on the environment's global namespace.
-1 4811 * If the global is not found, it will fall back to using the standard `require` using the `moduleName`.
-1 4812 * @private
-1 4813 * @method _requireGlobal
-1 4814 * @param {string} globalName The global module name
-1 4815 * @param {string} moduleName The fallback CommonJS module name
-1 4816 * @return {} The loaded module
-1 4817 */
-1 4818 Common._requireGlobal = function(globalName, moduleName) {
-1 4819 var obj = (typeof window !== 'undefined' ? window[globalName] : typeof global !== 'undefined' ? global[globalName] : null);
-1 4820 return obj || _dereq_(moduleName);
-1 4821 };
-1 4822 })();
-1 4823
-1 4824 }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
-1 4825 },{}],15:[function(_dereq_,module,exports){
-1 4826 /**
-1 4827 * The `Matter.Engine` module contains methods for creating and manipulating engines.
-1 4828 * An engine is a controller that manages updating the simulation of the world.
-1 4829 * See `Matter.Runner` for an optional game loop utility.
-1 4830 *
-1 4831 * See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples).
-1 4832 *
-1 4833 * @class Engine
-1 4834 */
-1 4835
-1 4836 var Engine = {};
-1 4837
-1 4838 module.exports = Engine;
-1 4839
-1 4840 var World = _dereq_('../body/World');
-1 4841 var Sleeping = _dereq_('./Sleeping');
-1 4842 var Resolver = _dereq_('../collision/Resolver');
-1 4843 var Render = _dereq_('../render/Render');
-1 4844 var Pairs = _dereq_('../collision/Pairs');
-1 4845 var Metrics = _dereq_('./Metrics');
-1 4846 var Grid = _dereq_('../collision/Grid');
-1 4847 var Events = _dereq_('./Events');
-1 4848 var Composite = _dereq_('../body/Composite');
-1 4849 var Constraint = _dereq_('../constraint/Constraint');
-1 4850 var Common = _dereq_('./Common');
-1 4851 var Body = _dereq_('../body/Body');
-1 4852
-1 4853 (function() {
-1 4854
-1 4855 /**
-1 4856 * Creates a new engine. The options parameter is an object that specifies any properties you wish to override the defaults.
-1 4857 * All properties have default values, and many are pre-calculated automatically based on other properties.
-1 4858 * See the properties section below for detailed information on what you can pass via the `options` object.
-1 4859 * @method create
-1 4860 * @param {object} [options]
-1 4861 * @return {engine} engine
-1 4862 */
-1 4863 Engine.create = function(element, options) {
-1 4864 // options may be passed as the first (and only) argument
-1 4865 options = Common.isElement(element) ? options : element;
-1 4866 element = Common.isElement(element) ? element : null;
-1 4867 options = options || {};
-1 4868
-1 4869 if (element || options.render) {
-1 4870 Common.warn('Engine.create: engine.render is deprecated (see docs)');
-1 4871 }
-1 4872
-1 4873 var defaults = {
-1 4874 positionIterations: 6,
-1 4875 velocityIterations: 4,
-1 4876 constraintIterations: 2,
-1 4877 enableSleeping: false,
-1 4878 events: [],
-1 4879 plugin: {},
-1 4880 timing: {
-1 4881 timestamp: 0,
-1 4882 timeScale: 1
-1 4883 },
-1 4884 broadphase: {
-1 4885 controller: Grid
-1 4886 }
-1 4887 };
-1 4888
-1 4889 var engine = Common.extend(defaults, options);
-1 4890
-1 4891 // @deprecated
-1 4892 if (element || engine.render) {
-1 4893 var renderDefaults = {
-1 4894 element: element,
-1 4895 controller: Render
-1 4896 };
-1 4897
-1 4898 engine.render = Common.extend(renderDefaults, engine.render);
-1 4899 }
-1 4900
-1 4901 // @deprecated
-1 4902 if (engine.render && engine.render.controller) {
-1 4903 engine.render = engine.render.controller.create(engine.render);
-1 4904 }
-1 4905
-1 4906 // @deprecated
-1 4907 if (engine.render) {
-1 4908 engine.render.engine = engine;
-1 4909 }
-1 4910
-1 4911 engine.world = options.world || World.create(engine.world);
-1 4912 engine.pairs = Pairs.create();
-1 4913 engine.broadphase = engine.broadphase.controller.create(engine.broadphase);
-1 4914 engine.metrics = engine.metrics || { extended: false };
-1 4915
-1 4916
-1 4917 return engine;
-1 4918 };
-1 4919
-1 4920 /**
-1 4921 * Moves the simulation forward in time by `delta` ms.
-1 4922 * The `correction` argument is an optional `Number` that specifies the time correction factor to apply to the update.
-1 4923 * This can help improve the accuracy of the simulation in cases where `delta` is changing between updates.
-1 4924 * The value of `correction` is defined as `delta / lastDelta`, i.e. the percentage change of `delta` over the last step.
-1 4925 * Therefore the value is always `1` (no correction) when `delta` constant (or when no correction is desired, which is the default).
-1 4926 * See the paper on <a href="http://lonesock.net/article/verlet.html">Time Corrected Verlet</a> for more information.
-1 4927 *
-1 4928 * Triggers `beforeUpdate` and `afterUpdate` events.
-1 4929 * Triggers `collisionStart`, `collisionActive` and `collisionEnd` events.
-1 4930 * @method update
-1 4931 * @param {engine} engine
-1 4932 * @param {number} [delta=16.666]
-1 4933 * @param {number} [correction=1]
-1 4934 */
-1 4935 Engine.update = function(engine, delta, correction) {
-1 4936 delta = delta || 1000 / 60;
-1 4937 correction = correction || 1;
-1 4938
-1 4939 var world = engine.world,
-1 4940 timing = engine.timing,
-1 4941 broadphase = engine.broadphase,
-1 4942 broadphasePairs = [],
-1 4943 i;
-1 4944
-1 4945 // increment timestamp
-1 4946 timing.timestamp += delta * timing.timeScale;
-1 4947
-1 4948 // create an event object
-1 4949 var event = {
-1 4950 timestamp: timing.timestamp
-1 4951 };
-1 4952
-1 4953 Events.trigger(engine, 'beforeUpdate', event);
-1 4954
-1 4955 // get lists of all bodies and constraints, no matter what composites they are in
-1 4956 var allBodies = Composite.allBodies(world),
-1 4957 allConstraints = Composite.allConstraints(world);
-1 4958
-1 4959
-1 4960 // if sleeping enabled, call the sleeping controller
-1 4961 if (engine.enableSleeping)
-1 4962 Sleeping.update(allBodies, timing.timeScale);
-1 4963
-1 4964 // applies gravity to all bodies
-1 4965 Engine._bodiesApplyGravity(allBodies, world.gravity);
-1 4966
-1 4967 // update all body position and rotation by integration
-1 4968 Engine._bodiesUpdate(allBodies, delta, timing.timeScale, correction, world.bounds);
-1 4969
-1 4970 // update all constraints (first pass)
-1 4971 Constraint.preSolveAll(allBodies);
-1 4972 for (i = 0; i < engine.constraintIterations; i++) {
-1 4973 Constraint.solveAll(allConstraints, timing.timeScale);
-1 4974 }
-1 4975 Constraint.postSolveAll(allBodies);
-1 4976
-1 4977 // broadphase pass: find potential collision pairs
-1 4978 if (broadphase.controller) {
-1 4979 // if world is dirty, we must flush the whole grid
-1 4980 if (world.isModified)
-1 4981 broadphase.controller.clear(broadphase);
-1 4982
-1 4983 // update the grid buckets based on current bodies
-1 4984 broadphase.controller.update(broadphase, allBodies, engine, world.isModified);
-1 4985 broadphasePairs = broadphase.pairsList;
-1 4986 } else {
-1 4987 // if no broadphase set, we just pass all bodies
-1 4988 broadphasePairs = allBodies;
-1 4989 }
-1 4990
-1 4991 // clear all composite modified flags
-1 4992 if (world.isModified) {
-1 4993 Composite.setModified(world, false, false, true);
-1 4994 }
-1 4995
-1 4996 // narrowphase pass: find actual collisions, then create or update collision pairs
-1 4997 var collisions = broadphase.detector(broadphasePairs, engine);
-1 4998
-1 4999 // update collision pairs
-1 5000 var pairs = engine.pairs,
-1 5001 timestamp = timing.timestamp;
-1 5002 Pairs.update(pairs, collisions, timestamp);
-1 5003 Pairs.removeOld(pairs, timestamp);
-1 5004
-1 5005 // wake up bodies involved in collisions
-1 5006 if (engine.enableSleeping)
-1 5007 Sleeping.afterCollisions(pairs.list, timing.timeScale);
-1 5008
-1 5009 // trigger collision events
-1 5010 if (pairs.collisionStart.length > 0)
-1 5011 Events.trigger(engine, 'collisionStart', { pairs: pairs.collisionStart });
-1 5012
-1 5013 // iteratively resolve position between collisions
-1 5014 Resolver.preSolvePosition(pairs.list);
-1 5015 for (i = 0; i < engine.positionIterations; i++) {
-1 5016 Resolver.solvePosition(pairs.list, timing.timeScale);
-1 5017 }
-1 5018 Resolver.postSolvePosition(allBodies);
-1 5019
-1 5020 // update all constraints (second pass)
-1 5021 Constraint.preSolveAll(allBodies);
-1 5022 for (i = 0; i < engine.constraintIterations; i++) {
-1 5023 Constraint.solveAll(allConstraints, timing.timeScale);
-1 5024 }
-1 5025 Constraint.postSolveAll(allBodies);
-1 5026
-1 5027 // iteratively resolve velocity between collisions
-1 5028 Resolver.preSolveVelocity(pairs.list);
-1 5029 for (i = 0; i < engine.velocityIterations; i++) {
-1 5030 Resolver.solveVelocity(pairs.list, timing.timeScale);
-1 5031 }
-1 5032
-1 5033 // trigger collision events
-1 5034 if (pairs.collisionActive.length > 0)
-1 5035 Events.trigger(engine, 'collisionActive', { pairs: pairs.collisionActive });
-1 5036
-1 5037 if (pairs.collisionEnd.length > 0)
-1 5038 Events.trigger(engine, 'collisionEnd', { pairs: pairs.collisionEnd });
-1 5039
-1 5040
-1 5041 // clear force buffers
-1 5042 Engine._bodiesClearForces(allBodies);
-1 5043
-1 5044 Events.trigger(engine, 'afterUpdate', event);
-1 5045
-1 5046 return engine;
-1 5047 };
-1 5048
-1 5049 /**
-1 5050 * Merges two engines by keeping the configuration of `engineA` but replacing the world with the one from `engineB`.
-1 5051 * @method merge
-1 5052 * @param {engine} engineA
-1 5053 * @param {engine} engineB
-1 5054 */
-1 5055 Engine.merge = function(engineA, engineB) {
-1 5056 Common.extend(engineA, engineB);
-1 5057
-1 5058 if (engineB.world) {
-1 5059 engineA.world = engineB.world;
-1 5060
-1 5061 Engine.clear(engineA);
-1 5062
-1 5063 var bodies = Composite.allBodies(engineA.world);
-1 5064
-1 5065 for (var i = 0; i < bodies.length; i++) {
-1 5066 var body = bodies[i];
-1 5067 Sleeping.set(body, false);
-1 5068 body.id = Common.nextId();
-1 5069 }
-1 5070 }
-1 5071 };
-1 5072
-1 5073 /**
-1 5074 * Clears the engine including the world, pairs and broadphase.
-1 5075 * @method clear
-1 5076 * @param {engine} engine
-1 5077 */
-1 5078 Engine.clear = function(engine) {
-1 5079 var world = engine.world;
-1 5080
-1 5081 Pairs.clear(engine.pairs);
-1 5082
-1 5083 var broadphase = engine.broadphase;
-1 5084 if (broadphase.controller) {
-1 5085 var bodies = Composite.allBodies(world);
-1 5086 broadphase.controller.clear(broadphase);
-1 5087 broadphase.controller.update(broadphase, bodies, engine, true);
-1 5088 }
-1 5089 };
-1 5090
-1 5091 /**
-1 5092 * Zeroes the `body.force` and `body.torque` force buffers.
-1 5093 * @method _bodiesClearForces
-1 5094 * @private
-1 5095 * @param {body[]} bodies
-1 5096 */
-1 5097 Engine._bodiesClearForces = function(bodies) {
-1 5098 for (var i = 0; i < bodies.length; i++) {
-1 5099 var body = bodies[i];
-1 5100
-1 5101 // reset force buffers
-1 5102 body.force.x = 0;
-1 5103 body.force.y = 0;
-1 5104 body.torque = 0;
-1 5105 }
-1 5106 };
-1 5107
-1 5108 /**
-1 5109 * Applys a mass dependant force to all given bodies.
-1 5110 * @method _bodiesApplyGravity
-1 5111 * @private
-1 5112 * @param {body[]} bodies
-1 5113 * @param {vector} gravity
-1 5114 */
-1 5115 Engine._bodiesApplyGravity = function(bodies, gravity) {
-1 5116 var gravityScale = typeof gravity.scale !== 'undefined' ? gravity.scale : 0.001;
-1 5117
-1 5118 if ((gravity.x === 0 && gravity.y === 0) || gravityScale === 0) {
-1 5119 return;
-1 5120 }
-1 5121
-1 5122 for (var i = 0; i < bodies.length; i++) {
-1 5123 var body = bodies[i];
-1 5124
-1 5125 if (body.isStatic || body.isSleeping)
-1 5126 continue;
-1 5127
-1 5128 // apply gravity
-1 5129 body.force.y += body.mass * gravity.y * gravityScale;
-1 5130 body.force.x += body.mass * gravity.x * gravityScale;
-1 5131 }
-1 5132 };
-1 5133
-1 5134 /**
-1 5135 * Applys `Body.update` to all given `bodies`.
-1 5136 * @method _bodiesUpdate
-1 5137 * @private
-1 5138 * @param {body[]} bodies
-1 5139 * @param {number} deltaTime
-1 5140 * The amount of time elapsed between updates
-1 5141 * @param {number} timeScale
-1 5142 * @param {number} correction
-1 5143 * The Verlet correction factor (deltaTime / lastDeltaTime)
-1 5144 * @param {bounds} worldBounds
-1 5145 */
-1 5146 Engine._bodiesUpdate = function(bodies, deltaTime, timeScale, correction, worldBounds) {
-1 5147 for (var i = 0; i < bodies.length; i++) {
-1 5148 var body = bodies[i];
-1 5149
-1 5150 if (body.isStatic || body.isSleeping)
-1 5151 continue;
-1 5152
-1 5153 Body.update(body, deltaTime, timeScale, correction);
-1 5154 }
-1 5155 };
-1 5156
-1 5157 /**
-1 5158 * An alias for `Runner.run`, see `Matter.Runner` for more information.
-1 5159 * @method run
-1 5160 * @param {engine} engine
-1 5161 */
-1 5162
-1 5163 /**
-1 5164 * Fired just before an update
-1 5165 *
-1 5166 * @event beforeUpdate
-1 5167 * @param {} event An event object
-1 5168 * @param {number} event.timestamp The engine.timing.timestamp of the event
-1 5169 * @param {} event.source The source object of the event
-1 5170 * @param {} event.name The name of the event
-1 5171 */
-1 5172
-1 5173 /**
-1 5174 * Fired after engine update and all collision events
-1 5175 *
-1 5176 * @event afterUpdate
-1 5177 * @param {} event An event object
-1 5178 * @param {number} event.timestamp The engine.timing.timestamp of the event
-1 5179 * @param {} event.source The source object of the event
-1 5180 * @param {} event.name The name of the event
-1 5181 */
-1 5182
-1 5183 /**
-1 5184 * Fired after engine update, provides a list of all pairs that have started to collide in the current tick (if any)
-1 5185 *
-1 5186 * @event collisionStart
-1 5187 * @param {} event An event object
-1 5188 * @param {} event.pairs List of affected pairs
-1 5189 * @param {number} event.timestamp The engine.timing.timestamp of the event
-1 5190 * @param {} event.source The source object of the event
-1 5191 * @param {} event.name The name of the event
-1 5192 */
-1 5193
-1 5194 /**
-1 5195 * Fired after engine update, provides a list of all pairs that are colliding in the current tick (if any)
-1 5196 *
-1 5197 * @event collisionActive
-1 5198 * @param {} event An event object
-1 5199 * @param {} event.pairs List of affected pairs
-1 5200 * @param {number} event.timestamp The engine.timing.timestamp of the event
-1 5201 * @param {} event.source The source object of the event
-1 5202 * @param {} event.name The name of the event
-1 5203 */
-1 5204
-1 5205 /**
-1 5206 * Fired after engine update, provides a list of all pairs that have ended collision in the current tick (if any)
-1 5207 *
-1 5208 * @event collisionEnd
-1 5209 * @param {} event An event object
-1 5210 * @param {} event.pairs List of affected pairs
-1 5211 * @param {number} event.timestamp The engine.timing.timestamp of the event
-1 5212 * @param {} event.source The source object of the event
-1 5213 * @param {} event.name The name of the event
-1 5214 */
-1 5215
-1 5216 /*
-1 5217 *
-1 5218 * Properties Documentation
-1 5219 *
-1 5220 */
-1 5221
-1 5222 /**
-1 5223 * An integer `Number` that specifies the number of position iterations to perform each update.
-1 5224 * The higher the value, the higher quality the simulation will be at the expense of performance.
-1 5225 *
-1 5226 * @property positionIterations
-1 5227 * @type number
-1 5228 * @default 6
-1 5229 */
-1 5230
-1 5231 /**
-1 5232 * An integer `Number` that specifies the number of velocity iterations to perform each update.
-1 5233 * The higher the value, the higher quality the simulation will be at the expense of performance.
-1 5234 *
-1 5235 * @property velocityIterations
-1 5236 * @type number
-1 5237 * @default 4
-1 5238 */
-1 5239
-1 5240 /**
-1 5241 * An integer `Number` that specifies the number of constraint iterations to perform each update.
-1 5242 * The higher the value, the higher quality the simulation will be at the expense of performance.
-1 5243 * The default value of `2` is usually very adequate.
-1 5244 *
-1 5245 * @property constraintIterations
-1 5246 * @type number
-1 5247 * @default 2
-1 5248 */
-1 5249
-1 5250 /**
-1 5251 * A flag that specifies whether the engine should allow sleeping via the `Matter.Sleeping` module.
-1 5252 * Sleeping can improve stability and performance, but often at the expense of accuracy.
-1 5253 *
-1 5254 * @property enableSleeping
-1 5255 * @type boolean
-1 5256 * @default false
-1 5257 */
-1 5258
-1 5259 /**
-1 5260 * An `Object` containing properties regarding the timing systems of the engine.
-1 5261 *
-1 5262 * @property timing
-1 5263 * @type object
-1 5264 */
-1 5265
-1 5266 /**
-1 5267 * A `Number` that specifies the global scaling factor of time for all bodies.
-1 5268 * A value of `0` freezes the simulation.
-1 5269 * A value of `0.1` gives a slow-motion effect.
-1 5270 * A value of `1.2` gives a speed-up effect.
-1 5271 *
-1 5272 * @property timing.timeScale
-1 5273 * @type number
-1 5274 * @default 1
-1 5275 */
-1 5276
-1 5277 /**
-1 5278 * A `Number` that specifies the current simulation-time in milliseconds starting from `0`.
-1 5279 * It is incremented on every `Engine.update` by the given `delta` argument.
-1 5280 *
-1 5281 * @property timing.timestamp
-1 5282 * @type number
-1 5283 * @default 0
-1 5284 */
-1 5285
-1 5286 /**
-1 5287 * An instance of a `Render` controller. The default value is a `Matter.Render` instance created by `Engine.create`.
-1 5288 * One may also develop a custom renderer module based on `Matter.Render` and pass an instance of it to `Engine.create` via `options.render`.
-1 5289 *
-1 5290 * A minimal custom renderer object must define at least three functions: `create`, `clear` and `world` (see `Matter.Render`).
-1 5291 * It is also possible to instead pass the _module_ reference via `options.render.controller` and `Engine.create` will instantiate one for you.
-1 5292 *
-1 5293 * @property render
-1 5294 * @type render
-1 5295 * @deprecated see Demo.js for an example of creating a renderer
-1 5296 * @default a Matter.Render instance
-1 5297 */
-1 5298
-1 5299 /**
-1 5300 * An instance of a broadphase controller. The default value is a `Matter.Grid` instance created by `Engine.create`.
-1 5301 *
-1 5302 * @property broadphase
-1 5303 * @type grid
-1 5304 * @default a Matter.Grid instance
-1 5305 */
-1 5306
-1 5307 /**
-1 5308 * A `World` composite object that will contain all simulated bodies and constraints.
-1 5309 *
-1 5310 * @property world
-1 5311 * @type world
-1 5312 * @default a Matter.World instance
-1 5313 */
-1 5314
-1 5315 /**
-1 5316 * An object reserved for storing plugin-specific properties.
-1 5317 *
-1 5318 * @property plugin
-1 5319 * @type {}
-1 5320 */
-1 5321
-1 5322 })();
-1 5323
-1 5324 },{"../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){
-1 5325 /**
-1 5326 * The `Matter.Events` module contains methods to fire and listen to events on other objects.
-1 5327 *
-1 5328 * See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples).
-1 5329 *
-1 5330 * @class Events
-1 5331 */
-1 5332
-1 5333 var Events = {};
-1 5334
-1 5335 module.exports = Events;
-1 5336
-1 5337 var Common = _dereq_('./Common');
-1 5338
-1 5339 (function() {
-1 5340
-1 5341 /**
-1 5342 * Subscribes a callback function to the given object's `eventName`.
-1 5343 * @method on
-1 5344 * @param {} object
-1 5345 * @param {string} eventNames
-1 5346 * @param {function} callback
-1 5347 */
-1 5348 Events.on = function(object, eventNames, callback) {
-1 5349 var names = eventNames.split(' '),
-1 5350 name;
-1 5351
-1 5352 for (var i = 0; i < names.length; i++) {
-1 5353 name = names[i];
-1 5354 object.events = object.events || {};
-1 5355 object.events[name] = object.events[name] || [];
-1 5356 object.events[name].push(callback);
-1 5357 }
-1 5358
-1 5359 return callback;
-1 5360 };
-1 5361
-1 5362 /**
-1 5363 * Removes the given event callback. If no callback, clears all callbacks in `eventNames`. If no `eventNames`, clears all events.
-1 5364 * @method off
-1 5365 * @param {} object
-1 5366 * @param {string} eventNames
-1 5367 * @param {function} callback
-1 5368 */
-1 5369 Events.off = function(object, eventNames, callback) {
-1 5370 if (!eventNames) {
-1 5371 object.events = {};
-1 5372 return;
-1 5373 }
-1 5374
-1 5375 // handle Events.off(object, callback)
-1 5376 if (typeof eventNames === 'function') {
-1 5377 callback = eventNames;
-1 5378 eventNames = Common.keys(object.events).join(' ');
-1 5379 }
-1 5380
-1 5381 var names = eventNames.split(' ');
-1 5382
-1 5383 for (var i = 0; i < names.length; i++) {
-1 5384 var callbacks = object.events[names[i]],
-1 5385 newCallbacks = [];
-1 5386
-1 5387 if (callback && callbacks) {
-1 5388 for (var j = 0; j < callbacks.length; j++) {
-1 5389 if (callbacks[j] !== callback)
-1 5390 newCallbacks.push(callbacks[j]);
-1 5391 }
-1 5392 }
-1 5393
-1 5394 object.events[names[i]] = newCallbacks;
-1 5395 }
-1 5396 };
-1 5397
-1 5398 /**
-1 5399 * Fires all the callbacks subscribed to the given object's `eventName`, in the order they subscribed, if any.
-1 5400 * @method trigger
-1 5401 * @param {} object
-1 5402 * @param {string} eventNames
-1 5403 * @param {} event
-1 5404 */
-1 5405 Events.trigger = function(object, eventNames, event) {
-1 5406 var names,
-1 5407 name,
-1 5408 callbacks,
-1 5409 eventClone;
-1 5410
-1 5411 if (object.events) {
-1 5412 if (!event)
-1 5413 event = {};
-1 5414
-1 5415 names = eventNames.split(' ');
-1 5416
-1 5417 for (var i = 0; i < names.length; i++) {
-1 5418 name = names[i];
-1 5419 callbacks = object.events[name];
-1 5420
-1 5421 if (callbacks) {
-1 5422 eventClone = Common.clone(event, false);
-1 5423 eventClone.name = name;
-1 5424 eventClone.source = object;
-1 5425
-1 5426 for (var j = 0; j < callbacks.length; j++) {
-1 5427 callbacks[j].apply(object, [eventClone]);
-1 5428 }
-1 5429 }
-1 5430 }
-1 5431 }
-1 5432 };
-1 5433
-1 5434 })();
-1 5435
-1 5436 },{"./Common":14}],17:[function(_dereq_,module,exports){
-1 5437 /**
-1 5438 * The `Matter` module is the top level namespace. It also includes a function for installing plugins on top of the library.
-1 5439 *
-1 5440 * @class Matter
-1 5441 */
-1 5442
-1 5443 var Matter = {};
-1 5444
-1 5445 module.exports = Matter;
-1 5446
-1 5447 var Plugin = _dereq_('./Plugin');
-1 5448 var Common = _dereq_('./Common');
-1 5449
-1 5450 (function() {
-1 5451
-1 5452 /**
-1 5453 * The library name.
-1 5454 * @property name
-1 5455 * @readOnly
-1 5456 * @type {String}
-1 5457 */
-1 5458 Matter.name = 'matter-js';
-1 5459
-1 5460 /**
-1 5461 * The library version.
-1 5462 * @property version
-1 5463 * @readOnly
-1 5464 * @type {String}
-1 5465 */
-1 5466 Matter.version = '0.14.2';
-1 5467
-1 5468 /**
-1 5469 * A list of plugin dependencies to be installed. These are normally set and installed through `Matter.use`.
-1 5470 * Alternatively you may set `Matter.uses` manually and install them by calling `Plugin.use(Matter)`.
-1 5471 * @property uses
-1 5472 * @type {Array}
-1 5473 */
-1 5474 Matter.uses = [];
-1 5475
-1 5476 /**
-1 5477 * The plugins that have been installed through `Matter.Plugin.install`. Read only.
-1 5478 * @property used
-1 5479 * @readOnly
-1 5480 * @type {Array}
-1 5481 */
-1 5482 Matter.used = [];
-1 5483
-1 5484 /**
-1 5485 * Installs the given plugins on the `Matter` namespace.
-1 5486 * This is a short-hand for `Plugin.use`, see it for more information.
-1 5487 * Call this function once at the start of your code, with all of the plugins you wish to install as arguments.
-1 5488 * Avoid calling this function multiple times unless you intend to manually control installation order.
-1 5489 * @method use
-1 5490 * @param ...plugin {Function} The plugin(s) to install on `base` (multi-argument).
-1 5491 */
-1 5492 Matter.use = function() {
-1 5493 Plugin.use(Matter, Array.prototype.slice.call(arguments));
-1 5494 };
-1 5495
-1 5496 /**
-1 5497 * Chains a function to excute before the original function on the given `path` relative to `Matter`.
-1 5498 * See also docs for `Common.chain`.
-1 5499 * @method before
-1 5500 * @param {string} path The path relative to `Matter`
-1 5501 * @param {function} func The function to chain before the original
-1 5502 * @return {function} The chained function that replaced the original
-1 5503 */
-1 5504 Matter.before = function(path, func) {
-1 5505 path = path.replace(/^Matter./, '');
-1 5506 return Common.chainPathBefore(Matter, path, func);
-1 5507 };
-1 5508
-1 5509 /**
-1 5510 * Chains a function to excute after the original function on the given `path` relative to `Matter`.
-1 5511 * See also docs for `Common.chain`.
-1 5512 * @method after
-1 5513 * @param {string} path The path relative to `Matter`
-1 5514 * @param {function} func The function to chain after the original
-1 5515 * @return {function} The chained function that replaced the original
-1 5516 */
-1 5517 Matter.after = function(path, func) {
-1 5518 path = path.replace(/^Matter./, '');
-1 5519 return Common.chainPathAfter(Matter, path, func);
-1 5520 };
-1 5521
-1 5522 })();
-1 5523
-1 5524 },{"./Common":14,"./Plugin":20}],18:[function(_dereq_,module,exports){
-1 5525
-1 5526 },{"../body/Composite":2,"./Common":14}],19:[function(_dereq_,module,exports){
-1 5527 /**
-1 5528 * The `Matter.Mouse` module contains methods for creating and manipulating mouse inputs.
-1 5529 *
-1 5530 * @class Mouse
-1 5531 */
-1 5532
-1 5533 var Mouse = {};
-1 5534
-1 5535 module.exports = Mouse;
-1 5536
-1 5537 var Common = _dereq_('../core/Common');
-1 5538
-1 5539 (function() {
-1 5540
-1 5541 /**
-1 5542 * Creates a mouse input.
-1 5543 * @method create
-1 5544 * @param {HTMLElement} element
-1 5545 * @return {mouse} A new mouse
-1 5546 */
-1 5547 Mouse.create = function(element) {
-1 5548 var mouse = {};
-1 5549
-1 5550 if (!element) {
-1 5551 Common.log('Mouse.create: element was undefined, defaulting to document.body', 'warn');
-1 5552 }
-1 5553
-1 5554 mouse.element = element || document.body;
-1 5555 mouse.absolute = { x: 0, y: 0 };
-1 5556 mouse.position = { x: 0, y: 0 };
-1 5557 mouse.mousedownPosition = { x: 0, y: 0 };
-1 5558 mouse.mouseupPosition = { x: 0, y: 0 };
-1 5559 mouse.offset = { x: 0, y: 0 };
-1 5560 mouse.scale = { x: 1, y: 1 };
-1 5561 mouse.wheelDelta = 0;
-1 5562 mouse.button = -1;
-1 5563 mouse.pixelRatio = mouse.element.getAttribute('data-pixel-ratio') || 1;
-1 5564
-1 5565 mouse.sourceEvents = {
-1 5566 mousemove: null,
-1 5567 mousedown: null,
-1 5568 mouseup: null,
-1 5569 mousewheel: null
-1 5570 };
-1 5571
-1 5572 mouse.mousemove = function(event) {
-1 5573 var position = Mouse._getRelativeMousePosition(event, mouse.element, mouse.pixelRatio),
-1 5574 touches = event.changedTouches;
-1 5575
-1 5576 if (touches) {
-1 5577 mouse.button = 0;
-1 5578 event.preventDefault();
-1 5579 }
-1 5580
-1 5581 mouse.absolute.x = position.x;
-1 5582 mouse.absolute.y = position.y;
-1 5583 mouse.position.x = mouse.absolute.x * mouse.scale.x + mouse.offset.x;
-1 5584 mouse.position.y = mouse.absolute.y * mouse.scale.y + mouse.offset.y;
-1 5585 mouse.sourceEvents.mousemove = event;
-1 5586 };
-1 5587
-1 5588 mouse.mousedown = function(event) {
-1 5589 var position = Mouse._getRelativeMousePosition(event, mouse.element, mouse.pixelRatio),
-1 5590 touches = event.changedTouches;
-1 5591
-1 5592 if (touches) {
-1 5593 mouse.button = 0;
-1 5594 event.preventDefault();
-1 5595 } else {
-1 5596 mouse.button = event.button;
-1 5597 }
-1 5598
-1 5599 mouse.absolute.x = position.x;
-1 5600 mouse.absolute.y = position.y;
-1 5601 mouse.position.x = mouse.absolute.x * mouse.scale.x + mouse.offset.x;
-1 5602 mouse.position.y = mouse.absolute.y * mouse.scale.y + mouse.offset.y;
-1 5603 mouse.mousedownPosition.x = mouse.position.x;
-1 5604 mouse.mousedownPosition.y = mouse.position.y;
-1 5605 mouse.sourceEvents.mousedown = event;
-1 5606 };
-1 5607
-1 5608 mouse.mouseup = function(event) {
-1 5609 var position = Mouse._getRelativeMousePosition(event, mouse.element, mouse.pixelRatio),
-1 5610 touches = event.changedTouches;
-1 5611
-1 5612 if (touches) {
-1 5613 event.preventDefault();
-1 5614 }
-1 5615
-1 5616 mouse.button = -1;
-1 5617 mouse.absolute.x = position.x;
-1 5618 mouse.absolute.y = position.y;
-1 5619 mouse.position.x = mouse.absolute.x * mouse.scale.x + mouse.offset.x;
-1 5620 mouse.position.y = mouse.absolute.y * mouse.scale.y + mouse.offset.y;
-1 5621 mouse.mouseupPosition.x = mouse.position.x;
-1 5622 mouse.mouseupPosition.y = mouse.position.y;
-1 5623 mouse.sourceEvents.mouseup = event;
-1 5624 };
-1 5625
-1 5626 mouse.mousewheel = function(event) {
-1 5627 mouse.wheelDelta = Math.max(-1, Math.min(1, event.wheelDelta || -event.detail));
-1 5628 event.preventDefault();
-1 5629 };
-1 5630
-1 5631 Mouse.setElement(mouse, mouse.element);
-1 5632
-1 5633 return mouse;
-1 5634 };
-1 5635
-1 5636 /**
-1 5637 * Sets the element the mouse is bound to (and relative to).
-1 5638 * @method setElement
-1 5639 * @param {mouse} mouse
-1 5640 * @param {HTMLElement} element
-1 5641 */
-1 5642 Mouse.setElement = function(mouse, element) {
-1 5643 mouse.element = element;
-1 5644
-1 5645 element.addEventListener('mousemove', mouse.mousemove);
-1 5646 element.addEventListener('mousedown', mouse.mousedown);
-1 5647 element.addEventListener('mouseup', mouse.mouseup);
-1 5648
-1 5649 element.addEventListener('mousewheel', mouse.mousewheel);
-1 5650 element.addEventListener('DOMMouseScroll', mouse.mousewheel);
-1 5651
-1 5652 element.addEventListener('touchmove', mouse.mousemove);
-1 5653 element.addEventListener('touchstart', mouse.mousedown);
-1 5654 element.addEventListener('touchend', mouse.mouseup);
-1 5655 };
-1 5656
-1 5657 /**
-1 5658 * Clears all captured source events.
-1 5659 * @method clearSourceEvents
-1 5660 * @param {mouse} mouse
-1 5661 */
-1 5662 Mouse.clearSourceEvents = function(mouse) {
-1 5663 mouse.sourceEvents.mousemove = null;
-1 5664 mouse.sourceEvents.mousedown = null;
-1 5665 mouse.sourceEvents.mouseup = null;
-1 5666 mouse.sourceEvents.mousewheel = null;
-1 5667 mouse.wheelDelta = 0;
-1 5668 };
-1 5669
-1 5670 /**
-1 5671 * Sets the mouse position offset.
-1 5672 * @method setOffset
-1 5673 * @param {mouse} mouse
-1 5674 * @param {vector} offset
-1 5675 */
-1 5676 Mouse.setOffset = function(mouse, offset) {
-1 5677 mouse.offset.x = offset.x;
-1 5678 mouse.offset.y = offset.y;
-1 5679 mouse.position.x = mouse.absolute.x * mouse.scale.x + mouse.offset.x;
-1 5680 mouse.position.y = mouse.absolute.y * mouse.scale.y + mouse.offset.y;
-1 5681 };
-1 5682
-1 5683 /**
-1 5684 * Sets the mouse position scale.
-1 5685 * @method setScale
-1 5686 * @param {mouse} mouse
-1 5687 * @param {vector} scale
-1 5688 */
-1 5689 Mouse.setScale = function(mouse, scale) {
-1 5690 mouse.scale.x = scale.x;
-1 5691 mouse.scale.y = scale.y;
-1 5692 mouse.position.x = mouse.absolute.x * mouse.scale.x + mouse.offset.x;
-1 5693 mouse.position.y = mouse.absolute.y * mouse.scale.y + mouse.offset.y;
-1 5694 };
-1 5695
-1 5696 /**
-1 5697 * Gets the mouse position relative to an element given a screen pixel ratio.
-1 5698 * @method _getRelativeMousePosition
-1 5699 * @private
-1 5700 * @param {} event
-1 5701 * @param {} element
-1 5702 * @param {number} pixelRatio
-1 5703 * @return {}
-1 5704 */
-1 5705 Mouse._getRelativeMousePosition = function(event, element, pixelRatio) {
-1 5706 var elementBounds = element.getBoundingClientRect(),
-1 5707 rootNode = (document.documentElement || document.body.parentNode || document.body),
-1 5708 scrollX = (window.pageXOffset !== undefined) ? window.pageXOffset : rootNode.scrollLeft,
-1 5709 scrollY = (window.pageYOffset !== undefined) ? window.pageYOffset : rootNode.scrollTop,
-1 5710 touches = event.changedTouches,
-1 5711 x, y;
-1 5712
-1 5713 if (touches) {
-1 5714 x = touches[0].pageX - elementBounds.left - scrollX;
-1 5715 y = touches[0].pageY - elementBounds.top - scrollY;
-1 5716 } else {
-1 5717 x = event.pageX - elementBounds.left - scrollX;
-1 5718 y = event.pageY - elementBounds.top - scrollY;
-1 5719 }
-1 5720
-1 5721 return {
-1 5722 x: x / (element.clientWidth / (element.width || element.clientWidth) * pixelRatio),
-1 5723 y: y / (element.clientHeight / (element.height || element.clientHeight) * pixelRatio)
-1 5724 };
-1 5725 };
-1 5726
-1 5727 })();
-1 5728
-1 5729 },{"../core/Common":14}],20:[function(_dereq_,module,exports){
-1 5730 /**
-1 5731 * The `Matter.Plugin` module contains functions for registering and installing plugins on modules.
-1 5732 *
-1 5733 * @class Plugin
-1 5734 */
-1 5735
-1 5736 var Plugin = {};
-1 5737
-1 5738 module.exports = Plugin;
-1 5739
-1 5740 var Common = _dereq_('./Common');
-1 5741
-1 5742 (function() {
-1 5743
-1 5744 Plugin._registry = {};
-1 5745
-1 5746 /**
-1 5747 * Registers a plugin object so it can be resolved later by name.
-1 5748 * @method register
-1 5749 * @param plugin {} The plugin to register.
-1 5750 * @return {object} The plugin.
-1 5751 */
-1 5752 Plugin.register = function(plugin) {
-1 5753 if (!Plugin.isPlugin(plugin)) {
-1 5754 Common.warn('Plugin.register:', Plugin.toString(plugin), 'does not implement all required fields.');
-1 5755 }
-1 5756
-1 5757 if (plugin.name in Plugin._registry) {
-1 5758 var registered = Plugin._registry[plugin.name],
-1 5759 pluginVersion = Plugin.versionParse(plugin.version).number,
-1 5760 registeredVersion = Plugin.versionParse(registered.version).number;
-1 5761
-1 5762 if (pluginVersion > registeredVersion) {
-1 5763 Common.warn('Plugin.register:', Plugin.toString(registered), 'was upgraded to', Plugin.toString(plugin));
-1 5764 Plugin._registry[plugin.name] = plugin;
-1 5765 } else if (pluginVersion < registeredVersion) {
-1 5766 Common.warn('Plugin.register:', Plugin.toString(registered), 'can not be downgraded to', Plugin.toString(plugin));
-1 5767 } else if (plugin !== registered) {
-1 5768 Common.warn('Plugin.register:', Plugin.toString(plugin), 'is already registered to different plugin object');
-1 5769 }
-1 5770 } else {
-1 5771 Plugin._registry[plugin.name] = plugin;
-1 5772 }
-1 5773
-1 5774 return plugin;
-1 5775 };
-1 5776
-1 5777 /**
-1 5778 * Resolves a dependency to a plugin object from the registry if it exists.
-1 5779 * The `dependency` may contain a version, but only the name matters when resolving.
-1 5780 * @method resolve
-1 5781 * @param dependency {string} The dependency.
-1 5782 * @return {object} The plugin if resolved, otherwise `undefined`.
-1 5783 */
-1 5784 Plugin.resolve = function(dependency) {
-1 5785 return Plugin._registry[Plugin.dependencyParse(dependency).name];
-1 5786 };
-1 5787
-1 5788 /**
-1 5789 * Returns a pretty printed plugin name and version.
-1 5790 * @method toString
-1 5791 * @param plugin {} The plugin.
-1 5792 * @return {string} Pretty printed plugin name and version.
-1 5793 */
-1 5794 Plugin.toString = function(plugin) {
-1 5795 return typeof plugin === 'string' ? plugin : (plugin.name || 'anonymous') + '@' + (plugin.version || plugin.range || '0.0.0');
-1 5796 };
-1 5797
-1 5798 /**
-1 5799 * Returns `true` if the object meets the minimum standard to be considered a plugin.
-1 5800 * This means it must define the following properties:
-1 5801 * - `name`
-1 5802 * - `version`
-1 5803 * - `install`
-1 5804 * @method isPlugin
-1 5805 * @param obj {} The obj to test.
-1 5806 * @return {boolean} `true` if the object can be considered a plugin otherwise `false`.
-1 5807 */
-1 5808 Plugin.isPlugin = function(obj) {
-1 5809 return obj && obj.name && obj.version && obj.install;
-1 5810 };
-1 5811
-1 5812 /**
-1 5813 * Returns `true` if a plugin with the given `name` been installed on `module`.
-1 5814 * @method isUsed
-1 5815 * @param module {} The module.
-1 5816 * @param name {string} The plugin name.
-1 5817 * @return {boolean} `true` if a plugin with the given `name` been installed on `module`, otherwise `false`.
-1 5818 */
-1 5819 Plugin.isUsed = function(module, name) {
-1 5820 return module.used.indexOf(name) > -1;
-1 5821 };
-1 5822
-1 5823 /**
-1 5824 * Returns `true` if `plugin.for` is applicable to `module` by comparing against `module.name` and `module.version`.
-1 5825 * If `plugin.for` is not specified then it is assumed to be applicable.
-1 5826 * The value of `plugin.for` is a string of the format `'module-name'` or `'module-name@version'`.
-1 5827 * @method isFor
-1 5828 * @param plugin {} The plugin.
-1 5829 * @param module {} The module.
-1 5830 * @return {boolean} `true` if `plugin.for` is applicable to `module`, otherwise `false`.
-1 5831 */
-1 5832 Plugin.isFor = function(plugin, module) {
-1 5833 var parsed = plugin.for && Plugin.dependencyParse(plugin.for);
-1 5834 return !plugin.for || (module.name === parsed.name && Plugin.versionSatisfies(module.version, parsed.range));
-1 5835 };
-1 5836
-1 5837 /**
-1 5838 * Installs the plugins by calling `plugin.install` on each plugin specified in `plugins` if passed, otherwise `module.uses`.
-1 5839 * For installing plugins on `Matter` see the convenience function `Matter.use`.
-1 5840 * Plugins may be specified either by their name or a reference to the plugin object.
-1 5841 * Plugins themselves may specify further dependencies, but each plugin is installed only once.
-1 5842 * Order is important, a topological sort is performed to find the best resulting order of installation.
-1 5843 * This sorting attempts to satisfy every dependency's requested ordering, but may not be exact in all cases.
-1 5844 * This function logs the resulting status of each dependency in the console, along with any warnings.
-1 5845 * - A green tick ✅ indicates a dependency was resolved and installed.
-1 5846 * - An orange diamond 🔶 indicates a dependency was resolved but a warning was thrown for it or one if its dependencies.
-1 5847 * - A red cross ❌ indicates a dependency could not be resolved.
-1 5848 * Avoid calling this function multiple times on the same module unless you intend to manually control installation order.
-1 5849 * @method use
-1 5850 * @param module {} The module install plugins on.
-1 5851 * @param [plugins=module.uses] {} The plugins to install on module (optional, defaults to `module.uses`).
-1 5852 */
-1 5853 Plugin.use = function(module, plugins) {
-1 5854 module.uses = (module.uses || []).concat(plugins || []);
-1 5855
-1 5856 if (module.uses.length === 0) {
-1 5857 Common.warn('Plugin.use:', Plugin.toString(module), 'does not specify any dependencies to install.');
-1 5858 return;
-1 5859 }
-1 5860
-1 5861 var dependencies = Plugin.dependencies(module),
-1 5862 sortedDependencies = Common.topologicalSort(dependencies),
-1 5863 status = [];
-1 5864
-1 5865 for (var i = 0; i < sortedDependencies.length; i += 1) {
-1 5866 if (sortedDependencies[i] === module.name) {
-1 5867 continue;
-1 5868 }
-1 5869
-1 5870 var plugin = Plugin.resolve(sortedDependencies[i]);
-1 5871
-1 5872 if (!plugin) {
-1 5873 status.push('❌ ' + sortedDependencies[i]);
-1 5874 continue;
-1 5875 }
-1 5876
-1 5877 if (Plugin.isUsed(module, plugin.name)) {
-1 5878 continue;
-1 5879 }
-1 5880
-1 5881 if (!Plugin.isFor(plugin, module)) {
-1 5882 Common.warn('Plugin.use:', Plugin.toString(plugin), 'is for', plugin.for, 'but installed on', Plugin.toString(module) + '.');
-1 5883 plugin._warned = true;
-1 5884 }
-1 5885
-1 5886 if (plugin.install) {
-1 5887 plugin.install(module);
-1 5888 } else {
-1 5889 Common.warn('Plugin.use:', Plugin.toString(plugin), 'does not specify an install function.');
-1 5890 plugin._warned = true;
-1 5891 }
-1 5892
-1 5893 if (plugin._warned) {
-1 5894 status.push('🔶 ' + Plugin.toString(plugin));
-1 5895 delete plugin._warned;
-1 5896 } else {
-1 5897 status.push('✅ ' + Plugin.toString(plugin));
-1 5898 }
-1 5899
-1 5900 module.used.push(plugin.name);
-1 5901 }
-1 5902
-1 5903 if (status.length > 0) {
-1 5904 Common.info(status.join(' '));
-1 5905 }
-1 5906 };
-1 5907
-1 5908 /**
-1 5909 * Recursively finds all of a module's dependencies and returns a flat dependency graph.
-1 5910 * @method dependencies
-1 5911 * @param module {} The module.
-1 5912 * @return {object} A dependency graph.
-1 5913 */
-1 5914 Plugin.dependencies = function(module, tracked) {
-1 5915 var parsedBase = Plugin.dependencyParse(module),
-1 5916 name = parsedBase.name;
-1 5917
-1 5918 tracked = tracked || {};
-1 5919
-1 5920 if (name in tracked) {
-1 5921 return;
-1 5922 }
-1 5923
-1 5924 module = Plugin.resolve(module) || module;
-1 5925
-1 5926 tracked[name] = Common.map(module.uses || [], function(dependency) {
-1 5927 if (Plugin.isPlugin(dependency)) {
-1 5928 Plugin.register(dependency);
-1 5929 }
-1 5930
-1 5931 var parsed = Plugin.dependencyParse(dependency),
-1 5932 resolved = Plugin.resolve(dependency);
-1 5933
-1 5934 if (resolved && !Plugin.versionSatisfies(resolved.version, parsed.range)) {
-1 5935 Common.warn(
-1 5936 'Plugin.dependencies:', Plugin.toString(resolved), 'does not satisfy',
-1 5937 Plugin.toString(parsed), 'used by', Plugin.toString(parsedBase) + '.'
-1 5938 );
-1 5939
-1 5940 resolved._warned = true;
-1 5941 module._warned = true;
-1 5942 } else if (!resolved) {
-1 5943 Common.warn(
-1 5944 'Plugin.dependencies:', Plugin.toString(dependency), 'used by',
-1 5945 Plugin.toString(parsedBase), 'could not be resolved.'
-1 5946 );
-1 5947
-1 5948 module._warned = true;
-1 5949 }
-1 5950
-1 5951 return parsed.name;
-1 5952 });
-1 5953
-1 5954 for (var i = 0; i < tracked[name].length; i += 1) {
-1 5955 Plugin.dependencies(tracked[name][i], tracked);
-1 5956 }
-1 5957
-1 5958 return tracked;
-1 5959 };
-1 5960
-1 5961 /**
-1 5962 * Parses a dependency string into its components.
-1 5963 * The `dependency` is a string of the format `'module-name'` or `'module-name@version'`.
-1 5964 * See documentation for `Plugin.versionParse` for a description of the format.
-1 5965 * This function can also handle dependencies that are already resolved (e.g. a module object).
-1 5966 * @method dependencyParse
-1 5967 * @param dependency {string} The dependency of the format `'module-name'` or `'module-name@version'`.
-1 5968 * @return {object} The dependency parsed into its components.
-1 5969 */
-1 5970 Plugin.dependencyParse = function(dependency) {
-1 5971 if (Common.isString(dependency)) {
-1 5972 var pattern = /^[\w-]+(@(\*|[\^~]?\d+\.\d+\.\d+(-[0-9A-Za-z-]+)?))?$/;
-1 5973
-1 5974 if (!pattern.test(dependency)) {
-1 5975 Common.warn('Plugin.dependencyParse:', dependency, 'is not a valid dependency string.');
-1 5976 }
-1 5977
-1 5978 return {
-1 5979 name: dependency.split('@')[0],
-1 5980 range: dependency.split('@')[1] || '*'
-1 5981 };
-1 5982 }
-1 5983
-1 5984 return {
-1 5985 name: dependency.name,
-1 5986 range: dependency.range || dependency.version
-1 5987 };
-1 5988 };
-1 5989
-1 5990 /**
-1 5991 * Parses a version string into its components.
-1 5992 * Versions are strictly of the format `x.y.z` (as in [semver](http://semver.org/)).
-1 5993 * Versions may optionally have a prerelease tag in the format `x.y.z-alpha`.
-1 5994 * Ranges are a strict subset of [npm ranges](https://docs.npmjs.com/misc/semver#advanced-range-syntax).
-1 5995 * Only the following range types are supported:
-1 5996 * - Tilde ranges e.g. `~1.2.3`
-1 5997 * - Caret ranges e.g. `^1.2.3`
-1 5998 * - Exact version e.g. `1.2.3`
-1 5999 * - Any version `*`
-1 6000 * @method versionParse
-1 6001 * @param range {string} The version string.
-1 6002 * @return {object} The version range parsed into its components.
-1 6003 */
-1 6004 Plugin.versionParse = function(range) {
-1 6005 var pattern = /^\*|[\^~]?\d+\.\d+\.\d+(-[0-9A-Za-z-]+)?$/;
-1 6006
-1 6007 if (!pattern.test(range)) {
-1 6008 Common.warn('Plugin.versionParse:', range, 'is not a valid version or range.');
-1 6009 }
-1 6010
-1 6011 var identifiers = range.split('-');
-1 6012 range = identifiers[0];
-1 6013
-1 6014 var isRange = isNaN(Number(range[0])),
-1 6015 version = isRange ? range.substr(1) : range,
-1 6016 parts = Common.map(version.split('.'), function(part) {
-1 6017 return Number(part);
-1 6018 });
-1 6019
-1 6020 return {
-1 6021 isRange: isRange,
-1 6022 version: version,
-1 6023 range: range,
-1 6024 operator: isRange ? range[0] : '',
-1 6025 parts: parts,
-1 6026 prerelease: identifiers[1],
-1 6027 number: parts[0] * 1e8 + parts[1] * 1e4 + parts[2]
-1 6028 };
-1 6029 };
-1 6030
-1 6031 /**
-1 6032 * Returns `true` if `version` satisfies the given `range`.
-1 6033 * See documentation for `Plugin.versionParse` for a description of the format.
-1 6034 * If a version or range is not specified, then any version (`*`) is assumed to satisfy.
-1 6035 * @method versionSatisfies
-1 6036 * @param version {string} The version string.
-1 6037 * @param range {string} The range string.
-1 6038 * @return {boolean} `true` if `version` satisfies `range`, otherwise `false`.
-1 6039 */
-1 6040 Plugin.versionSatisfies = function(version, range) {
-1 6041 range = range || '*';
-1 6042
-1 6043 var rangeParsed = Plugin.versionParse(range),
-1 6044 rangeParts = rangeParsed.parts,
-1 6045 versionParsed = Plugin.versionParse(version),
-1 6046 versionParts = versionParsed.parts;
-1 6047
-1 6048 if (rangeParsed.isRange) {
-1 6049 if (rangeParsed.operator === '*' || version === '*') {
-1 6050 return true;
-1 6051 }
-1 6052
-1 6053 if (rangeParsed.operator === '~') {
-1 6054 return versionParts[0] === rangeParts[0] && versionParts[1] === rangeParts[1] && versionParts[2] >= rangeParts[2];
-1 6055 }
-1 6056
-1 6057 if (rangeParsed.operator === '^') {
-1 6058 if (rangeParts[0] > 0) {
-1 6059 return versionParts[0] === rangeParts[0] && versionParsed.number >= rangeParsed.number;
-1 6060 }
-1 6061
-1 6062 if (rangeParts[1] > 0) {
-1 6063 return versionParts[1] === rangeParts[1] && versionParts[2] >= rangeParts[2];
-1 6064 }
-1 6065
-1 6066 return versionParts[2] === rangeParts[2];
-1 6067 }
-1 6068 }
-1 6069
-1 6070 return version === range || version === '*';
-1 6071 };
-1 6072
-1 6073 })();
-1 6074
-1 6075 },{"./Common":14}],21:[function(_dereq_,module,exports){
-1 6076 /**
-1 6077 * The `Matter.Runner` module is an optional utility which provides a game loop,
-1 6078 * that handles continuously updating a `Matter.Engine` for you within a browser.
-1 6079 * It is intended for development and debugging purposes, but may also be suitable for simple games.
-1 6080 * If you are using your own game loop instead, then you do not need the `Matter.Runner` module.
-1 6081 * Instead just call `Engine.update(engine, delta)` in your own loop.
-1 6082 *
-1 6083 * See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples).
-1 6084 *
-1 6085 * @class Runner
-1 6086 */
-1 6087
-1 6088 var Runner = {};
-1 6089
-1 6090 module.exports = Runner;
-1 6091
-1 6092 var Events = _dereq_('./Events');
-1 6093 var Engine = _dereq_('./Engine');
-1 6094 var Common = _dereq_('./Common');
-1 6095
-1 6096 (function() {
-1 6097
-1 6098 var _requestAnimationFrame,
-1 6099 _cancelAnimationFrame;
-1 6100
-1 6101 if (typeof window !== 'undefined') {
-1 6102 _requestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame
-1 6103 || window.mozRequestAnimationFrame || window.msRequestAnimationFrame;
-1 6104
-1 6105 _cancelAnimationFrame = window.cancelAnimationFrame || window.mozCancelAnimationFrame
-1 6106 || window.webkitCancelAnimationFrame || window.msCancelAnimationFrame;
-1 6107 }
-1 6108
-1 6109 if (!_requestAnimationFrame) {
-1 6110 var _frameTimeout;
-1 6111
-1 6112 _requestAnimationFrame = function(callback){
-1 6113 _frameTimeout = setTimeout(function() {
-1 6114 callback(Common.now());
-1 6115 }, 1000 / 60);
-1 6116 };
-1 6117
-1 6118 _cancelAnimationFrame = function() {
-1 6119 clearTimeout(_frameTimeout);
-1 6120 };
-1 6121 }
-1 6122
-1 6123 /**
-1 6124 * Creates a new Runner. The options parameter is an object that specifies any properties you wish to override the defaults.
-1 6125 * @method create
-1 6126 * @param {} options
-1 6127 */
-1 6128 Runner.create = function(options) {
-1 6129 var defaults = {
-1 6130 fps: 60,
-1 6131 correction: 1,
-1 6132 deltaSampleSize: 60,
-1 6133 counterTimestamp: 0,
-1 6134 frameCounter: 0,
-1 6135 deltaHistory: [],
-1 6136 timePrev: null,
-1 6137 timeScalePrev: 1,
-1 6138 frameRequestId: null,
-1 6139 isFixed: false,
-1 6140 enabled: true
-1 6141 };
-1 6142
-1 6143 var runner = Common.extend(defaults, options);
-1 6144
-1 6145 runner.delta = runner.delta || 1000 / runner.fps;
-1 6146 runner.deltaMin = runner.deltaMin || 1000 / runner.fps;
-1 6147 runner.deltaMax = runner.deltaMax || 1000 / (runner.fps * 0.5);
-1 6148 runner.fps = 1000 / runner.delta;
-1 6149
-1 6150 return runner;
-1 6151 };
-1 6152
-1 6153 /**
-1 6154 * Continuously ticks a `Matter.Engine` by calling `Runner.tick` on the `requestAnimationFrame` event.
-1 6155 * @method run
-1 6156 * @param {engine} engine
-1 6157 */
-1 6158 Runner.run = function(runner, engine) {
-1 6159 // create runner if engine is first argument
-1 6160 if (typeof runner.positionIterations !== 'undefined') {
-1 6161 engine = runner;
-1 6162 runner = Runner.create();
-1 6163 }
-1 6164
-1 6165 (function render(time){
-1 6166 runner.frameRequestId = _requestAnimationFrame(render);
-1 6167
-1 6168 if (time && runner.enabled) {
-1 6169 Runner.tick(runner, engine, time);
-1 6170 }
-1 6171 })();
-1 6172
-1 6173 return runner;
-1 6174 };
-1 6175
-1 6176 /**
-1 6177 * A game loop utility that updates the engine and renderer by one step (a 'tick').
-1 6178 * Features delta smoothing, time correction and fixed or dynamic timing.
-1 6179 * Triggers `beforeTick`, `tick` and `afterTick` events on the engine.
-1 6180 * Consider just `Engine.update(engine, delta)` if you're using your own loop.
-1 6181 * @method tick
-1 6182 * @param {runner} runner
-1 6183 * @param {engine} engine
-1 6184 * @param {number} time
-1 6185 */
-1 6186 Runner.tick = function(runner, engine, time) {
-1 6187 var timing = engine.timing,
-1 6188 correction = 1,
-1 6189 delta;
-1 6190
-1 6191 // create an event object
-1 6192 var event = {
-1 6193 timestamp: timing.timestamp
-1 6194 };
-1 6195
-1 6196 Events.trigger(runner, 'beforeTick', event);
-1 6197 Events.trigger(engine, 'beforeTick', event); // @deprecated
-1 6198
-1 6199 if (runner.isFixed) {
-1 6200 // fixed timestep
-1 6201 delta = runner.delta;
-1 6202 } else {
-1 6203 // dynamic timestep based on wall clock between calls
-1 6204 delta = (time - runner.timePrev) || runner.delta;
-1 6205 runner.timePrev = time;
-1 6206
-1 6207 // optimistically filter delta over a few frames, to improve stability
-1 6208 runner.deltaHistory.push(delta);
-1 6209 runner.deltaHistory = runner.deltaHistory.slice(-runner.deltaSampleSize);
-1 6210 delta = Math.min.apply(null, runner.deltaHistory);
-1 6211
-1 6212 // limit delta
-1 6213 delta = delta < runner.deltaMin ? runner.deltaMin : delta;
-1 6214 delta = delta > runner.deltaMax ? runner.deltaMax : delta;
-1 6215
-1 6216 // correction for delta
-1 6217 correction = delta / runner.delta;
-1 6218
-1 6219 // update engine timing object
-1 6220 runner.delta = delta;
-1 6221 }
-1 6222
-1 6223 // time correction for time scaling
-1 6224 if (runner.timeScalePrev !== 0)
-1 6225 correction *= timing.timeScale / runner.timeScalePrev;
-1 6226
-1 6227 if (timing.timeScale === 0)
-1 6228 correction = 0;
-1 6229
-1 6230 runner.timeScalePrev = timing.timeScale;
-1 6231 runner.correction = correction;
-1 6232
-1 6233 // fps counter
-1 6234 runner.frameCounter += 1;
-1 6235 if (time - runner.counterTimestamp >= 1000) {
-1 6236 runner.fps = runner.frameCounter * ((time - runner.counterTimestamp) / 1000);
-1 6237 runner.counterTimestamp = time;
-1 6238 runner.frameCounter = 0;
-1 6239 }
-1 6240
-1 6241 Events.trigger(runner, 'tick', event);
-1 6242 Events.trigger(engine, 'tick', event); // @deprecated
-1 6243
-1 6244 // if world has been modified, clear the render scene graph
-1 6245 if (engine.world.isModified
-1 6246 && engine.render
-1 6247 && engine.render.controller
-1 6248 && engine.render.controller.clear) {
-1 6249 engine.render.controller.clear(engine.render); // @deprecated
-1 6250 }
-1 6251
-1 6252 // update
-1 6253 Events.trigger(runner, 'beforeUpdate', event);
-1 6254 Engine.update(engine, delta, correction);
-1 6255 Events.trigger(runner, 'afterUpdate', event);
-1 6256
-1 6257 // render
-1 6258 // @deprecated
-1 6259 if (engine.render && engine.render.controller) {
-1 6260 Events.trigger(runner, 'beforeRender', event);
-1 6261 Events.trigger(engine, 'beforeRender', event); // @deprecated
-1 6262
-1 6263 engine.render.controller.world(engine.render);
-1 6264
-1 6265 Events.trigger(runner, 'afterRender', event);
-1 6266 Events.trigger(engine, 'afterRender', event); // @deprecated
-1 6267 }
-1 6268
-1 6269 Events.trigger(runner, 'afterTick', event);
-1 6270 Events.trigger(engine, 'afterTick', event); // @deprecated
-1 6271 };
-1 6272
-1 6273 /**
-1 6274 * Ends execution of `Runner.run` on the given `runner`, by canceling the animation frame request event loop.
-1 6275 * If you wish to only temporarily pause the engine, see `engine.enabled` instead.
-1 6276 * @method stop
-1 6277 * @param {runner} runner
-1 6278 */
-1 6279 Runner.stop = function(runner) {
-1 6280 _cancelAnimationFrame(runner.frameRequestId);
-1 6281 };
-1 6282
-1 6283 /**
-1 6284 * Alias for `Runner.run`.
-1 6285 * @method start
-1 6286 * @param {runner} runner
-1 6287 * @param {engine} engine
-1 6288 */
-1 6289 Runner.start = function(runner, engine) {
-1 6290 Runner.run(runner, engine);
-1 6291 };
-1 6292
-1 6293 /*
-1 6294 *
-1 6295 * Events Documentation
-1 6296 *
-1 6297 */
-1 6298
-1 6299 /**
-1 6300 * Fired at the start of a tick, before any updates to the engine or timing
-1 6301 *
-1 6302 * @event beforeTick
-1 6303 * @param {} event An event object
-1 6304 * @param {number} event.timestamp The engine.timing.timestamp of the event
-1 6305 * @param {} event.source The source object of the event
-1 6306 * @param {} event.name The name of the event
-1 6307 */
-1 6308
-1 6309 /**
-1 6310 * Fired after engine timing updated, but just before update
-1 6311 *
-1 6312 * @event tick
-1 6313 * @param {} event An event object
-1 6314 * @param {number} event.timestamp The engine.timing.timestamp of the event
-1 6315 * @param {} event.source The source object of the event
-1 6316 * @param {} event.name The name of the event
-1 6317 */
-1 6318
-1 6319 /**
-1 6320 * Fired at the end of a tick, after engine update and after rendering
-1 6321 *
-1 6322 * @event afterTick
-1 6323 * @param {} event An event object
-1 6324 * @param {number} event.timestamp The engine.timing.timestamp of the event
-1 6325 * @param {} event.source The source object of the event
-1 6326 * @param {} event.name The name of the event
-1 6327 */
-1 6328
-1 6329 /**
-1 6330 * Fired before update
-1 6331 *
-1 6332 * @event beforeUpdate
-1 6333 * @param {} event An event object
-1 6334 * @param {number} event.timestamp The engine.timing.timestamp of the event
-1 6335 * @param {} event.source The source object of the event
-1 6336 * @param {} event.name The name of the event
-1 6337 */
-1 6338
-1 6339 /**
-1 6340 * Fired after update
-1 6341 *
-1 6342 * @event afterUpdate
-1 6343 * @param {} event An event object
-1 6344 * @param {number} event.timestamp The engine.timing.timestamp of the event
-1 6345 * @param {} event.source The source object of the event
-1 6346 * @param {} event.name The name of the event
-1 6347 */
-1 6348
-1 6349 /**
-1 6350 * Fired before rendering
-1 6351 *
-1 6352 * @event beforeRender
-1 6353 * @param {} event An event object
-1 6354 * @param {number} event.timestamp The engine.timing.timestamp of the event
-1 6355 * @param {} event.source The source object of the event
-1 6356 * @param {} event.name The name of the event
-1 6357 * @deprecated
-1 6358 */
-1 6359
-1 6360 /**
-1 6361 * Fired after rendering
-1 6362 *
-1 6363 * @event afterRender
-1 6364 * @param {} event An event object
-1 6365 * @param {number} event.timestamp The engine.timing.timestamp of the event
-1 6366 * @param {} event.source The source object of the event
-1 6367 * @param {} event.name The name of the event
-1 6368 * @deprecated
-1 6369 */
-1 6370
-1 6371 /*
-1 6372 *
-1 6373 * Properties Documentation
-1 6374 *
-1 6375 */
-1 6376
-1 6377 /**
-1 6378 * A flag that specifies whether the runner is running or not.
-1 6379 *
-1 6380 * @property enabled
-1 6381 * @type boolean
-1 6382 * @default true
-1 6383 */
-1 6384
-1 6385 /**
-1 6386 * A `Boolean` that specifies if the runner should use a fixed timestep (otherwise it is variable).
-1 6387 * If timing is fixed, then the apparent simulation speed will change depending on the frame rate (but behaviour will be deterministic).
-1 6388 * If the timing is variable, then the apparent simulation speed will be constant (approximately, but at the cost of determininism).
-1 6389 *
-1 6390 * @property isFixed
-1 6391 * @type boolean
-1 6392 * @default false
-1 6393 */
-1 6394
-1 6395 /**
-1 6396 * A `Number` that specifies the time step between updates in milliseconds.
-1 6397 * If `engine.timing.isFixed` is set to `true`, then `delta` is fixed.
-1 6398 * If it is `false`, then `delta` can dynamically change to maintain the correct apparent simulation speed.
-1 6399 *
-1 6400 * @property delta
-1 6401 * @type number
-1 6402 * @default 1000 / 60
-1 6403 */
-1 6404
-1 6405 })();
-1 6406
-1 6407 },{"./Common":14,"./Engine":15,"./Events":16}],22:[function(_dereq_,module,exports){
-1 6408 /**
-1 6409 * The `Matter.Sleeping` module contains methods to manage the sleeping state of bodies.
-1 6410 *
-1 6411 * @class Sleeping
-1 6412 */
-1 6413
-1 6414 var Sleeping = {};
-1 6415
-1 6416 module.exports = Sleeping;
-1 6417
-1 6418 var Events = _dereq_('./Events');
-1 6419
-1 6420 (function() {
-1 6421
-1 6422 Sleeping._motionWakeThreshold = 0.18;
-1 6423 Sleeping._motionSleepThreshold = 0.08;
-1 6424 Sleeping._minBias = 0.9;
-1 6425
-1 6426 /**
-1 6427 * Puts bodies to sleep or wakes them up depending on their motion.
-1 6428 * @method update
-1 6429 * @param {body[]} bodies
-1 6430 * @param {number} timeScale
-1 6431 */
-1 6432 Sleeping.update = function(bodies, timeScale) {
-1 6433 var timeFactor = timeScale * timeScale * timeScale;
-1 6434
-1 6435 // update bodies sleeping status
-1 6436 for (var i = 0; i < bodies.length; i++) {
-1 6437 var body = bodies[i],
-1 6438 motion = body.speed * body.speed + body.angularSpeed * body.angularSpeed;
-1 6439
-1 6440 // wake up bodies if they have a force applied
-1 6441 if (body.force.x !== 0 || body.force.y !== 0) {
-1 6442 Sleeping.set(body, false);
-1 6443 continue;
-1 6444 }
-1 6445
-1 6446 var minMotion = Math.min(body.motion, motion),
-1 6447 maxMotion = Math.max(body.motion, motion);
-1 6448
-1 6449 // biased average motion estimation between frames
-1 6450 body.motion = Sleeping._minBias * minMotion + (1 - Sleeping._minBias) * maxMotion;
-1 6451
-1 6452 if (body.sleepThreshold > 0 && body.motion < Sleeping._motionSleepThreshold * timeFactor) {
-1 6453 body.sleepCounter += 1;
-1 6454
-1 6455 if (body.sleepCounter >= body.sleepThreshold)
-1 6456 Sleeping.set(body, true);
-1 6457 } else if (body.sleepCounter > 0) {
-1 6458 body.sleepCounter -= 1;
-1 6459 }
-1 6460 }
-1 6461 };
-1 6462
-1 6463 /**
-1 6464 * Given a set of colliding pairs, wakes the sleeping bodies involved.
-1 6465 * @method afterCollisions
-1 6466 * @param {pair[]} pairs
-1 6467 * @param {number} timeScale
-1 6468 */
-1 6469 Sleeping.afterCollisions = function(pairs, timeScale) {
-1 6470 var timeFactor = timeScale * timeScale * timeScale;
-1 6471
-1 6472 // wake up bodies involved in collisions
-1 6473 for (var i = 0; i < pairs.length; i++) {
-1 6474 var pair = pairs[i];
-1 6475
-1 6476 // don't wake inactive pairs
-1 6477 if (!pair.isActive)
-1 6478 continue;
-1 6479
-1 6480 var collision = pair.collision,
-1 6481 bodyA = collision.bodyA.parent,
-1 6482 bodyB = collision.bodyB.parent;
-1 6483
-1 6484 // don't wake if at least one body is static
-1 6485 if ((bodyA.isSleeping && bodyB.isSleeping) || bodyA.isStatic || bodyB.isStatic)
-1 6486 continue;
-1 6487
-1 6488 if (bodyA.isSleeping || bodyB.isSleeping) {
-1 6489 var sleepingBody = (bodyA.isSleeping && !bodyA.isStatic) ? bodyA : bodyB,
-1 6490 movingBody = sleepingBody === bodyA ? bodyB : bodyA;
-1 6491
-1 6492 if (!sleepingBody.isStatic && movingBody.motion > Sleeping._motionWakeThreshold * timeFactor) {
-1 6493 Sleeping.set(sleepingBody, false);
-1 6494 }
-1 6495 }
-1 6496 }
-1 6497 };
-1 6498
-1 6499 /**
-1 6500 * Set a body as sleeping or awake.
-1 6501 * @method set
-1 6502 * @param {body} body
-1 6503 * @param {boolean} isSleeping
-1 6504 */
-1 6505 Sleeping.set = function(body, isSleeping) {
-1 6506 var wasSleeping = body.isSleeping;
-1 6507
-1 6508 if (isSleeping) {
-1 6509 body.isSleeping = true;
-1 6510 body.sleepCounter = body.sleepThreshold;
-1 6511
-1 6512 body.positionImpulse.x = 0;
-1 6513 body.positionImpulse.y = 0;
-1 6514
-1 6515 body.positionPrev.x = body.position.x;
-1 6516 body.positionPrev.y = body.position.y;
-1 6517
-1 6518 body.anglePrev = body.angle;
-1 6519 body.speed = 0;
-1 6520 body.angularSpeed = 0;
-1 6521 body.motion = 0;
-1 6522
-1 6523 if (!wasSleeping) {
-1 6524 Events.trigger(body, 'sleepStart');
-1 6525 }
-1 6526 } else {
-1 6527 body.isSleeping = false;
-1 6528 body.sleepCounter = 0;
-1 6529
-1 6530 if (wasSleeping) {
-1 6531 Events.trigger(body, 'sleepEnd');
-1 6532 }
-1 6533 }
-1 6534 };
-1 6535
-1 6536 })();
-1 6537
-1 6538 },{"./Events":16}],23:[function(_dereq_,module,exports){
-1 6539 /**
-1 6540 * The `Matter.Bodies` module contains factory methods for creating rigid body models
-1 6541 * with commonly used body configurations (such as rectangles, circles and other polygons).
-1 6542 *
-1 6543 * See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples).
-1 6544 *
-1 6545 * @class Bodies
-1 6546 */
-1 6547
-1 6548 // TODO: true circle bodies
-1 6549
-1 6550 var Bodies = {};
-1 6551
-1 6552 module.exports = Bodies;
-1 6553
-1 6554 var Vertices = _dereq_('../geometry/Vertices');
-1 6555 var Common = _dereq_('../core/Common');
-1 6556 var Body = _dereq_('../body/Body');
-1 6557 var Bounds = _dereq_('../geometry/Bounds');
-1 6558 var Vector = _dereq_('../geometry/Vector');
-1 6559 var decomp;
-1 6560
-1 6561 (function() {
-1 6562
-1 6563 /**
-1 6564 * Creates a new rigid body model with a rectangle hull.
-1 6565 * The options parameter is an object that specifies any properties you wish to override the defaults.
-1 6566 * See the properties section of the `Matter.Body` module for detailed information on what you can pass via the `options` object.
-1 6567 * @method rectangle
-1 6568 * @param {number} x
-1 6569 * @param {number} y
-1 6570 * @param {number} width
-1 6571 * @param {number} height
-1 6572 * @param {object} [options]
-1 6573 * @return {body} A new rectangle body
-1 6574 */
-1 6575 Bodies.rectangle = function(x, y, width, height, options) {
-1 6576 options = options || {};
-1 6577
-1 6578 var rectangle = {
-1 6579 label: 'Rectangle Body',
-1 6580 position: { x: x, y: y },
-1 6581 vertices: Vertices.fromPath('L 0 0 L ' + width + ' 0 L ' + width + ' ' + height + ' L 0 ' + height)
-1 6582 };
-1 6583
-1 6584 if (options.chamfer) {
-1 6585 var chamfer = options.chamfer;
-1 6586 rectangle.vertices = Vertices.chamfer(rectangle.vertices, chamfer.radius,
-1 6587 chamfer.quality, chamfer.qualityMin, chamfer.qualityMax);
-1 6588 delete options.chamfer;
-1 6589 }
-1 6590
-1 6591 return Body.create(Common.extend({}, rectangle, options));
-1 6592 };
-1 6593
-1 6594 /**
-1 6595 * Creates a new rigid body model with a trapezoid hull.
-1 6596 * The options parameter is an object that specifies any properties you wish to override the defaults.
-1 6597 * See the properties section of the `Matter.Body` module for detailed information on what you can pass via the `options` object.
-1 6598 * @method trapezoid
-1 6599 * @param {number} x
-1 6600 * @param {number} y
-1 6601 * @param {number} width
-1 6602 * @param {number} height
-1 6603 * @param {number} slope
-1 6604 * @param {object} [options]
-1 6605 * @return {body} A new trapezoid body
-1 6606 */
-1 6607 Bodies.trapezoid = function(x, y, width, height, slope, options) {
-1 6608 options = options || {};
-1 6609
-1 6610 slope *= 0.5;
-1 6611 var roof = (1 - (slope * 2)) * width;
-1 6612
-1 6613 var x1 = width * slope,
-1 6614 x2 = x1 + roof,
-1 6615 x3 = x2 + x1,
-1 6616 verticesPath;
-1 6617
-1 6618 if (slope < 0.5) {
-1 6619 verticesPath = 'L 0 0 L ' + x1 + ' ' + (-height) + ' L ' + x2 + ' ' + (-height) + ' L ' + x3 + ' 0';
-1 6620 } else {
-1 6621 verticesPath = 'L 0 0 L ' + x2 + ' ' + (-height) + ' L ' + x3 + ' 0';
-1 6622 }
-1 6623
-1 6624 var trapezoid = {
-1 6625 label: 'Trapezoid Body',
-1 6626 position: { x: x, y: y },
-1 6627 vertices: Vertices.fromPath(verticesPath)
-1 6628 };
-1 6629
-1 6630 if (options.chamfer) {
-1 6631 var chamfer = options.chamfer;
-1 6632 trapezoid.vertices = Vertices.chamfer(trapezoid.vertices, chamfer.radius,
-1 6633 chamfer.quality, chamfer.qualityMin, chamfer.qualityMax);
-1 6634 delete options.chamfer;
-1 6635 }
-1 6636
-1 6637 return Body.create(Common.extend({}, trapezoid, options));
-1 6638 };
-1 6639
-1 6640 /**
-1 6641 * Creates a new rigid body model with a circle hull.
-1 6642 * The options parameter is an object that specifies any properties you wish to override the defaults.
-1 6643 * See the properties section of the `Matter.Body` module for detailed information on what you can pass via the `options` object.
-1 6644 * @method circle
-1 6645 * @param {number} x
-1 6646 * @param {number} y
-1 6647 * @param {number} radius
-1 6648 * @param {object} [options]
-1 6649 * @param {number} [maxSides]
-1 6650 * @return {body} A new circle body
-1 6651 */
-1 6652 Bodies.circle = function(x, y, radius, options, maxSides) {
-1 6653 options = options || {};
-1 6654
-1 6655 var circle = {
-1 6656 label: 'Circle Body',
-1 6657 circleRadius: radius
-1 6658 };
-1 6659
-1 6660 // approximate circles with polygons until true circles implemented in SAT
-1 6661 maxSides = maxSides || 25;
-1 6662 var sides = Math.ceil(Math.max(10, Math.min(maxSides, radius)));
-1 6663
-1 6664 // optimisation: always use even number of sides (half the number of unique axes)
-1 6665 if (sides % 2 === 1)
-1 6666 sides += 1;
-1 6667
-1 6668 return Bodies.polygon(x, y, sides, radius, Common.extend({}, circle, options));
-1 6669 };
-1 6670
-1 6671 /**
-1 6672 * Creates a new rigid body model with a regular polygon hull with the given number of sides.
-1 6673 * The options parameter is an object that specifies any properties you wish to override the defaults.
-1 6674 * See the properties section of the `Matter.Body` module for detailed information on what you can pass via the `options` object.
-1 6675 * @method polygon
-1 6676 * @param {number} x
-1 6677 * @param {number} y
-1 6678 * @param {number} sides
-1 6679 * @param {number} radius
-1 6680 * @param {object} [options]
-1 6681 * @return {body} A new regular polygon body
-1 6682 */
-1 6683 Bodies.polygon = function(x, y, sides, radius, options) {
-1 6684 options = options || {};
-1 6685
-1 6686 if (sides < 3)
-1 6687 return Bodies.circle(x, y, radius, options);
-1 6688
-1 6689 var theta = 2 * Math.PI / sides,
-1 6690 path = '',
-1 6691 offset = theta * 0.5;
-1 6692
-1 6693 for (var i = 0; i < sides; i += 1) {
-1 6694 var angle = offset + (i * theta),
-1 6695 xx = Math.cos(angle) * radius,
-1 6696 yy = Math.sin(angle) * radius;
-1 6697
-1 6698 path += 'L ' + xx.toFixed(3) + ' ' + yy.toFixed(3) + ' ';
-1 6699 }
-1 6700
-1 6701 var polygon = {
-1 6702 label: 'Polygon Body',
-1 6703 position: { x: x, y: y },
-1 6704 vertices: Vertices.fromPath(path)
-1 6705 };
-1 6706
-1 6707 if (options.chamfer) {
-1 6708 var chamfer = options.chamfer;
-1 6709 polygon.vertices = Vertices.chamfer(polygon.vertices, chamfer.radius,
-1 6710 chamfer.quality, chamfer.qualityMin, chamfer.qualityMax);
-1 6711 delete options.chamfer;
-1 6712 }
-1 6713
-1 6714 return Body.create(Common.extend({}, polygon, options));
-1 6715 };
-1 6716
-1 6717 /**
-1 6718 * Creates a body using the supplied vertices (or an array containing multiple sets of vertices).
-1 6719 * If the vertices are convex, they will pass through as supplied.
-1 6720 * Otherwise if the vertices are concave, they will be decomposed if [poly-decomp.js](https://github.com/schteppe/poly-decomp.js) is available.
-1 6721 * Note that this process is not guaranteed to support complex sets of vertices (e.g. those with holes may fail).
-1 6722 * By default the decomposition will discard collinear edges (to improve performance).
-1 6723 * It can also optionally discard any parts that have an area less than `minimumArea`.
-1 6724 * If the vertices can not be decomposed, the result will fall back to using the convex hull.
-1 6725 * The options parameter is an object that specifies any `Matter.Body` properties you wish to override the defaults.
-1 6726 * See the properties section of the `Matter.Body` module for detailed information on what you can pass via the `options` object.
-1 6727 * @method fromVertices
-1 6728 * @param {number} x
-1 6729 * @param {number} y
-1 6730 * @param [[vector]] vertexSets
-1 6731 * @param {object} [options]
-1 6732 * @param {bool} [flagInternal=false]
-1 6733 * @param {number} [removeCollinear=0.01]
-1 6734 * @param {number} [minimumArea=10]
-1 6735 * @return {body}
-1 6736 */
-1 6737 Bodies.fromVertices = function(x, y, vertexSets, options, flagInternal, removeCollinear, minimumArea) {
-1 6738 if (!decomp) {
-1 6739 decomp = Common._requireGlobal('decomp', 'poly-decomp');
-1 6740 }
-1 6741
-1 6742 var body,
-1 6743 parts,
-1 6744 isConvex,
-1 6745 vertices,
-1 6746 i,
-1 6747 j,
-1 6748 k,
-1 6749 v,
-1 6750 z;
-1 6751
-1 6752 options = options || {};
-1 6753 parts = [];
-1 6754
-1 6755 flagInternal = typeof flagInternal !== 'undefined' ? flagInternal : false;
-1 6756 removeCollinear = typeof removeCollinear !== 'undefined' ? removeCollinear : 0.01;
-1 6757 minimumArea = typeof minimumArea !== 'undefined' ? minimumArea : 10;
-1 6758
-1 6759 if (!decomp) {
-1 6760 Common.warn('Bodies.fromVertices: poly-decomp.js required. Could not decompose vertices. Fallback to convex hull.');
-1 6761 }
-1 6762
-1 6763 // ensure vertexSets is an array of arrays
-1 6764 if (!Common.isArray(vertexSets[0])) {
-1 6765 vertexSets = [vertexSets];
-1 6766 }
-1 6767
-1 6768 for (v = 0; v < vertexSets.length; v += 1) {
-1 6769 vertices = vertexSets[v];
-1 6770 isConvex = Vertices.isConvex(vertices);
-1 6771
-1 6772 if (isConvex || !decomp) {
-1 6773 if (isConvex) {
-1 6774 vertices = Vertices.clockwiseSort(vertices);
-1 6775 } else {
-1 6776 // fallback to convex hull when decomposition is not possible
-1 6777 vertices = Vertices.hull(vertices);
-1 6778 }
-1 6779
-1 6780 parts.push({
-1 6781 position: { x: x, y: y },
-1 6782 vertices: vertices
-1 6783 });
-1 6784 } else {
-1 6785 // initialise a decomposition
-1 6786 var concave = vertices.map(function(vertex) {
-1 6787 return [vertex.x, vertex.y];
-1 6788 });
-1 6789
-1 6790 // vertices are concave and simple, we can decompose into parts
-1 6791 decomp.makeCCW(concave);
-1 6792 if (removeCollinear !== false)
-1 6793 decomp.removeCollinearPoints(concave, removeCollinear);
-1 6794
-1 6795 // use the quick decomposition algorithm (Bayazit)
-1 6796 var decomposed = decomp.quickDecomp(concave);
-1 6797
-1 6798 // for each decomposed chunk
-1 6799 for (i = 0; i < decomposed.length; i++) {
-1 6800 var chunk = decomposed[i];
-1 6801
-1 6802 // convert vertices into the correct structure
-1 6803 var chunkVertices = chunk.map(function(vertices) {
-1 6804 return {
-1 6805 x: vertices[0],
-1 6806 y: vertices[1]
-1 6807 };
-1 6808 });
-1 6809
-1 6810 // skip small chunks
-1 6811 if (minimumArea > 0 && Vertices.area(chunkVertices) < minimumArea)
-1 6812 continue;
-1 6813
-1 6814 // create a compound part
-1 6815 parts.push({
-1 6816 position: Vertices.centre(chunkVertices),
-1 6817 vertices: chunkVertices
-1 6818 });
-1 6819 }
-1 6820 }
-1 6821 }
-1 6822
-1 6823 // create body parts
-1 6824 for (i = 0; i < parts.length; i++) {
-1 6825 parts[i] = Body.create(Common.extend(parts[i], options));
-1 6826 }
-1 6827
-1 6828 // flag internal edges (coincident part edges)
-1 6829 if (flagInternal) {
-1 6830 var coincident_max_dist = 5;
-1 6831
-1 6832 for (i = 0; i < parts.length; i++) {
-1 6833 var partA = parts[i];
-1 6834
-1 6835 for (j = i + 1; j < parts.length; j++) {
-1 6836 var partB = parts[j];
-1 6837
-1 6838 if (Bounds.overlaps(partA.bounds, partB.bounds)) {
-1 6839 var pav = partA.vertices,
-1 6840 pbv = partB.vertices;
-1 6841
-1 6842 // iterate vertices of both parts
-1 6843 for (k = 0; k < partA.vertices.length; k++) {
-1 6844 for (z = 0; z < partB.vertices.length; z++) {
-1 6845 // find distances between the vertices
-1 6846 var da = Vector.magnitudeSquared(Vector.sub(pav[(k + 1) % pav.length], pbv[z])),
-1 6847 db = Vector.magnitudeSquared(Vector.sub(pav[k], pbv[(z + 1) % pbv.length]));
-1 6848
-1 6849 // if both vertices are very close, consider the edge concident (internal)
-1 6850 if (da < coincident_max_dist && db < coincident_max_dist) {
-1 6851 pav[k].isInternal = true;
-1 6852 pbv[z].isInternal = true;
-1 6853 }
-1 6854 }
-1 6855 }
-1 6856
-1 6857 }
-1 6858 }
-1 6859 }
-1 6860 }
-1 6861
-1 6862 if (parts.length > 1) {
-1 6863 // create the parent body to be returned, that contains generated compound parts
-1 6864 body = Body.create(Common.extend({ parts: parts.slice(0) }, options));
-1 6865 Body.setPosition(body, { x: x, y: y });
-1 6866
-1 6867 return body;
-1 6868 } else {
-1 6869 return parts[0];
-1 6870 }
-1 6871 };
-1 6872
-1 6873 })();
-1 6874
-1 6875 },{"../body/Body":1,"../core/Common":14,"../geometry/Bounds":26,"../geometry/Vector":28,"../geometry/Vertices":29}],24:[function(_dereq_,module,exports){
-1 6876 /**
-1 6877 * The `Matter.Composites` module contains factory methods for creating composite bodies
-1 6878 * with commonly used configurations (such as stacks and chains).
-1 6879 *
-1 6880 * See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples).
-1 6881 *
-1 6882 * @class Composites
-1 6883 */
-1 6884
-1 6885 var Composites = {};
-1 6886
-1 6887 module.exports = Composites;
-1 6888
-1 6889 var Composite = _dereq_('../body/Composite');
-1 6890 var Constraint = _dereq_('../constraint/Constraint');
-1 6891 var Common = _dereq_('../core/Common');
-1 6892 var Body = _dereq_('../body/Body');
-1 6893 var Bodies = _dereq_('./Bodies');
-1 6894
-1 6895 (function() {
-1 6896
-1 6897 /**
-1 6898 * Create a new composite containing bodies created in the callback in a grid arrangement.
-1 6899 * This function uses the body's bounds to prevent overlaps.
-1 6900 * @method stack
-1 6901 * @param {number} xx
-1 6902 * @param {number} yy
-1 6903 * @param {number} columns
-1 6904 * @param {number} rows
-1 6905 * @param {number} columnGap
-1 6906 * @param {number} rowGap
-1 6907 * @param {function} callback
-1 6908 * @return {composite} A new composite containing objects created in the callback
-1 6909 */
-1 6910 Composites.stack = function(xx, yy, columns, rows, columnGap, rowGap, callback) {
-1 6911 var stack = Composite.create({ label: 'Stack' }),
-1 6912 x = xx,
-1 6913 y = yy,
-1 6914 lastBody,
-1 6915 i = 0;
-1 6916
-1 6917 for (var row = 0; row < rows; row++) {
-1 6918 var maxHeight = 0;
-1 6919
-1 6920 for (var column = 0; column < columns; column++) {
-1 6921 var body = callback(x, y, column, row, lastBody, i);
-1 6922
-1 6923 if (body) {
-1 6924 var bodyHeight = body.bounds.max.y - body.bounds.min.y,
-1 6925 bodyWidth = body.bounds.max.x - body.bounds.min.x;
-1 6926
-1 6927 if (bodyHeight > maxHeight)
-1 6928 maxHeight = bodyHeight;
-1 6929
-1 6930 Body.translate(body, { x: bodyWidth * 0.5, y: bodyHeight * 0.5 });
-1 6931
-1 6932 x = body.bounds.max.x + columnGap;
-1 6933
-1 6934 Composite.addBody(stack, body);
-1 6935
-1 6936 lastBody = body;
-1 6937 i += 1;
-1 6938 } else {
-1 6939 x += columnGap;
-1 6940 }
-1 6941 }
-1 6942
-1 6943 y += maxHeight + rowGap;
-1 6944 x = xx;
-1 6945 }
-1 6946
-1 6947 return stack;
-1 6948 };
-1 6949
-1 6950 /**
-1 6951 * Chains all bodies in the given composite together using constraints.
-1 6952 * @method chain
-1 6953 * @param {composite} composite
-1 6954 * @param {number} xOffsetA
-1 6955 * @param {number} yOffsetA
-1 6956 * @param {number} xOffsetB
-1 6957 * @param {number} yOffsetB
-1 6958 * @param {object} options
-1 6959 * @return {composite} A new composite containing objects chained together with constraints
-1 6960 */
-1 6961 Composites.chain = function(composite, xOffsetA, yOffsetA, xOffsetB, yOffsetB, options) {
-1 6962 var bodies = composite.bodies;
-1 6963
-1 6964 for (var i = 1; i < bodies.length; i++) {
-1 6965 var bodyA = bodies[i - 1],
-1 6966 bodyB = bodies[i],
-1 6967 bodyAHeight = bodyA.bounds.max.y - bodyA.bounds.min.y,
-1 6968 bodyAWidth = bodyA.bounds.max.x - bodyA.bounds.min.x,
-1 6969 bodyBHeight = bodyB.bounds.max.y - bodyB.bounds.min.y,
-1 6970 bodyBWidth = bodyB.bounds.max.x - bodyB.bounds.min.x;
-1 6971
-1 6972 var defaults = {
-1 6973 bodyA: bodyA,
-1 6974 pointA: { x: bodyAWidth * xOffsetA, y: bodyAHeight * yOffsetA },
-1 6975 bodyB: bodyB,
-1 6976 pointB: { x: bodyBWidth * xOffsetB, y: bodyBHeight * yOffsetB }
-1 6977 };
-1 6978
-1 6979 var constraint = Common.extend(defaults, options);
-1 6980
-1 6981 Composite.addConstraint(composite, Constraint.create(constraint));
-1 6982 }
-1 6983
-1 6984 composite.label += ' Chain';
-1 6985
-1 6986 return composite;
-1 6987 };
-1 6988
-1 6989 /**
-1 6990 * Connects bodies in the composite with constraints in a grid pattern, with optional cross braces.
-1 6991 * @method mesh
-1 6992 * @param {composite} composite
-1 6993 * @param {number} columns
-1 6994 * @param {number} rows
-1 6995 * @param {boolean} crossBrace
-1 6996 * @param {object} options
-1 6997 * @return {composite} The composite containing objects meshed together with constraints
-1 6998 */
-1 6999 Composites.mesh = function(composite, columns, rows, crossBrace, options) {
-1 7000 var bodies = composite.bodies,
-1 7001 row,
-1 7002 col,
-1 7003 bodyA,
-1 7004 bodyB,
-1 7005 bodyC;
-1 7006
-1 7007 for (row = 0; row < rows; row++) {
-1 7008 for (col = 1; col < columns; col++) {
-1 7009 bodyA = bodies[(col - 1) + (row * columns)];
-1 7010 bodyB = bodies[col + (row * columns)];
-1 7011 Composite.addConstraint(composite, Constraint.create(Common.extend({ bodyA: bodyA, bodyB: bodyB }, options)));
-1 7012 }
-1 7013
-1 7014 if (row > 0) {
-1 7015 for (col = 0; col < columns; col++) {
-1 7016 bodyA = bodies[col + ((row - 1) * columns)];
-1 7017 bodyB = bodies[col + (row * columns)];
-1 7018 Composite.addConstraint(composite, Constraint.create(Common.extend({ bodyA: bodyA, bodyB: bodyB }, options)));
-1 7019
-1 7020 if (crossBrace && col > 0) {
-1 7021 bodyC = bodies[(col - 1) + ((row - 1) * columns)];
-1 7022 Composite.addConstraint(composite, Constraint.create(Common.extend({ bodyA: bodyC, bodyB: bodyB }, options)));
-1 7023 }
-1 7024
-1 7025 if (crossBrace && col < columns - 1) {
-1 7026 bodyC = bodies[(col + 1) + ((row - 1) * columns)];
-1 7027 Composite.addConstraint(composite, Constraint.create(Common.extend({ bodyA: bodyC, bodyB: bodyB }, options)));
-1 7028 }
-1 7029 }
-1 7030 }
-1 7031 }
-1 7032
-1 7033 composite.label += ' Mesh';
-1 7034
-1 7035 return composite;
-1 7036 };
-1 7037
-1 7038 /**
-1 7039 * Create a new composite containing bodies created in the callback in a pyramid arrangement.
-1 7040 * This function uses the body's bounds to prevent overlaps.
-1 7041 * @method pyramid
-1 7042 * @param {number} xx
-1 7043 * @param {number} yy
-1 7044 * @param {number} columns
-1 7045 * @param {number} rows
-1 7046 * @param {number} columnGap
-1 7047 * @param {number} rowGap
-1 7048 * @param {function} callback
-1 7049 * @return {composite} A new composite containing objects created in the callback
-1 7050 */
-1 7051 Composites.pyramid = function(xx, yy, columns, rows, columnGap, rowGap, callback) {
-1 7052 return Composites.stack(xx, yy, columns, rows, columnGap, rowGap, function(x, y, column, row, lastBody, i) {
-1 7053 var actualRows = Math.min(rows, Math.ceil(columns / 2)),
-1 7054 lastBodyWidth = lastBody ? lastBody.bounds.max.x - lastBody.bounds.min.x : 0;
-1 7055
-1 7056 if (row > actualRows)
-1 7057 return;
-1 7058
-1 7059 // reverse row order
-1 7060 row = actualRows - row;
-1 7061
-1 7062 var start = row,
-1 7063 end = columns - 1 - row;
-1 7064
-1 7065 if (column < start || column > end)
-1 7066 return;
-1 7067
-1 7068 // retroactively fix the first body's position, since width was unknown
-1 7069 if (i === 1) {
-1 7070 Body.translate(lastBody, { x: (column + (columns % 2 === 1 ? 1 : -1)) * lastBodyWidth, y: 0 });
-1 7071 }
-1 7072
-1 7073 var xOffset = lastBody ? column * lastBodyWidth : 0;
-1 7074
-1 7075 return callback(xx + xOffset + column * columnGap, y, column, row, lastBody, i);
-1 7076 });
-1 7077 };
-1 7078
-1 7079 /**
-1 7080 * Creates a composite with a Newton's Cradle setup of bodies and constraints.
-1 7081 * @method newtonsCradle
-1 7082 * @param {number} xx
-1 7083 * @param {number} yy
-1 7084 * @param {number} number
-1 7085 * @param {number} size
-1 7086 * @param {number} length
-1 7087 * @return {composite} A new composite newtonsCradle body
-1 7088 */
-1 7089 Composites.newtonsCradle = function(xx, yy, number, size, length) {
-1 7090 var newtonsCradle = Composite.create({ label: 'Newtons Cradle' });
-1 7091
-1 7092 for (var i = 0; i < number; i++) {
-1 7093 var separation = 1.9,
-1 7094 circle = Bodies.circle(xx + i * (size * separation), yy + length, size,
-1 7095 { inertia: Infinity, restitution: 1, friction: 0, frictionAir: 0.0001, slop: 1 }),
-1 7096 constraint = Constraint.create({ pointA: { x: xx + i * (size * separation), y: yy }, bodyB: circle });
-1 7097
-1 7098 Composite.addBody(newtonsCradle, circle);
-1 7099 Composite.addConstraint(newtonsCradle, constraint);
-1 7100 }
-1 7101
-1 7102 return newtonsCradle;
-1 7103 };
-1 7104
-1 7105 /**
-1 7106 * Creates a composite with simple car setup of bodies and constraints.
-1 7107 * @method car
-1 7108 * @param {number} xx
-1 7109 * @param {number} yy
-1 7110 * @param {number} width
-1 7111 * @param {number} height
-1 7112 * @param {number} wheelSize
-1 7113 * @return {composite} A new composite car body
-1 7114 */
-1 7115 Composites.car = function(xx, yy, width, height, wheelSize) {
-1 7116 var group = Body.nextGroup(true),
-1 7117 wheelBase = 20,
-1 7118 wheelAOffset = -width * 0.5 + wheelBase,
-1 7119 wheelBOffset = width * 0.5 - wheelBase,
-1 7120 wheelYOffset = 0;
-1 7121
-1 7122 var car = Composite.create({ label: 'Car' }),
-1 7123 body = Bodies.rectangle(xx, yy, width, height, {
-1 7124 collisionFilter: {
-1 7125 group: group
-1 7126 },
-1 7127 chamfer: {
-1 7128 radius: height * 0.5
-1 7129 },
-1 7130 density: 0.0002
-1 7131 });
-1 7132
-1 7133 var wheelA = Bodies.circle(xx + wheelAOffset, yy + wheelYOffset, wheelSize, {
-1 7134 collisionFilter: {
-1 7135 group: group
-1 7136 },
-1 7137 friction: 0.8
-1 7138 });
-1 7139
-1 7140 var wheelB = Bodies.circle(xx + wheelBOffset, yy + wheelYOffset, wheelSize, {
-1 7141 collisionFilter: {
-1 7142 group: group
-1 7143 },
-1 7144 friction: 0.8
-1 7145 });
-1 7146
-1 7147 var axelA = Constraint.create({
-1 7148 bodyB: body,
-1 7149 pointB: { x: wheelAOffset, y: wheelYOffset },
-1 7150 bodyA: wheelA,
-1 7151 stiffness: 1,
-1 7152 length: 0
-1 7153 });
-1 7154
-1 7155 var axelB = Constraint.create({
-1 7156 bodyB: body,
-1 7157 pointB: { x: wheelBOffset, y: wheelYOffset },
-1 7158 bodyA: wheelB,
-1 7159 stiffness: 1,
-1 7160 length: 0
-1 7161 });
-1 7162
-1 7163 Composite.addBody(car, body);
-1 7164 Composite.addBody(car, wheelA);
-1 7165 Composite.addBody(car, wheelB);
-1 7166 Composite.addConstraint(car, axelA);
-1 7167 Composite.addConstraint(car, axelB);
-1 7168
-1 7169 return car;
-1 7170 };
-1 7171
-1 7172 /**
-1 7173 * Creates a simple soft body like object.
-1 7174 * @method softBody
-1 7175 * @param {number} xx
-1 7176 * @param {number} yy
-1 7177 * @param {number} columns
-1 7178 * @param {number} rows
-1 7179 * @param {number} columnGap
-1 7180 * @param {number} rowGap
-1 7181 * @param {boolean} crossBrace
-1 7182 * @param {number} particleRadius
-1 7183 * @param {} particleOptions
-1 7184 * @param {} constraintOptions
-1 7185 * @return {composite} A new composite softBody
-1 7186 */
-1 7187 Composites.softBody = function(xx, yy, columns, rows, columnGap, rowGap, crossBrace, particleRadius, particleOptions, constraintOptions) {
-1 7188 particleOptions = Common.extend({ inertia: Infinity }, particleOptions);
-1 7189 constraintOptions = Common.extend({ stiffness: 0.2, render: { type: 'line', anchors: false } }, constraintOptions);
-1 7190
-1 7191 var softBody = Composites.stack(xx, yy, columns, rows, columnGap, rowGap, function(x, y) {
-1 7192 return Bodies.circle(x, y, particleRadius, particleOptions);
-1 7193 });
-1 7194
-1 7195 Composites.mesh(softBody, columns, rows, crossBrace, constraintOptions);
-1 7196
-1 7197 softBody.label = 'Soft Body';
-1 7198
-1 7199 return softBody;
-1 7200 };
-1 7201
-1 7202 })();
-1 7203
-1 7204 },{"../body/Body":1,"../body/Composite":2,"../constraint/Constraint":12,"../core/Common":14,"./Bodies":23}],25:[function(_dereq_,module,exports){
-1 7205 /**
-1 7206 * The `Matter.Axes` module contains methods for creating and manipulating sets of axes.
-1 7207 *
-1 7208 * @class Axes
-1 7209 */
-1 7210
-1 7211 var Axes = {};
-1 7212
-1 7213 module.exports = Axes;
-1 7214
-1 7215 var Vector = _dereq_('../geometry/Vector');
-1 7216 var Common = _dereq_('../core/Common');
-1 7217
-1 7218 (function() {
-1 7219
-1 7220 /**
-1 7221 * Creates a new set of axes from the given vertices.
-1 7222 * @method fromVertices
-1 7223 * @param {vertices} vertices
-1 7224 * @return {axes} A new axes from the given vertices
-1 7225 */
-1 7226 Axes.fromVertices = function(vertices) {
-1 7227 var axes = {};
-1 7228
-1 7229 // find the unique axes, using edge normal gradients
-1 7230 for (var i = 0; i < vertices.length; i++) {
-1 7231 var j = (i + 1) % vertices.length,
-1 7232 normal = Vector.normalise({
-1 7233 x: vertices[j].y - vertices[i].y,
-1 7234 y: vertices[i].x - vertices[j].x
-1 7235 }),
-1 7236 gradient = (normal.y === 0) ? Infinity : (normal.x / normal.y);
-1 7237
-1 7238 // limit precision
-1 7239 gradient = gradient.toFixed(3).toString();
-1 7240 axes[gradient] = normal;
-1 7241 }
-1 7242
-1 7243 return Common.values(axes);
-1 7244 };
-1 7245
-1 7246 /**
-1 7247 * Rotates a set of axes by the given angle.
-1 7248 * @method rotate
-1 7249 * @param {axes} axes
-1 7250 * @param {number} angle
-1 7251 */
-1 7252 Axes.rotate = function(axes, angle) {
-1 7253 if (angle === 0)
-1 7254 return;
-1 7255
-1 7256 var cos = Math.cos(angle),
-1 7257 sin = Math.sin(angle);
-1 7258
-1 7259 for (var i = 0; i < axes.length; i++) {
-1 7260 var axis = axes[i],
-1 7261 xx;
-1 7262 xx = axis.x * cos - axis.y * sin;
-1 7263 axis.y = axis.x * sin + axis.y * cos;
-1 7264 axis.x = xx;
-1 7265 }
-1 7266 };
-1 7267
-1 7268 })();
-1 7269
-1 7270 },{"../core/Common":14,"../geometry/Vector":28}],26:[function(_dereq_,module,exports){
-1 7271 /**
-1 7272 * The `Matter.Bounds` module contains methods for creating and manipulating axis-aligned bounding boxes (AABB).
-1 7273 *
-1 7274 * @class Bounds
-1 7275 */
-1 7276
-1 7277 var Bounds = {};
-1 7278
-1 7279 module.exports = Bounds;
-1 7280
-1 7281 (function() {
-1 7282
-1 7283 /**
-1 7284 * Creates a new axis-aligned bounding box (AABB) for the given vertices.
-1 7285 * @method create
-1 7286 * @param {vertices} vertices
-1 7287 * @return {bounds} A new bounds object
-1 7288 */
-1 7289 Bounds.create = function(vertices) {
-1 7290 var bounds = {
-1 7291 min: { x: 0, y: 0 },
-1 7292 max: { x: 0, y: 0 }
-1 7293 };
-1 7294
-1 7295 if (vertices)
-1 7296 Bounds.update(bounds, vertices);
-1 7297
-1 7298 return bounds;
-1 7299 };
-1 7300
-1 7301 /**
-1 7302 * Updates bounds using the given vertices and extends the bounds given a velocity.
-1 7303 * @method update
-1 7304 * @param {bounds} bounds
-1 7305 * @param {vertices} vertices
-1 7306 * @param {vector} velocity
-1 7307 */
-1 7308 Bounds.update = function(bounds, vertices, velocity) {
-1 7309 bounds.min.x = Infinity;
-1 7310 bounds.max.x = -Infinity;
-1 7311 bounds.min.y = Infinity;
-1 7312 bounds.max.y = -Infinity;
-1 7313
-1 7314 for (var i = 0; i < vertices.length; i++) {
-1 7315 var vertex = vertices[i];
-1 7316 if (vertex.x > bounds.max.x) bounds.max.x = vertex.x;
-1 7317 if (vertex.x < bounds.min.x) bounds.min.x = vertex.x;
-1 7318 if (vertex.y > bounds.max.y) bounds.max.y = vertex.y;
-1 7319 if (vertex.y < bounds.min.y) bounds.min.y = vertex.y;
-1 7320 }
-1 7321
-1 7322 if (velocity) {
-1 7323 if (velocity.x > 0) {
-1 7324 bounds.max.x += velocity.x;
-1 7325 } else {
-1 7326 bounds.min.x += velocity.x;
-1 7327 }
-1 7328
-1 7329 if (velocity.y > 0) {
-1 7330 bounds.max.y += velocity.y;
-1 7331 } else {
-1 7332 bounds.min.y += velocity.y;
-1 7333 }
-1 7334 }
-1 7335 };
-1 7336
-1 7337 /**
-1 7338 * Returns true if the bounds contains the given point.
-1 7339 * @method contains
-1 7340 * @param {bounds} bounds
-1 7341 * @param {vector} point
-1 7342 * @return {boolean} True if the bounds contain the point, otherwise false
-1 7343 */
-1 7344 Bounds.contains = function(bounds, point) {
-1 7345 return point.x >= bounds.min.x && point.x <= bounds.max.x
-1 7346 && point.y >= bounds.min.y && point.y <= bounds.max.y;
-1 7347 };
-1 7348
-1 7349 /**
-1 7350 * Returns true if the two bounds intersect.
-1 7351 * @method overlaps
-1 7352 * @param {bounds} boundsA
-1 7353 * @param {bounds} boundsB
-1 7354 * @return {boolean} True if the bounds overlap, otherwise false
-1 7355 */
-1 7356 Bounds.overlaps = function(boundsA, boundsB) {
-1 7357 return (boundsA.min.x <= boundsB.max.x && boundsA.max.x >= boundsB.min.x
-1 7358 && boundsA.max.y >= boundsB.min.y && boundsA.min.y <= boundsB.max.y);
-1 7359 };
-1 7360
-1 7361 /**
-1 7362 * Translates the bounds by the given vector.
-1 7363 * @method translate
-1 7364 * @param {bounds} bounds
-1 7365 * @param {vector} vector
-1 7366 */
-1 7367 Bounds.translate = function(bounds, vector) {
-1 7368 bounds.min.x += vector.x;
-1 7369 bounds.max.x += vector.x;
-1 7370 bounds.min.y += vector.y;
-1 7371 bounds.max.y += vector.y;
-1 7372 };
-1 7373
-1 7374 /**
-1 7375 * Shifts the bounds to the given position.
-1 7376 * @method shift
-1 7377 * @param {bounds} bounds
-1 7378 * @param {vector} position
-1 7379 */
-1 7380 Bounds.shift = function(bounds, position) {
-1 7381 var deltaX = bounds.max.x - bounds.min.x,
-1 7382 deltaY = bounds.max.y - bounds.min.y;
-1 7383
-1 7384 bounds.min.x = position.x;
-1 7385 bounds.max.x = position.x + deltaX;
-1 7386 bounds.min.y = position.y;
-1 7387 bounds.max.y = position.y + deltaY;
-1 7388 };
-1 7389
-1 7390 })();
-1 7391
-1 7392 },{}],27:[function(_dereq_,module,exports){
-1 7393 /**
-1 7394 * The `Matter.Svg` module contains methods for converting SVG images into an array of vector points.
-1 7395 *
-1 7396 * To use this module you also need the SVGPathSeg polyfill: https://github.com/progers/pathseg
-1 7397 *
-1 7398 * See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples).
-1 7399 *
-1 7400 * @class Svg
-1 7401 */
-1 7402
-1 7403 var Svg = {};
-1 7404
-1 7405 module.exports = Svg;
-1 7406
-1 7407 var Bounds = _dereq_('../geometry/Bounds');
-1 7408 var Common = _dereq_('../core/Common');
-1 7409
-1 7410 (function() {
-1 7411
-1 7412 /**
-1 7413 * Converts an SVG path into an array of vector points.
-1 7414 * If the input path forms a concave shape, you must decompose the result into convex parts before use.
-1 7415 * See `Bodies.fromVertices` which provides support for this.
-1 7416 * Note that this function is not guaranteed to support complex paths (such as those with holes).
-1 7417 * You must load the `pathseg.js` polyfill on newer browsers.
-1 7418 * @method pathToVertices
-1 7419 * @param {SVGPathElement} path
-1 7420 * @param {Number} [sampleLength=15]
-1 7421 * @return {Vector[]} points
-1 7422 */
-1 7423 Svg.pathToVertices = function(path, sampleLength) {
-1 7424 if (typeof window !== 'undefined' && !('SVGPathSeg' in window)) {
-1 7425 Common.warn('Svg.pathToVertices: SVGPathSeg not defined, a polyfill is required.');
-1 7426 }
-1 7427
-1 7428 // https://github.com/wout/svg.topoly.js/blob/master/svg.topoly.js
-1 7429 var i, il, total, point, segment, segments,
-1 7430 segmentsQueue, lastSegment,
-1 7431 lastPoint, segmentIndex, points = [],
-1 7432 lx, ly, length = 0, x = 0, y = 0;
-1 7433
-1 7434 sampleLength = sampleLength || 15;
-1 7435
-1 7436 var addPoint = function(px, py, pathSegType) {
-1 7437 // all odd-numbered path types are relative except PATHSEG_CLOSEPATH (1)
-1 7438 var isRelative = pathSegType % 2 === 1 && pathSegType > 1;
-1 7439
-1 7440 // when the last point doesn't equal the current point add the current point
-1 7441 if (!lastPoint || px != lastPoint.x || py != lastPoint.y) {
-1 7442 if (lastPoint && isRelative) {
-1 7443 lx = lastPoint.x;
-1 7444 ly = lastPoint.y;
-1 7445 } else {
-1 7446 lx = 0;
-1 7447 ly = 0;
-1 7448 }
-1 7449
-1 7450 var point = {
-1 7451 x: lx + px,
-1 7452 y: ly + py
-1 7453 };
-1 7454
-1 7455 // set last point
-1 7456 if (isRelative || !lastPoint) {
-1 7457 lastPoint = point;
-1 7458 }
-1 7459
-1 7460 points.push(point);
-1 7461
-1 7462 x = lx + px;
-1 7463 y = ly + py;
-1 7464 }
-1 7465 };
-1 7466
-1 7467 var addSegmentPoint = function(segment) {
-1 7468 var segType = segment.pathSegTypeAsLetter.toUpperCase();
-1 7469
-1 7470 // skip path ends
-1 7471 if (segType === 'Z')
-1 7472 return;
-1 7473
-1 7474 // map segment to x and y
-1 7475 switch (segType) {
-1 7476
-1 7477 case 'M':
-1 7478 case 'L':
-1 7479 case 'T':
-1 7480 case 'C':
-1 7481 case 'S':
-1 7482 case 'Q':
-1 7483 x = segment.x;
-1 7484 y = segment.y;
-1 7485 break;
-1 7486 case 'H':
-1 7487 x = segment.x;
-1 7488 break;
-1 7489 case 'V':
-1 7490 y = segment.y;
-1 7491 break;
-1 7492 }
-1 7493
-1 7494 addPoint(x, y, segment.pathSegType);
-1 7495 };
-1 7496
-1 7497 // ensure path is absolute
-1 7498 Svg._svgPathToAbsolute(path);
-1 7499
-1 7500 // get total length
-1 7501 total = path.getTotalLength();
-1 7502
-1 7503 // queue segments
-1 7504 segments = [];
-1 7505 for (i = 0; i < path.pathSegList.numberOfItems; i += 1)
-1 7506 segments.push(path.pathSegList.getItem(i));
-1 7507
-1 7508 segmentsQueue = segments.concat();
-1 7509
-1 7510 // sample through path
-1 7511 while (length < total) {
-1 7512 // get segment at position
-1 7513 segmentIndex = path.getPathSegAtLength(length);
-1 7514 segment = segments[segmentIndex];
-1 7515
-1 7516 // new segment
-1 7517 if (segment != lastSegment) {
-1 7518 while (segmentsQueue.length && segmentsQueue[0] != segment)
-1 7519 addSegmentPoint(segmentsQueue.shift());
-1 7520
-1 7521 lastSegment = segment;
-1 7522 }
-1 7523
-1 7524 // add points in between when curving
-1 7525 // TODO: adaptive sampling
-1 7526 switch (segment.pathSegTypeAsLetter.toUpperCase()) {
-1 7527
-1 7528 case 'C':
-1 7529 case 'T':
-1 7530 case 'S':
-1 7531 case 'Q':
-1 7532 case 'A':
-1 7533 point = path.getPointAtLength(length);
-1 7534 addPoint(point.x, point.y, 0);
-1 7535 break;
-1 7536
-1 7537 }
-1 7538
-1 7539 // increment by sample value
-1 7540 length += sampleLength;
-1 7541 }
-1 7542
-1 7543 // add remaining segments not passed by sampling
-1 7544 for (i = 0, il = segmentsQueue.length; i < il; ++i)
-1 7545 addSegmentPoint(segmentsQueue[i]);
-1 7546
-1 7547 return points;
-1 7548 };
-1 7549
-1 7550 Svg._svgPathToAbsolute = function(path) {
-1 7551 // http://phrogz.net/convert-svg-path-to-all-absolute-commands
-1 7552 // Copyright (c) Gavin Kistner
-1 7553 // http://phrogz.net/js/_ReuseLicense.txt
-1 7554 // Modifications: tidy formatting and naming
-1 7555 var x0, y0, x1, y1, x2, y2, segs = path.pathSegList,
-1 7556 x = 0, y = 0, len = segs.numberOfItems;
-1 7557
-1 7558 for (var i = 0; i < len; ++i) {
-1 7559 var seg = segs.getItem(i),
-1 7560 segType = seg.pathSegTypeAsLetter;
-1 7561
-1 7562 if (/[MLHVCSQTA]/.test(segType)) {
-1 7563 if ('x' in seg) x = seg.x;
-1 7564 if ('y' in seg) y = seg.y;
-1 7565 } else {
-1 7566 if ('x1' in seg) x1 = x + seg.x1;
-1 7567 if ('x2' in seg) x2 = x + seg.x2;
-1 7568 if ('y1' in seg) y1 = y + seg.y1;
-1 7569 if ('y2' in seg) y2 = y + seg.y2;
-1 7570 if ('x' in seg) x += seg.x;
-1 7571 if ('y' in seg) y += seg.y;
-1 7572
-1 7573 switch (segType) {
-1 7574
-1 7575 case 'm':
-1 7576 segs.replaceItem(path.createSVGPathSegMovetoAbs(x, y), i);
-1 7577 break;
-1 7578 case 'l':
-1 7579 segs.replaceItem(path.createSVGPathSegLinetoAbs(x, y), i);
-1 7580 break;
-1 7581 case 'h':
-1 7582 segs.replaceItem(path.createSVGPathSegLinetoHorizontalAbs(x), i);
-1 7583 break;
-1 7584 case 'v':
-1 7585 segs.replaceItem(path.createSVGPathSegLinetoVerticalAbs(y), i);
-1 7586 break;
-1 7587 case 'c':
-1 7588 segs.replaceItem(path.createSVGPathSegCurvetoCubicAbs(x, y, x1, y1, x2, y2), i);
-1 7589 break;
-1 7590 case 's':
-1 7591 segs.replaceItem(path.createSVGPathSegCurvetoCubicSmoothAbs(x, y, x2, y2), i);
-1 7592 break;
-1 7593 case 'q':
-1 7594 segs.replaceItem(path.createSVGPathSegCurvetoQuadraticAbs(x, y, x1, y1), i);
-1 7595 break;
-1 7596 case 't':
-1 7597 segs.replaceItem(path.createSVGPathSegCurvetoQuadraticSmoothAbs(x, y), i);
-1 7598 break;
-1 7599 case 'a':
-1 7600 segs.replaceItem(path.createSVGPathSegArcAbs(x, y, seg.r1, seg.r2, seg.angle, seg.largeArcFlag, seg.sweepFlag), i);
-1 7601 break;
-1 7602 case 'z':
-1 7603 case 'Z':
-1 7604 x = x0;
-1 7605 y = y0;
-1 7606 break;
-1 7607
-1 7608 }
-1 7609 }
-1 7610
-1 7611 if (segType == 'M' || segType == 'm') {
-1 7612 x0 = x;
-1 7613 y0 = y;
-1 7614 }
-1 7615 }
-1 7616 };
-1 7617
-1 7618 })();
-1 7619 },{"../core/Common":14,"../geometry/Bounds":26}],28:[function(_dereq_,module,exports){
-1 7620 /**
-1 7621 * The `Matter.Vector` module contains methods for creating and manipulating vectors.
-1 7622 * Vectors are the basis of all the geometry related operations in the engine.
-1 7623 * A `Matter.Vector` object is of the form `{ x: 0, y: 0 }`.
-1 7624 *
-1 7625 * See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples).
-1 7626 *
-1 7627 * @class Vector
-1 7628 */
-1 7629
-1 7630 // TODO: consider params for reusing vector objects
-1 7631
-1 7632 var Vector = {};
-1 7633
-1 7634 module.exports = Vector;
-1 7635
-1 7636 (function() {
-1 7637
-1 7638 /**
-1 7639 * Creates a new vector.
-1 7640 * @method create
-1 7641 * @param {number} x
-1 7642 * @param {number} y
-1 7643 * @return {vector} A new vector
-1 7644 */
-1 7645 Vector.create = function(x, y) {
-1 7646 return { x: x || 0, y: y || 0 };
-1 7647 };
-1 7648
-1 7649 /**
-1 7650 * Returns a new vector with `x` and `y` copied from the given `vector`.
-1 7651 * @method clone
-1 7652 * @param {vector} vector
-1 7653 * @return {vector} A new cloned vector
-1 7654 */
-1 7655 Vector.clone = function(vector) {
-1 7656 return { x: vector.x, y: vector.y };
-1 7657 };
-1 7658
-1 7659 /**
-1 7660 * Returns the magnitude (length) of a vector.
-1 7661 * @method magnitude
-1 7662 * @param {vector} vector
-1 7663 * @return {number} The magnitude of the vector
-1 7664 */
-1 7665 Vector.magnitude = function(vector) {
-1 7666 return Math.sqrt((vector.x * vector.x) + (vector.y * vector.y));
-1 7667 };
-1 7668
-1 7669 /**
-1 7670 * Returns the magnitude (length) of a vector (therefore saving a `sqrt` operation).
-1 7671 * @method magnitudeSquared
-1 7672 * @param {vector} vector
-1 7673 * @return {number} The squared magnitude of the vector
-1 7674 */
-1 7675 Vector.magnitudeSquared = function(vector) {
-1 7676 return (vector.x * vector.x) + (vector.y * vector.y);
-1 7677 };
-1 7678
-1 7679 /**
-1 7680 * Rotates the vector about (0, 0) by specified angle.
-1 7681 * @method rotate
-1 7682 * @param {vector} vector
-1 7683 * @param {number} angle
-1 7684 * @param {vector} [output]
-1 7685 * @return {vector} The vector rotated about (0, 0)
-1 7686 */
-1 7687 Vector.rotate = function(vector, angle, output) {
-1 7688 var cos = Math.cos(angle), sin = Math.sin(angle);
-1 7689 if (!output) output = {};
-1 7690 var x = vector.x * cos - vector.y * sin;
-1 7691 output.y = vector.x * sin + vector.y * cos;
-1 7692 output.x = x;
-1 7693 return output;
-1 7694 };
-1 7695
-1 7696 /**
-1 7697 * Rotates the vector about a specified point by specified angle.
-1 7698 * @method rotateAbout
-1 7699 * @param {vector} vector
-1 7700 * @param {number} angle
-1 7701 * @param {vector} point
-1 7702 * @param {vector} [output]
-1 7703 * @return {vector} A new vector rotated about the point
-1 7704 */
-1 7705 Vector.rotateAbout = function(vector, angle, point, output) {
-1 7706 var cos = Math.cos(angle), sin = Math.sin(angle);
-1 7707 if (!output) output = {};
-1 7708 var x = point.x + ((vector.x - point.x) * cos - (vector.y - point.y) * sin);
-1 7709 output.y = point.y + ((vector.x - point.x) * sin + (vector.y - point.y) * cos);
-1 7710 output.x = x;
-1 7711 return output;
-1 7712 };
-1 7713
-1 7714 /**
-1 7715 * Normalises a vector (such that its magnitude is `1`).
-1 7716 * @method normalise
-1 7717 * @param {vector} vector
-1 7718 * @return {vector} A new vector normalised
-1 7719 */
-1 7720 Vector.normalise = function(vector) {
-1 7721 var magnitude = Vector.magnitude(vector);
-1 7722 if (magnitude === 0)
-1 7723 return { x: 0, y: 0 };
-1 7724 return { x: vector.x / magnitude, y: vector.y / magnitude };
-1 7725 };
-1 7726
-1 7727 /**
-1 7728 * Returns the dot-product of two vectors.
-1 7729 * @method dot
-1 7730 * @param {vector} vectorA
-1 7731 * @param {vector} vectorB
-1 7732 * @return {number} The dot product of the two vectors
-1 7733 */
-1 7734 Vector.dot = function(vectorA, vectorB) {
-1 7735 return (vectorA.x * vectorB.x) + (vectorA.y * vectorB.y);
-1 7736 };
-1 7737
-1 7738 /**
-1 7739 * Returns the cross-product of two vectors.
-1 7740 * @method cross
-1 7741 * @param {vector} vectorA
-1 7742 * @param {vector} vectorB
-1 7743 * @return {number} The cross product of the two vectors
-1 7744 */
-1 7745 Vector.cross = function(vectorA, vectorB) {
-1 7746 return (vectorA.x * vectorB.y) - (vectorA.y * vectorB.x);
-1 7747 };
-1 7748
-1 7749 /**
-1 7750 * Returns the cross-product of three vectors.
-1 7751 * @method cross3
-1 7752 * @param {vector} vectorA
-1 7753 * @param {vector} vectorB
-1 7754 * @param {vector} vectorC
-1 7755 * @return {number} The cross product of the three vectors
-1 7756 */
-1 7757 Vector.cross3 = function(vectorA, vectorB, vectorC) {
-1 7758 return (vectorB.x - vectorA.x) * (vectorC.y - vectorA.y) - (vectorB.y - vectorA.y) * (vectorC.x - vectorA.x);
-1 7759 };
-1 7760
-1 7761 /**
-1 7762 * Adds the two vectors.
-1 7763 * @method add
-1 7764 * @param {vector} vectorA
-1 7765 * @param {vector} vectorB
-1 7766 * @param {vector} [output]
-1 7767 * @return {vector} A new vector of vectorA and vectorB added
-1 7768 */
-1 7769 Vector.add = function(vectorA, vectorB, output) {
-1 7770 if (!output) output = {};
-1 7771 output.x = vectorA.x + vectorB.x;
-1 7772 output.y = vectorA.y + vectorB.y;
-1 7773 return output;
-1 7774 };
-1 7775
-1 7776 /**
-1 7777 * Subtracts the two vectors.
-1 7778 * @method sub
-1 7779 * @param {vector} vectorA
-1 7780 * @param {vector} vectorB
-1 7781 * @param {vector} [output]
-1 7782 * @return {vector} A new vector of vectorA and vectorB subtracted
-1 7783 */
-1 7784 Vector.sub = function(vectorA, vectorB, output) {
-1 7785 if (!output) output = {};
-1 7786 output.x = vectorA.x - vectorB.x;
-1 7787 output.y = vectorA.y - vectorB.y;
-1 7788 return output;
-1 7789 };
-1 7790
-1 7791 /**
-1 7792 * Multiplies a vector and a scalar.
-1 7793 * @method mult
-1 7794 * @param {vector} vector
-1 7795 * @param {number} scalar
-1 7796 * @return {vector} A new vector multiplied by scalar
-1 7797 */
-1 7798 Vector.mult = function(vector, scalar) {
-1 7799 return { x: vector.x * scalar, y: vector.y * scalar };
-1 7800 };
-1 7801
-1 7802 /**
-1 7803 * Divides a vector and a scalar.
-1 7804 * @method div
-1 7805 * @param {vector} vector
-1 7806 * @param {number} scalar
-1 7807 * @return {vector} A new vector divided by scalar
-1 7808 */
-1 7809 Vector.div = function(vector, scalar) {
-1 7810 return { x: vector.x / scalar, y: vector.y / scalar };
-1 7811 };
-1 7812
-1 7813 /**
-1 7814 * Returns the perpendicular vector. Set `negate` to true for the perpendicular in the opposite direction.
-1 7815 * @method perp
-1 7816 * @param {vector} vector
-1 7817 * @param {bool} [negate=false]
-1 7818 * @return {vector} The perpendicular vector
-1 7819 */
-1 7820 Vector.perp = function(vector, negate) {
-1 7821 negate = negate === true ? -1 : 1;
-1 7822 return { x: negate * -vector.y, y: negate * vector.x };
-1 7823 };
-1 7824
-1 7825 /**
-1 7826 * Negates both components of a vector such that it points in the opposite direction.
-1 7827 * @method neg
-1 7828 * @param {vector} vector
-1 7829 * @return {vector} The negated vector
-1 7830 */
-1 7831 Vector.neg = function(vector) {
-1 7832 return { x: -vector.x, y: -vector.y };
-1 7833 };
-1 7834
-1 7835 /**
-1 7836 * Returns the angle between the vector `vectorB - vectorA` and the x-axis in radians.
-1 7837 * @method angle
-1 7838 * @param {vector} vectorA
-1 7839 * @param {vector} vectorB
-1 7840 * @return {number} The angle in radians
-1 7841 */
-1 7842 Vector.angle = function(vectorA, vectorB) {
-1 7843 return Math.atan2(vectorB.y - vectorA.y, vectorB.x - vectorA.x);
-1 7844 };
-1 7845
-1 7846 /**
-1 7847 * Temporary vector pool (not thread-safe).
-1 7848 * @property _temp
-1 7849 * @type {vector[]}
-1 7850 * @private
-1 7851 */
-1 7852 Vector._temp = [
-1 7853 Vector.create(), Vector.create(),
-1 7854 Vector.create(), Vector.create(),
-1 7855 Vector.create(), Vector.create()
-1 7856 ];
-1 7857
-1 7858 })();
-1 7859 },{}],29:[function(_dereq_,module,exports){
-1 7860 /**
-1 7861 * The `Matter.Vertices` module contains methods for creating and manipulating sets of vertices.
-1 7862 * A set of vertices is an array of `Matter.Vector` with additional indexing properties inserted by `Vertices.create`.
-1 7863 * A `Matter.Body` maintains a set of vertices to represent the shape of the object (its convex hull).
-1 7864 *
-1 7865 * See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples).
-1 7866 *
-1 7867 * @class Vertices
-1 7868 */
-1 7869
-1 7870 var Vertices = {};
-1 7871
-1 7872 module.exports = Vertices;
-1 7873
-1 7874 var Vector = _dereq_('../geometry/Vector');
-1 7875 var Common = _dereq_('../core/Common');
-1 7876
-1 7877 (function() {
-1 7878
-1 7879 /**
-1 7880 * Creates a new set of `Matter.Body` compatible vertices.
-1 7881 * The `points` argument accepts an array of `Matter.Vector` points orientated around the origin `(0, 0)`, for example:
-1 7882 *
-1 7883 * [{ x: 0, y: 0 }, { x: 25, y: 50 }, { x: 50, y: 0 }]
-1 7884 *
-1 7885 * The `Vertices.create` method returns a new array of vertices, which are similar to Matter.Vector objects,
-1 7886 * but with some additional references required for efficient collision detection routines.
-1 7887 *
-1 7888 * Vertices must be specified in clockwise order.
-1 7889 *
-1 7890 * Note that the `body` argument is not optional, a `Matter.Body` reference must be provided.
-1 7891 *
-1 7892 * @method create
-1 7893 * @param {vector[]} points
-1 7894 * @param {body} body
-1 7895 */
-1 7896 Vertices.create = function(points, body) {
-1 7897 var vertices = [];
-1 7898
-1 7899 for (var i = 0; i < points.length; i++) {
-1 7900 var point = points[i],
-1 7901 vertex = {
-1 7902 x: point.x,
-1 7903 y: point.y,
-1 7904 index: i,
-1 7905 body: body,
-1 7906 isInternal: false
-1 7907 };
-1 7908
-1 7909 vertices.push(vertex);
-1 7910 }
-1 7911
-1 7912 return vertices;
-1 7913 };
-1 7914
-1 7915 /**
-1 7916 * Parses a string containing ordered x y pairs separated by spaces (and optionally commas),
-1 7917 * into a `Matter.Vertices` object for the given `Matter.Body`.
-1 7918 * For parsing SVG paths, see `Svg.pathToVertices`.
-1 7919 * @method fromPath
-1 7920 * @param {string} path
-1 7921 * @param {body} body
-1 7922 * @return {vertices} vertices
-1 7923 */
-1 7924 Vertices.fromPath = function(path, body) {
-1 7925 var pathPattern = /L?\s*([\-\d\.e]+)[\s,]*([\-\d\.e]+)*/ig,
-1 7926 points = [];
-1 7927
-1 7928 path.replace(pathPattern, function(match, x, y) {
-1 7929 points.push({ x: parseFloat(x), y: parseFloat(y) });
-1 7930 });
-1 7931
-1 7932 return Vertices.create(points, body);
-1 7933 };
-1 7934
-1 7935 /**
-1 7936 * Returns the centre (centroid) of the set of vertices.
-1 7937 * @method centre
-1 7938 * @param {vertices} vertices
-1 7939 * @return {vector} The centre point
-1 7940 */
-1 7941 Vertices.centre = function(vertices) {
-1 7942 var area = Vertices.area(vertices, true),
-1 7943 centre = { x: 0, y: 0 },
-1 7944 cross,
-1 7945 temp,
-1 7946 j;
-1 7947
-1 7948 for (var i = 0; i < vertices.length; i++) {
-1 7949 j = (i + 1) % vertices.length;
-1 7950 cross = Vector.cross(vertices[i], vertices[j]);
-1 7951 temp = Vector.mult(Vector.add(vertices[i], vertices[j]), cross);
-1 7952 centre = Vector.add(centre, temp);
-1 7953 }
-1 7954
-1 7955 return Vector.div(centre, 6 * area);
-1 7956 };
-1 7957
-1 7958 /**
-1 7959 * Returns the average (mean) of the set of vertices.
-1 7960 * @method mean
-1 7961 * @param {vertices} vertices
-1 7962 * @return {vector} The average point
-1 7963 */
-1 7964 Vertices.mean = function(vertices) {
-1 7965 var average = { x: 0, y: 0 };
-1 7966
-1 7967 for (var i = 0; i < vertices.length; i++) {
-1 7968 average.x += vertices[i].x;
-1 7969 average.y += vertices[i].y;
-1 7970 }
-1 7971
-1 7972 return Vector.div(average, vertices.length);
-1 7973 };
-1 7974
-1 7975 /**
-1 7976 * Returns the area of the set of vertices.
-1 7977 * @method area
-1 7978 * @param {vertices} vertices
-1 7979 * @param {bool} signed
-1 7980 * @return {number} The area
-1 7981 */
-1 7982 Vertices.area = function(vertices, signed) {
-1 7983 var area = 0,
-1 7984 j = vertices.length - 1;
-1 7985
-1 7986 for (var i = 0; i < vertices.length; i++) {
-1 7987 area += (vertices[j].x - vertices[i].x) * (vertices[j].y + vertices[i].y);
-1 7988 j = i;
-1 7989 }
-1 7990
-1 7991 if (signed)
-1 7992 return area / 2;
-1 7993
-1 7994 return Math.abs(area) / 2;
-1 7995 };
-1 7996
-1 7997 /**
-1 7998 * Returns the moment of inertia (second moment of area) of the set of vertices given the total mass.
-1 7999 * @method inertia
-1 8000 * @param {vertices} vertices
-1 8001 * @param {number} mass
-1 8002 * @return {number} The polygon's moment of inertia
-1 8003 */
-1 8004 Vertices.inertia = function(vertices, mass) {
-1 8005 var numerator = 0,
-1 8006 denominator = 0,
-1 8007 v = vertices,
-1 8008 cross,
-1 8009 j;
-1 8010
-1 8011 // find the polygon's moment of inertia, using second moment of area
-1 8012 // from equations at http://www.physicsforums.com/showthread.php?t=25293
-1 8013 for (var n = 0; n < v.length; n++) {
-1 8014 j = (n + 1) % v.length;
-1 8015 cross = Math.abs(Vector.cross(v[j], v[n]));
-1 8016 numerator += cross * (Vector.dot(v[j], v[j]) + Vector.dot(v[j], v[n]) + Vector.dot(v[n], v[n]));
-1 8017 denominator += cross;
-1 8018 }
-1 8019
-1 8020 return (mass / 6) * (numerator / denominator);
-1 8021 };
-1 8022
-1 8023 /**
-1 8024 * Translates the set of vertices in-place.
-1 8025 * @method translate
-1 8026 * @param {vertices} vertices
-1 8027 * @param {vector} vector
-1 8028 * @param {number} scalar
-1 8029 */
-1 8030 Vertices.translate = function(vertices, vector, scalar) {
-1 8031 var i;
-1 8032 if (scalar) {
-1 8033 for (i = 0; i < vertices.length; i++) {
-1 8034 vertices[i].x += vector.x * scalar;
-1 8035 vertices[i].y += vector.y * scalar;
-1 8036 }
-1 8037 } else {
-1 8038 for (i = 0; i < vertices.length; i++) {
-1 8039 vertices[i].x += vector.x;
-1 8040 vertices[i].y += vector.y;
-1 8041 }
-1 8042 }
-1 8043
-1 8044 return vertices;
-1 8045 };
-1 8046
-1 8047 /**
-1 8048 * Rotates the set of vertices in-place.
-1 8049 * @method rotate
-1 8050 * @param {vertices} vertices
-1 8051 * @param {number} angle
-1 8052 * @param {vector} point
-1 8053 */
-1 8054 Vertices.rotate = function(vertices, angle, point) {
-1 8055 if (angle === 0)
-1 8056 return;
-1 8057
-1 8058 var cos = Math.cos(angle),
-1 8059 sin = Math.sin(angle);
-1 8060
-1 8061 for (var i = 0; i < vertices.length; i++) {
-1 8062 var vertice = vertices[i],
-1 8063 dx = vertice.x - point.x,
-1 8064 dy = vertice.y - point.y;
-1 8065
-1 8066 vertice.x = point.x + (dx * cos - dy * sin);
-1 8067 vertice.y = point.y + (dx * sin + dy * cos);
-1 8068 }
-1 8069
-1 8070 return vertices;
-1 8071 };
-1 8072
-1 8073 /**
-1 8074 * Returns `true` if the `point` is inside the set of `vertices`.
-1 8075 * @method contains
-1 8076 * @param {vertices} vertices
-1 8077 * @param {vector} point
-1 8078 * @return {boolean} True if the vertices contains point, otherwise false
-1 8079 */
-1 8080 Vertices.contains = function(vertices, point) {
-1 8081 for (var i = 0; i < vertices.length; i++) {
-1 8082 var vertice = vertices[i],
-1 8083 nextVertice = vertices[(i + 1) % vertices.length];
-1 8084 if ((point.x - vertice.x) * (nextVertice.y - vertice.y) + (point.y - vertice.y) * (vertice.x - nextVertice.x) > 0) {
-1 8085 return false;
-1 8086 }
-1 8087 }
-1 8088
-1 8089 return true;
-1 8090 };
-1 8091
-1 8092 /**
-1 8093 * Scales the vertices from a point (default is centre) in-place.
-1 8094 * @method scale
-1 8095 * @param {vertices} vertices
-1 8096 * @param {number} scaleX
-1 8097 * @param {number} scaleY
-1 8098 * @param {vector} point
-1 8099 */
-1 8100 Vertices.scale = function(vertices, scaleX, scaleY, point) {
-1 8101 if (scaleX === 1 && scaleY === 1)
-1 8102 return vertices;
-1 8103
-1 8104 point = point || Vertices.centre(vertices);
-1 8105
-1 8106 var vertex,
-1 8107 delta;
-1 8108
-1 8109 for (var i = 0; i < vertices.length; i++) {
-1 8110 vertex = vertices[i];
-1 8111 delta = Vector.sub(vertex, point);
-1 8112 vertices[i].x = point.x + delta.x * scaleX;
-1 8113 vertices[i].y = point.y + delta.y * scaleY;
-1 8114 }
-1 8115
-1 8116 return vertices;
-1 8117 };
-1 8118
-1 8119 /**
-1 8120 * Chamfers a set of vertices by giving them rounded corners, returns a new set of vertices.
-1 8121 * The radius parameter is a single number or an array to specify the radius for each vertex.
-1 8122 * @method chamfer
-1 8123 * @param {vertices} vertices
-1 8124 * @param {number[]} radius
-1 8125 * @param {number} quality
-1 8126 * @param {number} qualityMin
-1 8127 * @param {number} qualityMax
-1 8128 */
-1 8129 Vertices.chamfer = function(vertices, radius, quality, qualityMin, qualityMax) {
-1 8130 if (typeof radius === 'number') {
-1 8131 radius = [radius];
-1 8132 } else {
-1 8133 radius = radius || [8];
-1 8134 }
-1 8135
-1 8136 // quality defaults to -1, which is auto
-1 8137 quality = (typeof quality !== 'undefined') ? quality : -1;
-1 8138 qualityMin = qualityMin || 2;
-1 8139 qualityMax = qualityMax || 14;
-1 8140
-1 8141 var newVertices = [];
-1 8142
-1 8143 for (var i = 0; i < vertices.length; i++) {
-1 8144 var prevVertex = vertices[i - 1 >= 0 ? i - 1 : vertices.length - 1],
-1 8145 vertex = vertices[i],
-1 8146 nextVertex = vertices[(i + 1) % vertices.length],
-1 8147 currentRadius = radius[i < radius.length ? i : radius.length - 1];
-1 8148
-1 8149 if (currentRadius === 0) {
-1 8150 newVertices.push(vertex);
-1 8151 continue;
-1 8152 }
-1 8153
-1 8154 var prevNormal = Vector.normalise({
-1 8155 x: vertex.y - prevVertex.y,
-1 8156 y: prevVertex.x - vertex.x
-1 8157 });
-1 8158
-1 8159 var nextNormal = Vector.normalise({
-1 8160 x: nextVertex.y - vertex.y,
-1 8161 y: vertex.x - nextVertex.x
-1 8162 });
-1 8163
-1 8164 var diagonalRadius = Math.sqrt(2 * Math.pow(currentRadius, 2)),
-1 8165 radiusVector = Vector.mult(Common.clone(prevNormal), currentRadius),
-1 8166 midNormal = Vector.normalise(Vector.mult(Vector.add(prevNormal, nextNormal), 0.5)),
-1 8167 scaledVertex = Vector.sub(vertex, Vector.mult(midNormal, diagonalRadius));
-1 8168
-1 8169 var precision = quality;
-1 8170
-1 8171 if (quality === -1) {
-1 8172 // automatically decide precision
-1 8173 precision = Math.pow(currentRadius, 0.32) * 1.75;
-1 8174 }
-1 8175
-1 8176 precision = Common.clamp(precision, qualityMin, qualityMax);
-1 8177
-1 8178 // use an even value for precision, more likely to reduce axes by using symmetry
-1 8179 if (precision % 2 === 1)
-1 8180 precision += 1;
-1 8181
-1 8182 var alpha = Math.acos(Vector.dot(prevNormal, nextNormal)),
-1 8183 theta = alpha / precision;
-1 8184
-1 8185 for (var j = 0; j < precision; j++) {
-1 8186 newVertices.push(Vector.add(Vector.rotate(radiusVector, theta * j), scaledVertex));
-1 8187 }
-1 8188 }
-1 8189
-1 8190 return newVertices;
-1 8191 };
-1 8192
-1 8193 /**
-1 8194 * Sorts the input vertices into clockwise order in place.
-1 8195 * @method clockwiseSort
-1 8196 * @param {vertices} vertices
-1 8197 * @return {vertices} vertices
-1 8198 */
-1 8199 Vertices.clockwiseSort = function(vertices) {
-1 8200 var centre = Vertices.mean(vertices);
-1 8201
-1 8202 vertices.sort(function(vertexA, vertexB) {
-1 8203 return Vector.angle(centre, vertexA) - Vector.angle(centre, vertexB);
-1 8204 });
-1 8205
-1 8206 return vertices;
-1 8207 };
-1 8208
-1 8209 /**
-1 8210 * Returns true if the vertices form a convex shape (vertices must be in clockwise order).
-1 8211 * @method isConvex
-1 8212 * @param {vertices} vertices
-1 8213 * @return {bool} `true` if the `vertices` are convex, `false` if not (or `null` if not computable).
-1 8214 */
-1 8215 Vertices.isConvex = function(vertices) {
-1 8216 // http://paulbourke.net/geometry/polygonmesh/
-1 8217 // Copyright (c) Paul Bourke (use permitted)
-1 8218
-1 8219 var flag = 0,
-1 8220 n = vertices.length,
-1 8221 i,
-1 8222 j,
-1 8223 k,
-1 8224 z;
-1 8225
-1 8226 if (n < 3)
-1 8227 return null;
-1 8228
-1 8229 for (i = 0; i < n; i++) {
-1 8230 j = (i + 1) % n;
-1 8231 k = (i + 2) % n;
-1 8232 z = (vertices[j].x - vertices[i].x) * (vertices[k].y - vertices[j].y);
-1 8233 z -= (vertices[j].y - vertices[i].y) * (vertices[k].x - vertices[j].x);
-1 8234
-1 8235 if (z < 0) {
-1 8236 flag |= 1;
-1 8237 } else if (z > 0) {
-1 8238 flag |= 2;
-1 8239 }
-1 8240
-1 8241 if (flag === 3) {
-1 8242 return false;
-1 8243 }
-1 8244 }
-1 8245
-1 8246 if (flag !== 0){
-1 8247 return true;
-1 8248 } else {
-1 8249 return null;
-1 8250 }
-1 8251 };
-1 8252
-1 8253 /**
-1 8254 * Returns the convex hull of the input vertices as a new array of points.
-1 8255 * @method hull
-1 8256 * @param {vertices} vertices
-1 8257 * @return [vertex] vertices
-1 8258 */
-1 8259 Vertices.hull = function(vertices) {
-1 8260 // http://geomalgorithms.com/a10-_hull-1.html
-1 8261
-1 8262 var upper = [],
-1 8263 lower = [],
-1 8264 vertex,
-1 8265 i;
-1 8266
-1 8267 // sort vertices on x-axis (y-axis for ties)
-1 8268 vertices = vertices.slice(0);
-1 8269 vertices.sort(function(vertexA, vertexB) {
-1 8270 var dx = vertexA.x - vertexB.x;
-1 8271 return dx !== 0 ? dx : vertexA.y - vertexB.y;
-1 8272 });
-1 8273
-1 8274 // build lower hull
-1 8275 for (i = 0; i < vertices.length; i += 1) {
-1 8276 vertex = vertices[i];
-1 8277
-1 8278 while (lower.length >= 2
-1 8279 && Vector.cross3(lower[lower.length - 2], lower[lower.length - 1], vertex) <= 0) {
-1 8280 lower.pop();
-1 8281 }
-1 8282
-1 8283 lower.push(vertex);
-1 8284 }
-1 8285
-1 8286 // build upper hull
-1 8287 for (i = vertices.length - 1; i >= 0; i -= 1) {
-1 8288 vertex = vertices[i];
-1 8289
-1 8290 while (upper.length >= 2
-1 8291 && Vector.cross3(upper[upper.length - 2], upper[upper.length - 1], vertex) <= 0) {
-1 8292 upper.pop();
-1 8293 }
-1 8294
-1 8295 upper.push(vertex);
-1 8296 }
-1 8297
-1 8298 // concatenation of the lower and upper hulls gives the convex hull
-1 8299 // omit last points because they are repeated at the beginning of the other list
-1 8300 upper.pop();
-1 8301 lower.pop();
-1 8302
-1 8303 return upper.concat(lower);
-1 8304 };
-1 8305
-1 8306 })();
-1 8307
-1 8308 },{"../core/Common":14,"../geometry/Vector":28}],30:[function(_dereq_,module,exports){
-1 8309 var Matter = module.exports = _dereq_('../core/Matter');
-1 8310
-1 8311 Matter.Body = _dereq_('../body/Body');
-1 8312 Matter.Composite = _dereq_('../body/Composite');
-1 8313 Matter.World = _dereq_('../body/World');
-1 8314
-1 8315 Matter.Contact = _dereq_('../collision/Contact');
-1 8316 Matter.Detector = _dereq_('../collision/Detector');
-1 8317 Matter.Grid = _dereq_('../collision/Grid');
-1 8318 Matter.Pairs = _dereq_('../collision/Pairs');
-1 8319 Matter.Pair = _dereq_('../collision/Pair');
-1 8320 Matter.Query = _dereq_('../collision/Query');
-1 8321 Matter.Resolver = _dereq_('../collision/Resolver');
-1 8322 Matter.SAT = _dereq_('../collision/SAT');
-1 8323
-1 8324 Matter.Constraint = _dereq_('../constraint/Constraint');
-1 8325 Matter.MouseConstraint = _dereq_('../constraint/MouseConstraint');
-1 8326
-1 8327 Matter.Common = _dereq_('../core/Common');
-1 8328 Matter.Engine = _dereq_('../core/Engine');
-1 8329 Matter.Events = _dereq_('../core/Events');
-1 8330 Matter.Mouse = _dereq_('../core/Mouse');
-1 8331 Matter.Runner = _dereq_('../core/Runner');
-1 8332 Matter.Sleeping = _dereq_('../core/Sleeping');
-1 8333 Matter.Plugin = _dereq_('../core/Plugin');
-1 8334
-1 8335
-1 8336 Matter.Bodies = _dereq_('../factory/Bodies');
-1 8337 Matter.Composites = _dereq_('../factory/Composites');
-1 8338
-1 8339 Matter.Axes = _dereq_('../geometry/Axes');
-1 8340 Matter.Bounds = _dereq_('../geometry/Bounds');
-1 8341 Matter.Svg = _dereq_('../geometry/Svg');
-1 8342 Matter.Vector = _dereq_('../geometry/Vector');
-1 8343 Matter.Vertices = _dereq_('../geometry/Vertices');
-1 8344
-1 8345 Matter.Render = _dereq_('../render/Render');
-1 8346 Matter.RenderPixi = _dereq_('../render/RenderPixi');
-1 8347
-1 8348 // aliases
-1 8349
-1 8350 Matter.World.add = Matter.Composite.add;
-1 8351 Matter.World.remove = Matter.Composite.remove;
-1 8352 Matter.World.addComposite = Matter.Composite.addComposite;
-1 8353 Matter.World.addBody = Matter.Composite.addBody;
-1 8354 Matter.World.addConstraint = Matter.Composite.addConstraint;
-1 8355 Matter.World.clear = Matter.Composite.clear;
-1 8356 Matter.Engine.run = Matter.Runner.run;
-1 8357
-1 8358 },{"../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){
-1 8359 /**
-1 8360 * The `Matter.Render` module is a simple HTML5 canvas based renderer for visualising instances of `Matter.Engine`.
-1 8361 * It is intended for development and debugging purposes, but may also be suitable for simple games.
-1 8362 * It includes a number of drawing options including wireframe, vector with support for sprites and viewports.
-1 8363 *
-1 8364 * @class Render
-1 8365 */
-1 8366
-1 8367 var Render = {};
-1 8368
-1 8369 module.exports = Render;
-1 8370
-1 8371 var Common = _dereq_('../core/Common');
-1 8372 var Composite = _dereq_('../body/Composite');
-1 8373 var Bounds = _dereq_('../geometry/Bounds');
-1 8374 var Events = _dereq_('../core/Events');
-1 8375 var Grid = _dereq_('../collision/Grid');
-1 8376 var Vector = _dereq_('../geometry/Vector');
-1 8377 var Mouse = _dereq_('../core/Mouse');
-1 8378
-1 8379 (function() {
-1 8380
-1 8381 var _requestAnimationFrame,
-1 8382 _cancelAnimationFrame;
-1 8383
-1 8384 if (typeof window !== 'undefined') {
-1 8385 _requestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame
-1 8386 || window.mozRequestAnimationFrame || window.msRequestAnimationFrame
-1 8387 || function(callback){ window.setTimeout(function() { callback(Common.now()); }, 1000 / 60); };
-1 8388
-1 8389 _cancelAnimationFrame = window.cancelAnimationFrame || window.mozCancelAnimationFrame
-1 8390 || window.webkitCancelAnimationFrame || window.msCancelAnimationFrame;
-1 8391 }
-1 8392
-1 8393 /**
-1 8394 * Creates a new renderer. The options parameter is an object that specifies any properties you wish to override the defaults.
-1 8395 * All properties have default values, and many are pre-calculated automatically based on other properties.
-1 8396 * See the properties section below for detailed information on what you can pass via the `options` object.
-1 8397 * @method create
-1 8398 * @param {object} [options]
-1 8399 * @return {render} A new renderer
-1 8400 */
-1 8401 Render.create = function(options) {
-1 8402 var defaults = {
-1 8403 controller: Render,
-1 8404 engine: null,
-1 8405 element: null,
-1 8406 canvas: null,
-1 8407 mouse: null,
-1 8408 frameRequestId: null,
-1 8409 options: {
-1 8410 width: 800,
-1 8411 height: 600,
-1 8412 pixelRatio: 1,
-1 8413 background: '#18181d',
-1 8414 wireframeBackground: '#0f0f13',
-1 8415 hasBounds: !!options.bounds,
-1 8416 enabled: true,
-1 8417 wireframes: true,
-1 8418 showSleeping: true,
-1 8419 showDebug: false,
-1 8420 showBroadphase: false,
-1 8421 showBounds: false,
-1 8422 showVelocity: false,
-1 8423 showCollisions: false,
-1 8424 showSeparations: false,
-1 8425 showAxes: false,
-1 8426 showPositions: false,
-1 8427 showAngleIndicator: false,
-1 8428 showIds: false,
-1 8429 showShadows: false,
-1 8430 showVertexNumbers: false,
-1 8431 showConvexHulls: false,
-1 8432 showInternalEdges: false,
-1 8433 showMousePosition: false
-1 8434 }
-1 8435 };
-1 8436
-1 8437 var render = Common.extend(defaults, options);
-1 8438
-1 8439 if (render.canvas) {
-1 8440 render.canvas.width = render.options.width || render.canvas.width;
-1 8441 render.canvas.height = render.options.height || render.canvas.height;
-1 8442 }
-1 8443
-1 8444 render.mouse = options.mouse;
-1 8445 render.engine = options.engine;
-1 8446 render.canvas = render.canvas || _createCanvas(render.options.width, render.options.height);
-1 8447 render.context = render.canvas.getContext('2d');
-1 8448 render.textures = {};
-1 8449
-1 8450 render.bounds = render.bounds || {
-1 8451 min: {
-1 8452 x: 0,
-1 8453 y: 0
-1 8454 },
-1 8455 max: {
-1 8456 x: render.canvas.width,
-1 8457 y: render.canvas.height
-1 8458 }
-1 8459 };
-1 8460
-1 8461 if (render.options.pixelRatio !== 1) {
-1 8462 Render.setPixelRatio(render, render.options.pixelRatio);
-1 8463 }
-1 8464
-1 8465 if (Common.isElement(render.element)) {
-1 8466 render.element.appendChild(render.canvas);
-1 8467 } else if (!render.canvas.parentNode) {
-1 8468 Common.log('Render.create: options.element was undefined, render.canvas was created but not appended', 'warn');
-1 8469 }
-1 8470
-1 8471 return render;
-1 8472 };
-1 8473
-1 8474 /**
-1 8475 * Continuously updates the render canvas on the `requestAnimationFrame` event.
-1 8476 * @method run
-1 8477 * @param {render} render
-1 8478 */
-1 8479 Render.run = function(render) {
-1 8480 (function loop(time){
-1 8481 render.frameRequestId = _requestAnimationFrame(loop);
-1 8482 Render.world(render);
-1 8483 })();
-1 8484 };
-1 8485
-1 8486 /**
-1 8487 * Ends execution of `Render.run` on the given `render`, by canceling the animation frame request event loop.
-1 8488 * @method stop
-1 8489 * @param {render} render
-1 8490 */
-1 8491 Render.stop = function(render) {
-1 8492 _cancelAnimationFrame(render.frameRequestId);
-1 8493 };
-1 8494
-1 8495 /**
-1 8496 * Sets the pixel ratio of the renderer and updates the canvas.
-1 8497 * To automatically detect the correct ratio, pass the string `'auto'` for `pixelRatio`.
-1 8498 * @method setPixelRatio
-1 8499 * @param {render} render
-1 8500 * @param {number} pixelRatio
-1 8501 */
-1 8502 Render.setPixelRatio = function(render, pixelRatio) {
-1 8503 var options = render.options,
-1 8504 canvas = render.canvas;
-1 8505
-1 8506 if (pixelRatio === 'auto') {
-1 8507 pixelRatio = _getPixelRatio(canvas);
-1 8508 }
-1 8509
-1 8510 options.pixelRatio = pixelRatio;
-1 8511 canvas.setAttribute('data-pixel-ratio', pixelRatio);
-1 8512 canvas.width = options.width * pixelRatio;
-1 8513 canvas.height = options.height * pixelRatio;
-1 8514 canvas.style.width = options.width + 'px';
-1 8515 canvas.style.height = options.height + 'px';
-1 8516 render.context.scale(pixelRatio, pixelRatio);
-1 8517 };
-1 8518
-1 8519 /**
-1 8520 * Positions and sizes the viewport around the given object bounds.
-1 8521 * Objects must have at least one of the following properties:
-1 8522 * - `object.bounds`
-1 8523 * - `object.position`
-1 8524 * - `object.min` and `object.max`
-1 8525 * - `object.x` and `object.y`
-1 8526 * @method lookAt
-1 8527 * @param {render} render
-1 8528 * @param {object[]} objects
-1 8529 * @param {vector} [padding]
-1 8530 * @param {bool} [center=true]
-1 8531 */
-1 8532 Render.lookAt = function(render, objects, padding, center) {
-1 8533 center = typeof center !== 'undefined' ? center : true;
-1 8534 objects = Common.isArray(objects) ? objects : [objects];
-1 8535 padding = padding || {
-1 8536 x: 0,
-1 8537 y: 0
-1 8538 };
-1 8539
-1 8540 // find bounds of all objects
-1 8541 var bounds = {
-1 8542 min: { x: Infinity, y: Infinity },
-1 8543 max: { x: -Infinity, y: -Infinity }
-1 8544 };
-1 8545
-1 8546 for (var i = 0; i < objects.length; i += 1) {
-1 8547 var object = objects[i],
-1 8548 min = object.bounds ? object.bounds.min : (object.min || object.position || object),
-1 8549 max = object.bounds ? object.bounds.max : (object.max || object.position || object);
-1 8550
-1 8551 if (min && max) {
-1 8552 if (min.x < bounds.min.x)
-1 8553 bounds.min.x = min.x;
-1 8554
-1 8555 if (max.x > bounds.max.x)
-1 8556 bounds.max.x = max.x;
-1 8557
-1 8558 if (min.y < bounds.min.y)
-1 8559 bounds.min.y = min.y;
-1 8560
-1 8561 if (max.y > bounds.max.y)
-1 8562 bounds.max.y = max.y;
-1 8563 }
-1 8564 }
-1 8565
-1 8566 // find ratios
-1 8567 var width = (bounds.max.x - bounds.min.x) + 2 * padding.x,
-1 8568 height = (bounds.max.y - bounds.min.y) + 2 * padding.y,
-1 8569 viewHeight = render.canvas.height,
-1 8570 viewWidth = render.canvas.width,
-1 8571 outerRatio = viewWidth / viewHeight,
-1 8572 innerRatio = width / height,
-1 8573 scaleX = 1,
-1 8574 scaleY = 1;
-1 8575
-1 8576 // find scale factor
-1 8577 if (innerRatio > outerRatio) {
-1 8578 scaleY = innerRatio / outerRatio;
-1 8579 } else {
-1 8580 scaleX = outerRatio / innerRatio;
-1 8581 }
-1 8582
-1 8583 // enable bounds
-1 8584 render.options.hasBounds = true;
-1 8585
-1 8586 // position and size
-1 8587 render.bounds.min.x = bounds.min.x;
-1 8588 render.bounds.max.x = bounds.min.x + width * scaleX;
-1 8589 render.bounds.min.y = bounds.min.y;
-1 8590 render.bounds.max.y = bounds.min.y + height * scaleY;
-1 8591
-1 8592 // center
-1 8593 if (center) {
-1 8594 render.bounds.min.x += width * 0.5 - (width * scaleX) * 0.5;
-1 8595 render.bounds.max.x += width * 0.5 - (width * scaleX) * 0.5;
-1 8596 render.bounds.min.y += height * 0.5 - (height * scaleY) * 0.5;
-1 8597 render.bounds.max.y += height * 0.5 - (height * scaleY) * 0.5;
-1 8598 }
-1 8599
-1 8600 // padding
-1 8601 render.bounds.min.x -= padding.x;
-1 8602 render.bounds.max.x -= padding.x;
-1 8603 render.bounds.min.y -= padding.y;
-1 8604 render.bounds.max.y -= padding.y;
-1 8605
-1 8606 // update mouse
-1 8607 if (render.mouse) {
-1 8608 Mouse.setScale(render.mouse, {
-1 8609 x: (render.bounds.max.x - render.bounds.min.x) / render.canvas.width,
-1 8610 y: (render.bounds.max.y - render.bounds.min.y) / render.canvas.height
-1 8611 });
-1 8612
-1 8613 Mouse.setOffset(render.mouse, render.bounds.min);
-1 8614 }
-1 8615 };
-1 8616
-1 8617 /**
-1 8618 * Applies viewport transforms based on `render.bounds` to a render context.
-1 8619 * @method startViewTransform
-1 8620 * @param {render} render
-1 8621 */
-1 8622 Render.startViewTransform = function(render) {
-1 8623 var boundsWidth = render.bounds.max.x - render.bounds.min.x,
-1 8624 boundsHeight = render.bounds.max.y - render.bounds.min.y,
-1 8625 boundsScaleX = boundsWidth / render.options.width,
-1 8626 boundsScaleY = boundsHeight / render.options.height;
-1 8627
-1 8628 render.context.scale(1 / boundsScaleX, 1 / boundsScaleY);
-1 8629 render.context.translate(-render.bounds.min.x, -render.bounds.min.y);
-1 8630 };
-1 8631
-1 8632 /**
-1 8633 * Resets all transforms on the render context.
-1 8634 * @method endViewTransform
-1 8635 * @param {render} render
-1 8636 */
-1 8637 Render.endViewTransform = function(render) {
-1 8638 render.context.setTransform(render.options.pixelRatio, 0, 0, render.options.pixelRatio, 0, 0);
-1 8639 };
-1 8640
-1 8641 /**
-1 8642 * Renders the given `engine`'s `Matter.World` object.
-1 8643 * This is the entry point for all rendering and should be called every time the scene changes.
-1 8644 * @method world
-1 8645 * @param {render} render
-1 8646 */
-1 8647 Render.world = function(render) {
-1 8648 var engine = render.engine,
-1 8649 world = engine.world,
-1 8650 canvas = render.canvas,
-1 8651 context = render.context,
-1 8652 options = render.options,
-1 8653 allBodies = Composite.allBodies(world),
-1 8654 allConstraints = Composite.allConstraints(world),
-1 8655 background = options.wireframes ? options.wireframeBackground : options.background,
-1 8656 bodies = [],
-1 8657 constraints = [],
-1 8658 i;
-1 8659
-1 8660 var event = {
-1 8661 timestamp: engine.timing.timestamp
-1 8662 };
-1 8663
-1 8664 Events.trigger(render, 'beforeRender', event);
-1 8665
-1 8666 // apply background if it has changed
-1 8667 if (render.currentBackground !== background)
-1 8668 _applyBackground(render, background);
-1 8669
-1 8670 // clear the canvas with a transparent fill, to allow the canvas background to show
-1 8671 context.globalCompositeOperation = 'source-in';
-1 8672 context.fillStyle = "transparent";
-1 8673 context.fillRect(0, 0, canvas.width, canvas.height);
-1 8674 context.globalCompositeOperation = 'source-over';
-1 8675
-1 8676 // handle bounds
-1 8677 if (options.hasBounds) {
-1 8678 // filter out bodies that are not in view
-1 8679 for (i = 0; i < allBodies.length; i++) {
-1 8680 var body = allBodies[i];
-1 8681 if (Bounds.overlaps(body.bounds, render.bounds))
-1 8682 bodies.push(body);
-1 8683 }
-1 8684
-1 8685 // filter out constraints that are not in view
-1 8686 for (i = 0; i < allConstraints.length; i++) {
-1 8687 var constraint = allConstraints[i],
-1 8688 bodyA = constraint.bodyA,
-1 8689 bodyB = constraint.bodyB,
-1 8690 pointAWorld = constraint.pointA,
-1 8691 pointBWorld = constraint.pointB;
-1 8692
-1 8693 if (bodyA) pointAWorld = Vector.add(bodyA.position, constraint.pointA);
-1 8694 if (bodyB) pointBWorld = Vector.add(bodyB.position, constraint.pointB);
-1 8695
-1 8696 if (!pointAWorld || !pointBWorld)
-1 8697 continue;
-1 8698
-1 8699 if (Bounds.contains(render.bounds, pointAWorld) || Bounds.contains(render.bounds, pointBWorld))
-1 8700 constraints.push(constraint);
-1 8701 }
-1 8702
-1 8703 // transform the view
-1 8704 Render.startViewTransform(render);
-1 8705
-1 8706 // update mouse
-1 8707 if (render.mouse) {
-1 8708 Mouse.setScale(render.mouse, {
-1 8709 x: (render.bounds.max.x - render.bounds.min.x) / render.canvas.width,
-1 8710 y: (render.bounds.max.y - render.bounds.min.y) / render.canvas.height
-1 8711 });
-1 8712
-1 8713 Mouse.setOffset(render.mouse, render.bounds.min);
-1 8714 }
-1 8715 } else {
-1 8716 constraints = allConstraints;
-1 8717 bodies = allBodies;
-1 8718 }
-1 8719
-1 8720 if (!options.wireframes || (engine.enableSleeping && options.showSleeping)) {
-1 8721 // fully featured rendering of bodies
-1 8722 Render.bodies(render, bodies, context);
-1 8723 } else {
-1 8724 if (options.showConvexHulls)
-1 8725 Render.bodyConvexHulls(render, bodies, context);
-1 8726
-1 8727 // optimised method for wireframes only
-1 8728 Render.bodyWireframes(render, bodies, context);
-1 8729 }
-1 8730
-1 8731 if (options.showBounds)
-1 8732 Render.bodyBounds(render, bodies, context);
-1 8733
-1 8734 if (options.showAxes || options.showAngleIndicator)
-1 8735 Render.bodyAxes(render, bodies, context);
-1 8736
-1 8737 if (options.showPositions)
-1 8738 Render.bodyPositions(render, bodies, context);
-1 8739
-1 8740 if (options.showVelocity)
-1 8741 Render.bodyVelocity(render, bodies, context);
-1 8742
-1 8743 if (options.showIds)
-1 8744 Render.bodyIds(render, bodies, context);
-1 8745
-1 8746 if (options.showSeparations)
-1 8747 Render.separations(render, engine.pairs.list, context);
-1 8748
-1 8749 if (options.showCollisions)
-1 8750 Render.collisions(render, engine.pairs.list, context);
-1 8751
-1 8752 if (options.showVertexNumbers)
-1 8753 Render.vertexNumbers(render, bodies, context);
-1 8754
-1 8755 if (options.showMousePosition)
-1 8756 Render.mousePosition(render, render.mouse, context);
-1 8757
-1 8758 Render.constraints(constraints, context);
-1 8759
-1 8760 if (options.showBroadphase && engine.broadphase.controller === Grid)
-1 8761 Render.grid(render, engine.broadphase, context);
-1 8762
-1 8763 if (options.showDebug)
-1 8764 Render.debug(render, context);
-1 8765
-1 8766 if (options.hasBounds) {
-1 8767 // revert view transforms
-1 8768 Render.endViewTransform(render);
-1 8769 }
-1 8770
-1 8771 Events.trigger(render, 'afterRender', event);
-1 8772 };
-1 8773
-1 8774 /**
-1 8775 * Description
-1 8776 * @private
-1 8777 * @method debug
-1 8778 * @param {render} render
-1 8779 * @param {RenderingContext} context
-1 8780 */
-1 8781 Render.debug = function(render, context) {
-1 8782 var c = context,
-1 8783 engine = render.engine,
-1 8784 world = engine.world,
-1 8785 metrics = engine.metrics,
-1 8786 options = render.options,
-1 8787 bodies = Composite.allBodies(world),
-1 8788 space = " ";
-1 8789
-1 8790 if (engine.timing.timestamp - (render.debugTimestamp || 0) >= 500) {
-1 8791 var text = "";
-1 8792
-1 8793 if (metrics.timing) {
-1 8794 text += "fps: " + Math.round(metrics.timing.fps) + space;
-1 8795 }
-1 8796
-1 8797
-1 8798 render.debugString = text;
-1 8799 render.debugTimestamp = engine.timing.timestamp;
-1 8800 }
-1 8801
-1 8802 if (render.debugString) {
-1 8803 c.font = "12px Arial";
-1 8804
-1 8805 if (options.wireframes) {
-1 8806 c.fillStyle = 'rgba(255,255,255,0.5)';
-1 8807 } else {
-1 8808 c.fillStyle = 'rgba(0,0,0,0.5)';
-1 8809 }
-1 8810
-1 8811 var split = render.debugString.split('\n');
-1 8812
-1 8813 for (var i = 0; i < split.length; i++) {
-1 8814 c.fillText(split[i], 50, 50 + i * 18);
-1 8815 }
-1 8816 }
-1 8817 };
-1 8818
-1 8819 /**
-1 8820 * Description
-1 8821 * @private
-1 8822 * @method constraints
-1 8823 * @param {constraint[]} constraints
-1 8824 * @param {RenderingContext} context
-1 8825 */
-1 8826 Render.constraints = function(constraints, context) {
-1 8827 var c = context;
-1 8828
-1 8829 for (var i = 0; i < constraints.length; i++) {
-1 8830 var constraint = constraints[i];
-1 8831
-1 8832 if (!constraint.render.visible || !constraint.pointA || !constraint.pointB)
-1 8833 continue;
-1 8834
-1 8835 var bodyA = constraint.bodyA,
-1 8836 bodyB = constraint.bodyB,
-1 8837 start,
-1 8838 end;
-1 8839
-1 8840 if (bodyA) {
-1 8841 start = Vector.add(bodyA.position, constraint.pointA);
-1 8842 } else {
-1 8843 start = constraint.pointA;
-1 8844 }
-1 8845
-1 8846 if (constraint.render.type === 'pin') {
-1 8847 c.beginPath();
-1 8848 c.arc(start.x, start.y, 3, 0, 2 * Math.PI);
-1 8849 c.closePath();
-1 8850 } else {
-1 8851 if (bodyB) {
-1 8852 end = Vector.add(bodyB.position, constraint.pointB);
-1 8853 } else {
-1 8854 end = constraint.pointB;
-1 8855 }
-1 8856
-1 8857 c.beginPath();
-1 8858 c.moveTo(start.x, start.y);
-1 8859
-1 8860 if (constraint.render.type === 'spring') {
-1 8861 var delta = Vector.sub(end, start),
-1 8862 normal = Vector.perp(Vector.normalise(delta)),
-1 8863 coils = Math.ceil(Common.clamp(constraint.length / 5, 12, 20)),
-1 8864 offset;
-1 8865
-1 8866 for (var j = 1; j < coils; j += 1) {
-1 8867 offset = j % 2 === 0 ? 1 : -1;
-1 8868
-1 8869 c.lineTo(
-1 8870 start.x + delta.x * (j / coils) + normal.x * offset * 4,
-1 8871 start.y + delta.y * (j / coils) + normal.y * offset * 4
-1 8872 );
-1 8873 }
-1 8874 }
-1 8875
-1 8876 c.lineTo(end.x, end.y);
-1 8877 }
-1 8878
-1 8879 if (constraint.render.lineWidth) {
-1 8880 c.lineWidth = constraint.render.lineWidth;
-1 8881 c.strokeStyle = constraint.render.strokeStyle;
-1 8882 c.stroke();
-1 8883 }
-1 8884
-1 8885 if (constraint.render.anchors) {
-1 8886 c.fillStyle = constraint.render.strokeStyle;
-1 8887 c.beginPath();
-1 8888 c.arc(start.x, start.y, 3, 0, 2 * Math.PI);
-1 8889 c.arc(end.x, end.y, 3, 0, 2 * Math.PI);
-1 8890 c.closePath();
-1 8891 c.fill();
-1 8892 }
-1 8893 }
-1 8894 };
-1 8895
-1 8896 /**
-1 8897 * Description
-1 8898 * @private
-1 8899 * @method bodyShadows
-1 8900 * @param {render} render
-1 8901 * @param {body[]} bodies
-1 8902 * @param {RenderingContext} context
-1 8903 */
-1 8904 Render.bodyShadows = function(render, bodies, context) {
-1 8905 var c = context,
-1 8906 engine = render.engine;
-1 8907
-1 8908 for (var i = 0; i < bodies.length; i++) {
-1 8909 var body = bodies[i];
-1 8910
-1 8911 if (!body.render.visible)
-1 8912 continue;
-1 8913
-1 8914 if (body.circleRadius) {
-1 8915 c.beginPath();
-1 8916 c.arc(body.position.x, body.position.y, body.circleRadius, 0, 2 * Math.PI);
-1 8917 c.closePath();
-1 8918 } else {
-1 8919 c.beginPath();
-1 8920 c.moveTo(body.vertices[0].x, body.vertices[0].y);
-1 8921 for (var j = 1; j < body.vertices.length; j++) {
-1 8922 c.lineTo(body.vertices[j].x, body.vertices[j].y);
-1 8923 }
-1 8924 c.closePath();
-1 8925 }
-1 8926
-1 8927 var distanceX = body.position.x - render.options.width * 0.5,
-1 8928 distanceY = body.position.y - render.options.height * 0.2,
-1 8929 distance = Math.abs(distanceX) + Math.abs(distanceY);
-1 8930
-1 8931 c.shadowColor = 'rgba(0,0,0,0.15)';
-1 8932 c.shadowOffsetX = 0.05 * distanceX;
-1 8933 c.shadowOffsetY = 0.05 * distanceY;
-1 8934 c.shadowBlur = 1 + 12 * Math.min(1, distance / 1000);
-1 8935
-1 8936 c.fill();
-1 8937
-1 8938 c.shadowColor = null;
-1 8939 c.shadowOffsetX = null;
-1 8940 c.shadowOffsetY = null;
-1 8941 c.shadowBlur = null;
-1 8942 }
-1 8943 };
-1 8944
-1 8945 /**
-1 8946 * Description
-1 8947 * @private
-1 8948 * @method bodies
-1 8949 * @param {render} render
-1 8950 * @param {body[]} bodies
-1 8951 * @param {RenderingContext} context
-1 8952 */
-1 8953 Render.bodies = function(render, bodies, context) {
-1 8954 var c = context,
-1 8955 engine = render.engine,
-1 8956 options = render.options,
-1 8957 showInternalEdges = options.showInternalEdges || !options.wireframes,
-1 8958 body,
-1 8959 part,
-1 8960 i,
-1 8961 k;
-1 8962
-1 8963 for (i = 0; i < bodies.length; i++) {
-1 8964 body = bodies[i];
-1 8965
-1 8966 if (!body.render.visible)
-1 8967 continue;
-1 8968
-1 8969 // handle compound parts
-1 8970 for (k = body.parts.length > 1 ? 1 : 0; k < body.parts.length; k++) {
-1 8971 part = body.parts[k];
-1 8972
-1 8973 if (!part.render.visible)
-1 8974 continue;
-1 8975
-1 8976 if (options.showSleeping && body.isSleeping) {
-1 8977 c.globalAlpha = 0.5 * part.render.opacity;
-1 8978 } else if (part.render.opacity !== 1) {
-1 8979 c.globalAlpha = part.render.opacity;
-1 8980 }
-1 8981
-1 8982 if (part.render.sprite && part.render.sprite.texture && !options.wireframes) {
-1 8983 // part sprite
-1 8984 var sprite = part.render.sprite,
-1 8985 texture = _getTexture(render, sprite.texture);
-1 8986
-1 8987 c.translate(part.position.x, part.position.y);
-1 8988 c.rotate(part.angle);
-1 8989
-1 8990 c.drawImage(
-1 8991 texture,
-1 8992 texture.width * -sprite.xOffset * sprite.xScale,
-1 8993 texture.height * -sprite.yOffset * sprite.yScale,
-1 8994 texture.width * sprite.xScale,
-1 8995 texture.height * sprite.yScale
-1 8996 );
-1 8997
-1 8998 // revert translation, hopefully faster than save / restore
-1 8999 c.rotate(-part.angle);
-1 9000 c.translate(-part.position.x, -part.position.y);
-1 9001 } else {
-1 9002 // part polygon
-1 9003 if (part.circleRadius) {
-1 9004 c.beginPath();
-1 9005 c.arc(part.position.x, part.position.y, part.circleRadius, 0, 2 * Math.PI);
-1 9006 } else {
-1 9007 c.beginPath();
-1 9008 c.moveTo(part.vertices[0].x, part.vertices[0].y);
-1 9009
-1 9010 for (var j = 1; j < part.vertices.length; j++) {
-1 9011 if (!part.vertices[j - 1].isInternal || showInternalEdges) {
-1 9012 c.lineTo(part.vertices[j].x, part.vertices[j].y);
-1 9013 } else {
-1 9014 c.moveTo(part.vertices[j].x, part.vertices[j].y);
-1 9015 }
-1 9016
-1 9017 if (part.vertices[j].isInternal && !showInternalEdges) {
-1 9018 c.moveTo(part.vertices[(j + 1) % part.vertices.length].x, part.vertices[(j + 1) % part.vertices.length].y);
-1 9019 }
-1 9020 }
-1 9021
-1 9022 c.lineTo(part.vertices[0].x, part.vertices[0].y);
-1 9023 c.closePath();
-1 9024 }
-1 9025
-1 9026 if (!options.wireframes) {
-1 9027 c.fillStyle = part.render.fillStyle;
-1 9028
-1 9029 if (part.render.lineWidth) {
-1 9030 c.lineWidth = part.render.lineWidth;
-1 9031 c.strokeStyle = part.render.strokeStyle;
-1 9032 c.stroke();
-1 9033 }
-1 9034
-1 9035 c.fill();
-1 9036 } else {
-1 9037 c.lineWidth = 1;
-1 9038 c.strokeStyle = '#bbb';
-1 9039 c.stroke();
-1 9040 }
-1 9041 }
-1 9042
-1 9043 c.globalAlpha = 1;
-1 9044 }
-1 9045 }
-1 9046 };
-1 9047
-1 9048 /**
-1 9049 * Optimised method for drawing body wireframes in one pass
-1 9050 * @private
-1 9051 * @method bodyWireframes
-1 9052 * @param {render} render
-1 9053 * @param {body[]} bodies
-1 9054 * @param {RenderingContext} context
-1 9055 */
-1 9056 Render.bodyWireframes = function(render, bodies, context) {
-1 9057 var c = context,
-1 9058 showInternalEdges = render.options.showInternalEdges,
-1 9059 body,
-1 9060 part,
-1 9061 i,
-1 9062 j,
-1 9063 k;
-1 9064
-1 9065 c.beginPath();
-1 9066
-1 9067 // render all bodies
-1 9068 for (i = 0; i < bodies.length; i++) {
-1 9069 body = bodies[i];
-1 9070
-1 9071 if (!body.render.visible)
-1 9072 continue;
-1 9073
-1 9074 // handle compound parts
-1 9075 for (k = body.parts.length > 1 ? 1 : 0; k < body.parts.length; k++) {
-1 9076 part = body.parts[k];
-1 9077
-1 9078 c.moveTo(part.vertices[0].x, part.vertices[0].y);
-1 9079
-1 9080 for (j = 1; j < part.vertices.length; j++) {
-1 9081 if (!part.vertices[j - 1].isInternal || showInternalEdges) {
-1 9082 c.lineTo(part.vertices[j].x, part.vertices[j].y);
-1 9083 } else {
-1 9084 c.moveTo(part.vertices[j].x, part.vertices[j].y);
-1 9085 }
-1 9086
-1 9087 if (part.vertices[j].isInternal && !showInternalEdges) {
-1 9088 c.moveTo(part.vertices[(j + 1) % part.vertices.length].x, part.vertices[(j + 1) % part.vertices.length].y);
-1 9089 }
-1 9090 }
-1 9091
-1 9092 c.lineTo(part.vertices[0].x, part.vertices[0].y);
-1 9093 }
-1 9094 }
-1 9095
-1 9096 c.lineWidth = 1;
-1 9097 c.strokeStyle = '#bbb';
-1 9098 c.stroke();
-1 9099 };
-1 9100
-1 9101 /**
-1 9102 * Optimised method for drawing body convex hull wireframes in one pass
-1 9103 * @private
-1 9104 * @method bodyConvexHulls
-1 9105 * @param {render} render
-1 9106 * @param {body[]} bodies
-1 9107 * @param {RenderingContext} context
-1 9108 */
-1 9109 Render.bodyConvexHulls = function(render, bodies, context) {
-1 9110 var c = context,
-1 9111 body,
-1 9112 part,
-1 9113 i,
-1 9114 j,
-1 9115 k;
-1 9116
-1 9117 c.beginPath();
-1 9118
-1 9119 // render convex hulls
-1 9120 for (i = 0; i < bodies.length; i++) {
-1 9121 body = bodies[i];
-1 9122
-1 9123 if (!body.render.visible || body.parts.length === 1)
-1 9124 continue;
-1 9125
-1 9126 c.moveTo(body.vertices[0].x, body.vertices[0].y);
-1 9127
-1 9128 for (j = 1; j < body.vertices.length; j++) {
-1 9129 c.lineTo(body.vertices[j].x, body.vertices[j].y);
-1 9130 }
-1 9131
-1 9132 c.lineTo(body.vertices[0].x, body.vertices[0].y);
-1 9133 }
-1 9134
-1 9135 c.lineWidth = 1;
-1 9136 c.strokeStyle = 'rgba(255,255,255,0.2)';
-1 9137 c.stroke();
-1 9138 };
-1 9139
-1 9140 /**
-1 9141 * Renders body vertex numbers.
-1 9142 * @private
-1 9143 * @method vertexNumbers
-1 9144 * @param {render} render
-1 9145 * @param {body[]} bodies
-1 9146 * @param {RenderingContext} context
-1 9147 */
-1 9148 Render.vertexNumbers = function(render, bodies, context) {
-1 9149 var c = context,
-1 9150 i,
-1 9151 j,
-1 9152 k;
-1 9153
-1 9154 for (i = 0; i < bodies.length; i++) {
-1 9155 var parts = bodies[i].parts;
-1 9156 for (k = parts.length > 1 ? 1 : 0; k < parts.length; k++) {
-1 9157 var part = parts[k];
-1 9158 for (j = 0; j < part.vertices.length; j++) {
-1 9159 c.fillStyle = 'rgba(255,255,255,0.2)';
-1 9160 c.fillText(i + '_' + j, part.position.x + (part.vertices[j].x - part.position.x) * 0.8, part.position.y + (part.vertices[j].y - part.position.y) * 0.8);
-1 9161 }
-1 9162 }
-1 9163 }
-1 9164 };
-1 9165
-1 9166 /**
-1 9167 * Renders mouse position.
-1 9168 * @private
-1 9169 * @method mousePosition
-1 9170 * @param {render} render
-1 9171 * @param {mouse} mouse
-1 9172 * @param {RenderingContext} context
-1 9173 */
-1 9174 Render.mousePosition = function(render, mouse, context) {
-1 9175 var c = context;
-1 9176 c.fillStyle = 'rgba(255,255,255,0.8)';
-1 9177 c.fillText(mouse.position.x + ' ' + mouse.position.y, mouse.position.x + 5, mouse.position.y - 5);
-1 9178 };
-1 9179
-1 9180 /**
-1 9181 * Draws body bounds
-1 9182 * @private
-1 9183 * @method bodyBounds
-1 9184 * @param {render} render
-1 9185 * @param {body[]} bodies
-1 9186 * @param {RenderingContext} context
-1 9187 */
-1 9188 Render.bodyBounds = function(render, bodies, context) {
-1 9189 var c = context,
-1 9190 engine = render.engine,
-1 9191 options = render.options;
-1 9192
-1 9193 c.beginPath();
-1 9194
-1 9195 for (var i = 0; i < bodies.length; i++) {
-1 9196 var body = bodies[i];
-1 9197
-1 9198 if (body.render.visible) {
-1 9199 var parts = bodies[i].parts;
-1 9200 for (var j = parts.length > 1 ? 1 : 0; j < parts.length; j++) {
-1 9201 var part = parts[j];
-1 9202 c.rect(part.bounds.min.x, part.bounds.min.y, part.bounds.max.x - part.bounds.min.x, part.bounds.max.y - part.bounds.min.y);
-1 9203 }
-1 9204 }
-1 9205 }
-1 9206
-1 9207 if (options.wireframes) {
-1 9208 c.strokeStyle = 'rgba(255,255,255,0.08)';
-1 9209 } else {
-1 9210 c.strokeStyle = 'rgba(0,0,0,0.1)';
-1 9211 }
-1 9212
-1 9213 c.lineWidth = 1;
-1 9214 c.stroke();
-1 9215 };
-1 9216
-1 9217 /**
-1 9218 * Draws body angle indicators and axes
-1 9219 * @private
-1 9220 * @method bodyAxes
-1 9221 * @param {render} render
-1 9222 * @param {body[]} bodies
-1 9223 * @param {RenderingContext} context
-1 9224 */
-1 9225 Render.bodyAxes = function(render, bodies, context) {
-1 9226 var c = context,
-1 9227 engine = render.engine,
-1 9228 options = render.options,
-1 9229 part,
-1 9230 i,
-1 9231 j,
-1 9232 k;
-1 9233
-1 9234 c.beginPath();
-1 9235
-1 9236 for (i = 0; i < bodies.length; i++) {
-1 9237 var body = bodies[i],
-1 9238 parts = body.parts;
-1 9239
-1 9240 if (!body.render.visible)
-1 9241 continue;
-1 9242
-1 9243 if (options.showAxes) {
-1 9244 // render all axes
-1 9245 for (j = parts.length > 1 ? 1 : 0; j < parts.length; j++) {
-1 9246 part = parts[j];
-1 9247 for (k = 0; k < part.axes.length; k++) {
-1 9248 var axis = part.axes[k];
-1 9249 c.moveTo(part.position.x, part.position.y);
-1 9250 c.lineTo(part.position.x + axis.x * 20, part.position.y + axis.y * 20);
-1 9251 }
-1 9252 }
-1 9253 } else {
-1 9254 for (j = parts.length > 1 ? 1 : 0; j < parts.length; j++) {
-1 9255 part = parts[j];
-1 9256 for (k = 0; k < part.axes.length; k++) {
-1 9257 // render a single axis indicator
-1 9258 c.moveTo(part.position.x, part.position.y);
-1 9259 c.lineTo((part.vertices[0].x + part.vertices[part.vertices.length-1].x) / 2,
-1 9260 (part.vertices[0].y + part.vertices[part.vertices.length-1].y) / 2);
-1 9261 }
-1 9262 }
-1 9263 }
-1 9264 }
-1 9265
-1 9266 if (options.wireframes) {
-1 9267 c.strokeStyle = 'indianred';
-1 9268 c.lineWidth = 1;
-1 9269 } else {
-1 9270 c.strokeStyle = 'rgba(255, 255, 255, 0.4)';
-1 9271 c.globalCompositeOperation = 'overlay';
-1 9272 c.lineWidth = 2;
-1 9273 }
-1 9274
-1 9275 c.stroke();
-1 9276 c.globalCompositeOperation = 'source-over';
-1 9277 };
-1 9278
-1 9279 /**
-1 9280 * Draws body positions
-1 9281 * @private
-1 9282 * @method bodyPositions
-1 9283 * @param {render} render
-1 9284 * @param {body[]} bodies
-1 9285 * @param {RenderingContext} context
-1 9286 */
-1 9287 Render.bodyPositions = function(render, bodies, context) {
-1 9288 var c = context,
-1 9289 engine = render.engine,
-1 9290 options = render.options,
-1 9291 body,
-1 9292 part,
-1 9293 i,
-1 9294 k;
-1 9295
-1 9296 c.beginPath();
-1 9297
-1 9298 // render current positions
-1 9299 for (i = 0; i < bodies.length; i++) {
-1 9300 body = bodies[i];
-1 9301
-1 9302 if (!body.render.visible)
-1 9303 continue;
-1 9304
-1 9305 // handle compound parts
-1 9306 for (k = 0; k < body.parts.length; k++) {
-1 9307 part = body.parts[k];
-1 9308 c.arc(part.position.x, part.position.y, 3, 0, 2 * Math.PI, false);
-1 9309 c.closePath();
-1 9310 }
-1 9311 }
-1 9312
-1 9313 if (options.wireframes) {
-1 9314 c.fillStyle = 'indianred';
-1 9315 } else {
-1 9316 c.fillStyle = 'rgba(0,0,0,0.5)';
-1 9317 }
-1 9318 c.fill();
-1 9319
-1 9320 c.beginPath();
-1 9321
-1 9322 // render previous positions
-1 9323 for (i = 0; i < bodies.length; i++) {
-1 9324 body = bodies[i];
-1 9325 if (body.render.visible) {
-1 9326 c.arc(body.positionPrev.x, body.positionPrev.y, 2, 0, 2 * Math.PI, false);
-1 9327 c.closePath();
-1 9328 }
-1 9329 }
-1 9330
-1 9331 c.fillStyle = 'rgba(255,165,0,0.8)';
-1 9332 c.fill();
-1 9333 };
-1 9334
-1 9335 /**
-1 9336 * Draws body velocity
-1 9337 * @private
-1 9338 * @method bodyVelocity
-1 9339 * @param {render} render
-1 9340 * @param {body[]} bodies
-1 9341 * @param {RenderingContext} context
-1 9342 */
-1 9343 Render.bodyVelocity = function(render, bodies, context) {
-1 9344 var c = context;
-1 9345
-1 9346 c.beginPath();
-1 9347
-1 9348 for (var i = 0; i < bodies.length; i++) {
-1 9349 var body = bodies[i];
-1 9350
-1 9351 if (!body.render.visible)
-1 9352 continue;
-1 9353
-1 9354 c.moveTo(body.position.x, body.position.y);
-1 9355 c.lineTo(body.position.x + (body.position.x - body.positionPrev.x) * 2, body.position.y + (body.position.y - body.positionPrev.y) * 2);
-1 9356 }
-1 9357
-1 9358 c.lineWidth = 3;
-1 9359 c.strokeStyle = 'cornflowerblue';
-1 9360 c.stroke();
-1 9361 };
-1 9362
-1 9363 /**
-1 9364 * Draws body ids
-1 9365 * @private
-1 9366 * @method bodyIds
-1 9367 * @param {render} render
-1 9368 * @param {body[]} bodies
-1 9369 * @param {RenderingContext} context
-1 9370 */
-1 9371 Render.bodyIds = function(render, bodies, context) {
-1 9372 var c = context,
-1 9373 i,
-1 9374 j;
-1 9375
-1 9376 for (i = 0; i < bodies.length; i++) {
-1 9377 if (!bodies[i].render.visible)
-1 9378 continue;
-1 9379
-1 9380 var parts = bodies[i].parts;
-1 9381 for (j = parts.length > 1 ? 1 : 0; j < parts.length; j++) {
-1 9382 var part = parts[j];
-1 9383 c.font = "12px Arial";
-1 9384 c.fillStyle = 'rgba(255,255,255,0.5)';
-1 9385 c.fillText(part.id, part.position.x + 10, part.position.y - 10);
-1 9386 }
-1 9387 }
-1 9388 };
-1 9389
-1 9390 /**
-1 9391 * Description
-1 9392 * @private
-1 9393 * @method collisions
-1 9394 * @param {render} render
-1 9395 * @param {pair[]} pairs
-1 9396 * @param {RenderingContext} context
-1 9397 */
-1 9398 Render.collisions = function(render, pairs, context) {
-1 9399 var c = context,
-1 9400 options = render.options,
-1 9401 pair,
-1 9402 collision,
-1 9403 corrected,
-1 9404 bodyA,
-1 9405 bodyB,
-1 9406 i,
-1 9407 j;
-1 9408
-1 9409 c.beginPath();
-1 9410
-1 9411 // render collision positions
-1 9412 for (i = 0; i < pairs.length; i++) {
-1 9413 pair = pairs[i];
-1 9414
-1 9415 if (!pair.isActive)
-1 9416 continue;
-1 9417
-1 9418 collision = pair.collision;
-1 9419 for (j = 0; j < pair.activeContacts.length; j++) {
-1 9420 var contact = pair.activeContacts[j],
-1 9421 vertex = contact.vertex;
-1 9422 c.rect(vertex.x - 1.5, vertex.y - 1.5, 3.5, 3.5);
-1 9423 }
-1 9424 }
-1 9425
-1 9426 if (options.wireframes) {
-1 9427 c.fillStyle = 'rgba(255,255,255,0.7)';
-1 9428 } else {
-1 9429 c.fillStyle = 'orange';
-1 9430 }
-1 9431 c.fill();
-1 9432
-1 9433 c.beginPath();
-1 9434
-1 9435 // render collision normals
-1 9436 for (i = 0; i < pairs.length; i++) {
-1 9437 pair = pairs[i];
-1 9438
-1 9439 if (!pair.isActive)
-1 9440 continue;
-1 9441
-1 9442 collision = pair.collision;
-1 9443
-1 9444 if (pair.activeContacts.length > 0) {
-1 9445 var normalPosX = pair.activeContacts[0].vertex.x,
-1 9446 normalPosY = pair.activeContacts[0].vertex.y;
-1 9447
-1 9448 if (pair.activeContacts.length === 2) {
-1 9449 normalPosX = (pair.activeContacts[0].vertex.x + pair.activeContacts[1].vertex.x) / 2;
-1 9450 normalPosY = (pair.activeContacts[0].vertex.y + pair.activeContacts[1].vertex.y) / 2;
-1 9451 }
-1 9452
-1 9453 if (collision.bodyB === collision.supports[0].body || collision.bodyA.isStatic === true) {
-1 9454 c.moveTo(normalPosX - collision.normal.x * 8, normalPosY - collision.normal.y * 8);
-1 9455 } else {
-1 9456 c.moveTo(normalPosX + collision.normal.x * 8, normalPosY + collision.normal.y * 8);
-1 9457 }
-1 9458
-1 9459 c.lineTo(normalPosX, normalPosY);
-1 9460 }
-1 9461 }
-1 9462
-1 9463 if (options.wireframes) {
-1 9464 c.strokeStyle = 'rgba(255,165,0,0.7)';
-1 9465 } else {
-1 9466 c.strokeStyle = 'orange';
-1 9467 }
-1 9468
-1 9469 c.lineWidth = 1;
-1 9470 c.stroke();
-1 9471 };
-1 9472
-1 9473 /**
-1 9474 * Description
-1 9475 * @private
-1 9476 * @method separations
-1 9477 * @param {render} render
-1 9478 * @param {pair[]} pairs
-1 9479 * @param {RenderingContext} context
-1 9480 */
-1 9481 Render.separations = function(render, pairs, context) {
-1 9482 var c = context,
-1 9483 options = render.options,
-1 9484 pair,
-1 9485 collision,
-1 9486 corrected,
-1 9487 bodyA,
-1 9488 bodyB,
-1 9489 i,
-1 9490 j;
-1 9491
-1 9492 c.beginPath();
-1 9493
-1 9494 // render separations
-1 9495 for (i = 0; i < pairs.length; i++) {
-1 9496 pair = pairs[i];
-1 9497
-1 9498 if (!pair.isActive)
-1 9499 continue;
-1 9500
-1 9501 collision = pair.collision;
-1 9502 bodyA = collision.bodyA;
-1 9503 bodyB = collision.bodyB;
-1 9504
-1 9505 var k = 1;
-1 9506
-1 9507 if (!bodyB.isStatic && !bodyA.isStatic) k = 0.5;
-1 9508 if (bodyB.isStatic) k = 0;
-1 9509
-1 9510 c.moveTo(bodyB.position.x, bodyB.position.y);
-1 9511 c.lineTo(bodyB.position.x - collision.penetration.x * k, bodyB.position.y - collision.penetration.y * k);
-1 9512
-1 9513 k = 1;
-1 9514
-1 9515 if (!bodyB.isStatic && !bodyA.isStatic) k = 0.5;
-1 9516 if (bodyA.isStatic) k = 0;
-1 9517
-1 9518 c.moveTo(bodyA.position.x, bodyA.position.y);
-1 9519 c.lineTo(bodyA.position.x + collision.penetration.x * k, bodyA.position.y + collision.penetration.y * k);
-1 9520 }
-1 9521
-1 9522 if (options.wireframes) {
-1 9523 c.strokeStyle = 'rgba(255,165,0,0.5)';
-1 9524 } else {
-1 9525 c.strokeStyle = 'orange';
-1 9526 }
-1 9527 c.stroke();
-1 9528 };
-1 9529
-1 9530 /**
-1 9531 * Description
-1 9532 * @private
-1 9533 * @method grid
-1 9534 * @param {render} render
-1 9535 * @param {grid} grid
-1 9536 * @param {RenderingContext} context
-1 9537 */
-1 9538 Render.grid = function(render, grid, context) {
-1 9539 var c = context,
-1 9540 options = render.options;
-1 9541
-1 9542 if (options.wireframes) {
-1 9543 c.strokeStyle = 'rgba(255,180,0,0.1)';
-1 9544 } else {
-1 9545 c.strokeStyle = 'rgba(255,180,0,0.5)';
-1 9546 }
-1 9547
-1 9548 c.beginPath();
-1 9549
-1 9550 var bucketKeys = Common.keys(grid.buckets);
-1 9551
-1 9552 for (var i = 0; i < bucketKeys.length; i++) {
-1 9553 var bucketId = bucketKeys[i];
-1 9554
-1 9555 if (grid.buckets[bucketId].length < 2)
-1 9556 continue;
-1 9557
-1 9558 var region = bucketId.split(/C|R/);
-1 9559 c.rect(0.5 + parseInt(region[1], 10) * grid.bucketWidth,
-1 9560 0.5 + parseInt(region[2], 10) * grid.bucketHeight,
-1 9561 grid.bucketWidth,
-1 9562 grid.bucketHeight);
-1 9563 }
-1 9564
-1 9565 c.lineWidth = 1;
-1 9566 c.stroke();
-1 9567 };
-1 9568
-1 9569 /**
-1 9570 * Description
-1 9571 * @private
-1 9572 * @method inspector
-1 9573 * @param {inspector} inspector
-1 9574 * @param {RenderingContext} context
-1 9575 */
-1 9576 Render.inspector = function(inspector, context) {
-1 9577 var engine = inspector.engine,
-1 9578 selected = inspector.selected,
-1 9579 render = inspector.render,
-1 9580 options = render.options,
-1 9581 bounds;
-1 9582
-1 9583 if (options.hasBounds) {
-1 9584 var boundsWidth = render.bounds.max.x - render.bounds.min.x,
-1 9585 boundsHeight = render.bounds.max.y - render.bounds.min.y,
-1 9586 boundsScaleX = boundsWidth / render.options.width,
-1 9587 boundsScaleY = boundsHeight / render.options.height;
-1 9588
-1 9589 context.scale(1 / boundsScaleX, 1 / boundsScaleY);
-1 9590 context.translate(-render.bounds.min.x, -render.bounds.min.y);
-1 9591 }
-1 9592
-1 9593 for (var i = 0; i < selected.length; i++) {
-1 9594 var item = selected[i].data;
-1 9595
-1 9596 context.translate(0.5, 0.5);
-1 9597 context.lineWidth = 1;
-1 9598 context.strokeStyle = 'rgba(255,165,0,0.9)';
-1 9599 context.setLineDash([1,2]);
-1 9600
-1 9601 switch (item.type) {
-1 9602
-1 9603 case 'body':
-1 9604
-1 9605 // render body selections
-1 9606 bounds = item.bounds;
-1 9607 context.beginPath();
-1 9608 context.rect(Math.floor(bounds.min.x - 3), Math.floor(bounds.min.y - 3),
-1 9609 Math.floor(bounds.max.x - bounds.min.x + 6), Math.floor(bounds.max.y - bounds.min.y + 6));
-1 9610 context.closePath();
-1 9611 context.stroke();
-1 9612
-1 9613 break;
-1 9614
-1 9615 case 'constraint':
-1 9616
-1 9617 // render constraint selections
-1 9618 var point = item.pointA;
-1 9619 if (item.bodyA)
-1 9620 point = item.pointB;
-1 9621 context.beginPath();
-1 9622 context.arc(point.x, point.y, 10, 0, 2 * Math.PI);
-1 9623 context.closePath();
-1 9624 context.stroke();
-1 9625
-1 9626 break;
-1 9627
-1 9628 }
-1 9629
-1 9630 context.setLineDash([]);
-1 9631 context.translate(-0.5, -0.5);
-1 9632 }
-1 9633
-1 9634 // render selection region
-1 9635 if (inspector.selectStart !== null) {
-1 9636 context.translate(0.5, 0.5);
-1 9637 context.lineWidth = 1;
-1 9638 context.strokeStyle = 'rgba(255,165,0,0.6)';
-1 9639 context.fillStyle = 'rgba(255,165,0,0.1)';
-1 9640 bounds = inspector.selectBounds;
-1 9641 context.beginPath();
-1 9642 context.rect(Math.floor(bounds.min.x), Math.floor(bounds.min.y),
-1 9643 Math.floor(bounds.max.x - bounds.min.x), Math.floor(bounds.max.y - bounds.min.y));
-1 9644 context.closePath();
-1 9645 context.stroke();
-1 9646 context.fill();
-1 9647 context.translate(-0.5, -0.5);
-1 9648 }
-1 9649
-1 9650 if (options.hasBounds)
-1 9651 context.setTransform(1, 0, 0, 1, 0, 0);
-1 9652 };
-1 9653
-1 9654 /**
-1 9655 * Description
-1 9656 * @method _createCanvas
-1 9657 * @private
-1 9658 * @param {} width
-1 9659 * @param {} height
-1 9660 * @return canvas
-1 9661 */
-1 9662 var _createCanvas = function(width, height) {
-1 9663 var canvas = document.createElement('canvas');
-1 9664 canvas.width = width;
-1 9665 canvas.height = height;
-1 9666 canvas.oncontextmenu = function() { return false; };
-1 9667 canvas.onselectstart = function() { return false; };
-1 9668 return canvas;
-1 9669 };
-1 9670
-1 9671 /**
-1 9672 * Gets the pixel ratio of the canvas.
-1 9673 * @method _getPixelRatio
-1 9674 * @private
-1 9675 * @param {HTMLElement} canvas
-1 9676 * @return {Number} pixel ratio
-1 9677 */
-1 9678 var _getPixelRatio = function(canvas) {
-1 9679 var context = canvas.getContext('2d'),
-1 9680 devicePixelRatio = window.devicePixelRatio || 1,
-1 9681 backingStorePixelRatio = context.webkitBackingStorePixelRatio || context.mozBackingStorePixelRatio
-1 9682 || context.msBackingStorePixelRatio || context.oBackingStorePixelRatio
-1 9683 || context.backingStorePixelRatio || 1;
-1 9684
-1 9685 return devicePixelRatio / backingStorePixelRatio;
-1 9686 };
-1 9687
-1 9688 /**
-1 9689 * Gets the requested texture (an Image) via its path
-1 9690 * @method _getTexture
-1 9691 * @private
-1 9692 * @param {render} render
-1 9693 * @param {string} imagePath
-1 9694 * @return {Image} texture
-1 9695 */
-1 9696 var _getTexture = function(render, imagePath) {
-1 9697 var image = render.textures[imagePath];
-1 9698
-1 9699 if (image)
-1 9700 return image;
-1 9701
-1 9702 image = render.textures[imagePath] = new Image();
-1 9703 image.src = imagePath;
-1 9704
-1 9705 return image;
-1 9706 };
-1 9707
-1 9708 /**
-1 9709 * Applies the background to the canvas using CSS.
-1 9710 * @method applyBackground
-1 9711 * @private
-1 9712 * @param {render} render
-1 9713 * @param {string} background
-1 9714 */
-1 9715 var _applyBackground = function(render, background) {
-1 9716 var cssBackground = background;
-1 9717
-1 9718 if (/(jpg|gif|png)$/.test(background))
-1 9719 cssBackground = 'url(' + background + ')';
-1 9720
-1 9721 render.canvas.style.background = cssBackground;
-1 9722 render.canvas.style.backgroundSize = "contain";
-1 9723 render.currentBackground = background;
-1 9724 };
-1 9725
-1 9726 /*
-1 9727 *
-1 9728 * Events Documentation
-1 9729 *
-1 9730 */
-1 9731
-1 9732 /**
-1 9733 * Fired before rendering
-1 9734 *
-1 9735 * @event beforeRender
-1 9736 * @param {} event An event object
-1 9737 * @param {number} event.timestamp The engine.timing.timestamp of the event
-1 9738 * @param {} event.source The source object of the event
-1 9739 * @param {} event.name The name of the event
-1 9740 */
-1 9741
-1 9742 /**
-1 9743 * Fired after rendering
-1 9744 *
-1 9745 * @event afterRender
-1 9746 * @param {} event An event object
-1 9747 * @param {number} event.timestamp The engine.timing.timestamp of the event
-1 9748 * @param {} event.source The source object of the event
-1 9749 * @param {} event.name The name of the event
-1 9750 */
-1 9751
-1 9752 /*
-1 9753 *
-1 9754 * Properties Documentation
-1 9755 *
-1 9756 */
-1 9757
-1 9758 /**
-1 9759 * A back-reference to the `Matter.Render` module.
-1 9760 *
-1 9761 * @property controller
-1 9762 * @type render
-1 9763 */
-1 9764
-1 9765 /**
-1 9766 * A reference to the `Matter.Engine` instance to be used.
-1 9767 *
-1 9768 * @property engine
-1 9769 * @type engine
-1 9770 */
-1 9771
-1 9772 /**
-1 9773 * A reference to the element where the canvas is to be inserted (if `render.canvas` has not been specified)
-1 9774 *
-1 9775 * @property element
-1 9776 * @type HTMLElement
-1 9777 * @default null
-1 9778 */
-1 9779
-1 9780 /**
-1 9781 * The canvas element to render to. If not specified, one will be created if `render.element` has been specified.
-1 9782 *
-1 9783 * @property canvas
-1 9784 * @type HTMLCanvasElement
-1 9785 * @default null
-1 9786 */
-1 9787
-1 9788 /**
-1 9789 * The configuration options of the renderer.
-1 9790 *
-1 9791 * @property options
-1 9792 * @type {}
-1 9793 */
-1 9794
-1 9795 /**
-1 9796 * The target width in pixels of the `render.canvas` to be created.
-1 9797 *
-1 9798 * @property options.width
-1 9799 * @type number
-1 9800 * @default 800
-1 9801 */
-1 9802
-1 9803 /**
-1 9804 * The target height in pixels of the `render.canvas` to be created.
-1 9805 *
-1 9806 * @property options.height
-1 9807 * @type number
-1 9808 * @default 600
-1 9809 */
-1 9810
-1 9811 /**
-1 9812 * A flag that specifies if `render.bounds` should be used when rendering.
-1 9813 *
-1 9814 * @property options.hasBounds
-1 9815 * @type boolean
-1 9816 * @default false
-1 9817 */
-1 9818
-1 9819 /**
-1 9820 * A `Bounds` object that specifies the drawing view region.
-1 9821 * Rendering will be automatically transformed and scaled to fit within the canvas size (`render.options.width` and `render.options.height`).
-1 9822 * This allows for creating views that can pan or zoom around the scene.
-1 9823 * You must also set `render.options.hasBounds` to `true` to enable bounded rendering.
-1 9824 *
-1 9825 * @property bounds
-1 9826 * @type bounds
-1 9827 */
-1 9828
-1 9829 /**
-1 9830 * The 2d rendering context from the `render.canvas` element.
-1 9831 *
-1 9832 * @property context
-1 9833 * @type CanvasRenderingContext2D
-1 9834 */
-1 9835
-1 9836 /**
-1 9837 * The sprite texture cache.
-1 9838 *
-1 9839 * @property textures
-1 9840 * @type {}
-1 9841 */
-1 9842
-1 9843 })();
-1 9844
-1 9845 },{"../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){
-1 9846 /**
-1 9847 * The `Matter.RenderPixi` module is an example renderer using pixi.js.
-1 9848 * See also `Matter.Render` for a canvas based renderer.
-1 9849 *
-1 9850 * @class RenderPixi
-1 9851 * @deprecated the Matter.RenderPixi module will soon be removed from the Matter.js core.
-1 9852 * It will likely be moved to its own repository (but maintenance will be limited).
-1 9853 */
-1 9854
-1 9855 var RenderPixi = {};
-1 9856
-1 9857 module.exports = RenderPixi;
-1 9858
-1 9859 var Bounds = _dereq_('../geometry/Bounds');
-1 9860 var Composite = _dereq_('../body/Composite');
-1 9861 var Common = _dereq_('../core/Common');
-1 9862 var Events = _dereq_('../core/Events');
-1 9863 var Vector = _dereq_('../geometry/Vector');
-1 9864
-1 9865 (function() {
-1 9866
-1 9867 var _requestAnimationFrame,
-1 9868 _cancelAnimationFrame;
-1 9869
-1 9870 if (typeof window !== 'undefined') {
-1 9871 _requestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame
-1 9872 || window.mozRequestAnimationFrame || window.msRequestAnimationFrame
-1 9873 || function(callback){ window.setTimeout(function() { callback(Common.now()); }, 1000 / 60); };
-1 9874
-1 9875 _cancelAnimationFrame = window.cancelAnimationFrame || window.mozCancelAnimationFrame
-1 9876 || window.webkitCancelAnimationFrame || window.msCancelAnimationFrame;
-1 9877 }
-1 9878
-1 9879 /**
-1 9880 * Creates a new Pixi.js WebGL renderer
-1 9881 * @method create
-1 9882 * @param {object} options
-1 9883 * @return {RenderPixi} A new renderer
-1 9884 * @deprecated
-1 9885 */
-1 9886 RenderPixi.create = function(options) {
-1 9887 Common.warn('RenderPixi.create: Matter.RenderPixi is deprecated (see docs)');
-1 9888
-1 9889 var defaults = {
-1 9890 controller: RenderPixi,
-1 9891 engine: null,
-1 9892 element: null,
-1 9893 frameRequestId: null,
-1 9894 canvas: null,
-1 9895 renderer: null,
-1 9896 container: null,
-1 9897 spriteContainer: null,
-1 9898 pixiOptions: null,
-1 9899 options: {
-1 9900 width: 800,
-1 9901 height: 600,
-1 9902 background: '#fafafa',
-1 9903 wireframeBackground: '#222',
-1 9904 hasBounds: false,
-1 9905 enabled: true,
-1 9906 wireframes: true,
-1 9907 showSleeping: true,
-1 9908 showDebug: false,
-1 9909 showBroadphase: false,
-1 9910 showBounds: false,
-1 9911 showVelocity: false,
-1 9912 showCollisions: false,
-1 9913 showAxes: false,
-1 9914 showPositions: false,
-1 9915 showAngleIndicator: false,
-1 9916 showIds: false,
-1 9917 showShadows: false
-1 9918 }
-1 9919 };
-1 9920
-1 9921 var render = Common.extend(defaults, options),
-1 9922 transparent = !render.options.wireframes && render.options.background === 'transparent';
-1 9923
-1 9924 // init pixi
-1 9925 render.pixiOptions = render.pixiOptions || {
-1 9926 view: render.canvas,
-1 9927 transparent: transparent,
-1 9928 antialias: true,
-1 9929 backgroundColor: options.background
-1 9930 };
-1 9931
-1 9932 render.mouse = options.mouse;
-1 9933 render.engine = options.engine;
-1 9934 render.renderer = render.renderer || new PIXI.WebGLRenderer(render.options.width, render.options.height, render.pixiOptions);
-1 9935 render.container = render.container || new PIXI.Container();
-1 9936 render.spriteContainer = render.spriteContainer || new PIXI.Container();
-1 9937 render.canvas = render.canvas || render.renderer.view;
-1 9938 render.bounds = render.bounds || {
-1 9939 min: {
-1 9940 x: 0,
-1 9941 y: 0
-1 9942 },
-1 9943 max: {
-1 9944 x: render.options.width,
-1 9945 y: render.options.height
-1 9946 }
-1 9947 };
-1 9948
-1 9949 // event listeners
-1 9950 Events.on(render.engine, 'beforeUpdate', function() {
-1 9951 RenderPixi.clear(render);
-1 9952 });
-1 9953
-1 9954 // caches
-1 9955 render.textures = {};
-1 9956 render.sprites = {};
-1 9957 render.primitives = {};
-1 9958
-1 9959 // use a sprite batch for performance
-1 9960 render.container.addChild(render.spriteContainer);
-1 9961
-1 9962 // insert canvas
-1 9963 if (Common.isElement(render.element)) {
-1 9964 render.element.appendChild(render.canvas);
-1 9965 } else {
-1 9966 Common.warn('No "render.element" passed, "render.canvas" was not inserted into document.');
-1 9967 }
-1 9968
-1 9969 // prevent menus on canvas
-1 9970 render.canvas.oncontextmenu = function() { return false; };
-1 9971 render.canvas.onselectstart = function() { return false; };
-1 9972
-1 9973 return render;
-1 9974 };
-1 9975
-1 9976 /**
-1 9977 * Continuously updates the render canvas on the `requestAnimationFrame` event.
-1 9978 * @method run
-1 9979 * @param {render} render
-1 9980 * @deprecated
-1 9981 */
-1 9982 RenderPixi.run = function(render) {
-1 9983 (function loop(time){
-1 9984 render.frameRequestId = _requestAnimationFrame(loop);
-1 9985 RenderPixi.world(render);
-1 9986 })();
-1 9987 };
-1 9988
-1 9989 /**
-1 9990 * Ends execution of `Render.run` on the given `render`, by canceling the animation frame request event loop.
-1 9991 * @method stop
-1 9992 * @param {render} render
-1 9993 * @deprecated
-1 9994 */
-1 9995 RenderPixi.stop = function(render) {
-1 9996 _cancelAnimationFrame(render.frameRequestId);
-1 9997 };
-1 9998
-1 9999 /**
-1 10000 * Clears the scene graph
-1 10001 * @method clear
-1 10002 * @param {RenderPixi} render
-1 10003 * @deprecated
-1 10004 */
-1 10005 RenderPixi.clear = function(render) {
-1 10006 var container = render.container,
-1 10007 spriteContainer = render.spriteContainer;
-1 10008
-1 10009 // clear stage container
-1 10010 while (container.children[0]) {
-1 10011 container.removeChild(container.children[0]);
-1 10012 }
-1 10013
-1 10014 // clear sprite batch
-1 10015 while (spriteContainer.children[0]) {
-1 10016 spriteContainer.removeChild(spriteContainer.children[0]);
-1 10017 }
-1 10018
-1 10019 var bgSprite = render.sprites['bg-0'];
-1 10020
-1 10021 // clear caches
-1 10022 render.textures = {};
-1 10023 render.sprites = {};
-1 10024 render.primitives = {};
-1 10025
-1 10026 // set background sprite
-1 10027 render.sprites['bg-0'] = bgSprite;
-1 10028 if (bgSprite)
-1 10029 container.addChildAt(bgSprite, 0);
-1 10030
-1 10031 // add sprite batch back into container
-1 10032 render.container.addChild(render.spriteContainer);
-1 10033
-1 10034 // reset background state
-1 10035 render.currentBackground = null;
-1 10036
-1 10037 // reset bounds transforms
-1 10038 container.scale.set(1, 1);
-1 10039 container.position.set(0, 0);
-1 10040 };
-1 10041
-1 10042 /**
-1 10043 * Sets the background of the canvas
-1 10044 * @method setBackground
-1 10045 * @param {RenderPixi} render
-1 10046 * @param {string} background
-1 10047 * @deprecated
-1 10048 */
-1 10049 RenderPixi.setBackground = function(render, background) {
-1 10050 if (render.currentBackground !== background) {
-1 10051 var isColor = background.indexOf && background.indexOf('#') !== -1,
-1 10052 bgSprite = render.sprites['bg-0'];
-1 10053
-1 10054 if (isColor) {
-1 10055 // if solid background color
-1 10056 var color = Common.colorToNumber(background);
-1 10057 render.renderer.backgroundColor = color;
-1 10058
-1 10059 // remove background sprite if existing
-1 10060 if (bgSprite)
-1 10061 render.container.removeChild(bgSprite);
-1 10062 } else {
-1 10063 // initialise background sprite if needed
-1 10064 if (!bgSprite) {
-1 10065 var texture = _getTexture(render, background);
-1 10066
-1 10067 bgSprite = render.sprites['bg-0'] = new PIXI.Sprite(texture);
-1 10068 bgSprite.position.x = 0;
-1 10069 bgSprite.position.y = 0;
-1 10070 render.container.addChildAt(bgSprite, 0);
-1 10071 }
-1 10072 }
-1 10073
-1 10074 render.currentBackground = background;
-1 10075 }
-1 10076 };
-1 10077
-1 10078 /**
-1 10079 * Description
-1 10080 * @method world
-1 10081 * @param {engine} engine
-1 10082 * @deprecated
-1 10083 */
-1 10084 RenderPixi.world = function(render) {
-1 10085 var engine = render.engine,
-1 10086 world = engine.world,
-1 10087 renderer = render.renderer,
-1 10088 container = render.container,
-1 10089 options = render.options,
-1 10090 bodies = Composite.allBodies(world),
-1 10091 allConstraints = Composite.allConstraints(world),
-1 10092 constraints = [],
-1 10093 i;
-1 10094
-1 10095 if (options.wireframes) {
-1 10096 RenderPixi.setBackground(render, options.wireframeBackground);
-1 10097 } else {
-1 10098 RenderPixi.setBackground(render, options.background);
-1 10099 }
-1 10100
-1 10101 // handle bounds
-1 10102 var boundsWidth = render.bounds.max.x - render.bounds.min.x,
-1 10103 boundsHeight = render.bounds.max.y - render.bounds.min.y,
-1 10104 boundsScaleX = boundsWidth / render.options.width,
-1 10105 boundsScaleY = boundsHeight / render.options.height;
-1 10106
-1 10107 if (options.hasBounds) {
-1 10108 // Hide bodies that are not in view
-1 10109 for (i = 0; i < bodies.length; i++) {
-1 10110 var body = bodies[i];
-1 10111 body.render.sprite.visible = Bounds.overlaps(body.bounds, render.bounds);
-1 10112 }
-1 10113
-1 10114 // filter out constraints that are not in view
-1 10115 for (i = 0; i < allConstraints.length; i++) {
-1 10116 var constraint = allConstraints[i],
-1 10117 bodyA = constraint.bodyA,
-1 10118 bodyB = constraint.bodyB,
-1 10119 pointAWorld = constraint.pointA,
-1 10120 pointBWorld = constraint.pointB;
-1 10121
-1 10122 if (bodyA) pointAWorld = Vector.add(bodyA.position, constraint.pointA);
-1 10123 if (bodyB) pointBWorld = Vector.add(bodyB.position, constraint.pointB);
-1 10124
-1 10125 if (!pointAWorld || !pointBWorld)
-1 10126 continue;
-1 10127
-1 10128 if (Bounds.contains(render.bounds, pointAWorld) || Bounds.contains(render.bounds, pointBWorld))
-1 10129 constraints.push(constraint);
-1 10130 }
-1 10131
-1 10132 // transform the view
-1 10133 container.scale.set(1 / boundsScaleX, 1 / boundsScaleY);
-1 10134 container.position.set(-render.bounds.min.x * (1 / boundsScaleX), -render.bounds.min.y * (1 / boundsScaleY));
-1 10135 } else {
-1 10136 constraints = allConstraints;
-1 10137 }
-1 10138
-1 10139 for (i = 0; i < bodies.length; i++)
-1 10140 RenderPixi.body(render, bodies[i]);
-1 10141
-1 10142 for (i = 0; i < constraints.length; i++)
-1 10143 RenderPixi.constraint(render, constraints[i]);
-1 10144
-1 10145 renderer.render(container);
-1 10146 };
-1 10147
-1 10148
-1 10149 /**
-1 10150 * Description
-1 10151 * @method constraint
-1 10152 * @param {engine} engine
-1 10153 * @param {constraint} constraint
-1 10154 * @deprecated
-1 10155 */
-1 10156 RenderPixi.constraint = function(render, constraint) {
-1 10157 var engine = render.engine,
-1 10158 bodyA = constraint.bodyA,
-1 10159 bodyB = constraint.bodyB,
-1 10160 pointA = constraint.pointA,
-1 10161 pointB = constraint.pointB,
-1 10162 container = render.container,
-1 10163 constraintRender = constraint.render,
-1 10164 primitiveId = 'c-' + constraint.id,
-1 10165 primitive = render.primitives[primitiveId];
-1 10166
-1 10167 // initialise constraint primitive if not existing
-1 10168 if (!primitive)
-1 10169 primitive = render.primitives[primitiveId] = new PIXI.Graphics();
-1 10170
-1 10171 // don't render if constraint does not have two end points
-1 10172 if (!constraintRender.visible || !constraint.pointA || !constraint.pointB) {
-1 10173 primitive.clear();
-1 10174 return;
-1 10175 }
-1 10176
-1 10177 // add to scene graph if not already there
-1 10178 if (Common.indexOf(container.children, primitive) === -1)
-1 10179 container.addChild(primitive);
-1 10180
-1 10181 // render the constraint on every update, since they can change dynamically
-1 10182 primitive.clear();
-1 10183 primitive.beginFill(0, 0);
-1 10184 primitive.lineStyle(constraintRender.lineWidth, Common.colorToNumber(constraintRender.strokeStyle), 1);
-1 10185
-1 10186 if (bodyA) {
-1 10187 primitive.moveTo(bodyA.position.x + pointA.x, bodyA.position.y + pointA.y);
-1 10188 } else {
-1 10189 primitive.moveTo(pointA.x, pointA.y);
-1 10190 }
-1 10191
-1 10192 if (bodyB) {
-1 10193 primitive.lineTo(bodyB.position.x + pointB.x, bodyB.position.y + pointB.y);
-1 10194 } else {
-1 10195 primitive.lineTo(pointB.x, pointB.y);
-1 10196 }
-1 10197
-1 10198 primitive.endFill();
-1 10199 };
-1 10200
-1 10201 /**
-1 10202 * Description
-1 10203 * @method body
-1 10204 * @param {engine} engine
-1 10205 * @param {body} body
-1 10206 * @deprecated
-1 10207 */
-1 10208 RenderPixi.body = function(render, body) {
-1 10209 var engine = render.engine,
-1 10210 bodyRender = body.render;
-1 10211
-1 10212 if (!bodyRender.visible)
-1 10213 return;
-1 10214
-1 10215 if (bodyRender.sprite && bodyRender.sprite.texture) {
-1 10216 var spriteId = 'b-' + body.id,
-1 10217 sprite = render.sprites[spriteId],
-1 10218 spriteContainer = render.spriteContainer;
-1 10219
-1 10220 // initialise body sprite if not existing
-1 10221 if (!sprite)
-1 10222 sprite = render.sprites[spriteId] = _createBodySprite(render, body);
-1 10223
-1 10224 // add to scene graph if not already there
-1 10225 if (Common.indexOf(spriteContainer.children, sprite) === -1)
-1 10226 spriteContainer.addChild(sprite);
-1 10227
-1 10228 // update body sprite
-1 10229 sprite.position.x = body.position.x;
-1 10230 sprite.position.y = body.position.y;
-1 10231 sprite.rotation = body.angle;
-1 10232 sprite.scale.x = bodyRender.sprite.xScale || 1;
-1 10233 sprite.scale.y = bodyRender.sprite.yScale || 1;
-1 10234 } else {
-1 10235 var primitiveId = 'b-' + body.id,
-1 10236 primitive = render.primitives[primitiveId],
-1 10237 container = render.container;
-1 10238
-1 10239 // initialise body primitive if not existing
-1 10240 if (!primitive) {
-1 10241 primitive = render.primitives[primitiveId] = _createBodyPrimitive(render, body);
-1 10242 primitive.initialAngle = body.angle;
-1 10243 }
-1 10244
-1 10245 // add to scene graph if not already there
-1 10246 if (Common.indexOf(container.children, primitive) === -1)
-1 10247 container.addChild(primitive);
-1 10248
-1 10249 // update body primitive
-1 10250 primitive.position.x = body.position.x;
-1 10251 primitive.position.y = body.position.y;
-1 10252 primitive.rotation = body.angle - primitive.initialAngle;
-1 10253 }
-1 10254 };
-1 10255
-1 10256 /**
-1 10257 * Creates a body sprite
-1 10258 * @method _createBodySprite
-1 10259 * @private
-1 10260 * @param {RenderPixi} render
-1 10261 * @param {body} body
-1 10262 * @return {PIXI.Sprite} sprite
-1 10263 * @deprecated
-1 10264 */
-1 10265 var _createBodySprite = function(render, body) {
-1 10266 var bodyRender = body.render,
-1 10267 texturePath = bodyRender.sprite.texture,
-1 10268 texture = _getTexture(render, texturePath),
-1 10269 sprite = new PIXI.Sprite(texture);
-1 10270
-1 10271 sprite.anchor.x = body.render.sprite.xOffset;
-1 10272 sprite.anchor.y = body.render.sprite.yOffset;
-1 10273
-1 10274 return sprite;
-1 10275 };
-1 10276
-1 10277 /**
-1 10278 * Creates a body primitive
-1 10279 * @method _createBodyPrimitive
-1 10280 * @private
-1 10281 * @param {RenderPixi} render
-1 10282 * @param {body} body
-1 10283 * @return {PIXI.Graphics} graphics
-1 10284 * @deprecated
-1 10285 */
-1 10286 var _createBodyPrimitive = function(render, body) {
-1 10287 var bodyRender = body.render,
-1 10288 options = render.options,
-1 10289 primitive = new PIXI.Graphics(),
-1 10290 fillStyle = Common.colorToNumber(bodyRender.fillStyle),
-1 10291 strokeStyle = Common.colorToNumber(bodyRender.strokeStyle),
-1 10292 strokeStyleIndicator = Common.colorToNumber(bodyRender.strokeStyle),
-1 10293 strokeStyleWireframe = Common.colorToNumber('#bbb'),
-1 10294 strokeStyleWireframeIndicator = Common.colorToNumber('#CD5C5C'),
-1 10295 part;
-1 10296
-1 10297 primitive.clear();
-1 10298
-1 10299 // handle compound parts
-1 10300 for (var k = body.parts.length > 1 ? 1 : 0; k < body.parts.length; k++) {
-1 10301 part = body.parts[k];
-1 10302
-1 10303 if (!options.wireframes) {
-1 10304 primitive.beginFill(fillStyle, 1);
-1 10305 primitive.lineStyle(bodyRender.lineWidth, strokeStyle, 1);
-1 10306 } else {
-1 10307 primitive.beginFill(0, 0);
-1 10308 primitive.lineStyle(1, strokeStyleWireframe, 1);
-1 10309 }
-1 10310
-1 10311 primitive.moveTo(part.vertices[0].x - body.position.x, part.vertices[0].y - body.position.y);
-1 10312
-1 10313 for (var j = 1; j < part.vertices.length; j++) {
-1 10314 primitive.lineTo(part.vertices[j].x - body.position.x, part.vertices[j].y - body.position.y);
-1 10315 }
-1 10316
-1 10317 primitive.lineTo(part.vertices[0].x - body.position.x, part.vertices[0].y - body.position.y);
-1 10318
-1 10319 primitive.endFill();
-1 10320
-1 10321 // angle indicator
-1 10322 if (options.showAngleIndicator || options.showAxes) {
-1 10323 primitive.beginFill(0, 0);
-1 10324
-1 10325 if (options.wireframes) {
-1 10326 primitive.lineStyle(1, strokeStyleWireframeIndicator, 1);
-1 10327 } else {
-1 10328 primitive.lineStyle(1, strokeStyleIndicator);
-1 10329 }
-1 10330
-1 10331 primitive.moveTo(part.position.x - body.position.x, part.position.y - body.position.y);
-1 10332 primitive.lineTo(((part.vertices[0].x + part.vertices[part.vertices.length-1].x) / 2 - body.position.x),
-1 10333 ((part.vertices[0].y + part.vertices[part.vertices.length-1].y) / 2 - body.position.y));
-1 10334
-1 10335 primitive.endFill();
-1 10336 }
-1 10337 }
-1 10338
-1 10339 return primitive;
-1 10340 };
-1 10341
-1 10342 /**
-1 10343 * Gets the requested texture (a PIXI.Texture) via its path
-1 10344 * @method _getTexture
-1 10345 * @private
-1 10346 * @param {RenderPixi} render
-1 10347 * @param {string} imagePath
-1 10348 * @return {PIXI.Texture} texture
-1 10349 * @deprecated
-1 10350 */
-1 10351 var _getTexture = function(render, imagePath) {
-1 10352 var texture = render.textures[imagePath];
-1 10353
-1 10354 if (!texture)
-1 10355 texture = render.textures[imagePath] = PIXI.Texture.fromImage(imagePath);
-1 10356
-1 10357 return texture;
-1 10358 };
-1 10359
-1 10360 })();
-1 10361
-1 10362 },{"../body/Composite":2,"../core/Common":14,"../core/Events":16,"../geometry/Bounds":26,"../geometry/Vector":28}]},{},[30])(30)
-1 10363 });
-1 10364
-1 10365 }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
-1 10366 },{}],2:[function(require,module,exports){
-1 10367 var Matter = require('matter-js');
-1 10368
-1 10369 var TILE_SIZE = 20;
-1 10370 var WIDTH = 10 * TILE_SIZE;
-1 10371 var HEIGHT = 30 * TILE_SIZE;
-1 10372
-1 10373 var BLOCKS = [{
-1 10374 label: 'I',
-1 10375 color: 'cyan',
-1 10376 points: [{x: -2, y: 0}, {x: -1, y: 0}, {x: 0, y: 0}, {x: 1, y: 0}],
-1 10377 }, {
-1 10378 label: 'J',
-1 10379 color: 'blue',
-1 10380 points: [{x: -2, y: 0}, {x: -1, y: 0}, {x: 0, y: 0}, {x: 0, y: 1}],
-1 10381 }, {
-1 10382 label: 'L',
-1 10383 color: 'orange',
-1 10384 points: [{x: -1, y: 0}, {x: 0, y: 0}, {x: 1, y: 0}, {x: -1, y: 1}],
-1 10385 }, {
-1 10386 label: 'O',
-1 10387 color: 'yellow',
-1 10388 points: [{x: -1, y: 0}, {x: 0, y: 0}, {x: -1, y: 1}, {x: 0, y: 1}],
-1 10389 }, {
-1 10390 label: 'S',
-1 10391 color: 'green',
-1 10392 points: [{x: 0, y: 0}, {x: 1, y: 0}, {x: -1, y: 1}, {x: 0, y: 1}],
-1 10393 }, {
-1 10394 label: 'T',
-1 10395 color: 'purple',
-1 10396 points: [{x: -1, y: 0}, {x: 0, y: 0}, {x: 1, y: 0}, {x: 0, y: 1}],
-1 10397 }, {
-1 10398 label: 'Z',
-1 10399 color: 'red',
-1 10400 points: [{x: -1, y: 0}, {x: 0, y: 0}, {x: 0, y: 1}, {x: 1, y: 1}],
-1 10401 }];
-1 10402
-1 10403 var engine = Matter.Engine.create();
-1 10404 var runner = Matter.Runner.create();
-1 10405
-1 10406 var ground = Matter.Bodies.rectangle(WIDTH / 2, HEIGHT + 50, WIDTH, 100, {isStatic: true});
-1 10407 Matter.World.add(engine.world, [ground]);
-1 10408
-1 10409 var falling;
-1 10410 var control = true;
-1 10411
-1 10412 var spawn = function() {
-1 10413 var block = BLOCKS[Math.floor(Math.random() * BLOCKS.length)];
-1 10414 var parts = block.points.map(function(d) {
-1 10415 return Matter.Bodies.rectangle(
-1 10416 WIDTH / 2 + d.x * TILE_SIZE,
-1 10417 d.y * TILE_SIZE,
-1 10418 TILE_SIZE,
-1 10419 TILE_SIZE,
-1 10420 {render: {fillStyle: block.color}});
-1 10421 });
-1 10422 falling = Matter.Body.create({
-1 10423 density: 0.001,
-1 10424 friction: 0.1,
-1 10425 restitution: 0,
-1 10426 parts: parts,
-1 10427 });
-1 10428 control = true;
-1 10429 Matter.World.add(engine.world, [falling]);
-1 10430 };
-1 10431
-1 10432 Matter.Events.on(engine, 'collisionStart', function(event) {
-1 10433 event.pairs.forEach(function(pair) {
-1 10434 if (falling.parts.includes(pair.bodyA) ||
-1 10435 falling.parts.includes(pair.bodyB)) {
-1 10436 spawn();
-1 10437 }
-1 10438 });
-1 10439 });
-1 10440
-1 10441 var previousTimestamp;
-1 10442 Matter.Events.on(engine, 'beforeUpdate', function(event) {
-1 10443 if (previousTimestamp && control) {
-1 10444 var dt = event.timestamp - previousTimestamp;
-1 10445 var dy = dt * 0.1;
-1 10446 Matter.Body.setVelocity(falling, {x: 0, y: dy});
-1 10447 Matter.Body.setPosition(falling, {
-1 10448 x: falling.position.x,
-1 10449 y: falling.position.y + dy,
-1 10450 });
-1 10451 }
-1 10452 previousTimestamp = event.timestamp;
-1 10453 });
-1 10454
-1 10455 Matter.Events.on(engine, 'afterUpdate', function() {
-1 10456 var allBodies = Matter.Composite.allBodies(engine.world);
-1 10457 allBodies.forEach(function(body) {
-1 10458 if (!body.isStatic && body.position.y > HEIGHT) {
-1 10459 Matter.Composite.remove(engine.world, body, true);
-1 10460 if (body == falling) {
-1 10461 spawn();
-1 10462 }
-1 10463 }
-1 10464 });
-1 10465 });
-1 10466
-1 10467 document.addEventListener('keydown', function(event) {
-1 10468 if (event.key == 'ArrowLeft') {
-1 10469 event.preventDefault();
-1 10470 Matter.Body.setPosition(falling, {
-1 10471 x: falling.position.x - TILE_SIZE / 2,
-1 10472 y: falling.position.y,
-1 10473 });
-1 10474 } else if (event.key == 'ArrowRight') {
-1 10475 event.preventDefault();
-1 10476 Matter.Body.setPosition(falling, {
-1 10477 x: falling.position.x + TILE_SIZE / 2,
-1 10478 y: falling.position.y,
-1 10479 });
-1 10480 } else if (event.key == 'ArrowUp') {
-1 10481 event.preventDefault();
-1 10482 Matter.Body.rotate(falling, -Math.PI / 2);
-1 10483 } else if (event.key == 'ArrowDown') {
-1 10484 event.preventDefault();
-1 10485 control = false;
-1 10486 Matter.Body.setVelocity(falling, {x: 0, y: falling.velocity.y * 2});
-1 10487 } else if (event.key == 'Escape') {
-1 10488 event.preventDefault();
-1 10489 Matter.Composite.clear(engine.world, true);
-1 10490 spawn();
-1 10491 } else if (event.key == 'p') {
-1 10492 event.preventDefault();
-1 10493 runner.enabled = !runner.enabled;
-1 10494 }
-1 10495 });
-1 10496
-1 10497 document.addEventListener('DOMContentLoaded', function() {
-1 10498 var render = Matter.Render.create({
-1 10499 element: document.body,
-1 10500 engine: engine,
-1 10501 options: {
-1 10502 width: WIDTH,
-1 10503 height: HEIGHT,
-1 10504 wireframes: false,
-1 10505 },
-1 10506 });
-1 10507 Matter.Render.run(render);
-1 10508 Matter.Runner.run(runner, engine);
-1 10509
-1 10510 render.canvas.style.background = 'linear-gradient(90deg, transparent 50%, rgba(255,255,255,.5) 50%)';
-1 10511 render.canvas.style.backgroundSize = TILE_SIZE * 2 + 'px';
-1 10512
-1 10513 spawn();
-1 10514 }, 100);
-1 10515
-1 10516 },{"matter-js":1}]},{},[2]);
diff --git a/docs/index.html b/docs/index.html
@@ -0,0 +1,16 @@
-1 1 <!DOCTYPE html>
-1 2 <meta charset="utf-8" />
-1 3 <meta name="viewport" content="width=device-width">
-1 4 <title>Tricky Towers</title>
-1 5 <style type="text/css">body{margin: 2em auto; max-width: 38em; line-height: 1.5; color: #333; padding: 0 1em} h1, h2, h3 {line-height: 1.2}</style>
-1 6 <h1 id="tricky-towers">Tricky Towers</h1>
-1 7 <p>This is a simple <a href="http://trickytowers.com/">tricky towers</a> clone using <a href="http://brm.io/matter-js/">matter.js</a>. If you do not know the game: It is basically tetris with physics.</p>
-1 8 <h2 id="controls">Controls</h2>
-1 9 <ul>
-1 10 <li>Left/Right/Up/Down - control falling block</li>
-1 11 <li>P - pause</li>
-1 12 <li>Esc - Restart</li>
-1 13 </ul>
-1 14 <h2 id="code">Code</h2>
-1 15 <p><a href="https://github.com/xi/trickytowers" class="uri">https://github.com/xi/trickytowers</a></p>
-1 16 <script src="./build.js"></script>