import { assert } from "../../../assert.js";
import { computeTriangleRayIntersectionBarycentricEdge } from "./computeTriangleRayIntersectionBarycentricEdge.js";

/**
 * Compute barycentric coordinates for triangle intersection
 * NOTE:  most of the code is inlined for speed to avoid allocation and function calls
 * @see https://github.com/erich666/jgt-code/blob/master/Volume_02/Number_1/Moller1997a/raytri.c
 * @source https://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm (Möller and Trumbore, « Fast, Minimum Storage Ray-Triangle Intersection », Journal of Graphics Tools, vol. 2,‎ 1997, p. 21–28)
 * @param {number[]} result [t,u,v, normal_x, normal_y, normal_z] will be written here
 * @param {number} origin_x
 * @param {number} origin_y
 * @param {number} origin_z
 * @param {number} direction_x
 * @param {number} direction_y
 * @param {number} direction_z
 * @param {number} ax
 * @param {number} ay
 * @param {number} az
 * @param {number} bx
 * @param {number} by
 * @param {number} bz
 * @param {number} cx
 * @param {number} cy
 * @param {number} cz
 * @returns {boolean}
 */
export function computeTriangleRayIntersectionBarycentric(
    result,
    origin_x, origin_y, origin_z,
    direction_x, direction_y, direction_z,
    ax, ay, az,
    bx, by, bz,
    cx, cy, cz
) {
    assert.isNumber(ax, 'ax');
    assert.isNumber(ay, 'ay');
    assert.isNumber(az, 'az');

    assert.isNumber(bx, 'bx');
    assert.isNumber(by, 'by');
    assert.isNumber(bz, 'bz');

    assert.isNumber(cx, 'cx');
    assert.isNumber(cy, 'cy');
    assert.isNumber(cz, 'cz');

    // nan checks
    assert.notNaN(ax, 'ax');
    assert.notNaN(ay, 'ay');
    assert.notNaN(az, 'az');

    assert.notNaN(bx, 'bx');
    assert.notNaN(by, 'by');
    assert.notNaN(bz, 'bz');

    assert.notNaN(cx, 'cx');
    assert.notNaN(cy, 'cy');
    assert.notNaN(cz, 'cz');

    // finate number check
    assert.isFinite(ax, 'ax');
    assert.isFinite(ay, 'ay');
    assert.isFinite(az, 'az');

    assert.isFinite(bx, 'bx');
    assert.isFinite(by, 'by');
    assert.isFinite(bz, 'bz');

    assert.isFinite(cx, 'cx');
    assert.isFinite(cy, 'cy');
    assert.isFinite(cz, 'cz');


    // find vectors for two edges sharing vert

    // edge1 = a - b
    const edge1_x = bx - ax;
    const edge1_y = by - ay;
    const edge1_z = bz - az;

    // edge2 = c - a
    const edge2_x = cx - ax;
    const edge2_y = cy - ay;
    const edge2_z = cz - az;

    return computeTriangleRayIntersectionBarycentricEdge(
        result,
        origin_x, origin_y, origin_z,
        direction_x, direction_y, direction_z,
        ax, ay, az,
        edge1_x, edge1_y, edge1_z,
        edge2_x, edge2_y, edge2_z
    );
}


