UNPKG

spark-matter-js

Version:

A fork of the Matter.js 2D physics engine for Meta Spark

341 lines (290 loc) 10.3 kB
/** * This module has now been replaced by `Matter.Detector`. * * All usage should be migrated to `Matter.Detector` or another alternative. * For back-compatibility purposes this module will remain for a short term and then later removed in a future release. * * The `Matter.Grid` module contains methods for creating and manipulating collision broadphase grid structures. * * @class Grid * @deprecated */ var Grid = {}; module.exports = Grid; var Pair = require('./Pair'); var Common = require('../core/Common'); var deprecated = Common.deprecated; (function() { /** * Creates a new grid. * @deprecated replaced by Matter.Detector * @method create * @param {} options * @return {grid} A new grid */ Grid.create = function(options) { var defaults = { buckets: {}, pairs: {}, pairsList: [], bucketWidth: 48, bucketHeight: 48 }; return Common.extend(defaults, options); }; /** * The width of a single grid bucket. * * @property bucketWidth * @type number * @default 48 */ /** * The height of a single grid bucket. * * @property bucketHeight * @type number * @default 48 */ /** * Updates the grid. * @deprecated replaced by Matter.Detector * @method update * @param {grid} grid * @param {body[]} bodies * @param {engine} engine * @param {boolean} forceUpdate */ Grid.update = function(grid, bodies, engine, forceUpdate) { var i, col, row, world = engine.world, buckets = grid.buckets, bucket, bucketId, gridChanged = false; for (i = 0; i < bodies.length; i++) { var body = bodies[i]; if (body.isSleeping && !forceUpdate) continue; // temporary back compatibility bounds check if (world.bounds && (body.bounds.max.x < world.bounds.min.x || body.bounds.min.x > world.bounds.max.x || body.bounds.max.y < world.bounds.min.y || body.bounds.min.y > world.bounds.max.y)) continue; var newRegion = Grid._getRegion(grid, body); // if the body has changed grid region if (!body.region || newRegion.id !== body.region.id || forceUpdate) { if (!body.region || forceUpdate) body.region = newRegion; var union = Grid._regionUnion(newRegion, body.region); // 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]; var isInsideNewRegion = (col >= newRegion.startCol && col <= newRegion.endCol && row >= newRegion.startRow && row <= newRegion.endRow); var isInsideOldRegion = (col >= body.region.startCol && col <= body.region.endCol && row >= body.region.startRow && row <= body.region.endRow); // remove from old region buckets if (!isInsideNewRegion && isInsideOldRegion) { if (isInsideOldRegion) { if (bucket) Grid._bucketRemoveBody(grid, bucket, body); } } // add to new region buckets if (body.region === newRegion || (isInsideNewRegion && !isInsideOldRegion) || forceUpdate) { if (!bucket) bucket = Grid._createBucket(buckets, bucketId); Grid._bucketAddBody(grid, bucket, body); } } } // set the new region body.region = newRegion; // flag changes so we can update pairs gridChanged = true; } } // update pairs list only if pairs changed (i.e. a body changed region) if (gridChanged) grid.pairsList = Grid._createActivePairsList(grid); }; deprecated(Grid, 'update', 'Grid.update ➤ replaced by Matter.Detector'); /** * Clears the grid. * @deprecated replaced by Matter.Detector * @method clear * @param {grid} grid */ Grid.clear = function(grid) { grid.buckets = {}; grid.pairs = {}; grid.pairsList = []; }; deprecated(Grid, 'clear', 'Grid.clear ➤ replaced by Matter.Detector'); /** * Finds the union of two regions. * @method _regionUnion * @deprecated replaced by Matter.Detector * @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); return Grid._createRegion(startCol, endCol, startRow, endRow); }; /** * Gets the region a given body falls in for a given grid. * @method _getRegion * @deprecated replaced by Matter.Detector * @private * @param {} grid * @param {} body * @return {} region */ Grid._getRegion = function(grid, body) { var bounds = body.bounds, 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 * @deprecated replaced by Matter.Detector * @private * @param {} startCol * @param {} endCol * @param {} startRow * @param {} endRow * @return {} region */ Grid._createRegion = function(startCol, endCol, startRow, endRow) { return { id: startCol + ',' + endCol + ',' + startRow + ',' + endRow, startCol: startCol, endCol: endCol, startRow: startRow, endRow: endRow }; }; /** * Gets the bucket id at the given position. * @method _getBucketId * @deprecated replaced by Matter.Detector * @private * @param {} column * @param {} row * @return {string} bucket id */ Grid._getBucketId = function(column, row) { return 'C' + column + 'R' + row; }; /** * Creates a bucket. * @method _createBucket * @deprecated replaced by Matter.Detector * @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 * @deprecated replaced by Matter.Detector * @private * @param {} grid * @param {} bucket * @param {} body */ Grid._bucketAddBody = function(grid, bucket, body) { var gridPairs = grid.pairs, pairId = Pair.id, bucketLength = bucket.length, i; // add new pairs for (i = 0; i < bucketLength; i++) { var bodyB = bucket[i]; if (body.id === bodyB.id || (body.isStatic && bodyB.isStatic)) continue; // keep track of the number of buckets the pair exists in // important for Grid.update to work var id = pairId(body, bodyB), pair = gridPairs[id]; if (pair) { pair[2] += 1; } else { gridPairs[id] = [body, bodyB, 1]; } } // add to bodies (after pairs, otherwise pairs with self) bucket.push(body); }; /** * Removes a body from a bucket. * @method _bucketRemoveBody * @deprecated replaced by Matter.Detector * @private * @param {} grid * @param {} bucket * @param {} body */ Grid._bucketRemoveBody = function(grid, bucket, body) { var gridPairs = grid.pairs, pairId = Pair.id, i; // remove from bucket bucket.splice(Common.indexOf(bucket, body), 1); var bucketLength = bucket.length; // update pair counts for (i = 0; i < bucketLength; i++) { // keep track of the number of buckets the pair exists in // important for _createActivePairsList to work var pair = gridPairs[pairId(body, bucket[i])]; if (pair) pair[2] -= 1; } }; /** * Generates a list of the active pairs in the grid. * @method _createActivePairsList * @deprecated replaced by Matter.Detector * @private * @param {} grid * @return [] pairs */ Grid._createActivePairsList = function(grid) { var pair, gridPairs = grid.pairs, pairKeys = Common.keys(gridPairs), pairKeysLength = pairKeys.length, pairs = [], k; // iterate over grid.pairs for (k = 0; k < pairKeysLength; k++) { pair = gridPairs[pairKeys[k]]; // if pair exists in at least one bucket // it is a pair that needs further collision testing so push it if (pair[2] > 0) { pairs.push(pair); } else { delete gridPairs[pairKeys[k]]; } } return pairs; }; })();