import { v3_dot } from "../../vec3/v3_dot.js";

/**
 * Given 3 planes, compute point of their intersection.
 * This only works when the planes are "convex", that is - no two planes are parallel.
 * Simply put - intersection must exist to be found.
 *
 * NOTE: Based on Intersection of 3 planes, Graphics Gems 1 pg 305
 *
 * @param {Float32Array|number[]|vec3} result
 * @param {number} result_offset
 * @param {number} a_normal_x
 * @param {number} a_normal_y
 * @param {number} a_normal_z
 * @param {number} a_constant
 * @param {number} b_normal_x
 * @param {number} b_normal_y
 * @param {number} b_normal_z
 * @param {number} b_constant
 * @param {number} c_normal_x
 * @param {number} c_normal_y
 * @param {number} c_normal_z
 * @param {number} c_constant
 * @returns {boolean} true if planes intersect, false otherwise
 */
export function plane3_compute_convex_3_plane_intersection(
    result, result_offset,
    a_normal_x, a_normal_y, a_normal_z, a_constant,
    b_normal_x, b_normal_y, b_normal_z, b_constant,
    c_normal_x, c_normal_y, c_normal_z, c_constant
) {

    /*
    float3 bxc = cross(P1.xyz, P2.xyz);
    float3 cxa = cross(P2.xyz, P0.xyz);
    float3 axb = cross(P0.xyz, P1.xyz);
    float3 r = -P0.w * bxc - P1.w * cxa - P2.w * axb;
    return r * (1 / dot(P0.xyz, bxc));
     */
    const bxc_x = b_normal_y * c_normal_z - b_normal_z * c_normal_y;
    const bxc_y = b_normal_z * c_normal_x - b_normal_x * c_normal_z;
    const bxc_z = b_normal_x * c_normal_y - b_normal_y * c_normal_x;

    const cxa_x = c_normal_y * a_normal_z - c_normal_z * a_normal_y;
    const cxa_y = c_normal_z * a_normal_x - c_normal_x * a_normal_z;
    const cxa_z = c_normal_x * a_normal_y - c_normal_y * a_normal_x;

    const axb_x = a_normal_y * b_normal_z - a_normal_z * b_normal_y;
    const axb_y = a_normal_z * b_normal_x - a_normal_x * b_normal_z;
    const axb_z = a_normal_x * b_normal_y - a_normal_y * b_normal_x;

    const determinant = v3_dot(a_normal_x, a_normal_y, a_normal_z, bxc_x, bxc_y, bxc_z);

    if (determinant === 0) {
        // planes are not convex, there is no intersection
        return false;
    }

    const d = 1 / determinant;

    const neg_a_constant = -a_constant;

    const x = (bxc_x * neg_a_constant - cxa_x * b_constant - axb_x * c_constant) * d;
    const y = (bxc_y * neg_a_constant - cxa_y * b_constant - axb_y * c_constant) * d;
    const z = (bxc_z * neg_a_constant - cxa_z * b_constant - axb_z * c_constant) * d;

    result[result_offset] = x;
    result[result_offset + 1] = y;
    result[result_offset + 2] = z;

    return true;
}
