import { SCRATCH_UINT32_TRAVERSAL_STACK } from "../../../collection/SCRATCH_UINT32_TRAVERSAL_STACK.js";
import { NULL_NODE } from "../BVH.js";

const stack = SCRATCH_UINT32_TRAVERSAL_STACK;

/**
 *
 * @param {BVH} bvh
 * @param {number[]} result
 * @param {number} result_offset
 * @param {number} root
 * @param {BVHQuery} query
 * @returns {number}
 */
export function bvh_query_leaves_generic(
    result, result_offset,
    bvh, root, query
) {

    if (root === NULL_NODE) {
        return 0;
    }

    /**
     *
     * @type {number}
     */
    const stack_top = stack.pointer++;

    stack[stack_top] = root;

    let result_cursor = result_offset;

    while (stack.pointer > stack_top) {
        stack.pointer--;

        /**
         *
         * @type {number}
         */
        const node = stack[stack.pointer];

        // test node against the ray
        const pass = query.evaluate(node, bvh);

        if (!pass) {
            continue;
        }

        const node_is_leaf = bvh.node_is_leaf(node);

        if (!node_is_leaf) {

            // read in-order
            const child1 = bvh.node_get_child1(node);
            const child2 = bvh.node_get_child2(node);

            // write to stack in reverse order, so that fist child ends up being visited first
            stack[stack.pointer++] = child2;
            stack[stack.pointer++] = child1;

        } else {
            // leaf node

            result[result_cursor++] = node;
        }
    }

    return result_cursor - result_offset;
}
