import { Mesh, MeshBasicMaterial, PerspectiveCamera, PlaneGeometry, Scene } from "three";
import { isDevEnvironment, showBalloonError } from "./debug/index.js";
// Adapted from WebARCameraBackground
/**
 * Assigns the camera feed to a texture - this must be called during the render loop.
 */
export function updateTextureFromXRFrame(renderer, target) {
    const xrframe = renderer.xr.getFrame();
    if (!xrframe) {
        console.warn("No XRFrame available");
        return false;
    }
    // If camera feed is not present, then abort and hiden background
    const enabledFeatures = xrframe.session.enabledFeatures;
    if (enabledFeatures && !enabledFeatures.some(x => x === 'camera-access')) {
        console.error(`No camera feed available - please request the 'camera-access' feature before starting WebXR or add the ARCameraBackground component to your scene.

Example to request camera-access in global scope:
NeedleXRSession.onSessionRequestStart(evt => {
    evt.init.optionalFeatures = evt.init.optionalFeatures || [];
    evt.init.optionalFeatures.push('camera-access');
});
`);
        if (isDevEnvironment()) {
            showBalloonError("No camera feed available - please request the 'camera-access' feature before starting WebXR or add the ARCameraBackground component to your scene");
        }
        return false;
    }
    // https://chromium.googlesource.com/chromium/src/+/7c5ac3c0f95b97cf12be95a5c1c0a8ff163246d8/third_party/webxr_test_pages/webxr-samples/proposals/camera-access-barebones.html
    const pose = xrframe.getViewerPose(renderer.xr.getReferenceSpace());
    if (pose) {
        for (const view of pose.views) {
            // @ts-ignore
            if ('camera' in view && view.camera) {
                let binding = renderer.xr.getBinding();
                // not sure how / why this can be null, but we can recreate it here
                if (!binding)
                    binding = new XRWebGLBinding(xrframe.session, renderer.getContext());
                if (binding) {
                    let glImage = null;
                    if ('getCameraImage' in binding) {
                        ensureTextureIsInitialized(renderer, target);
                        // discussion on exactly this:
                        // https://discourse.threejs.org/t/using-a-webgltexture-as-texture-for-three-js/46245/8
                        // HACK from https://stackoverflow.com/a/55084367 to inject a custom texture into three.js
                        const texProps = renderer.properties.get(target);
                        if (texProps) {
                            // @ts-ignore
                            glImage = binding.getCameraImage(view.camera);
                            texProps.__webglTexture = glImage;
                            return true;
                        }
                        else {
                            console.warn("No texture properties found for target texture");
                        }
                    }
                }
                else {
                    console.error(view.camera, renderer.xr);
                }
            }
            else {
                console.error("NO CAMERA IN VIEW");
            }
        }
    }
    else {
        console.error(renderer.xr.getReferenceSpace(), xrframe);
    }
    return false;
}
const initcache = new WeakMap();
function ensureTextureIsInitialized(renderer, texture) {
    // ensure the texture is initialized
    const inits = initcache.get(texture) || new WeakSet();
    if (inits.has(renderer)) {
        return;
    }
    inits.add(renderer);
    initcache.set(texture, inits);
    console.debug("Initialize texture for camera feed");
    const material = new MeshBasicMaterial();
    const geometry = new PlaneGeometry();
    const scene = new Scene();
    scene.add(new Mesh(geometry, material));
    const camera = new PerspectiveCamera();
    material.map = texture;
    renderer.render(scene, camera);
}
;
//# sourceMappingURL=engine_utils_screenshot.xr.js.map