import { v4_dot } from "../../vec4/v4_dot.js";
import Vector3 from "../../Vector3.js";

const V1 = new Vector3();
const V2 = new Vector3();

/**
 * 2,0,or -2; 2: above, -2 : below, 0 : intersects plane
 * NOTE: used an article by Bart Wronski https://bartwronski.com/2017/04/13/cull-that-cone/
 * @param {number} plane_normal_x
 * @param {number} plane_normal_y
 * @param {number} plane_normal_z
 * @param {number} plane_constant
 * @param {number} originX
 * @param {number} originY
 * @param {number} originZ
 * @param {number} directionX
 * @param {number} directionY
 * @param {number} directionZ
 * @param {number} angle
 * @param {number} length
 * @returns {number}
 */
export function computeConePlaneSide(
    plane_normal_x, plane_normal_y, plane_normal_z,
    plane_constant,
    originX, originY, originZ,
    directionX, directionY, directionZ,
    angle,
    length
) {

    /*
    ORIGINAL HLSL:
    bool TestConeVsPlane(in float3 origin, in float3 forward, in float size, in float angle, in float4 testPlane)
    {
        const float3 V1 = cross(testPlane.xyz, forward);
        const float3 V2 = cross(V1, forward);

        const float3 capRimPoint =  origin +
                                    size * cos(angle) * forward +
                                    size * sin(angle) * V2;

        return dot(float4(capRimPoint, 1.0f), testPlane) >= 0.0f || dot(float4(origin, 1.0f), testPlane) >= 0.0f;
    }
     */

    V1._crossVectors(plane_normal_x, plane_normal_y, plane_normal_z, directionX, directionY, directionZ);
    V2._crossVectors(V1.x, V1.y, V1.z, directionX, directionY, directionZ);

    const scaled_cos = length * Math.cos(angle);
    const scaled_sin = length * Math.sin(angle);

    // compute cap rim point (closest point to the plane on the wide side of the cone)
    V1.set(
        originX + scaled_cos * directionX + scaled_sin * V2.x,
        originY + scaled_cos * directionY + scaled_sin * V2.y,
        originZ + scaled_cos * directionZ + scaled_sin * V2.z
    );

    const rim_point_side = v4_dot(
        V1.x, V1.y, V1.z, 1,
        plane_normal_x, plane_normal_y, plane_normal_z, plane_constant
    );

    const origin_point_side = v4_dot(
        originX, originY, originZ, 1,
        plane_normal_x, plane_normal_y, plane_normal_z, plane_constant
    );

    let result = 0;

    if (rim_point_side >= 0) {
        result += 1;
    } else {
        result -= 1;
    }

    if (origin_point_side >= 0) {
        result += 1;
    } else {
        result -= 1;
    }

    return result;
}
