UNPKG

@hughsk/fulltilt

Version:

Standalone device orientation + device motion normalization and conversion library

213 lines (133 loc) 3.97 kB
////// FULLTILT.Quaternion ////// FULLTILT.Quaternion = function ( x, y, z, w ) { var quat, outQuat; this.set = function ( x, y, z, w ) { this.x = x || 0; this.y = y || 0; this.z = z || 0; this.w = w || 1; }; this.copy = function ( quaternion ) { this.x = quaternion.x; this.y = quaternion.y; this.z = quaternion.z; this.w = quaternion.w; }; this.setFromEuler = (function () { var _x, _y, _z; var _x_2, _y_2, _z_2; var cX, cY, cZ, sX, sY, sZ; return function ( euler ) { euler = euler || {}; _z = ( euler.alpha || 0 ) * degToRad; _x = ( euler.beta || 0 ) * degToRad; _y = ( euler.gamma || 0 ) * degToRad; _z_2 = _z / 2; _x_2 = _x / 2; _y_2 = _y / 2; cX = Math.cos( _x_2 ); cY = Math.cos( _y_2 ); cZ = Math.cos( _z_2 ); sX = Math.sin( _x_2 ); sY = Math.sin( _y_2 ); sZ = Math.sin( _z_2 ); this.set( sX * cY * cZ - cX * sY * sZ, // x cX * sY * cZ + sX * cY * sZ, // y cX * cY * sZ + sX * sY * cZ, // z cX * cY * cZ - sX * sY * sZ // w ); this.normalize(); return this; }; })(); this.setFromRotationMatrix = (function () { var R; return function( matrix ) { R = matrix.elements; this.set( 0.5 * Math.sqrt( 1 + R[0] - R[4] - R[8] ) * sign( R[7] - R[5] ), // x 0.5 * Math.sqrt( 1 - R[0] + R[4] - R[8] ) * sign( R[2] - R[6] ), // y 0.5 * Math.sqrt( 1 - R[0] - R[4] + R[8] ) * sign( R[3] - R[1] ), // z 0.5 * Math.sqrt( 1 + R[0] + R[4] + R[8] ) // w ); return this; }; })(); this.multiply = function ( quaternion ) { outQuat = FULLTILT.Quaternion.prototype.multiplyQuaternions( this, quaternion ); this.copy( outQuat ); return this; }; this.rotateX = function ( angle ) { outQuat = FULLTILT.Quaternion.prototype.rotateByAxisAngle( this, [ 1, 0, 0 ], angle ); this.copy( outQuat ); return this; }; this.rotateY = function ( angle ) { outQuat = FULLTILT.Quaternion.prototype.rotateByAxisAngle( this, [ 0, 1, 0 ], angle ); this.copy( outQuat ); return this; }; this.rotateZ = function ( angle ) { outQuat = FULLTILT.Quaternion.prototype.rotateByAxisAngle( this, [ 0, 0, 1 ], angle ); this.copy( outQuat ); return this; }; this.normalize = function () { return FULLTILT.Quaternion.prototype.normalize( this ); }; // Initialize object values this.set( x, y, z, w ); }; FULLTILT.Quaternion.prototype = { constructor: FULLTILT.Quaternion, multiplyQuaternions: function () { var multipliedQuat = new FULLTILT.Quaternion(); return function ( a, b ) { var qax = a.x, qay = a.y, qaz = a.z, qaw = a.w; var qbx = b.x, qby = b.y, qbz = b.z, qbw = b.w; multipliedQuat.set( qax * qbw + qaw * qbx + qay * qbz - qaz * qby, // x qay * qbw + qaw * qby + qaz * qbx - qax * qbz, // y qaz * qbw + qaw * qbz + qax * qby - qay * qbx, // z qaw * qbw - qax * qbx - qay * qby - qaz * qbz // w ); return multipliedQuat; }; }(), normalize: function( q ) { var len = Math.sqrt( q.x * q.x + q.y * q.y + q.z * q.z + q.w * q.w ); if ( len === 0 ) { q.x = 0; q.y = 0; q.z = 0; q.w = 1; } else { len = 1 / len; q.x *= len; q.y *= len; q.z *= len; q.w *= len; } return q; }, rotateByAxisAngle: function () { var outputQuaternion = new FULLTILT.Quaternion(); var transformQuaternion = new FULLTILT.Quaternion(); var halfAngle, sA; return function ( targetQuaternion, axis, angle ) { halfAngle = ( angle || 0 ) / 2; sA = Math.sin( halfAngle ); transformQuaternion.set( ( axis[ 0 ] || 0 ) * sA, // x ( axis[ 1 ] || 0 ) * sA, // y ( axis[ 2 ] || 0 ) * sA, // z Math.cos( halfAngle ) // w ); // Multiply quaternion by q outputQuaternion = FULLTILT.Quaternion.prototype.multiplyQuaternions( targetQuaternion, transformQuaternion ); return FULLTILT.Quaternion.prototype.normalize( outputQuaternion ); }; }() };