import { v3_length } from "../../../core/geom/vec3/v3_length.js";

/**
 * Compute the Minkowski-difference support point for two convex shapes.
 *
 * `support_{A−B}(d) = support_A(+d) − support_B(−d)`
 *
 * This is the bread-and-butter operation of both GJK and MPR — every
 * iteration of either algorithm calls it once with a search direction
 * to extend the simplex or portal. Factoring it lets the two
 * algorithms share the per-call scratch buffers (the support results
 * for A and B before the subtraction) so a build that imports both
 * doesn't carry duplicate state.
 *
 * The supplied direction need not be unit — we normalise here, since
 * the {@link AbstractShape3D#support} contract assumes a unit vector
 * and shape support implementations (sphere especially) don't bother
 * to renormalise internally.
 *
 * NOTE: the robust penetration query (`gjk_epa_penetration.js`) computes
 * its own Minkowski-difference support inline rather than calling this
 * helper — it is self-contained (its own GJK + EPA) and works on world-
 * space support providers, so it does not share this body-space path.
 *
 * @param {Float64Array|number[]} result  3-vector destination
 * @param {number} result_offset
 * @param {AbstractShape3D} shape_a
 * @param {AbstractShape3D} shape_b
 * @param {number} dir_x  search direction (any non-zero magnitude)
 * @param {number} dir_y
 * @param {number} dir_z
 */
export function minkowski_support(
    result, result_offset,
    shape_a,
    shape_b,
    dir_x, dir_y, dir_z
) {
    const len = v3_length(dir_x, dir_y, dir_z);

    if (len > 0) {
        // normalise

        const inv = 1 / len;

        dir_x *= inv;
        dir_y *= inv;
        dir_z *= inv;

    }

    shape_a.support(scratch_support_a, 0, dir_x, dir_y, dir_z);
    shape_b.support(scratch_support_b, 0, -dir_x, -dir_y, -dir_z);

    result[result_offset] = scratch_support_a[0] - scratch_support_b[0];
    result[result_offset + 1] = scratch_support_a[1] - scratch_support_b[1];
    result[result_offset + 2] = scratch_support_a[2] - scratch_support_b[2];
}

/**
 * Per-shape scratch buffers for the support-function results before
 * they're subtracted into the Minkowski-difference point. Module-scoped
 * because the physics step is single-threaded; both GJK and MPR run
 * sequentially within one narrowphase iteration.
 *
 * Float64 — matches the precision-sweep treatment of the rest of the
 * solver path.
 */
const scratch_support_a = new Float64Array(3);
const scratch_support_b = new Float64Array(3);
