mirror of
https://github.com/liabru/matter-js.git
synced 2024-11-27 09:50:52 -05:00
updated builds, note that "matter.js" is now the edge build
This commit is contained in:
parent
62ad79fa2c
commit
d626793887
6 changed files with 4635 additions and 98 deletions
|
@ -1,5 +1,5 @@
|
||||||
/**
|
/**
|
||||||
* Matter.js 0.5.0 2014-02-28
|
* matter-0.5.0.js 0.5.0-alpha 2014-02-28
|
||||||
* http://brm.io/matter-js/
|
* http://brm.io/matter-js/
|
||||||
* License: MIT
|
* License: MIT
|
||||||
*/
|
*/
|
8
build/matter-0.5.0.min.js
vendored
Normal file
8
build/matter-0.5.0.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
488
build/matter.js
488
build/matter.js
|
@ -1,5 +1,5 @@
|
||||||
/**
|
/**
|
||||||
* Matter.js 0.5.0 2014-02-28
|
* matter.js 0.5.0-edge 2014-03-11
|
||||||
* http://brm.io/matter-js/
|
* http://brm.io/matter-js/
|
||||||
* License: MIT
|
* License: MIT
|
||||||
*/
|
*/
|
||||||
|
@ -155,19 +155,30 @@ var Body = {};
|
||||||
* Description
|
* Description
|
||||||
* @method resetForcesAll
|
* @method resetForcesAll
|
||||||
* @param {body[]} bodies
|
* @param {body[]} bodies
|
||||||
* @param {vector} gravity
|
|
||||||
*/
|
*/
|
||||||
Body.resetForcesAll = function(bodies, gravity) {
|
Body.resetForcesAll = function(bodies) {
|
||||||
for (var i = 0; i < bodies.length; i++) {
|
for (var i = 0; i < bodies.length; i++) {
|
||||||
var body = bodies[i];
|
var body = bodies[i];
|
||||||
|
|
||||||
if (body.isStatic || body.isSleeping)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// reset force buffers
|
// reset force buffers
|
||||||
body.force.x = 0;
|
body.force.x = 0;
|
||||||
body.force.y = 0;
|
body.force.y = 0;
|
||||||
body.torque = 0;
|
body.torque = 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description
|
||||||
|
* @method applyGravityAll
|
||||||
|
* @param {body[]} bodies
|
||||||
|
* @param {vector} gravity
|
||||||
|
*/
|
||||||
|
Body.applyGravityAll = function(bodies, gravity) {
|
||||||
|
for (var i = 0; i < bodies.length; i++) {
|
||||||
|
var body = bodies[i];
|
||||||
|
|
||||||
|
if (body.isStatic || body.isSleeping)
|
||||||
|
continue;
|
||||||
|
|
||||||
// apply gravity
|
// apply gravity
|
||||||
body.force.y += body.mass * gravity.y * 0.001;
|
body.force.y += body.mass * gravity.y * 0.001;
|
||||||
|
@ -913,77 +924,112 @@ var Manager = {};
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
|
||||||
var _pairMaxIdleLife = 500;
|
var _pairMaxIdleLife = 1000;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Description
|
* Description
|
||||||
* @method updatePairs
|
* @method updatePairs
|
||||||
* @param {object} pairs
|
* @param {object} pairs
|
||||||
* @param {pair[]} pairsList
|
* @param {collision[]} collisions
|
||||||
* @param {pair[]} candidatePairs
|
|
||||||
* @param {metrics} metrics
|
|
||||||
* @param {detector} detector
|
|
||||||
* @return {bool} pairsUpdated flag
|
|
||||||
*/
|
*/
|
||||||
Manager.updatePairs = function(pairs, pairsList, candidatePairs, metrics, detector) {
|
Manager.updatePairs = function(pairs, collisions) {
|
||||||
var i;
|
var pairsList = pairs.list,
|
||||||
|
pairsTable = pairs.table,
|
||||||
|
collisionStart = pairs.collisionStart,
|
||||||
|
collisionEnd = pairs.collisionEnd,
|
||||||
|
collisionActive = pairs.collisionActive,
|
||||||
|
activePairIds = [],
|
||||||
|
collision,
|
||||||
|
pairId,
|
||||||
|
pair,
|
||||||
|
i;
|
||||||
|
|
||||||
// first set all pairs inactive
|
// clear collision state arrays, but maintain old reference
|
||||||
for (i = 0; i < pairsList.length; i++) {
|
collisionStart.length = 0;
|
||||||
var pair = pairsList[i];
|
collisionEnd.length = 0;
|
||||||
Pair.setActive(pair, false);
|
collisionActive.length = 0;
|
||||||
}
|
|
||||||
|
|
||||||
// detect collisions in current step
|
|
||||||
var pairsUpdated = false,
|
|
||||||
collisions = detector(candidatePairs, metrics);
|
|
||||||
|
|
||||||
// set collision pairs to active, or create if pair is new
|
|
||||||
for (i = 0; i < collisions.length; i++) {
|
for (i = 0; i < collisions.length; i++) {
|
||||||
var collision = collisions[i],
|
collision = collisions[i];
|
||||||
|
|
||||||
|
if (collision.collided) {
|
||||||
pairId = Pair.id(collision.bodyA, collision.bodyB);
|
pairId = Pair.id(collision.bodyA, collision.bodyB);
|
||||||
|
activePairIds.push(pairId);
|
||||||
|
|
||||||
if (pairId in pairs) {
|
if (pairId in pairsTable) {
|
||||||
Pair.update(pairs[pairId], collision);
|
// pair already exists (but may or may not be active)
|
||||||
|
pair = pairsTable[pairId];
|
||||||
|
|
||||||
|
if (pair.isActive) {
|
||||||
|
// pair exists and is active
|
||||||
|
collisionActive.push(pair);
|
||||||
} else {
|
} else {
|
||||||
pairs[pairId] = Pair.create(collision);
|
// pair exists but was inactive, so a collision has just started again
|
||||||
pairsUpdated = true;
|
collisionStart.push(pair);
|
||||||
|
}
|
||||||
|
|
||||||
|
// update the pair
|
||||||
|
Pair.update(pair, collision);
|
||||||
|
} else {
|
||||||
|
// pair did not exist, create a new pair
|
||||||
|
pair = Pair.create(collision);
|
||||||
|
pairsTable[pairId] = pair;
|
||||||
|
|
||||||
|
// push the new pair
|
||||||
|
collisionStart.push(pair);
|
||||||
|
pairsList.push(pair);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return pairsUpdated;
|
// deactivate previously active pairs that are now inactive
|
||||||
|
for (i = 0; i < pairsList.length; i++) {
|
||||||
|
pair = pairsList[i];
|
||||||
|
if (pair.isActive && activePairIds.indexOf(pair.id) === -1) {
|
||||||
|
Pair.setActive(pair, false);
|
||||||
|
collisionEnd.push(pair);
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Description
|
* Description
|
||||||
* @method removeOldPairs
|
* @method removeOldPairs
|
||||||
* @param {object} pairs
|
* @param {object} pairs
|
||||||
* @param {pair[]} pairsList
|
|
||||||
* @return {bool} pairsRemoved flag
|
|
||||||
*/
|
*/
|
||||||
Manager.removeOldPairs = function(pairs, pairsList) {
|
Manager.removeOldPairs = function(pairs) {
|
||||||
var timeNow = Common.now(),
|
var pairsList = pairs.list,
|
||||||
pairsRemoved = false,
|
pairsTable = pairs.table,
|
||||||
|
timeNow = Common.now(),
|
||||||
|
indexesToRemove = [],
|
||||||
|
pair,
|
||||||
|
collision,
|
||||||
|
pairIndex,
|
||||||
i;
|
i;
|
||||||
|
|
||||||
for (i = 0; i < pairsList.length; i++) {
|
for (i = 0; i < pairsList.length; i++) {
|
||||||
var pair = pairsList[i],
|
pair = pairsList[i];
|
||||||
collision = pair.collision;
|
collision = pair.collision;
|
||||||
|
|
||||||
// never remove sleeping pairs
|
// never remove sleeping pairs
|
||||||
if (collision.bodyA.isSleeping || collision.bodyB.isSleeping) {
|
if (collision.bodyA.isSleeping || collision.bodyB.isSleeping) {
|
||||||
pair.timestamp = timeNow;
|
pair.timeUpdated = timeNow;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if pair is inactive for too long, remove it
|
// if pair is inactive for too long, mark it to be removed
|
||||||
if (timeNow - pair.timestamp > _pairMaxIdleLife) {
|
if (timeNow - pair.timeUpdated > _pairMaxIdleLife) {
|
||||||
delete pairs[pair.id];
|
indexesToRemove.push(i);
|
||||||
pairsRemoved = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return pairsRemoved;
|
// remove marked pairs
|
||||||
|
for (i = 0; i < indexesToRemove.length; i++) {
|
||||||
|
pairIndex = indexesToRemove[i];
|
||||||
|
pair = pairsList[pairIndex];
|
||||||
|
delete pairsTable[pair.id];
|
||||||
|
pairsList.splice(pairIndex, 1);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
@ -1011,15 +1057,19 @@ var Pair = {};
|
||||||
*/
|
*/
|
||||||
Pair.create = function(collision) {
|
Pair.create = function(collision) {
|
||||||
var bodyA = collision.bodyA,
|
var bodyA = collision.bodyA,
|
||||||
bodyB = collision.bodyB;
|
bodyB = collision.bodyB,
|
||||||
|
timestamp = Common.now();
|
||||||
|
|
||||||
var pair = {
|
var pair = {
|
||||||
id: Pair.id(bodyA, bodyB),
|
id: Pair.id(bodyA, bodyB),
|
||||||
|
bodyA: bodyA,
|
||||||
|
bodyB: bodyB,
|
||||||
contacts: {},
|
contacts: {},
|
||||||
activeContacts: [],
|
activeContacts: [],
|
||||||
separation: 0,
|
separation: 0,
|
||||||
isActive: true,
|
isActive: true,
|
||||||
timestamp: Common.now(),
|
timeCreated: timestamp,
|
||||||
|
timeUpdated: timestamp,
|
||||||
inverseMass: bodyA.inverseMass + bodyB.inverseMass,
|
inverseMass: bodyA.inverseMass + bodyB.inverseMass,
|
||||||
friction: Math.min(bodyA.friction, bodyB.friction),
|
friction: Math.min(bodyA.friction, bodyB.friction),
|
||||||
restitution: Math.max(bodyA.restitution, bodyB.restitution),
|
restitution: Math.max(bodyA.restitution, bodyB.restitution),
|
||||||
|
@ -1073,7 +1123,7 @@ var Pair = {};
|
||||||
Pair.setActive = function(pair, isActive) {
|
Pair.setActive = function(pair, isActive) {
|
||||||
if (isActive) {
|
if (isActive) {
|
||||||
pair.isActive = true;
|
pair.isActive = true;
|
||||||
pair.timestamp = Common.now();
|
pair.timeUpdated = Common.now();
|
||||||
} else {
|
} else {
|
||||||
pair.isActive = false;
|
pair.isActive = false;
|
||||||
pair.activeContacts = [];
|
pair.activeContacts = [];
|
||||||
|
@ -1902,21 +1952,34 @@ var Common = {};
|
||||||
/**
|
/**
|
||||||
* Description
|
* Description
|
||||||
* @method extend
|
* @method extend
|
||||||
* @param {} obj, obj, obj...
|
* @param {} obj
|
||||||
|
* @param {boolean} deep
|
||||||
* @return {} obj extended
|
* @return {} obj extended
|
||||||
*/
|
*/
|
||||||
Common.extend = function(obj) {
|
Common.extend = function(obj, deep) {
|
||||||
var args = Array.prototype.slice.call(arguments, 1);
|
var argsStart,
|
||||||
|
args,
|
||||||
|
deepClone;
|
||||||
|
|
||||||
|
if (typeof deep === 'boolean') {
|
||||||
|
argsStart = 2;
|
||||||
|
deepClone = deep;
|
||||||
|
} else {
|
||||||
|
argsStart = 1;
|
||||||
|
deepClone = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
args = Array.prototype.slice.call(arguments, argsStart);
|
||||||
|
|
||||||
for (var i = 0; i < args.length; i++) {
|
for (var i = 0; i < args.length; i++) {
|
||||||
var source = args[i];
|
var source = args[i];
|
||||||
|
|
||||||
if (source) {
|
if (source) {
|
||||||
for (var prop in source) {
|
for (var prop in source) {
|
||||||
if (source[prop].constructor === Object) {
|
if (deepClone && source[prop].constructor === Object) {
|
||||||
if (!obj[prop] || obj[prop].constructor === Object) {
|
if (!obj[prop] || obj[prop].constructor === Object) {
|
||||||
obj[prop] = obj[prop] || {};
|
obj[prop] = obj[prop] || {};
|
||||||
Common.extend(obj[prop], source[prop]);
|
Common.extend(obj[prop], deepClone, source[prop]);
|
||||||
} else {
|
} else {
|
||||||
obj[prop] = source[prop];
|
obj[prop] = source[prop];
|
||||||
}
|
}
|
||||||
|
@ -1930,6 +1993,17 @@ var Common = {};
|
||||||
return obj;
|
return obj;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new clone of the object, if deep is true references will also be cloned
|
||||||
|
* @method clone
|
||||||
|
* @param {} obj
|
||||||
|
* @param {bool} deep
|
||||||
|
* @return {} obj cloned
|
||||||
|
*/
|
||||||
|
Common.clone = function(obj, deep) {
|
||||||
|
return Common.extend({}, deep, obj);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Description
|
* Description
|
||||||
* @method keys
|
* @method keys
|
||||||
|
@ -2123,11 +2197,17 @@ var Engine = {};
|
||||||
positionIterations: 6,
|
positionIterations: 6,
|
||||||
velocityIterations: 4,
|
velocityIterations: 4,
|
||||||
constraintIterations: 1,
|
constraintIterations: 1,
|
||||||
pairs: {},
|
pairs: {
|
||||||
pairsList: [],
|
table: {},
|
||||||
|
list: [],
|
||||||
|
collisionStart: [],
|
||||||
|
collisionActive: [],
|
||||||
|
collisionEnd: []
|
||||||
|
},
|
||||||
enableSleeping: false,
|
enableSleeping: false,
|
||||||
timeScale: 1,
|
timeScale: 1,
|
||||||
input: {},
|
input: {},
|
||||||
|
events: [],
|
||||||
timing: {
|
timing: {
|
||||||
fps: _fps,
|
fps: _fps,
|
||||||
timestamp: 0,
|
timestamp: 0,
|
||||||
|
@ -2167,16 +2247,6 @@ var Engine = {};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
engine.events = {
|
|
||||||
tick: function(engine) {
|
|
||||||
Engine.update(engine, engine.timing.delta, engine.timing.correction);
|
|
||||||
},
|
|
||||||
render: function(engine) {
|
|
||||||
if (engine.render.options.enabled)
|
|
||||||
engine.render.controller.world(engine);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return engine;
|
return engine;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2188,6 +2258,7 @@ var Engine = {};
|
||||||
Engine.run = function(engine) {
|
Engine.run = function(engine) {
|
||||||
var timing = engine.timing,
|
var timing = engine.timing,
|
||||||
delta,
|
delta,
|
||||||
|
correction,
|
||||||
counterTimestamp = 0,
|
counterTimestamp = 0,
|
||||||
frameCounter = 0,
|
frameCounter = 0,
|
||||||
deltaHistory = [];
|
deltaHistory = [];
|
||||||
|
@ -2198,6 +2269,22 @@ var Engine = {};
|
||||||
if (!engine.enabled)
|
if (!engine.enabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// create an event object
|
||||||
|
var event = {
|
||||||
|
timestamp: timestamp
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fired at the start of a tick, before any updates to the engine or timing
|
||||||
|
*
|
||||||
|
* @event beforeTick
|
||||||
|
* @param {} event An event object
|
||||||
|
* @param {DOMHighResTimeStamp} event.timestamp The timestamp of the current tick
|
||||||
|
* @param {} event.source The source object of the event
|
||||||
|
* @param {} event.name The name of the event
|
||||||
|
*/
|
||||||
|
Events.trigger(engine, 'beforeTick', event);
|
||||||
|
|
||||||
delta = (timestamp - timing.timestamp) || _delta;
|
delta = (timestamp - timing.timestamp) || _delta;
|
||||||
|
|
||||||
// optimistically filter delta over a few frames, to improve stability
|
// optimistically filter delta over a few frames, to improve stability
|
||||||
|
@ -2209,20 +2296,138 @@ var Engine = {};
|
||||||
delta = delta < engine.timing.deltaMin ? engine.timing.deltaMin : delta;
|
delta = delta < engine.timing.deltaMin ? engine.timing.deltaMin : delta;
|
||||||
delta = delta > engine.timing.deltaMax ? engine.timing.deltaMax : delta;
|
delta = delta > engine.timing.deltaMax ? engine.timing.deltaMax : delta;
|
||||||
|
|
||||||
|
// verlet time correction
|
||||||
|
correction = delta / timing.delta;
|
||||||
|
|
||||||
|
// update engine timing object
|
||||||
timing.timestamp = timestamp;
|
timing.timestamp = timestamp;
|
||||||
timing.correction = delta / timing.delta;
|
timing.correction = correction;
|
||||||
timing.delta = delta;
|
timing.delta = delta;
|
||||||
|
|
||||||
|
// fps counter
|
||||||
frameCounter += 1;
|
frameCounter += 1;
|
||||||
|
|
||||||
if (timestamp - counterTimestamp >= 1000) {
|
if (timestamp - counterTimestamp >= 1000) {
|
||||||
timing.fps = frameCounter * ((timestamp - counterTimestamp) / 1000);
|
timing.fps = frameCounter * ((timestamp - counterTimestamp) / 1000);
|
||||||
counterTimestamp = timestamp;
|
counterTimestamp = timestamp;
|
||||||
frameCounter = 0;
|
frameCounter = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
engine.events.tick(engine);
|
/**
|
||||||
engine.events.render(engine);
|
* Fired after engine timing updated, but just before engine state updated
|
||||||
|
*
|
||||||
|
* @event tick
|
||||||
|
* @param {} event An event object
|
||||||
|
* @param {DOMHighResTimeStamp} event.timestamp The timestamp of the current tick
|
||||||
|
* @param {} event.source The source object of the event
|
||||||
|
* @param {} event.name The name of the event
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Fired just before an update
|
||||||
|
*
|
||||||
|
* @event beforeUpdate
|
||||||
|
* @param {} event An event object
|
||||||
|
* @param {DOMHighResTimeStamp} event.timestamp The timestamp of the current tick
|
||||||
|
* @param {} event.source The source object of the event
|
||||||
|
* @param {} event.name The name of the event
|
||||||
|
*/
|
||||||
|
Events.trigger(engine, 'tick beforeUpdate', event);
|
||||||
|
|
||||||
|
// update
|
||||||
|
Engine.update(engine, delta, correction);
|
||||||
|
|
||||||
|
var pairs = engine.pairs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fired after engine update, provides a list of all pairs that have started to collide in the current tick (if any)
|
||||||
|
*
|
||||||
|
* @event collisionStart
|
||||||
|
* @param {} event An event object
|
||||||
|
* @param {} event.pairs List of affected pairs
|
||||||
|
* @param {DOMHighResTimeStamp} event.timestamp The timestamp of the current tick
|
||||||
|
* @param {} event.source The source object of the event
|
||||||
|
* @param {} event.name The name of the event
|
||||||
|
*/
|
||||||
|
if (pairs.collisionStart.length > 0) {
|
||||||
|
Events.trigger(engine, 'collisionStart', {
|
||||||
|
pairs: pairs.collisionStart
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fired after engine update, provides a list of all pairs that are colliding in the current tick (if any)
|
||||||
|
*
|
||||||
|
* @event collisionActive
|
||||||
|
* @param {} event An event object
|
||||||
|
* @param {} event.pairs List of affected pairs
|
||||||
|
* @param {DOMHighResTimeStamp} event.timestamp The timestamp of the current tick
|
||||||
|
* @param {} event.source The source object of the event
|
||||||
|
* @param {} event.name The name of the event
|
||||||
|
*/
|
||||||
|
if (pairs.collisionActive.length > 0) {
|
||||||
|
Events.trigger(engine, 'collisionActive', {
|
||||||
|
pairs: pairs.collisionActive
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fired after engine update, provides a list of all pairs that have ended collision in the current tick (if any)
|
||||||
|
*
|
||||||
|
* @event collisionEnd
|
||||||
|
* @param {} event An event object
|
||||||
|
* @param {} event.pairs List of affected pairs
|
||||||
|
* @param {DOMHighResTimeStamp} event.timestamp The timestamp of the current tick
|
||||||
|
* @param {} event.source The source object of the event
|
||||||
|
* @param {} event.name The name of the event
|
||||||
|
*/
|
||||||
|
if (pairs.collisionEnd.length > 0) {
|
||||||
|
Events.trigger(engine, 'collisionEnd', {
|
||||||
|
pairs: pairs.collisionEnd
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fired after engine update and all collision events
|
||||||
|
*
|
||||||
|
* @event afterUpdate
|
||||||
|
* @param {} event An event object
|
||||||
|
* @param {DOMHighResTimeStamp} event.timestamp The timestamp of the current tick
|
||||||
|
* @param {} event.source The source object of the event
|
||||||
|
* @param {} event.name The name of the event
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Fired just before rendering
|
||||||
|
*
|
||||||
|
* @event beforeRender
|
||||||
|
* @param {} event An event object
|
||||||
|
* @param {DOMHighResTimeStamp} event.timestamp The timestamp of the current tick
|
||||||
|
* @param {} event.source The source object of the event
|
||||||
|
* @param {} event.name The name of the event
|
||||||
|
*/
|
||||||
|
Events.trigger(engine, 'afterUpdate beforeRender', event);
|
||||||
|
|
||||||
|
// render
|
||||||
|
if (engine.render.options.enabled)
|
||||||
|
engine.render.controller.world(engine);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fired after rendering
|
||||||
|
*
|
||||||
|
* @event afterRender
|
||||||
|
* @param {} event An event object
|
||||||
|
* @param {DOMHighResTimeStamp} event.timestamp The timestamp of the current tick
|
||||||
|
* @param {} event.source The source object of the event
|
||||||
|
* @param {} event.name The name of the event
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Fired after engine update and after rendering
|
||||||
|
*
|
||||||
|
* @event afterTick
|
||||||
|
* @param {} event An event object
|
||||||
|
* @param {DOMHighResTimeStamp} event.timestamp The timestamp of the current tick
|
||||||
|
* @param {} event.source The source object of the event
|
||||||
|
* @param {} event.name The name of the event
|
||||||
|
*/
|
||||||
|
Events.trigger(engine, 'afterTick afterRender', event);
|
||||||
})();
|
})();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2240,16 +2445,23 @@ var Engine = {};
|
||||||
broadphasePairs = [],
|
broadphasePairs = [],
|
||||||
i;
|
i;
|
||||||
|
|
||||||
Body.resetForcesAll(world.bodies, world.gravity);
|
|
||||||
Metrics.reset(engine.metrics);
|
Metrics.reset(engine.metrics);
|
||||||
|
|
||||||
|
if (engine.enableSleeping)
|
||||||
|
Sleeping.update(world.bodies);
|
||||||
|
|
||||||
|
Body.applyGravityAll(world.bodies, world.gravity);
|
||||||
|
|
||||||
MouseConstraint.update(engine.mouseConstraint, world.bodies, engine.input);
|
MouseConstraint.update(engine.mouseConstraint, world.bodies, engine.input);
|
||||||
|
|
||||||
Body.updateAll(world.bodies, delta * engine.timeScale, correction, world.bounds);
|
Body.updateAll(world.bodies, delta * engine.timeScale, correction, world.bounds);
|
||||||
|
|
||||||
|
// update all constraints
|
||||||
for (i = 0; i < engine.constraintIterations; i++) {
|
for (i = 0; i < engine.constraintIterations; i++) {
|
||||||
Constraint.updateAll(world.constraints);
|
Constraint.updateAll(world.constraints);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// broadphase pass: find potential collision pairs
|
||||||
if (broadphase.controller) {
|
if (broadphase.controller) {
|
||||||
broadphase.controller.update(broadphase.instance, world.bodies, engine);
|
broadphase.controller.update(broadphase.instance, world.bodies, engine);
|
||||||
broadphasePairs = broadphase.instance.pairsList;
|
broadphasePairs = broadphase.instance.pairsList;
|
||||||
|
@ -2257,33 +2469,35 @@ var Engine = {};
|
||||||
broadphasePairs = world.bodies;
|
broadphasePairs = world.bodies;
|
||||||
}
|
}
|
||||||
|
|
||||||
var pairsUpdated = Manager.updatePairs(engine.pairs, engine.pairsList, broadphasePairs, engine.metrics, broadphase.detector),
|
// narrowphase pass: find actual collisions, then create or update collision pairs
|
||||||
pairsRemoved = Manager.removeOldPairs(engine.pairs, engine.pairsList);
|
var collisions = broadphase.detector(broadphasePairs, engine.metrics);
|
||||||
|
|
||||||
if (pairsUpdated || pairsRemoved)
|
// update pairs
|
||||||
engine.pairsList = Common.values(engine.pairs);
|
var pairs = engine.pairs;
|
||||||
|
Manager.updatePairs(pairs, collisions);
|
||||||
|
Manager.removeOldPairs(pairs);
|
||||||
|
|
||||||
// wake up bodies involved in collisions
|
// wake up bodies involved in collisions
|
||||||
if (engine.enableSleeping)
|
if (engine.enableSleeping)
|
||||||
Sleeping.afterCollisions(engine.pairsList);
|
Sleeping.afterCollisions(pairs.list);
|
||||||
|
|
||||||
// iteratively resolve velocity between collisions
|
// iteratively resolve velocity between collisions
|
||||||
Resolver.preSolveVelocity(engine.pairsList);
|
Resolver.preSolveVelocity(pairs.list);
|
||||||
for (i = 0; i < engine.velocityIterations; i++) {
|
for (i = 0; i < engine.velocityIterations; i++) {
|
||||||
Resolver.solveVelocity(engine.pairsList);
|
Resolver.solveVelocity(pairs.list);
|
||||||
}
|
}
|
||||||
|
|
||||||
// iteratively resolve position between collisions
|
// iteratively resolve position between collisions
|
||||||
for (i = 0; i < engine.positionIterations; i++) {
|
for (i = 0; i < engine.positionIterations; i++) {
|
||||||
Resolver.solvePosition(engine.pairsList);
|
Resolver.solvePosition(pairs.list);
|
||||||
}
|
}
|
||||||
Resolver.postSolvePosition(world.bodies);
|
Resolver.postSolvePosition(world.bodies);
|
||||||
|
|
||||||
if (engine.enableSleeping)
|
|
||||||
Sleeping.update(world.bodies);
|
|
||||||
|
|
||||||
Metrics.update(engine.metrics, engine);
|
Metrics.update(engine.metrics, engine);
|
||||||
|
|
||||||
|
// clear force buffers
|
||||||
|
Body.resetForcesAll(world.bodies);
|
||||||
|
|
||||||
return engine;
|
return engine;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2327,8 +2541,8 @@ var Engine = {};
|
||||||
Engine.clear = function(engine) {
|
Engine.clear = function(engine) {
|
||||||
var world = engine.world;
|
var world = engine.world;
|
||||||
|
|
||||||
engine.pairs = {};
|
engine.pairs.table = {};
|
||||||
engine.pairsList = [];
|
engine.pairs.list = [];
|
||||||
|
|
||||||
World.addComposite(engine.world, engine.mouseConstraint);
|
World.addComposite(engine.world, engine.mouseConstraint);
|
||||||
|
|
||||||
|
@ -2347,6 +2561,95 @@ var Engine = {};
|
||||||
; // End src/core/Engine.js
|
; // End src/core/Engine.js
|
||||||
|
|
||||||
|
|
||||||
|
// Begin src/core/Events.js
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See [Demo.js](https://github.com/liabru/matter-js/blob/master/demo/js/Demo.js)
|
||||||
|
* and [DemoMobile.js](https://github.com/liabru/matter-js/blob/master/demo/js/DemoMobile.js) for usage examples.
|
||||||
|
*
|
||||||
|
* @class Events
|
||||||
|
*/
|
||||||
|
|
||||||
|
var Events = {};
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subscribes a callback function to the given object's eventName
|
||||||
|
* @method on
|
||||||
|
* @param {} object
|
||||||
|
* @param {string} eventNames
|
||||||
|
* @param {function} callback
|
||||||
|
*/
|
||||||
|
Events.on = function(object, eventNames, callback) {
|
||||||
|
var names = eventNames.split(' '),
|
||||||
|
name;
|
||||||
|
|
||||||
|
for (var i = 0; i < names.length; i++) {
|
||||||
|
name = names[i];
|
||||||
|
object.events = object.events || {};
|
||||||
|
object.events[name] = object.events[name] || [];
|
||||||
|
object.events[name].push(callback);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fires all the callbacks subscribed to the given object's eventName, in the order they subscribed, if any
|
||||||
|
* @method fire
|
||||||
|
* @param {} object
|
||||||
|
* @param {string} eventNames
|
||||||
|
* @param {} event
|
||||||
|
*/
|
||||||
|
Events.trigger = function(object, eventNames, event) {
|
||||||
|
var names,
|
||||||
|
name,
|
||||||
|
callbacks,
|
||||||
|
eventClone;
|
||||||
|
|
||||||
|
if (object.events) {
|
||||||
|
event = event || {};
|
||||||
|
names = eventNames.split(' ');
|
||||||
|
|
||||||
|
for (var i = 0; i < names.length; i++) {
|
||||||
|
name = names[i];
|
||||||
|
|
||||||
|
if (name in object.events) {
|
||||||
|
callbacks = object.events[name];
|
||||||
|
eventClone = Common.clone(event, false);
|
||||||
|
eventClone.name = name;
|
||||||
|
eventClone.source = object;
|
||||||
|
|
||||||
|
for (var j = 0; j < callbacks.length; j++) {
|
||||||
|
callbacks[j].apply(object, [eventClone]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears all callbacks for the given event names if supplied, otherwise all events
|
||||||
|
* @method clear
|
||||||
|
* @param {} object
|
||||||
|
* @param {string} eventNames
|
||||||
|
*/
|
||||||
|
Events.clear = function(object, eventNames) {
|
||||||
|
if (!eventNames) {
|
||||||
|
object.events = {};
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var names = eventNames.split(' ');
|
||||||
|
for (var i = 0; i < names.length; i++) {
|
||||||
|
object.events[names[i]] = [];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
})();
|
||||||
|
|
||||||
|
; // End src/core/Events.js
|
||||||
|
|
||||||
|
|
||||||
// Begin src/core/Metrics.js
|
// Begin src/core/Metrics.js
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2410,7 +2713,7 @@ var Metrics = {};
|
||||||
broadphase = engine.broadphase[engine.broadphase.current];
|
broadphase = engine.broadphase[engine.broadphase.current];
|
||||||
|
|
||||||
metrics.collisions = metrics.narrowDetections;
|
metrics.collisions = metrics.narrowDetections;
|
||||||
metrics.pairs = engine.pairsList.length;
|
metrics.pairs = engine.pairs.list.length;
|
||||||
metrics.bodies = world.bodies.length;
|
metrics.bodies = world.bodies.length;
|
||||||
metrics.midEff = (metrics.narrowDetections / (metrics.midphaseTests || 1)).toFixed(2);
|
metrics.midEff = (metrics.narrowDetections / (metrics.midphaseTests || 1)).toFixed(2);
|
||||||
metrics.narrowEff = (metrics.narrowDetections / (metrics.narrowphaseTests || 1)).toFixed(2);
|
metrics.narrowEff = (metrics.narrowDetections / (metrics.narrowphaseTests || 1)).toFixed(2);
|
||||||
|
@ -2569,6 +2872,12 @@ var Sleeping = {};
|
||||||
var body = bodies[i],
|
var body = bodies[i],
|
||||||
motion = body.speed * body.speed + body.angularSpeed * body.angularSpeed;
|
motion = body.speed * body.speed + body.angularSpeed * body.angularSpeed;
|
||||||
|
|
||||||
|
// wake up bodies if they have a force applied
|
||||||
|
if (body.force.x > 0 || body.force.y > 0) {
|
||||||
|
Sleeping.set(body, false);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
var minMotion = Math.min(body.motion, motion),
|
var minMotion = Math.min(body.motion, motion),
|
||||||
maxMotion = Math.max(body.motion, motion);
|
maxMotion = Math.max(body.motion, motion);
|
||||||
|
|
||||||
|
@ -2594,11 +2903,17 @@ var Sleeping = {};
|
||||||
Sleeping.afterCollisions = function(pairs) {
|
Sleeping.afterCollisions = function(pairs) {
|
||||||
// wake up bodies involved in collisions
|
// wake up bodies involved in collisions
|
||||||
for (var i = 0; i < pairs.length; i++) {
|
for (var i = 0; i < pairs.length; i++) {
|
||||||
var pair = pairs[i],
|
var pair = pairs[i];
|
||||||
collision = pair.collision,
|
|
||||||
|
// don't wake inactive pairs
|
||||||
|
if (!pair.isActive)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var collision = pair.collision,
|
||||||
bodyA = collision.bodyA,
|
bodyA = collision.bodyA,
|
||||||
bodyB = collision.bodyB;
|
bodyB = collision.bodyB;
|
||||||
|
|
||||||
|
// don't wake if at least one body is static
|
||||||
if ((bodyA.isSleeping && bodyB.isSleeping) || bodyA.isStatic || bodyB.isStatic)
|
if ((bodyA.isSleeping && bodyB.isSleeping) || bodyA.isStatic || bodyB.isStatic)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -3790,8 +4105,8 @@ var Render = {};
|
||||||
Render.constraint(world.constraints[i], context);
|
Render.constraint(world.constraints[i], context);
|
||||||
|
|
||||||
if (options.showCollisions)
|
if (options.showCollisions)
|
||||||
for (i = 0; i < engine.pairsList.length; i++)
|
for (i = 0; i < engine.pairs.list.length; i++)
|
||||||
Render.collision(engine, engine.pairsList[i], context);
|
Render.collision(engine, engine.pairs.list[i], context);
|
||||||
|
|
||||||
if (options.showBroadphase && engine.broadphase.current === 'grid')
|
if (options.showBroadphase && engine.broadphase.current === 'grid')
|
||||||
Render.grid(engine, engine.broadphase[engine.broadphase.current].instance, context);
|
Render.grid(engine, engine.broadphase[engine.broadphase.current].instance, context);
|
||||||
|
@ -3826,7 +4141,7 @@ var Render = {};
|
||||||
text += "\n";
|
text += "\n";
|
||||||
|
|
||||||
text += "collisions: " + engine.metrics.collisions + space;
|
text += "collisions: " + engine.metrics.collisions + space;
|
||||||
text += "pairs: " + engine.pairs.length + space;
|
text += "pairs: " + engine.pairs.list.length + space;
|
||||||
text += "broad: " + engine.metrics.broadEff + space;
|
text += "broad: " + engine.metrics.broadEff + space;
|
||||||
text += "mid: " + engine.metrics.midEff + space;
|
text += "mid: " + engine.metrics.midEff + space;
|
||||||
text += "narrow: " + engine.metrics.narrowEff + space;
|
text += "narrow: " + engine.metrics.narrowEff + space;
|
||||||
|
@ -4187,6 +4502,7 @@ Matter.Vector = Vector;
|
||||||
Matter.Vertices = Vertices;
|
Matter.Vertices = Vertices;
|
||||||
Matter.Gui = Gui;
|
Matter.Gui = Gui;
|
||||||
Matter.Render = Render;
|
Matter.Render = Render;
|
||||||
|
Matter.Events = Events;
|
||||||
|
|
||||||
// CommonJS module
|
// CommonJS module
|
||||||
if (typeof exports !== 'undefined') {
|
if (typeof exports !== 'undefined') {
|
||||||
|
|
6
build/matter.min.js
vendored
6
build/matter.min.js
vendored
File diff suppressed because one or more lines are too long
|
@ -6,7 +6,7 @@
|
||||||
<meta name="robots" content="noindex">
|
<meta name="robots" content="noindex">
|
||||||
<script type="text/javascript" src="./js/lib/dat.gui.min.js"></script>
|
<script type="text/javascript" src="./js/lib/dat.gui.min.js"></script>
|
||||||
<script type="text/javascript" src="./js/lib/resurrect.js"></script>
|
<script type="text/javascript" src="./js/lib/resurrect.js"></script>
|
||||||
<script type="text/javascript" src="./js/lib/matter.js"></script>
|
<script type="text/javascript" src="./js/lib/matter-0.5.0.js"></script>
|
||||||
<script type="text/javascript" src="./js/Demo.js"></script>
|
<script type="text/javascript" src="./js/Demo.js"></script>
|
||||||
<link rel="stylesheet" href="./css/style.css" type="text/css">
|
<link rel="stylesheet" href="./css/style.css" type="text/css">
|
||||||
<title>Matter.js Physics Engine Demo</title>
|
<title>Matter.js Physics Engine Demo</title>
|
||||||
|
|
4213
demo/js/lib/matter-0.5.0.js
Normal file
4213
demo/js/lib/matter-0.5.0.js
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue