GameLib.D3.Vector3 = function(x, y, z) { this.x = 0; this.y = 0; this.z = 0; if (x) { this.x = x; } if (y) { this.y = y; } if (z) { this.z = z; } }; GameLib.D3.Vector3.prototype.subtract = function (v) { if (v instanceof GameLib.D3.Vector3) { this.x -= v.x; this.y -= v.y; this.z -= v.z; } if (v instanceof GameLib.D3.Vector4) { console.warn("trying to subtract vector of bigger length (4 vs 3))"); } return this; }; 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.prototype.negative = function () { this.x *= -1; this.y *= -1; this.z *= -1; return this; }; 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); 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.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.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.multiply = function (s) { if (s instanceof 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; 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; this.x = x; this.y = y; this.z = z; } 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 / Math.sqrt(v2); this.x *= invLength; this.y *= invLength; this.z *= invLength; return this; };