GameLib.D3.API.Quaternion = function (x, y, z, w, axis, angle) { if (GameLib.D3.Utils.UndefinedOrNull(x)) { x = 0; } this.x = x; if (GameLib.D3.Utils.UndefinedOrNull(y)) { y = 0; } this.y = y; if (GameLib.D3.Utils.UndefinedOrNull(z)) { z = 0; } this.z = z; if (GameLib.D3.Utils.UndefinedOrNull(w)) { w = 1; } this.w = w; if (GameLib.D3.Utils.UndefinedOrNull(axis)) { axis = new GameLib.D3.API.Vector3(); } this.axis = axis; if (GameLib.D3.Utils.UndefinedOrNull(angle)) { angle = 0; } this.angle = angle; }; GameLib.D3.API.Quaternion.prototype.translate = function (v) { this.x += v.x; this.y += v.y; this.z += v.z; return this; }; GameLib.D3.API.Quaternion.prototype.copy = function () { return new GameLib.D3.API.Quaternion( this.x, this.y, this.z, this.w ); }; /** * Note, this normalize function leaves 'w' component untouched */ GameLib.D3.API.Quaternion.prototype.normalize = function () { var EPSILON = 0.000001; var v2 = this.x * this.x + this.y * this.y + this.z * this.z; 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; }; GameLib.D3.API.Quaternion.prototype.multiply = function (q) { var x, y, z, w; var a = q; var b = this; if (q instanceof GameLib.D3.API.Matrix4) { x = a.rows[0].x * b.x + a.rows[0].y * b.y + a.rows[0].z * b.z + a.rows[0].w * b.w; y = a.rows[1].x * b.x + a.rows[1].y * b.y + a.rows[1].z * b.z + a.rows[1].w * b.w; z = a.rows[2].x * b.x + a.rows[2].y * b.y + a.rows[2].z * b.z + a.rows[2].w * b.w; w = a.rows[3].x * b.x + a.rows[3].y * b.y + a.rows[3].z * b.z + a.rows[3].w * b.w; this.x = x; this.y = y; this.z = z; this.w = w; return this; } else if (q instanceof GameLib.D3.API.Quaternion) { x = ((a.x * b.x) - (a.y * b.y) - (a.z * b.z) - (a.w * a.w)); y = ((a.x * b.y) + (a.y * b.x) - (a.z * b.w) + (a.w * a.z)); z = ((a.x * b.z) + (a.y * b.w) + (a.z * b.x) - (a.w * a.y)); w = ((a.x * b.w) - (a.y * b.z) + (a.z * b.y) + (a.w * a.x)); this.x = x; this.y = y; this.z = z; this.w = w; return this; } else { console.log("This functionality not implemented - please do this"); throw new Error("This functionality not implemented - please do this"); } }; GameLib.D3.API.Quaternion.prototype.setFromAngle = function (angle) { this.instance.setFromAxisAngle(this.axis.instance, angle); this.x = this.instance.x; this.y = this.instance.y; this.z = this.instance.z; this.w = this.instance.w; return this; }; GameLib.D3.API.Quaternion.prototype.subtract = function (v) { if (v instanceof GameLib.D3.API.Vector3) { this.x -= v.x; this.y -= v.y; this.z -= v.z; } if (v instanceof GameLib.D3.API.Quaternion) { this.x -= v.x; this.y -= v.y; this.z -= v.z; this.w -= v.w; } return this; }; GameLib.D3.API.Quaternion.prototype.magnitude = function () { return Math.sqrt( (this.x * this.x) + (this.y * this.y) + (this.z * this.z) + (this.w * this.w) ); }; GameLib.D3.API.Quaternion.prototype.normalize = function () { var magnitude = this.magnitude(); if (magnitude < 0.000001) { return this; //do nothing for zero vector } this.x *= magnitude; this.y *= magnitude; this.z *= magnitude; this.w *= magnitude; return this; }; /** * * @param matrix4 GameLib.D3.Matrix4 */ GameLib.D3.API.Quaternion.prototype.setFromRotationMatrix = function(matrix4) { this.instance.setFromRotationMatrix(matrix4.instance); this.x = this.instance.x; this.y = this.instance.y; this.z = this.instance.z; this.w = this.instance.w; }; /** * * @param quaternion GameLib.D3.Quaternion * @param t * @returns {GameLib.D3.Quaternion} */ GameLib.D3.API.Quaternion.prototype.slerp = function (quaternion, t) { this.updateInstance(); this.instance.slerp(quaternion.instance, t); this.x = this.instance.x; this.y = this.instance.y; this.z = this.instance.z; this.w = this.instance.w; return this; };