UNPKG

dualsense-ts

Version:

The natural interface for your DualSense Classic and DualSense Access controllers, with Typescript

44 lines 1.48 kB
"use strict"; /** * Minimal quaternion math for AHRS sensor fusion. * * Quaternions are represented as [w, x, y, z] tuples where w is the * scalar part. All functions are pure — no mutations, no allocations * beyond the returned tuple. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.IDENTITY = void 0; exports.normalize = normalize; exports.toEuler = toEuler; /** Identity quaternion — no rotation. */ exports.IDENTITY = [1, 0, 0, 0]; /** Normalize a quaternion to unit length. */ function normalize(q) { const [w, x, y, z] = q; const invNorm = 1 / Math.sqrt(w * w + x * x + y * y + z * z); return [w * invNorm, x * invNorm, y * invNorm, z * invNorm]; } /** * Extract Euler angles (Tait-Bryan ZYX intrinsic) from a unit quaternion. * * Convention: pitch = X-axis, yaw = Y-axis, roll = Z-axis. * All angles in radians, range (-PI, PI]. */ function toEuler(q) { const [w, x, y, z] = q; // Roll (Z-axis) const sinr = 2 * (w * z + x * y); const cosr = 1 - 2 * (y * y + z * z); const roll = Math.atan2(sinr, cosr); // Pitch (X-axis) const sinp = 2 * (w * x - y * z); const pitch = Math.abs(sinp) >= 1 ? Math.sign(sinp) * (Math.PI / 2) // gimbal lock : Math.asin(sinp); // Yaw (Y-axis) const siny = 2 * (w * y + z * x); const cosy = 1 - 2 * (x * x + y * y); const yaw = Math.atan2(siny, cosy); return { pitch, yaw, roll }; } //# sourceMappingURL=quaternion.js.map