UNPKG

phaser

Version:

A fast, free and fun HTML5 Game Framework for Desktop and Mobile web browsers.

108 lines (85 loc) 3.7 kB
/** * The `Matter.Detector` module contains methods for detecting collisions given a set of pairs. * * @class Detector */ // TODO: speculative contacts var Detector = {}; module.exports = Detector; var SAT = require('./SAT'); var Pair = require('./Pair'); var Bounds = require('../geometry/Bounds'); (function() { /** * Finds all collisions given a list of pairs. * @method collisions * @param {pair[]} broadphasePairs * @param {engine} engine * @return {array} collisions */ Detector.collisions = function(broadphasePairs, engine) { var collisions = [], pairsTable = engine.pairs.table; // @if DEBUG var metrics = engine.metrics; // @endif for (var i = 0; i < broadphasePairs.length; i++) { var bodyA = broadphasePairs[i][0], bodyB = broadphasePairs[i][1]; if ((bodyA.isStatic || bodyA.isSleeping) && (bodyB.isStatic || bodyB.isSleeping)) continue; if (!Detector.canCollide(bodyA.collisionFilter, bodyB.collisionFilter)) continue; // @if DEBUG metrics.midphaseTests += 1; // @endif // 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]; for (var k = bodyB.parts.length > 1 ? 1 : 0; k < bodyB.parts.length; k++) { var partB = bodyB.parts[k]; if ((partA === bodyA && partB === bodyB) || Bounds.overlaps(partA.bounds, partB.bounds)) { // find a previous collision we could reuse var pairId = Pair.id(partA, partB), pair = pairsTable[pairId], previousCollision; if (pair && pair.isActive) { previousCollision = pair.collision; } else { previousCollision = null; } // narrow phase var collision = SAT.collides(partA, partB, previousCollision); // @if DEBUG metrics.narrowphaseTests += 1; if (collision.reused) metrics.narrowReuseCount += 1; // @endif if (collision.collided) { collisions.push(collision); // @if DEBUG metrics.narrowDetections += 1; // @endif } } } } } } return collisions; }; /** * Returns `true` if both supplied collision filters will allow a collision to occur. * See `body.collisionFilter` for more information. * @method canCollide * @param {} filterA * @param {} filterB * @return {bool} `true` if collision can occur */ Detector.canCollide = function(filterA, filterB) { if (filterA.group === filterB.group && filterA.group !== 0) return filterA.group > 0; return (filterA.mask & filterB.category) !== 0 && (filterB.mask & filterA.category) !== 0; }; })();