const K = Math.SQRT1_2 / 511;

/**
 * Based on GDC talk from Bungie on destiny, compressing quaternions for animation
 *
 * @author Alex Goldring
 * @copyright Company Named Limited (c) 2026
 *
 * @param {number[]} output
 * @param {number} output_offset
 * @param {number} value
 */
export function quat_decode_from_uint32(output, output_offset, value) {
    //read components
    const max = value & 0x3;

    const iv0 = (value >> 2) & 0x3FF;
    const iv1 = (value >> 12) & 0x3FF;
    const iv2 = (value >> 22) & 0x3FF;

    //scale components back to quaternion range
    const v0 = iv0 * K - Math.SQRT1_2;
    const v1 = iv1 * K - Math.SQRT1_2;
    const v2 = iv2 * K - Math.SQRT1_2;

    //restore dropped component using quaternion identity: x^2 + y^2 + z^2 + w^2 = 1
    const dropped_2 = 1 - v0 * v0 - v1 * v1 - v2 * v2;
    const dropped = Math.sqrt(dropped_2);

    let x, y, z, w;
    if (max === 0) {
        x = dropped
        y = v0
        z = v1
        w = v2
    } else if (max === 1) {
        x = v0
        y = dropped
        z = v1
        w = v2
    } else if (max === 2) {
        x = v0
        y = v1
        z = dropped
        w = v2
    } else {
        x = v0
        y = v1
        z = v2
        w = dropped
    }

    output[output_offset] = x;
    output[output_offset + 1] = y;
    output[output_offset + 2] = z;
    output[output_offset + 3] = w;
}