var Class = require('../utils/Class'); var Vector3 = new Class({ initialize: function Vector3(x, y, z){ this.x = 0; this.y = 0; this.z = 0; if (typeof x === 'object') { this.x = x.x || 0; this.y = x.y || 0; this.z = x.z || 0; } else { this.x = x || 0; this.y = y || 0; this.z = z || 0; } } , up: function (){ this.x = 0; this.y = 1; this.z = 0; return this; } , clone: function (){ return new Vector3(this.x, this.y, this.z); } , crossVectors: function (a, b){ var ax = a.x; var ay = a.y; var az = a.z; var bx = b.x; var by = b.y; var bz = b.z; this.x = ay * bz - az * by; this.y = az * bx - ax * bz; this.z = ax * by - ay * bx; return this; } , equals: function (v){ return ((this.x === v.x) && (this.y === v.y) && (this.z === v.z)); } , copy: function (src){ this.x = src.x; this.y = src.y; this.z = src.z || 0; return this; } , set: function (x, y, z){ if (typeof x === 'object') { this.x = x.x || 0; this.y = x.y || 0; this.z = x.z || 0; } else { this.x = x || 0; this.y = y || 0; this.z = z || 0; } return this; } , add: function (v){ this.x += v.x; this.y += v.y; this.z += v.z || 0; return this; } , subtract: function (v){ this.x -= v.x; this.y -= v.y; this.z -= v.z || 0; return this; } , multiply: function (v){ this.x *= v.x; this.y *= v.y; this.z *= v.z || 1; return this; } , scale: function (scale){ if (isFinite(scale)) { this.x *= scale; this.y *= scale; this.z *= scale; } else { this.x = 0; this.y = 0; this.z = 0; } return this; } , divide: function (v){ this.x /= v.x; this.y /= v.y; this.z /= v.z || 1; return this; } , negate: function (){ this.x = - this.x; this.y = - this.y; this.z = - this.z; return this; } , distance: function (v){ var dx = v.x - this.x; var dy = v.y - this.y; var dz = v.z - this.z || 0; return Math.sqrt(dx * dx + dy * dy + dz * dz); } , distanceSq: function (v){ var dx = v.x - this.x; var dy = v.y - this.y; var dz = v.z - this.z || 0; return dx * dx + dy * dy + dz * dz; } , length: function (){ var x = this.x; var y = this.y; var z = this.z; return Math.sqrt(x * x + y * y + z * z); } , lengthSq: function (){ var x = this.x; var y = this.y; var z = this.z; return x * x + y * y + z * z; } , normalize: function (){ var x = this.x; var y = this.y; var z = this.z; var len = x * x + y * y + z * z; if (len > 0) { len = 1 / Math.sqrt(len); this.x = x * len; this.y = y * len; this.z = z * len; } return this; } , dot: function (v){ return this.x * v.x + this.y * v.y + this.z * v.z; } , cross: function (v){ var ax = this.x; var ay = this.y; var az = this.z; var bx = v.x; var by = v.y; var bz = v.z; this.x = ay * bz - az * by; this.y = az * bx - ax * bz; this.z = ax * by - ay * bx; return this; } , lerp: function (v, t){ if (t === undefined) { t = 0; } var ax = this.x; var ay = this.y; var az = this.z; this.x = ax + t * (v.x - ax); this.y = ay + t * (v.y - ay); this.z = az + t * (v.z - az); return this; } , transformMat3: function (mat){ var x = this.x; var y = this.y; var z = this.z; var m = mat.val; this.x = x * m[0] + y * m[3] + z * m[6]; this.y = x * m[1] + y * m[4] + z * m[7]; this.z = x * m[2] + y * m[5] + z * m[8]; return this; } , transformMat4: function (mat){ var x = this.x; var y = this.y; var z = this.z; var m = mat.val; this.x = m[0] * x + m[4] * y + m[8] * z + m[12]; this.y = m[1] * x + m[5] * y + m[9] * z + m[13]; this.z = m[2] * x + m[6] * y + m[10] * z + m[14]; return this; } , transformCoordinates: function (mat){ var x = this.x; var y = this.y; var z = this.z; var m = mat.val; var tx = (x * m[0]) + (y * m[4]) + (z * m[8]) + m[12]; var ty = (x * m[1]) + (y * m[5]) + (z * m[9]) + m[13]; var tz = (x * m[2]) + (y * m[6]) + (z * m[10]) + m[14]; var tw = (x * m[3]) + (y * m[7]) + (z * m[11]) + m[15]; this.x = tx / tw; this.y = ty / tw; this.z = tz / tw; return this; } , transformQuat: function (q){ var x = this.x; var y = this.y; var z = this.z; var qx = q.x; var qy = q.y; var qz = q.z; var qw = q.w; var ix = qw * x + qy * z - qz * y; var iy = qw * y + qz * x - qx * z; var iz = qw * z + qx * y - qy * x; var iw = - qx * x - qy * y - qz * z; this.x = ix * qw + iw * - qx + iy * - qz - iz * - qy; this.y = iy * qw + iw * - qy + iz * - qx - ix * - qz; this.z = iz * qw + iw * - qz + ix * - qy - iy * - qx; return this; } , project: function (mat){ var x = this.x; var y = this.y; var z = this.z; var m = mat.val; var a00 = m[0]; var a01 = m[1]; var a02 = m[2]; var a03 = m[3]; var a10 = m[4]; var a11 = m[5]; var a12 = m[6]; var a13 = m[7]; var a20 = m[8]; var a21 = m[9]; var a22 = m[10]; var a23 = m[11]; var a30 = m[12]; var a31 = m[13]; var a32 = m[14]; var a33 = m[15]; var lw = 1 / (x * a03 + y * a13 + z * a23 + a33); this.x = (x * a00 + y * a10 + z * a20 + a30) * lw; this.y = (x * a01 + y * a11 + z * a21 + a31) * lw; this.z = (x * a02 + y * a12 + z * a22 + a32) * lw; return this; } , unproject: function (viewport, invProjectionView){ var viewX = viewport.x; var viewY = viewport.y; var viewWidth = viewport.z; var viewHeight = viewport.w; var x = this.x - viewX; var y = (viewHeight - this.y - 1) - viewY; var z = this.z; this.x = (2 * x) / viewWidth - 1; this.y = (2 * y) / viewHeight - 1; this.z = 2 * z - 1; return this.project(invProjectionView); } , reset: function (){ this.x = 0; this.y = 0; this.z = 0; return this; } } ); module.exports = Vector3;