constructor()

in src/renderers/webgl/utils/IntersectionTester.ts [12:84]


    constructor(renderProgram: RenderProgram, maxDistance: number = 100, resolution: number = 1.0) {
        let vertexCount = 0;
        let bvh: BVH | null = null;
        let lookup: Splat[] = [];

        const build = () => {
            if (renderProgram.renderData === null) {
                console.error("IntersectionTester cannot be called before renderProgram has been initialized");
                return;
            }
            lookup = [];
            const renderData = renderProgram.renderData as RenderData;
            const boxes = new Array<Box3>(renderData.offsets.size);
            let i = 0;
            const bounds = new Box3(
                new Vector3(Infinity, Infinity, Infinity),
                new Vector3(-Infinity, -Infinity, -Infinity),
            );
            for (const splat of renderData.offsets.keys()) {
                const splatBounds = splat.bounds;
                boxes[i++] = splatBounds;
                bounds.expand(splatBounds.min);
                bounds.expand(splatBounds.max);
                lookup.push(splat);
            }
            bounds.permute();
            bvh = new BVH(bounds, boxes);
            vertexCount = renderData.vertexCount;
        };

        this.testPoint = (x: number, y: number) => {
            if (renderProgram.renderData === null || renderProgram.camera === null) {
                console.error("IntersectionTester cannot be called before renderProgram has been initialized");
                return null;
            }

            build();

            if (bvh === null) {
                console.error("Failed to build octree for IntersectionTester");
                return null;
            }

            const renderData = renderProgram.renderData as RenderData;
            const camera = renderProgram.camera as Camera;

            if (vertexCount !== renderData.vertexCount) {
                console.warn("IntersectionTester has not been rebuilt since the last render");
            }

            const ray = camera.screenPointToRay(x, y);
            for (let x = 0; x < maxDistance; x += resolution) {
                const point = camera.position.add(ray.multiply(x));
                const minPoint = new Vector3(
                    point.x - resolution / 2,
                    point.y - resolution / 2,
                    point.z - resolution / 2,
                );
                const maxPoint = new Vector3(
                    point.x + resolution / 2,
                    point.y + resolution / 2,
                    point.z + resolution / 2,
                );
                const queryBox = new Box3(minPoint, maxPoint);
                const points = bvh.queryRange(queryBox);
                if (points.length > 0) {
                    return lookup[points[0]];
                }
            }

            return null;
        };
    }