UNPKG

p2s

Version:

A JavaScript 2D physics engine.

133 lines (107 loc) 3.37 kB
var Shape = require('./Shape') , vec2 = require('../math/vec2') , Utils = require('../utils/Utils'); module.exports = Plane; /** * Plane shape class. The plane is facing in the Y direction. * @class Plane * @extends Shape * @constructor * @param {object} [options] (Note that this options object will be passed on to the {{#crossLink "Shape"}}{{/crossLink}} constructor.) * @example * var body = new Body(); * var shape = new Plane(); * body.addShape(shape); */ function Plane(options){ options = options ? Utils.shallowClone(options) : {}; options.type = Shape.PLANE; Shape.call(this, options); } Plane.prototype = new Shape(); Plane.prototype.constructor = Plane; /** * Compute moment of inertia * @method computeMomentOfInertia */ Plane.prototype.computeMomentOfInertia = function(){ return 0; // Plane is infinite. The inertia should therefore be infinty but by convention we set 0 here }; /** * Update the bounding radius * @method updateBoundingRadius */ Plane.prototype.updateBoundingRadius = function(){ this.boundingRadius = Number.MAX_VALUE; }; /** * @method computeAABB * @param {AABB} out * @param {Array} position * @param {Number} angle */ Plane.prototype.computeAABB = function(out, position, angle){ var a = angle % (2 * Math.PI); var set = vec2.set; var max = 1e7; var lowerBound = out.lowerBound; var upperBound = out.upperBound; // Set max bounds set(lowerBound, -max, -max); set(upperBound, max, max); if(a === 0){ // y goes from -inf to 0 upperBound[1] = position[1]; } else if(a === Math.PI / 2){ // x goes from 0 to inf lowerBound[0] = position[0]; } else if(a === Math.PI){ // y goes from 0 to inf lowerBound[1] = position[1]; } else if(a === 3*Math.PI/2){ // x goes from -inf to 0 upperBound[0] = position[0]; } }; Plane.prototype.updateArea = function(){ this.area = Number.MAX_VALUE; }; var intersectPlane_planePointToFrom = vec2.create(); var intersectPlane_normal = vec2.create(); var intersectPlane_len = vec2.create(); /** * @method raycast * @param {RayResult} result * @param {Ray} ray * @param {array} position * @param {number} angle */ Plane.prototype.raycast = function(result, ray, position, angle){ var from = ray.from; var to = ray.to; var direction = ray.direction; var planePointToFrom = intersectPlane_planePointToFrom; var normal = intersectPlane_normal; var len = intersectPlane_len; // Get plane normal vec2.set(normal, 0, 1); vec2.rotate(normal, normal, angle); vec2.subtract(len, from, position); var planeToFrom = vec2.dot(len, normal); vec2.subtract(len, to, position); var planeToTo = vec2.dot(len, normal); if(planeToFrom * planeToTo > 0){ // "from" and "to" are on the same side of the plane... bail out return; } if(vec2.squaredDistance(from, to) < planeToFrom * planeToFrom){ return; } var n_dot_dir = vec2.dot(normal, direction); vec2.subtract(planePointToFrom, from, position); var t = -vec2.dot(normal, planePointToFrom) / n_dot_dir / ray.length; ray.reportIntersection(result, t, normal, -1); }; Plane.prototype.pointTest = function(localPoint){ return localPoint[1] <= 0; };