/** * @classdesc * * Ray class responsible for casting ray's and testing their collisions with mapped objects. * * @namespace Raycaster.Ray * @class Raycaster.Ray * @constructor * @since 0.6.0 * * @param {object} [options] - Ray's congfiguration options. May include: * @param {Phaser.Geom.Point|Point} [options.origin = {x:0, y:0}] - Ray's position. * @param {number} [options.angle = 0] - Ray's angle in radians. * @param {number} [options.angleDeg = 0] - Ray's angle in degrees. * @param {number} [options.cone = 0] - Ray's cone angle in radians. * @param {number} [options.coneDeg = 0] - Ray's cone angle in degrees. * @param {number} [options.range = Phaser.Math.MAX_SAFE_INTEGER] - Ray's range. * @param {number} [options.collisionRange = Phaser.Math.MAX_SAFE_INTEGER] - Ray's maximum collision range of ray's field of view. * @param {number} [options.detectionRange = Phaser.Math.MAX_SAFE_INTEGER] - Maximum distance between ray's position and tested objects bounding boxes. * @param {boolean} [options.ignoreNotIntersectedRays = true] - If set true, ray returns false when it didn't hit anything. Otherwise returns ray's target position. * @param {boolean} [options.autoSlice = false] - If set true, ray will automatically slice intersections into array of triangles and store it in {@link Raycaster.Ray#slicedIntersections Ray.slicedIntersections}. * @param {boolean} [options.round = false] - If set true, point where ray hit will be rounded. * @param {(boolean|'arcade'|'matter')} [options.enablePhysics = false] - Add to ray physics body. Body will be a circle with radius equal to {@link Raycaster.Ray#collisionRange Ray.collisionRange}. If set true, arcade physics body will be added. * @param {Raycaster} [raycaster] - Parent raycaster object. */ export function Ray(options, raycaster) { /** * Reference to parent Raycaster object. * * @name Raycaster.Ray#_raycaster * @type {Raycaster} * @private * @since 0.6.0 */ this._raycaster = raycaster ? raycaster : false; /** * Ray's source position. * * @name Raycaster.Ray#origin * @type {Phaser.Geom.Point} * @since 0.6.0 */ this.origin = new Phaser.Geom.Point(); /** * Ray's representation used to calculating intersections. * * @name Raycaster.Ray#_ray * @type {Phaser.Geom.Line} * @private * @since 0.6.0 */ this._ray = new Phaser.Geom.Line(); /** * Ray's angle in radians. * * @name Raycaster.Ray#angle * @type {number} * @default 0 * @since 0.6.0 */ this.angle = 0; /** * Ray's cone width angle in radians. * * @name Raycaster.Ray#cone * @type {number} * @default 0 * @since 0.7.0 */ this.cone = 0; /** * Ray's maximum range * * @name Raycaster.Ray#rayRange * @type {number} * @default Phaser.Math.MAX_SAFE_INTEGER * @since 0.6.0 */ this.rayRange = Phaser.Math.MAX_SAFE_INTEGER; /** * Ray's maximum detection range. Objects outside detection range won't be tested. * Ray tests all objects when set to 0. * * @name Raycaster.Ray#detectionRange * @type {number} * @default * @since 0.6.0 */ this.detectionRange = 0; /** * Ray's representation of detection range used in calculating if objects are in range. * * @name Raycaster.Ray#detectionRangeCircle * @type {Phaser.Geom.Circle} * @private * @since 0.6.0 */ this.detectionRangeCircle = new Phaser.Geom.Circle(); /** * Ray's maximum collision range of ray's field of view. Radius of {@link Raycaster.Ray#collisionRangeCircle Ray.body}. * * @name Raycaster.Ray#collisionRange * @type {number} * @default Phaser.Math.MAX_SAFE_INTEGER * @since 0.8.0 */ this.collisionRange = Phaser.Math.MAX_SAFE_INTEGER; /** * If set true, ray returns false when it didn't hit anything. Otherwise returns ray's target position. * * @name Raycaster.Ray#ignoreNotIntersectedRays * @type {boolean} * @default true * @since 0.6.0 */ this.ignoreNotIntersectedRays = true; /** * If set true, ray's hit points will be rounded. * * @name Raycaster.Ray#round * @type {boolean} * @default false * @since 0.8.1 */ this.round = false; /** * If set true, ray will automatically slice intersections into array of triangles and store it in {@link Raycaster.Ray#slicedIntersections Ray.slicedIntersections}. * * @name Raycaster.Ray#autoSlice * @type {boolean} * @default false * @since 0.8.0 */ this.autoSlice = false; /** * Array of intersections from last raycast representing field of view. * * @name Raycaster.Ray#intersections * @type {object[]} * @default [] * @since 0.8.0 */ this.intersections = []; /** * Array of triangles representing slices of field of view from last raycast. * * @name Raycaster.Ray#slicedIntersections * @type {Phaser.Geom.Triangle[]} * @default [] * @since 0.8.0 */ this.slicedIntersections = []; /** * Physics body for testing field of view collisions. * * @name Raycaster.Ray#body * @type {object} * @default undefined * @since 0.8.0 */ //this.body = false; /** * Physics body type. * * @name Raycaster.Ray#bodyType * @type {(boolean|'arcade'|'matter')} * @default false * @since 0.9.0 */ this.bodyType = false; /** * Ray casting stats. * * @name Raycaster.Ray#_stats * @type {object} * @private * @since 0.10.0 * * @property {string} method Used casting method (cast, castCircle, castCone). * @property {number} rays Casted rays. * @property {number} testedMappedObjects Tested mapped objects. * @property {number} hitMappedObjects Hit mapped objects. * @property {number} segments Tested segments. * @property {number} time Casting time. */ this._stats = { method: 'cast', rays: 0, testedMappedObjects: 0, hitMappedObjects: 0, segments: 0, time: 0 }; /** * Ray's graphics object used for debug * * @name Raycaster.Ray#graphics * @type {Phaser.GameObjects.Graphics} * @private * @since 0.10.0 */ this.graphics; this.config(options); }; Ray.prototype = { config: require('./config.js').config, getStats: require('./stats.js').getStats, setRay: require('./ray.js').setRay, setOrigin: require('./origin.js').setOrigin, setRayRange: require('./range.js').setRayRange, setAngle: require('./angle.js').setAngle, setAngleDeg: require('./angle.js').setAngleDeg, setCone: require('./cone.js').setCone, setConeDeg: require('./cone.js').setConeDeg, setDetectionRange: require('./range.js').setDetectionRange, boundsInRange: require('./range.js').boundsInRange, cast: require('./cast.js').cast, castCircle: require('./castCircle.js').castCircle, castCone: require('./castCone.js').castCone, slice: require('./slice.js').slice, setCollisionRange: require('./range.js').setCollisionRange, enablePhysics: require('./enablePhysics.js').enablePhysics, overlap: require('./overlap.js').overlap, processOverlap: require('./overlap.js').processOverlap, testArcadeOverlap: require('./overlap.js').testArcadeOverlap, testMatterOverlap: require('./overlap.js').testMatterOverlap, setCollisionCategory: require('./matter-physics-methods.js').setCollisionCategory, setCollisionGroup: require('./matter-physics-methods.js').setCollisionGroup, setCollidesWith: require('./matter-physics-methods.js').setCollidesWith, setOnCollide: require('./matter-physics-methods.js').setOnCollide, setOnCollideEnd: require('./matter-physics-methods.js').setOnCollideEnd, setOnCollideActive: require('./matter-physics-methods.js').setOnCollideActive, setOnCollideWith: require('./matter-physics-methods.js').setOnCollideWith, drawDebug: require('./debug.js').drawDebug, destroy: require('./destroy.js').destroy, };