UNPKG

@egjs/view360

Version:

360 integrated viewing solution from inside-out view to outside-in view. It provides user-friendly service by rotating 360 degrees through various user interaction such as motion sensor and touch.

228 lines (208 loc) 5.76 kB
/** * Original Code * https://github.com/toji/gl-matrix/blob/v2.3.2/src/gl-matrix/quat.js * Quaternion util * modified by egjs */ import glMatrix from "./common.js"; /** * @class Quaternion * @name quat */ var quat = {}; /** * Creates a new identity quat * * @returns {quat} a new quaternion */ quat.create = function() { var out = new glMatrix.ARRAY_TYPE(4); out[0] = 0; out[1] = 0; out[2] = 0; out[3] = 1; return out; }; /** * Creates a new quat initialized with values from an existing quaternion * * @param {quat} a quaternion to clone * @returns {quat} a new quaternion * @function */ quat.clone = function(a) { var out = new glMatrix.ARRAY_TYPE(4); out[0] = a[0]; out[1] = a[1]; out[2] = a[2]; out[3] = a[3]; return out; }; /** * Creates a new quat initialized with the given values * * @param {Number} x X component * @param {Number} y Y component * @param {Number} z Z component * @param {Number} w W component * @returns {quat} a new quaternion * @function */ quat.fromValues = function(x, y, z, w) { var out = new glMatrix.ARRAY_TYPE(4); out[0] = x; out[1] = y; out[2] = z; out[3] = w; return out; };; /** * Copy the values from one quat to another * * @param {quat} out the receiving quaternion * @param {quat} a the source quaternion * @returns {quat} out * @function */ quat.copy = function(out, a) { out[0] = a[0]; out[1] = a[1]; out[2] = a[2]; out[3] = a[3]; return out; }; /** * Sets a quat from the given angle and rotation axis, * then returns it. * * @param {quat} out the receiving quaternion * @param {vec3} axis the axis around which to rotate * @param {Number} rad the angle in radians * @returns {quat} out **/ quat.setAxisAngle = function(out, axis, rad) { rad = rad * 0.5; var s = Math.sin(rad); out[0] = s * axis[0]; out[1] = s * axis[1]; out[2] = s * axis[2]; out[3] = Math.cos(rad); return out; }; /** * Multiplies two quat's * * @param {quat} out the receiving quaternion * @param {quat} a the first operand * @param {quat} b the second operand * @returns {quat} out */ quat.multiply = function(out, a, b) { var ax = a[0], ay = a[1], az = a[2], aw = a[3], bx = b[0], by = b[1], bz = b[2], bw = b[3]; out[0] = ax * bw + aw * bx + ay * bz - az * by; out[1] = ay * bw + aw * by + az * bx - ax * bz; out[2] = az * bw + aw * bz + ax * by - ay * bx; out[3] = aw * bw - ax * bx - ay * by - az * bz; return out; }; /** * Rotates a quaternion by the given angle about the X axis * * @param {quat} out quat receiving operation result * @param {quat} a quat to rotate * @param {number} rad angle (in radians) to rotate * @returns {quat} out */ quat.rotateX = function (out, a, rad) { rad *= 0.5; var ax = a[0], ay = a[1], az = a[2], aw = a[3], bx = Math.sin(rad), bw = Math.cos(rad); out[0] = ax * bw + aw * bx; out[1] = ay * bw + az * bx; out[2] = az * bw - ay * bx; out[3] = aw * bw - ax * bx; return out; }; /** * Rotates a quaternion by the given angle about the Y axis * * @param {quat} out quat receiving operation result * @param {quat} a quat to rotate * @param {number} rad angle (in radians) to rotate * @returns {quat} out */ quat.rotateY = function (out, a, rad) { rad *= 0.5; var ax = a[0], ay = a[1], az = a[2], aw = a[3], by = Math.sin(rad), bw = Math.cos(rad); out[0] = ax * bw - az * by; out[1] = ay * bw + aw * by; out[2] = az * bw + ax * by; out[3] = aw * bw - ay * by; return out; }; /** * Calculates the conjugate of a quat * If the quaternion is normalized, this function is faster than quat.inverse and produces the same result. * * @param {quat} out the receiving quaternion * @param {quat} a quat to calculate conjugate of * @returns {quat} out */ quat.conjugate = function (out, a) { out[0] = -a[0]; out[1] = -a[1]; out[2] = -a[2]; out[3] = a[3]; return out; }; /** * Normalize a quat * * @param {quat} out the receiving quaternion * @param {quat} a quaternion to normalize * @returns {quat} out * @function */ quat.normalize = function(out, a) { var x = a[0], y = a[1], z = a[2], w = a[3]; var len = x*x + y*y + z*z + w*w; if (len > 0) { len = 1 / Math.sqrt(len); out[0] = x * len; out[1] = y * len; out[2] = z * len; out[3] = w * len; } return out; }; /** * Returns whether or not the quaternions have approximately the same elements in the same position (when compared with ===) * * @param {quat} a The first quaternion. * @param {quat} b The second quaternion. * @returns {Boolean} True if the vectors are equal, false otherwise. */ quat.equals = function (a, b) { let a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3]; let b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3]; return (Math.abs(a0 - b0) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a3), Math.abs(b3))); } /** * Returns whether or not the quaternions have exactly the same elements in the same position (when compared with ===) * * @param {quat} a The first quaternion. * @param {quat} b The second quaternion. * @returns {Boolean} True if the vectors are equal, false otherwise. */ quat.exactEquals = function (a, b) { return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3]; }; export default quat;