import vec2 from '../glmatrix/vec2'; /** * @constructor * @alias clay.Vector2 * @param {number} x * @param {number} y */ var Vector2 = function(x, y) { x = x || 0; y = y || 0; /** * Storage of Vector2, read and write of x, y will change the values in array * All methods also operate on the array instead of x, y components * @name array * @type {Float32Array} * @memberOf clay.Vector2# */ this.array = vec2.fromValues(x, y); /** * Dirty flag is used by the Node to determine * if the matrix is updated to latest * @name _dirty * @type {boolean} * @memberOf clay.Vector2# */ this._dirty = true; }; Vector2.prototype = { constructor: Vector2, /** * Add b to self * @param {clay.Vector2} b * @return {clay.Vector2} */ add: function(b) { vec2.add(this.array, this.array, b.array); this._dirty = true; return this; }, /** * Set x and y components * @param {number} x * @param {number} y * @return {clay.Vector2} */ set: function(x, y) { this.array[0] = x; this.array[1] = y; this._dirty = true; return this; }, /** * Set x and y components from array * @param {Float32Array|number[]} arr * @return {clay.Vector2} */ setArray: function(arr) { this.array[0] = arr[0]; this.array[1] = arr[1]; this._dirty = true; return this; }, /** * Clone a new Vector2 * @return {clay.Vector2} */ clone: function() { return new Vector2(this.x, this.y); }, /** * Copy x, y from b * @param {clay.Vector2} b * @return {clay.Vector2} */ copy: function(b) { vec2.copy(this.array, b.array); this._dirty = true; return this; }, /** * Cross product of self and b, written to a Vector3 out * @param {clay.Vector3} out * @param {clay.Vector2} b * @return {clay.Vector2} */ cross: function(out, b) { vec2.cross(out.array, this.array, b.array); out._dirty = true; return this; }, /** * Alias for distance * @param {clay.Vector2} b * @return {number} */ dist: function(b) { return vec2.dist(this.array, b.array); }, /** * Distance between self and b * @param {clay.Vector2} b * @return {number} */ distance: function(b) { return vec2.distance(this.array, b.array); }, /** * Alias for divide * @param {clay.Vector2} b * @return {clay.Vector2} */ div: function(b) { vec2.div(this.array, this.array, b.array); this._dirty = true; return this; }, /** * Divide self by b * @param {clay.Vector2} b * @return {clay.Vector2} */ divide: function(b) { vec2.divide(this.array, this.array, b.array); this._dirty = true; return this; }, /** * Dot product of self and b * @param {clay.Vector2} b * @return {number} */ dot: function(b) { return vec2.dot(this.array, b.array); }, /** * Alias of length * @return {number} */ len: function() { return vec2.len(this.array); }, /** * Calculate the length * @return {number} */ length: function() { return vec2.length(this.array); }, /** * Linear interpolation between a and b * @param {clay.Vector2} a * @param {clay.Vector2} b * @param {number} t * @return {clay.Vector2} */ lerp: function(a, b, t) { vec2.lerp(this.array, a.array, b.array, t); this._dirty = true; return this; }, /** * Minimum of self and b * @param {clay.Vector2} b * @return {clay.Vector2} */ min: function(b) { vec2.min(this.array, this.array, b.array); this._dirty = true; return this; }, /** * Maximum of self and b * @param {clay.Vector2} b * @return {clay.Vector2} */ max: function(b) { vec2.max(this.array, this.array, b.array); this._dirty = true; return this; }, /** * Alias for multiply * @param {clay.Vector2} b * @return {clay.Vector2} */ mul: function(b) { vec2.mul(this.array, this.array, b.array); this._dirty = true; return this; }, /** * Mutiply self and b * @param {clay.Vector2} b * @return {clay.Vector2} */ multiply: function(b) { vec2.multiply(this.array, this.array, b.array); this._dirty = true; return this; }, /** * Negate self * @return {clay.Vector2} */ negate: function() { vec2.negate(this.array, this.array); this._dirty = true; return this; }, /** * Normalize self * @return {clay.Vector2} */ normalize: function() { vec2.normalize(this.array, this.array); this._dirty = true; return this; }, /** * Generate random x, y components with a given scale * @param {number} scale * @return {clay.Vector2} */ random: function(scale) { vec2.random(this.array, scale); this._dirty = true; return this; }, /** * Scale self * @param {number} scale * @return {clay.Vector2} */ scale: function(s) { vec2.scale(this.array, this.array, s); this._dirty = true; return this; }, /** * Scale b and add to self * @param {clay.Vector2} b * @param {number} scale * @return {clay.Vector2} */ scaleAndAdd: function(b, s) { vec2.scaleAndAdd(this.array, this.array, b.array, s); this._dirty = true; return this; }, /** * Alias for squaredDistance * @param {clay.Vector2} b * @return {number} */ sqrDist: function(b) { return vec2.sqrDist(this.array, b.array); }, /** * Squared distance between self and b * @param {clay.Vector2} b * @return {number} */ squaredDistance: function(b) { return vec2.squaredDistance(this.array, b.array); }, /** * Alias for squaredLength * @return {number} */ sqrLen: function() { return vec2.sqrLen(this.array); }, /** * Squared length of self * @return {number} */ squaredLength: function() { return vec2.squaredLength(this.array); }, /** * Alias for subtract * @param {clay.Vector2} b * @return {clay.Vector2} */ sub: function(b) { vec2.sub(this.array, this.array, b.array); this._dirty = true; return this; }, /** * Subtract b from self * @param {clay.Vector2} b * @return {clay.Vector2} */ subtract: function(b) { vec2.subtract(this.array, this.array, b.array); this._dirty = true; return this; }, /** * Transform self with a Matrix2 m * @param {clay.Matrix2} m * @return {clay.Vector2} */ transformMat2: function(m) { vec2.transformMat2(this.array, this.array, m.array); this._dirty = true; return this; }, /** * Transform self with a Matrix2d m * @param {clay.Matrix2d} m * @return {clay.Vector2} */ transformMat2d: function(m) { vec2.transformMat2d(this.array, this.array, m.array); this._dirty = true; return this; }, /** * Transform self with a Matrix3 m * @param {clay.Matrix3} m * @return {clay.Vector2} */ transformMat3: function(m) { vec2.transformMat3(this.array, this.array, m.array); this._dirty = true; return this; }, /** * Transform self with a Matrix4 m * @param {clay.Matrix4} m * @return {clay.Vector2} */ transformMat4: function(m) { vec2.transformMat4(this.array, this.array, m.array); this._dirty = true; return this; }, toString: function() { return '[' + Array.prototype.join.call(this.array, ',') + ']'; }, toArray: function () { return Array.prototype.slice.call(this.array); } }; // Getter and Setter if (Object.defineProperty) { var proto = Vector2.prototype; /** * @name x * @type {number} * @memberOf clay.Vector2 * @instance */ Object.defineProperty(proto, 'x', { get: function () { return this.array[0]; }, set: function (value) { this.array[0] = value; this._dirty = true; } }); /** * @name y * @type {number} * @memberOf clay.Vector2 * @instance */ Object.defineProperty(proto, 'y', { get: function () { return this.array[1]; }, set: function (value) { this.array[1] = value; this._dirty = true; } }); } // Supply methods that are not in place /** * @param {clay.Vector2} out * @param {clay.Vector2} a * @param {clay.Vector2} b * @return {clay.Vector2} */ Vector2.add = function(out, a, b) { vec2.add(out.array, a.array, b.array); out._dirty = true; return out; }; /** * @param {clay.Vector2} out * @param {number} x * @param {number} y * @return {clay.Vector2} */ Vector2.set = function(out, x, y) { vec2.set(out.array, x, y); out._dirty = true; return out; }; /** * @param {clay.Vector2} out * @param {clay.Vector2} b * @return {clay.Vector2} */ Vector2.copy = function(out, b) { vec2.copy(out.array, b.array); out._dirty = true; return out; }; /** * @param {clay.Vector3} out * @param {clay.Vector2} a * @param {clay.Vector2} b * @return {clay.Vector2} */ Vector2.cross = function(out, a, b) { vec2.cross(out.array, a.array, b.array); out._dirty = true; return out; }; /** * @param {clay.Vector2} a * @param {clay.Vector2} b * @return {number} */ Vector2.dist = function(a, b) { return vec2.distance(a.array, b.array); }; /** * @function * @param {clay.Vector2} a * @param {clay.Vector2} b * @return {number} */ Vector2.distance = Vector2.dist; /** * @param {clay.Vector2} out * @param {clay.Vector2} a * @param {clay.Vector2} b * @return {clay.Vector2} */ Vector2.div = function(out, a, b) { vec2.divide(out.array, a.array, b.array); out._dirty = true; return out; }; /** * @function * @param {clay.Vector2} out * @param {clay.Vector2} a * @param {clay.Vector2} b * @return {clay.Vector2} */ Vector2.divide = Vector2.div; /** * @param {clay.Vector2} a * @param {clay.Vector2} b * @return {number} */ Vector2.dot = function(a, b) { return vec2.dot(a.array, b.array); }; /** * @param {clay.Vector2} a * @return {number} */ Vector2.len = function(b) { return vec2.length(b.array); }; // Vector2.length = Vector2.len; /** * @param {clay.Vector2} out * @param {clay.Vector2} a * @param {clay.Vector2} b * @param {number} t * @return {clay.Vector2} */ Vector2.lerp = function(out, a, b, t) { vec2.lerp(out.array, a.array, b.array, t); out._dirty = true; return out; }; /** * @param {clay.Vector2} out * @param {clay.Vector2} a * @param {clay.Vector2} b * @return {clay.Vector2} */ Vector2.min = function(out, a, b) { vec2.min(out.array, a.array, b.array); out._dirty = true; return out; }; /** * @param {clay.Vector2} out * @param {clay.Vector2} a * @param {clay.Vector2} b * @return {clay.Vector2} */ Vector2.max = function(out, a, b) { vec2.max(out.array, a.array, b.array); out._dirty = true; return out; }; /** * @param {clay.Vector2} out * @param {clay.Vector2} a * @param {clay.Vector2} b * @return {clay.Vector2} */ Vector2.mul = function(out, a, b) { vec2.multiply(out.array, a.array, b.array); out._dirty = true; return out; }; /** * @function * @param {clay.Vector2} out * @param {clay.Vector2} a * @param {clay.Vector2} b * @return {clay.Vector2} */ Vector2.multiply = Vector2.mul; /** * @param {clay.Vector2} out * @param {clay.Vector2} a * @return {clay.Vector2} */ Vector2.negate = function(out, a) { vec2.negate(out.array, a.array); out._dirty = true; return out; }; /** * @param {clay.Vector2} out * @param {clay.Vector2} a * @return {clay.Vector2} */ Vector2.normalize = function(out, a) { vec2.normalize(out.array, a.array); out._dirty = true; return out; }; /** * @param {clay.Vector2} out * @param {number} scale * @return {clay.Vector2} */ Vector2.random = function(out, scale) { vec2.random(out.array, scale); out._dirty = true; return out; }; /** * @param {clay.Vector2} out * @param {clay.Vector2} a * @param {number} scale * @return {clay.Vector2} */ Vector2.scale = function(out, a, scale) { vec2.scale(out.array, a.array, scale); out._dirty = true; return out; }; /** * @param {clay.Vector2} out * @param {clay.Vector2} a * @param {clay.Vector2} b * @param {number} scale * @return {clay.Vector2} */ Vector2.scaleAndAdd = function(out, a, b, scale) { vec2.scaleAndAdd(out.array, a.array, b.array, scale); out._dirty = true; return out; }; /** * @param {clay.Vector2} a * @param {clay.Vector2} b * @return {number} */ Vector2.sqrDist = function(a, b) { return vec2.sqrDist(a.array, b.array); }; /** * @function * @param {clay.Vector2} a * @param {clay.Vector2} b * @return {number} */ Vector2.squaredDistance = Vector2.sqrDist; /** * @param {clay.Vector2} a * @return {number} */ Vector2.sqrLen = function(a) { return vec2.sqrLen(a.array); }; /** * @function * @param {clay.Vector2} a * @return {number} */ Vector2.squaredLength = Vector2.sqrLen; /** * @param {clay.Vector2} out * @param {clay.Vector2} a * @param {clay.Vector2} b * @return {clay.Vector2} */ Vector2.sub = function(out, a, b) { vec2.subtract(out.array, a.array, b.array); out._dirty = true; return out; }; /** * @function * @param {clay.Vector2} out * @param {clay.Vector2} a * @param {clay.Vector2} b * @return {clay.Vector2} */ Vector2.subtract = Vector2.sub; /** * @param {clay.Vector2} out * @param {clay.Vector2} a * @param {clay.Matrix2} m * @return {clay.Vector2} */ Vector2.transformMat2 = function(out, a, m) { vec2.transformMat2(out.array, a.array, m.array); out._dirty = true; return out; }; /** * @param {clay.Vector2} out * @param {clay.Vector2} a * @param {clay.Matrix2d} m * @return {clay.Vector2} */ Vector2.transformMat2d = function(out, a, m) { vec2.transformMat2d(out.array, a.array, m.array); out._dirty = true; return out; }; /** * @param {clay.Vector2} out * @param {clay.Vector2} a * @param {Matrix3} m * @return {clay.Vector2} */ Vector2.transformMat3 = function(out, a, m) { vec2.transformMat3(out.array, a.array, m.array); out._dirty = true; return out; }; /** * @param {clay.Vector2} out * @param {clay.Vector2} a * @param {clay.Matrix4} m * @return {clay.Vector2} */ Vector2.transformMat4 = function(out, a, m) { vec2.transformMat4(out.array, a.array, m.array); out._dirty = true; return out; }; export default Vector2;