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