/*

    one option of Algorithm (problem-orthogonal only, rectangles under perspective projection do not behave this way):
    - compute normal vectors for each face
    - transform normal vectors
    - if vector is pointing away from the viewer - ignore it
    - compute rectangular area of the related face
    - sum up
 */


/**
 * NOTE: Consider using an optimized aabb projection method based on Jim Arvo's Graphics Gems algorithm: https://stackoverflow.com/a/58630206/3973586
 * Almost everything is inlined for speed
 * @param {number[]} aabb_corners
 * @param {number[]|mat4|Float32Array} projection_matrix
 * @returns {number}
 */
export function aabb3_project_to_2d(aabb_corners, projection_matrix) {

    // read matrix into local variables for speed
    const a0 = projection_matrix[0];
    const a1 = projection_matrix[1];
    const a3 = projection_matrix[3];

    const b0 = projection_matrix[4];
    const b1 = projection_matrix[5];
    const b3 = projection_matrix[7];

    const c0 = projection_matrix[8];
    const c1 = projection_matrix[9];
    const c3 = projection_matrix[11];

    const d0 = projection_matrix[12];
    const d1 = projection_matrix[13];
    const d3 = projection_matrix[15];

    // initialize bounds
    let x0 = Number.POSITIVE_INFINITY;
    let y0 = Number.POSITIVE_INFINITY;

    let x1 = Number.NEGATIVE_INFINITY;
    let y1 = Number.NEGATIVE_INFINITY;


    for (let i = 0; i < 24; i += 3) {

        // read corner
        const _x = aabb_corners[i];
        const _y = aabb_corners[i + 1];
        const _z = aabb_corners[i + 2];

        // apply transform
        const t_x = a0 * _x + b0 * _y + c0 * _z + d0;
        const t_y = a1 * _x + b1 * _y + c1 * _z + d1;
        const t_w = a3 * _x + b3 * _y + c3 * _z + d3;

        // perspective divide and normalization (-1,1 space projected to -0.5,0.5)
        const d = 0.5 / t_w;

        // finally compute screen-space coordinates of the corner
        const x = t_x * d;
        const y = t_y * d;

        if (x0 > x) {
            x0 = x;
        }

        if (x1 < x) {
            x1 = x;
        }

        if (y0 > y) {
            y0 = y;
        }
        if (y1 < y) {
            y1 = y;
        }

    }

    const dx = x1 - x0;
    const dy = y1 - y0;

    return dx * dy;
}
