UNPKG

p2s

Version:

A JavaScript 2D physics engine.

172 lines (148 loc) 4.41 kB
var vec2 = require('../math/vec2'); var Body = require('../objects/Body'); module.exports = Broadphase; /** * Base class for broadphase implementations. Don't use this class directly. * @class Broadphase * @constructor */ function Broadphase(type){ this.type = type; /** * The resulting overlapping pairs. Will be filled with results during .getCollisionPairs(). * @property result * @type {Array} */ this.result = []; /** * The world to search for collision pairs in. To change it, use .setWorld() * @property world * @type {World} * @readOnly */ this.world = null; /** * The bounding volume type to use in the broadphase algorithms. Should be set to Broadphase.AABB or Broadphase.BOUNDING_CIRCLE. * @property {Number} boundingVolumeType */ this.boundingVolumeType = Broadphase.AABB; } /** * Axis aligned bounding box type. * @static * @property {Number} AABB */ Broadphase.AABB = 1; /** * Bounding circle type. * @static * @property {Number} BOUNDING_CIRCLE */ Broadphase.BOUNDING_CIRCLE = 2; /** * Set the world that we are searching for collision pairs in. * @method setWorld * @param {World} world */ Broadphase.prototype.setWorld = function(world){ this.world = world; }; /** * Get all potential intersecting body pairs. * @method getCollisionPairs * @param {World} world The world to search in. * @return {Array} An array of the bodies, ordered in pairs. Example: A result of [a,b,c,d] means that the potential pairs are: (a,b), (c,d). */ Broadphase.prototype.getCollisionPairs = function(/*world*/){}; /** * Check whether the bounding radius of two bodies overlap. * @method boundingRadiusCheck * @param {Body} bodyA * @param {Body} bodyB * @return {Boolean} */ Broadphase.boundingRadiusCheck = function(bodyA, bodyB){ var d2 = vec2.squaredDistance(bodyA.position, bodyB.position), r = bodyA.boundingRadius + bodyB.boundingRadius; return d2 <= r*r; }; /** * Check whether the AABB of two bodies overlap. * @method aabbCheck * @param {Body} bodyA * @param {Body} bodyB * @return {Boolean} */ Broadphase.aabbCheck = function(bodyA, bodyB){ return bodyA.getAABB().overlaps(bodyB.getAABB()); }; /** * Check whether the bounding volumes of two bodies overlap. * @method boundingVolumeCheck * @param {Body} bodyA * @param {Body} bodyB * @return {Boolean} */ Broadphase.prototype.boundingVolumeCheck = function(bodyA, bodyB){ var result; switch(this.boundingVolumeType){ case Broadphase.BOUNDING_CIRCLE: result = Broadphase.boundingRadiusCheck(bodyA,bodyB); break; case Broadphase.AABB: result = Broadphase.aabbCheck(bodyA,bodyB); break; default: throw new Error('Bounding volume type not recognized: '+this.boundingVolumeType); } return result; }; /** * Check whether two bodies are allowed to collide at all. * @method canCollide * @param {Body} bodyA * @param {Body} bodyB * @return {Boolean} */ Broadphase.canCollide = function(bodyA, bodyB){ var KINEMATIC = Body.KINEMATIC; var STATIC = Body.STATIC; var typeA = bodyA.type; var typeB = bodyB.type; // Cannot collide static bodies if(typeA === STATIC && typeB === STATIC){ return false; } // Cannot collide static vs kinematic bodies if( (typeA === KINEMATIC && typeB === STATIC) || (typeA === STATIC && typeB === KINEMATIC)){ return false; } // Cannot collide kinematic vs kinematic if(typeA === KINEMATIC && typeB === KINEMATIC){ return false; } // Cannot collide both sleeping bodies if(bodyA.sleepState === Body.SLEEPING && bodyB.sleepState === Body.SLEEPING){ return false; } // Cannot collide if one is static and the other is sleeping if( (bodyA.sleepState === Body.SLEEPING && typeB === STATIC) || (bodyB.sleepState === Body.SLEEPING && typeA === STATIC)){ return false; } return true; }; Broadphase.NAIVE = 1; Broadphase.SAP = 2; /** * Returns all the bodies within an AABB. * @method aabbQuery * @param {World} world * @param {AABB} aabb * @param {array} result An array to store resulting bodies in. * @return {array} */ Broadphase.prototype.aabbQuery = function(/*world, aabb, result*/){ // To be implemented in subclasses };