mirror of
https://github.com/liabru/matter-js.git
synced 2025-03-14 00:38:41 -04:00
Merge commit '076bee9099a029fc9cd2810e8860c29ca044a1c6' into optim-detector-collision
This commit is contained in:
commit
81511fd58f
7 changed files with 225 additions and 227 deletions
|
@ -43,6 +43,7 @@ var Axes = require('../geometry/Axes');
|
|||
type: 'body',
|
||||
label: 'Body',
|
||||
pairs: [],
|
||||
region: null,
|
||||
parts: [],
|
||||
plugin: {},
|
||||
angle: 0,
|
||||
|
|
|
@ -16,6 +16,7 @@ module.exports = Composite;
|
|||
var Events = require('../core/Events');
|
||||
var Common = require('../core/Common');
|
||||
var Body = require('./Body');
|
||||
var Grid = require('../collision/Grid');
|
||||
|
||||
(function() {
|
||||
|
||||
|
@ -206,6 +207,7 @@ var Body = require('./Body');
|
|||
composite.bodies.push(body);
|
||||
Composite.setModified(composite, true, true, false);
|
||||
Composite.addBodies(composite, [body]);
|
||||
|
||||
return composite;
|
||||
};
|
||||
|
||||
|
@ -248,6 +250,10 @@ var Body = require('./Body');
|
|||
return bodyA.id - bodyB.id;
|
||||
});
|
||||
|
||||
if (composite.grid) {
|
||||
Grid.addBodies(composite.grid, bodies, composite);
|
||||
}
|
||||
|
||||
if (composite.parent && composite.parent.type === 'composite') {
|
||||
composite.parent.addBodies(composite.parent, bodies);
|
||||
}
|
||||
|
@ -268,6 +274,10 @@ var Body = require('./Body');
|
|||
allBodies.splice(position, 1);
|
||||
}
|
||||
|
||||
if (composite.grid) {
|
||||
Grid.removeBodies(composite.grid, bodies);
|
||||
}
|
||||
|
||||
if (composite.parent && composite.parent.type === 'composite') {
|
||||
composite.parent.removeBodies(composite.parent, bodies);
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ var Common = require('../core/Common');
|
|||
|
||||
var defaults = {
|
||||
label: 'World',
|
||||
grid: null,
|
||||
gravity: {
|
||||
x: 0,
|
||||
y: 1,
|
||||
|
|
|
@ -21,15 +21,15 @@ var dummyPair = { idA: 1 << 30, idB: (1 << 30) + 1 };
|
|||
(function() {
|
||||
|
||||
/**
|
||||
* Finds all collisions given a list of pairs.
|
||||
* Finds all collisions given a list of bodies and their potential collision pairs
|
||||
* @method collisions
|
||||
* @param {pair[]} broadphasePairs
|
||||
* @param {bodies[]} bodies
|
||||
* @param {engine} engine
|
||||
* @return {array} collisions
|
||||
*/
|
||||
Detector.collisions = function(broadphasePairs, engine) {
|
||||
var pairs = engine.pairs,
|
||||
oldPairs = pairs.list,
|
||||
Detector.collisions = function(bodies, engine) {
|
||||
var allPairs = engine.pairs,
|
||||
oldPairs = allPairs.list,
|
||||
newPairs = [],
|
||||
collisionStart,
|
||||
collisionActive,
|
||||
|
@ -50,9 +50,9 @@ var dummyPair = { idA: 1 << 30, idB: (1 << 30) + 1 };
|
|||
collisionStart = [];
|
||||
collisionActive = [];
|
||||
collisionEnd = [];
|
||||
pairs.collisionStart = collisionStart;
|
||||
pairs.collisionActive = collisionActive;
|
||||
pairs.collisionEnd = collisionEnd;
|
||||
allPairs.collisionStart = collisionStart;
|
||||
allPairs.collisionActive = collisionActive;
|
||||
allPairs.collisionEnd = collisionEnd;
|
||||
}
|
||||
|
||||
oldPairs.push(dummyPair);
|
||||
|
@ -60,63 +60,70 @@ var dummyPair = { idA: 1 << 30, idB: (1 << 30) + 1 };
|
|||
var pairIndex = 0,
|
||||
oldPair = oldPairs[pairIndex++];
|
||||
|
||||
for (var i = 0; i < broadphasePairs.length; i++) {
|
||||
var bodyA = broadphasePairs[i][0],
|
||||
bodyB = broadphasePairs[i][1];
|
||||
for (var i = 0; i < bodies.length; i++) {
|
||||
var bodyA = bodies[i],
|
||||
partsA = bodyA.parts,
|
||||
firstPartsA = bodyA.parts.length > 1 ? 1 : 0,
|
||||
pairs = bodyA.pairs;
|
||||
|
||||
if ((bodyA.isStatic || bodyA.isSleeping) && (bodyB.isStatic || bodyB.isSleeping))
|
||||
continue;
|
||||
|
||||
if (!Detector.canCollide(bodyA.collisionFilter, bodyB.collisionFilter))
|
||||
continue;
|
||||
for (var j = 0; j < pairs.length; j++) {
|
||||
var bodyB = pairs[j][0];
|
||||
|
||||
// @if DEBUG
|
||||
metrics.midphaseTests += 1;
|
||||
// @endif
|
||||
if ((bodyA.isStatic || bodyA.isSleeping) && (bodyB.isStatic || bodyB.isSleeping))
|
||||
continue;
|
||||
|
||||
if (!Detector.canCollide(bodyA.collisionFilter, bodyB.collisionFilter))
|
||||
continue;
|
||||
|
||||
// mid phase
|
||||
if (Bounds.overlaps(bodyA.bounds, bodyB.bounds)) {
|
||||
for (var j = bodyA.parts.length > 1 ? 1 : 0; j < bodyA.parts.length; j++) {
|
||||
var partA = bodyA.parts[j];
|
||||
// @if DEBUG
|
||||
metrics.midphaseTests += 1;
|
||||
// @endif
|
||||
|
||||
for (var k = bodyB.parts.length > 1 ? 1 : 0; k < bodyB.parts.length; k++) {
|
||||
var partB = bodyB.parts[k];
|
||||
// mid phase
|
||||
if (Bounds.overlaps(bodyA.bounds, bodyB.bounds)) {
|
||||
for (var l = firstPartsA; l < partsA.length; l++) {
|
||||
var partA = partsA[l];
|
||||
|
||||
if ((partA === bodyA && partB === bodyB) || Bounds.overlaps(partA.bounds, partB.bounds)) {
|
||||
// narrow phase
|
||||
var collision = SAT.collides(partA, partB);
|
||||
var partsB = bodyB.parts;
|
||||
for (var k = partsB.length > 1 ? 1 : 0; k < partsB.length; k++) {
|
||||
var partB = partsB[k];
|
||||
|
||||
// @if DEBUG
|
||||
metrics.narrowphaseTests += 1;
|
||||
// @endif
|
||||
|
||||
if (collision) {
|
||||
var newPair = Pair.create(collision);
|
||||
newPairs.push(newPair);
|
||||
|
||||
if (hasCollisionEvent) {
|
||||
// Check old pairs to determine which collisions are new
|
||||
// and which collisions are not active anymore
|
||||
var idA = collision.bodyA.id;
|
||||
var idB = collision.bodyB.id;
|
||||
while (oldPair.idA < idA || (oldPair.idA === idA && oldPair.idB < idB)) {
|
||||
collisionEnd.push(oldPair);
|
||||
oldPair = oldPairs[pairIndex++];
|
||||
}
|
||||
|
||||
if (oldPair.idA === idA && oldPair.idB === idB) {
|
||||
// Pair was already active
|
||||
collisionActive.push(newPair);
|
||||
oldPair = oldPairs[pairIndex++];
|
||||
} else {
|
||||
// Pair could not be found, collision is new
|
||||
collisionStart.push(newPair);
|
||||
}
|
||||
}
|
||||
if ((partA === bodyA && partB === bodyB) || Bounds.overlaps(partA.bounds, partB.bounds)) {
|
||||
// narrow phase
|
||||
var collision = SAT.collides(partA, partB);
|
||||
|
||||
// @if DEBUG
|
||||
metrics.narrowDetections += 1;
|
||||
metrics.narrowphaseTests += 1;
|
||||
// @endif
|
||||
|
||||
if (collision) {
|
||||
var newPair = Pair.create(collision);
|
||||
newPairs.push(newPair);
|
||||
|
||||
if (hasCollisionEvent) {
|
||||
// Check old pairs to determine which collisions are new
|
||||
// and which collisions are not active anymore
|
||||
var idA = collision.bodyA.id;
|
||||
var idB = collision.bodyB.id;
|
||||
while (oldPair.idA < idA || (oldPair.idA === idA && oldPair.idB < idB)) {
|
||||
collisionEnd.push(oldPair);
|
||||
oldPair = oldPairs[pairIndex++];
|
||||
}
|
||||
|
||||
if (oldPair.idA === idA && oldPair.idB === idB) {
|
||||
// Pair was already active
|
||||
collisionActive.push(newPair);
|
||||
oldPair = oldPairs[pairIndex++];
|
||||
} else {
|
||||
// Pair could not be found, collision is new
|
||||
collisionStart.push(newPair);
|
||||
}
|
||||
}
|
||||
|
||||
// @if DEBUG
|
||||
metrics.narrowDetections += 1;
|
||||
// @endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -131,7 +138,7 @@ var dummyPair = { idA: 1 << 30, idB: (1 << 30) + 1 };
|
|||
}
|
||||
}
|
||||
|
||||
pairs.list = newPairs;
|
||||
allPairs.list = newPairs;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -8,8 +8,6 @@ var Grid = {};
|
|||
|
||||
module.exports = Grid;
|
||||
|
||||
var Pair = require('./Pair');
|
||||
var Detector = require('./Detector');
|
||||
var Common = require('../core/Common');
|
||||
|
||||
(function() {
|
||||
|
@ -23,10 +21,7 @@ var Common = require('../core/Common');
|
|||
Grid.create = function(options) {
|
||||
var defaults = {
|
||||
controller: Grid,
|
||||
detector: Detector.collisions,
|
||||
buckets: {},
|
||||
pairs: {},
|
||||
pairsList: [],
|
||||
buckets: [],
|
||||
bucketWidth: 48,
|
||||
bucketHeight: 48
|
||||
};
|
||||
|
@ -56,126 +51,148 @@ var Common = require('../core/Common');
|
|||
* @param {grid} grid
|
||||
* @param {body[]} bodies
|
||||
* @param {engine} engine
|
||||
* @param {boolean} forceUpdate
|
||||
*/
|
||||
Grid.update = function(grid, bodies, engine, forceUpdate) {
|
||||
Grid.update = function(grid, bodies, engine) {
|
||||
var i, col, row,
|
||||
world = engine.world,
|
||||
buckets = grid.buckets,
|
||||
bucket,
|
||||
bucketId,
|
||||
gridChanged = false;
|
||||
world = engine.world,
|
||||
worldMinX = world.bounds.min.x,
|
||||
worldMaxX = world.bounds.max.x,
|
||||
worldMinY = world.bounds.min.y,
|
||||
worldMaxY = world.bounds.max.y,
|
||||
worldBounded = isFinite(worldMinX) ||
|
||||
isFinite(worldMaxX) ||
|
||||
isFinite(worldMinY) ||
|
||||
isFinite(worldMaxY);
|
||||
|
||||
// @if DEBUG
|
||||
var metrics = engine.metrics;
|
||||
metrics.broadphaseTests = 0;
|
||||
// @endif
|
||||
|
||||
var pairsList = [];
|
||||
|
||||
for (i = 0; i < bodies.length; i++) {
|
||||
var body = bodies[i];
|
||||
|
||||
if (!body.isSleeping || forceUpdate) {
|
||||
if (body.isSleeping)
|
||||
continue;
|
||||
|
||||
// don't update out of world bodies
|
||||
var bounds = body.bounds;
|
||||
if (bounds.max.x < world.bounds.min.x || bounds.min.x > world.bounds.max.x
|
||||
|| bounds.max.y < world.bounds.min.y || bounds.min.y > world.bounds.max.y)
|
||||
continue;
|
||||
// don't update out of world bodies
|
||||
var bounds = body.bounds;
|
||||
if (worldBounded && (bounds.max.x < worldMinX || bounds.min.x > worldMaxX
|
||||
|| bounds.max.y < worldMinY || bounds.min.y > worldMaxY))
|
||||
continue;
|
||||
|
||||
var newRegion = Grid._getRegion(grid, bounds);
|
||||
var oldRegion = body.region;
|
||||
var newRegion = Grid._getRegion(grid, bounds);
|
||||
var oldRegion = body.region;
|
||||
|
||||
// if the body has changed grid region
|
||||
if (
|
||||
!oldRegion ||
|
||||
newRegion.startCol !== oldRegion.startCol ||
|
||||
newRegion.endCol !== oldRegion.endCol ||
|
||||
newRegion.startRow !== oldRegion.startRow ||
|
||||
newRegion.endRow !== oldRegion.endRow ||
|
||||
forceUpdate
|
||||
) {
|
||||
// set the new region
|
||||
body.region = newRegion;
|
||||
|
||||
// @if DEBUG
|
||||
metrics.broadphaseTests += 1;
|
||||
// @endif
|
||||
// if the body has changed grid region
|
||||
if (
|
||||
newRegion.startCol === oldRegion.startCol &&
|
||||
newRegion.endCol === oldRegion.endCol &&
|
||||
newRegion.startRow === oldRegion.startRow &&
|
||||
newRegion.endRow === oldRegion.endRow
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!oldRegion || forceUpdate)
|
||||
oldRegion = newRegion;
|
||||
// @if DEBUG
|
||||
metrics.broadphaseTests += 1;
|
||||
// @endif
|
||||
|
||||
var union = Grid._regionUnion(newRegion, oldRegion);
|
||||
var startCol = Math.min(newRegion.startCol, oldRegion.startCol),
|
||||
endCol = Math.max(newRegion.endCol, oldRegion.endCol),
|
||||
startRow = Math.min(newRegion.startRow, oldRegion.startRow),
|
||||
endRow = Math.max(newRegion.endRow, oldRegion.endRow);
|
||||
|
||||
// update grid buckets affected by region change
|
||||
// iterate over the union of both regions
|
||||
for (col = union.startCol; col <= union.endCol; col++) {
|
||||
for (row = union.startRow; row <= union.endRow; row++) {
|
||||
bucketId = Grid._getBucketId(col, row);
|
||||
bucket = buckets[bucketId];
|
||||
// update grid buckets affected by region change
|
||||
// iterate over the union of both regions
|
||||
for (col = startCol; col <= endCol; col++) {
|
||||
var isInsideNewColumn = (col >= newRegion.startCol && col <= newRegion.endCol);
|
||||
var isInsideOldColumn = (col >= oldRegion.startCol && col <= oldRegion.endCol);
|
||||
|
||||
var isInsideNewRegion = (col >= newRegion.startCol && col <= newRegion.endCol
|
||||
&& row >= newRegion.startRow && row <= newRegion.endRow);
|
||||
for (row = startRow; row <= endRow; row++) {
|
||||
var isInsideNewRegion = isInsideNewColumn && (row >= newRegion.startRow && row <= newRegion.endRow);
|
||||
var isInsideOldRegion = isInsideOldColumn && (row >= oldRegion.startRow && row <= oldRegion.endRow);
|
||||
|
||||
var isInsideOldRegion = (col >= oldRegion.startCol && col <= oldRegion.endCol
|
||||
&& row >= oldRegion.startRow && row <= oldRegion.endRow);
|
||||
|
||||
// remove from old region buckets
|
||||
if (!isInsideNewRegion && isInsideOldRegion) {
|
||||
if (bucket)
|
||||
Grid._bucketRemoveBody(grid, bucket, body);
|
||||
}
|
||||
|
||||
// add to new region buckets
|
||||
if (oldRegion === newRegion || (isInsideNewRegion && !isInsideOldRegion) || forceUpdate) {
|
||||
if (!bucket)
|
||||
bucket = Grid._createBucket(buckets, bucketId);
|
||||
Grid._bucketAddBody(grid, bucket, body);
|
||||
}
|
||||
// remove from old region buckets
|
||||
if (isInsideOldRegion) {
|
||||
if (!isInsideNewRegion) {
|
||||
Grid._bucketRemoveBody(grid, body, buckets[col][row]);
|
||||
}
|
||||
} else if (isInsideNewRegion) {
|
||||
Grid._bucketAddBody(grid, body, buckets, col, row);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// set the new region
|
||||
body.region = newRegion;
|
||||
Grid.clear = function(grid, bodies) {
|
||||
grid.buckets = [];
|
||||
for (var i = 0; i < bodies.length; i++) {
|
||||
bodies.pairs.length = 0;
|
||||
}
|
||||
};
|
||||
|
||||
// flag changes so we can update pairs
|
||||
gridChanged = true;
|
||||
Grid.removeBodies = function (grid, bodies) {
|
||||
var i, col, row,
|
||||
buckets = grid.buckets;
|
||||
|
||||
for (i = 0; i < bodies.length; i++) {
|
||||
var body = bodies[i],
|
||||
region = body.region,
|
||||
startCol = region.startCol,
|
||||
endCol = region.endCol,
|
||||
startRow = region.startRow,
|
||||
endRow = region.endRow;
|
||||
|
||||
for (col = startCol; col <= endCol; col++) {
|
||||
for (row = startRow; row <= endRow; row++) {
|
||||
Grid._bucketRemoveBody(grid, body, buckets[col][row]);
|
||||
}
|
||||
}
|
||||
|
||||
var pairs = body.pairs;
|
||||
for (var p = 0; p < pairs.length; p += 1)
|
||||
pairsList.push(pairs[p]);
|
||||
body.region = null;
|
||||
body.pairs.length = 0;
|
||||
}
|
||||
|
||||
grid.pairsList = pairsList;
|
||||
};
|
||||
|
||||
/**
|
||||
* Clears the grid.
|
||||
* @method clear
|
||||
* @param {grid} grid
|
||||
*/
|
||||
Grid.clear = function(grid) {
|
||||
grid.buckets = {};
|
||||
grid.pairs = {};
|
||||
grid.pairsList = [];
|
||||
};
|
||||
Grid.addBodies = function(grid, bodies, world) {
|
||||
var i, col, row,
|
||||
buckets = grid.buckets,
|
||||
worldMinX = world.bounds.min.x,
|
||||
worldMaxX = world.bounds.max.x,
|
||||
worldMinY = world.bounds.min.y,
|
||||
worldMaxY = world.bounds.max.y,
|
||||
worldBounded = isFinite(worldMinX) ||
|
||||
isFinite(worldMaxX) ||
|
||||
isFinite(worldMinY) ||
|
||||
isFinite(worldMaxY);
|
||||
|
||||
/**
|
||||
* Finds the union of two regions.
|
||||
* @method _regionUnion
|
||||
* @private
|
||||
* @param {} regionA
|
||||
* @param {} regionB
|
||||
* @return {} region
|
||||
*/
|
||||
Grid._regionUnion = function(regionA, regionB) {
|
||||
var startCol = Math.min(regionA.startCol, regionB.startCol),
|
||||
endCol = Math.max(regionA.endCol, regionB.endCol),
|
||||
startRow = Math.min(regionA.startRow, regionB.startRow),
|
||||
endRow = Math.max(regionA.endRow, regionB.endRow);
|
||||
for (i = 0; i < bodies.length; i++) {
|
||||
var body = bodies[i];
|
||||
// don't update out of world bodies
|
||||
var bounds = body.bounds;
|
||||
if (worldBounded && (bounds.max.x < worldMinX || bounds.min.x > worldMaxX
|
||||
|| bounds.max.y < worldMinY || bounds.min.y > worldMaxY))
|
||||
continue;
|
||||
|
||||
return Grid._createRegion(startCol, endCol, startRow, endRow);
|
||||
var newRegion = Grid._getRegion(grid, bounds);
|
||||
|
||||
// set the new region
|
||||
body.region = newRegion;
|
||||
|
||||
// update grid buckets affected by region change
|
||||
// iterate over the union of both regions
|
||||
for (col = newRegion.startCol; col <= newRegion.endCol; col++) {
|
||||
for (row = newRegion.startRow; row <= newRegion.endRow; row++) {
|
||||
Grid._bucketAddBody(grid, body, buckets, col, row);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -187,58 +204,14 @@ var Common = require('../core/Common');
|
|||
* @return {} region
|
||||
*/
|
||||
Grid._getRegion = function(grid, bounds) {
|
||||
var startCol = Math.floor(bounds.min.x / grid.bucketWidth),
|
||||
endCol = Math.floor(bounds.max.x / grid.bucketWidth),
|
||||
startRow = Math.floor(bounds.min.y / grid.bucketHeight),
|
||||
endRow = Math.floor(bounds.max.y / grid.bucketHeight);
|
||||
|
||||
return Grid._createRegion(startCol, endCol, startRow, endRow);
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a region.
|
||||
* @method _createRegion
|
||||
* @private
|
||||
* @param {} startCol
|
||||
* @param {} endCol
|
||||
* @param {} startRow
|
||||
* @param {} endRow
|
||||
* @return {} region
|
||||
*/
|
||||
Grid._createRegion = function(startCol, endCol, startRow, endRow) {
|
||||
return {
|
||||
startCol: startCol,
|
||||
endCol: endCol,
|
||||
startRow: startRow,
|
||||
endRow: endRow
|
||||
startCol: Math.floor(bounds.min.x / grid.bucketWidth),
|
||||
endCol: Math.floor(bounds.max.x / grid.bucketWidth),
|
||||
startRow: Math.floor(bounds.min.y / grid.bucketHeight),
|
||||
endRow: Math.floor(bounds.max.y / grid.bucketHeight)
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the bucket id at the given position.
|
||||
* @method _getBucketId
|
||||
* @private
|
||||
* @param {} column
|
||||
* @param {} row
|
||||
* @return {string} bucket id
|
||||
*/
|
||||
Grid._getBucketId = function(column, row) {
|
||||
return 'C' + column + 'R' + row;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a bucket.
|
||||
* @method _createBucket
|
||||
* @private
|
||||
* @param {} buckets
|
||||
* @param {} bucketId
|
||||
* @return {} bucket
|
||||
*/
|
||||
Grid._createBucket = function(buckets, bucketId) {
|
||||
var bucket = buckets[bucketId] = [];
|
||||
return bucket;
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds a body to a bucket.
|
||||
* @method _bucketAddBody
|
||||
|
@ -247,8 +220,10 @@ var Common = require('../core/Common');
|
|||
* @param {} bucket
|
||||
* @param {} body
|
||||
*/
|
||||
Grid._bucketAddBody = function(grid, bucket, body) {
|
||||
Grid._bucketAddBody = function(grid, body, buckets, col, row) {
|
||||
// add new pairs
|
||||
var bucketCol = buckets[col] || (buckets[col] = []),
|
||||
bucket = bucketCol[row] || (bucketCol[row] = []);
|
||||
|
||||
var bodyA;
|
||||
for (var i = 0; i < bucket.length; i++) {
|
||||
|
@ -270,17 +245,17 @@ var Common = require('../core/Common');
|
|||
var pairs = bodyA.pairs;
|
||||
for (var p = 0; p < pairs.length; p += 1) {
|
||||
var pair = pairs[p];
|
||||
if (pair[1] === bodyB) {
|
||||
pair[2] += 1;
|
||||
if (pair[0] === bodyB) {
|
||||
pair[1] += 1;
|
||||
break;
|
||||
} else if (pair[1].id > bodyB.id) {
|
||||
pairs.splice(p, 0, [bodyA, bodyB, 1]);
|
||||
pairs.splice(p, 0, [bodyB, 1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (p === pairs.length)
|
||||
pairs.push([bodyA, bodyB, 1]);
|
||||
pairs.push([bodyB, 1]);
|
||||
}
|
||||
|
||||
// add to bodies (after pairs, otherwise pairs with self)
|
||||
|
@ -295,7 +270,7 @@ var Common = require('../core/Common');
|
|||
* @param {} bucket
|
||||
* @param {} body
|
||||
*/
|
||||
Grid._bucketRemoveBody = function(grid, bucket, body) {
|
||||
Grid._bucketRemoveBody = function(grid, body, bucket) {
|
||||
// remove from bucket
|
||||
bucket.splice(Common.indexOf(bucket, body), 1);
|
||||
|
||||
|
@ -315,11 +290,11 @@ var Common = require('../core/Common');
|
|||
var pairs = bodyA.pairs;
|
||||
for (var p = 0; p < pairs.length; p += 1) {
|
||||
var pair = pairs[p];
|
||||
if (pair[1] === bodyB) {
|
||||
if (pair[2] === 1) {
|
||||
if (pair[0] === bodyB) {
|
||||
if (pair[1] === 1) {
|
||||
pairs.splice(p, 1);
|
||||
} else {
|
||||
pair[2] -= 1;
|
||||
pair[1] -= 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ var Render = require('../render/Render');
|
|||
var Pairs = require('../collision/Pairs');
|
||||
var Metrics = require('./Metrics');
|
||||
var Grid = require('../collision/Grid');
|
||||
var Detector = require('../collision/Detector');
|
||||
var Events = require('./Events');
|
||||
var Composite = require('../body/Composite');
|
||||
var Constraint = require('../constraint/Constraint');
|
||||
|
@ -88,6 +89,8 @@ var Body = require('../body/Body');
|
|||
engine.broadphase = engine.broadphase.controller.create(engine.broadphase);
|
||||
engine.metrics = engine.metrics || { extended: false };
|
||||
|
||||
engine.world.grid = engine.broadphase;
|
||||
|
||||
// @if DEBUG
|
||||
engine.metrics = Metrics.create(engine.metrics);
|
||||
// @endif
|
||||
|
@ -159,15 +162,11 @@ var Body = require('../body/Body');
|
|||
// broadphase pass: find potential collision pairs
|
||||
if (broadphase.controller) {
|
||||
// if world is dirty, we must flush the whole grid
|
||||
if (world.isModified)
|
||||
broadphase.controller.clear(broadphase);
|
||||
// if (world.isModified)
|
||||
// broadphase.controller.reset(broadphase, allBodies, engine);
|
||||
|
||||
// update the grid buckets based on current bodies
|
||||
broadphase.controller.update(broadphase, allBodies, engine, world.isModified);
|
||||
broadphasePairs = broadphase.pairsList;
|
||||
} else {
|
||||
// if no broadphase set, we just pass all bodies
|
||||
broadphasePairs = allBodies;
|
||||
broadphase.controller.update(broadphase, allBodies, engine);
|
||||
}
|
||||
|
||||
// clear all composite modified flags
|
||||
|
@ -177,7 +176,7 @@ var Body = require('../body/Body');
|
|||
|
||||
// narrowphase pass: find actual collisions, then create or update collision pairs
|
||||
// var timestamp = timing.timestamp;
|
||||
broadphase.detector(broadphasePairs, engine);
|
||||
Detector.collisions(allBodies, engine);
|
||||
|
||||
// update collision pairs
|
||||
var pairs = engine.pairs;
|
||||
|
@ -267,8 +266,7 @@ var Body = require('../body/Body');
|
|||
var broadphase = engine.broadphase;
|
||||
if (broadphase.controller) {
|
||||
var bodies = Composite.allBodies(world);
|
||||
broadphase.controller.clear(broadphase);
|
||||
broadphase.controller.update(broadphase, bodies, engine, true);
|
||||
broadphase.controller.clear(broadphase, bodies);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -1199,19 +1199,25 @@ var Mouse = require('../core/Mouse');
|
|||
|
||||
c.beginPath();
|
||||
|
||||
var bucketKeys = Common.keys(grid.buckets);
|
||||
var buckets = grid.buckets;
|
||||
var columnKeys = Common.keys(buckets);
|
||||
|
||||
for (var i = 0; i < bucketKeys.length; i++) {
|
||||
var bucketId = bucketKeys[i];
|
||||
for (var i = 0; i < columnKeys.length; i += 1) {
|
||||
var columnKey = columnKeys[i];
|
||||
var column = buckets[columnKey];
|
||||
var rowKeys = Object.keys(column);
|
||||
for (var j = 0; j < rowKeys.length; j += 1) {
|
||||
var rowKey = rowKeys[j];
|
||||
var bucket = column[rowKey];
|
||||
|
||||
if (grid.buckets[bucketId].length < 2)
|
||||
continue;
|
||||
if (bucket.length < 2)
|
||||
continue;
|
||||
|
||||
var region = bucketId.split(/C|R/);
|
||||
c.rect(0.5 + parseInt(region[1], 10) * grid.bucketWidth,
|
||||
0.5 + parseInt(region[2], 10) * grid.bucketHeight,
|
||||
grid.bucketWidth,
|
||||
grid.bucketHeight);
|
||||
c.rect(0.5 + parseInt(columnKey, 10) * grid.bucketWidth,
|
||||
0.5 + parseInt(rowKey, 10) * grid.bucketHeight,
|
||||
grid.bucketWidth,
|
||||
grid.bucketHeight);
|
||||
}
|
||||
}
|
||||
|
||||
c.lineWidth = 1;
|
||||
|
|
Loading…
Add table
Reference in a new issue