/*Matter physics methods for ray body*/
/**
* Sets the collision category of this ray's Matter Body. This number must be a power of two between 2^0 (= 1) and 2^31.
* Two bodies with different collision groups (see {@link #setCollisionGroup}) will only collide if their collision
* categories are included in their collision masks (see {@link #setCollidesWith}).
*
* @method Raycaster.Ray#setCollisionCategory
* @memberof Raycaster.Ray
* @instance
* @since 0.9.1
*
* @param {number} value - Unique category bitfield.
*
* @return {Raycaster.Ray} {@link Raycaster.Ray Raycaster.Ray} instance
*/
export function setCollisionCategory(value) {
this.body.collisionFilter.category = value;
return this;
};
/**
* Sets the collision group of this ray's Matter Body. If this is zero or two Matter Bodies have different values,
* they will collide according to the usual rules (see {@link #setCollisionCategory} and {@link #setCollisionGroup}).
* If two Matter Bodies have the same positive value, they will always collide; if they have the same negative value,
* they will never collide.
*
* @method Raycaster.Ray#setCollisionCategory
* @memberof Raycaster.Ray
* @instance
* @since 0.9.1
*
* @param {number} value - Unique group index.
*
* @return {Raycaster.Ray} {@link Raycaster.Ray Raycaster.Ray} instance
*/
export function setCollisionGroup(value) {
this.body.collisionFilter.group = value;
return this;
};
/**
* Sets the collision mask for this ray's Matter Body. Two Matter Bodies with different collision groups will only
* collide if each one includes the other's category in its mask based on a bitwise AND, i.e. `(categoryA & maskB) !== 0`
* and `(categoryB & maskA) !== 0` are both true.*
*
* @method Raycaster.Ray#setCollidesWith
* @memberof Raycaster.Ray
* @instance
* @since 0.9.1
*
* @param {(number|number[])} categories - A unique category bitfield, or an array of them.
*
* @return {Raycaster.Ray} {@link Raycaster.Ray Raycaster.Ray} instance
*/
export function setCollidesWith(categories) {
var flags = 0;
if (!Array.isArray(categories))
{
flags = categories;
}
else
{
for (var i = 0; i < categories.length; i++)
{
flags |= categories[i];
}
}
this.body.collisionFilter.mask = flags;
return this;
};
/**
* The callback is sent a `Phaser.Types.Physics.Matter.MatterCollisionData` object.
*
* This does not change the bodies collision category, group or filter. Those must be set in addition
* to the callback.
*
* @method Raycaster.Ray#setOnCollide
* @memberof Raycaster.Ray
* @instance
* @since 0.9.1
*
* @param {function} callback - The callback to invoke when this body starts colliding with another.
*
* @return {Raycaster.Ray} {@link Raycaster.Ray Raycaster.Ray} instance
*/
export function setOnCollide(callback) {
let self = this;
this.body.onCollideCallback = function(collisionInfo) {
if(collisionInfo.rayCollided) {
callback(collisionInfo);
}
else if(self.processOverlap(collisionInfo)) {
collisionInfo.rayCollided = true;
callback(collisionInfo);
}
};
return this;
};
/**
* The callback is sent a `Phaser.Types.Physics.Matter.MatterCollisionData` object.
*
* This does not change the bodies collision category, group or filter. Those must be set in addition
* to the callback.
*
* @method Raycaster.Ray#setOnCollideEnd
* @memberof Raycaster.Ray
* @instance
* @since 0.9.1
*
* @param {function} callback - The callback to invoke when this body stops colliding with another.
*
* @return {Raycaster.Ray} {@link Raycaster.Ray Raycaster.Ray} instance
*/
export function setOnCollideEnd(callback) {
this.body.onCollideEndCallback = function(collisionInfo) {
if(collisionInfo.rayCollided) {
collisionInfo.rayCollided = false;
callback(collisionInfo);
}
}
return this;
};
/**
* The callback is sent a `Phaser.Types.Physics.Matter.MatterCollisionData` object.
*
* This does not change the bodies collision category, group or filter. Those must be set in addition
* to the callback.
*
* @method Raycaster.Ray#setOnCollideActive
* @memberof Raycaster.Ray
* @instance
* @since 0.9.1
*
* @param {function} callback - The callback to invoke for the duration of this body colliding with another.
*
* @return {Raycaster.Ray} {@link Raycaster.Ray Raycaster.Ray} instance
*/
export function setOnCollideActive(callback) {
let self = this;
let func = function(collisionInfo) {
if(self.processOverlap(collisionInfo)) {
let body = collisionInfo.bodyA.label === 'phaser-raycaster-ray-body' ? collisionInfo.bodyB : collisionInfo.bodyA;
if(collisionInfo.rayCollided !== true) {
collisionInfo.rayCollided = true;
if(self.body.onCollideCallback) {
self.body.onCollideCallback(collisionInfo);
}
if(self.body.onCollideWith !== undefined && self.body.onCollideWith[body.id]) {
self.body.onCollideWith[body.id](body, collisionInfo);
}
}
if(callback)
callback(collisionInfo);
}
else {
if(self.body.onCollideEndCallback && collisionInfo.rayCollided === true) {
self.body.onCollideEndCallback(collisionInfo);
}
}
}
this.body.onCollideActiveCallback = func;
return this;
}
/**
* The callback is sent a reference to the other body, along with a `Phaser.Types.Physics.Matter.MatterCollisionData` object.
*
* This does not change the bodies collision category, group or filter. Those must be set in addition
* to the callback.
*
* @method Raycaster.Ray#setOnCollideWith
* @memberof Raycaster.Ray
* @instance
* @since 0.9.1
*
* @param {(MatterJS.Body|MatterJS.Body[])} body - The body, or an array of bodies, to test for collisions with.
* @param {function} callback - The callback to invoke when this body collides with the given body or bodies.
*
* @return {Raycaster.Ray} {@link Raycaster.Ray Raycaster.Ray} instance
*/
export function setOnCollideWith(body, callback) {
let self = this;
let func = function(body, collisionInfo) {
if(collisionInfo.rayCollided) {
callback(body, collisionInfo);
}
else if(self.processOverlap(collisionInfo)) {
collisionInfo.rayCollided = true;
callback(body, collisionInfo);
}
}
if (!Array.isArray(body))
{
body = [ body ];
}
for (var i = 0; i < body.length; i++)
{
var src = (body[i].hasOwnProperty('body')) ? body[i].body : body[i];
this.body.setOnCollideWith(src, func);
}
return this;
};