GameLib.D3.Vector3 = function Vector3(x, y, z) { this.x = x || 0; this.y = y || 0; this.z = z || 0; }; GameLib.D3.Vector3.prototype.subtract = function (v) { return new GameLib.D3.Vector3( this.x - v.x, this.y - v.y, this.z - v.z ); }; GameLib.D3.Vector3.prototype.sub = function (v) { return new GameLib.D3.Vector3( this.x - v.x, this.y - v.y, this.z - v.z ); }; GameLib.D3.Vector3.prototype.cross = function (v) { return new GameLib.D3.Vector3( this.y * v.z - this.z * v.y, this.z * v.x - this.x * v.z, this.x * v.y - this.y * v.x ); }; GameLib.D3.Vector3.clockwise = function (u, v, w, viewPoint) { var normal = GameLib.D3.Vector3.normal(u, v, w); var uv = u.copy(); var winding = normal.dot(uv.subtract(viewPoint)); return (winding > 0); }; GameLib.D3.Vector3.normal = function (u, v, w) { var vv = v.copy(); var wv = w.copy(); return vv.subtract(u).cross(wv.subtract(u)); }; GameLib.D3.Vector3.prototype.lookAt = function (at, up) { var lookAtMatrix = GameLib.D3.Matrix4.lookAt(this, at, up); return this.multiply(lookAtMatrix); }; GameLib.D3.Vector3.prototype.translate = function (v) { this.x += v.x; this.y += v.y; this.z += v.z; return this; }; GameLib.D3.Vector3.prototype.add = function (v) { return new GameLib.D3.Vector3( this.x + v.x, this.y + v.y, this.z + v.z ); }; GameLib.D3.Vector3.prototype.squared = function () { return this.x * this.x + this.y * this.y + this.z * this.z; }; GameLib.D3.Vector3.prototype.copy = function () { return new GameLib.D3.Vector3( this.x, this.y, this.z ); }; GameLib.D3.Vector3.prototype.set = function (x, y, z) { this.x = x; this.y = y; this.z = z; }; GameLib.D3.Vector3.prototype.lerp = function ( v, alpha ) { return new GameLib.D3.Vector3( this.x + ( v.x - this.x ) * alpha, this.y + ( v.y - this.y ) * alpha, this.z + ( v.z - this.z ) * alpha ); }; GameLib.D3.Vector3.prototype.distanceTo = function(v) { var dx = this.x - v.x, dy = this.y - v.y, dz = this.z - v.z; return Math.sqrt(dx * dx + dy * dy + dz * dz); }; /** * @return {number} */ GameLib.D3.Vector3.AngleDirection = function(forward, directionToCheck, up) { var perp = forward.cross(directionToCheck); var dir = perp.dot(up); if (dir > 0.0) { return 1.0; } else if (dir < 0.0) { return -1.0; } else { return 0.0; } }; GameLib.D3.Vector3.prototype.multiply = function (s) { if (s instanceof GameLib.D3.Vector3) { return new GameLib.D3.Vector3( this.x * s.x, this.y * s.y, this.z * s.z ) } else if (s instanceof GameLib.D3.Matrix4) { var x = s.rows[0].x * this.x + s.rows[0].y * this.y + s.rows[0].z * this.z + s.rows[0].w; var y = s.rows[1].x * this.x + s.rows[1].y * this.y + s.rows[1].z * this.z + s.rows[1].w; var z = s.rows[2].x * this.x + s.rows[2].y * this.y + s.rows[2].z * this.z + s.rows[2].w; return new GameLib.D3.Vector3( x, y, z ); } else if (s instanceof GameLib.D3.Matrix3) { var x = s.rows[0].x * this.x + s.rows[0].y * this.y + s.rows[0].z * this.z; var y = s.rows[1].x * this.x + s.rows[1].y * this.y + s.rows[1].z * this.z; var z = s.rows[2].x * this.x + s.rows[2].y * this.y + s.rows[2].z * this.z; return new GameLib.D3.Vector3( x, y, z ); } else if(!isNaN(parseFloat(s)) && isFinite(s)) { return new GameLib.D3.Vector3( this.x * s, this.y * s, this.z * s ); } else { console.log("functionality not implemented - please do this"); throw new Error("not implemented"); return this; } }; GameLib.D3.Vector3.prototype.dot = function (v) { return (this.x * v.x) + (this.y * v.y) + (this.z * v.z); }; GameLib.D3.Vector3.prototype.normalize = function () { var EPSILON = 0.000001; var v2 = this.squared(); if (v2 < EPSILON) { return this; //do nothing for zero vector } var invLength = 1.0 / Math.sqrt(v2); return new GameLib.D3.Vector3( this.x * invLength, this.y * invLength, this.z * invLength ); }; GameLib.D3.Vector3.prototype.clone = function () { return new GameLib.D3.Vector3( this.x, this.y, this.z ); }; GameLib.D3.Vector3.prototype.applyQuaternion = function(q) { var x = this.x, y = this.y, z = this.z; var qx = q.x, qy = q.y, qz = q.z, qw = q.w; // calculate quat * vector 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; // calculate result * inverse quat return new GameLib.D3.Vector3( ix * qw + iw * - qx + iy * - qz - iz * - qy, iy * qw + iw * - qy + iz * - qx - ix * - qz, iz * qw + iw * - qz + ix * - qy - iy * - qx ); }; GameLib.D3.Vector3.prototype.clamp = function(min, max) { this.x = Math.max( min.x, Math.min( max.x, this.x ) ); this.y = Math.max( min.y, Math.min( max.y, this.y ) ); this.z = Math.max( min.z, Math.min( max.z, this.z ) ); return this; }; GameLib.D3.Vector3.prototype.negate = function() { this.x = -this.x; this.y = -this.y; this.z = -this.z; return this; }; GameLib.D3.Vector3.prototype.length = function() { return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z ); }; GameLib.D3.Vector3.prototype.reflect = function(normal) { return this.sub( v1.copy( normal ).multiply( 2 * this.dot( normal ) ) ); }; GameLib.D3.Vector3.prototype.angleTo = function (v) { var theta = this.dot( v ) / ( Math.sqrt( this.lengthSq() * v.lengthSq() ) ); return Math.acos( exports.Math.clamp( theta, - 1, 1 ) ); };