[SOLVED] Error with AR hitTest

Error: Failed to execute 'requestHitTestSourceForTransientInput' on 'XRSession': Hit test feature is not supported by the session.

I get the following when trying to tap the screen in AR mode.

I am starting AR with:

this.app.touch.on(pc.EVENT_TOUCHSTART, function() {
    console.log("touched");
    // check support
    if (this.app.xr.isAvailable(pc.XRTYPE_AR)) {
        console.log("supported");
        // start session
        this.cameraEntity.camera.startXr(pc.XRTYPE_AR, pc.XRSPACE_LOCALFLOOR);
        console.log("started");
    }
}, this);

I get all three console logs and the camera starts in fullscreen.

I then test for hitTest support with

if (! this.app.xr.hitTest)
    return;
else
    console.log("app.xr.hitTest exists");

And it prints the string in the console.

Then finally I do

this.app.xr.input.on('add', function(inputSource) {
    inputSource.hitTestStart({
        callback: function(err, hitTestSource) {
            if (err) {   
                console.error(err);
            } else {
                console.log("working");
            }
        }
    });
});

I dont get the “working” instead I get the above error.

What browsers and OSs are you working with and can you provide the full source/project please?

Android
Chrome stable version 85
If you want I can upload it to github, but here’s the full code:
Index.html:

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>PlayCanvas AR</title>
    <meta name='viewport' content='width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no' />
    <style>
        body {
            margin: 0;
            overflow: hidden;
        }
    </style>
    <script src='playcanvas-stable.min.js'></script>
    <script src="ammo.751ec5f.js"></script>
</head>

<body>
    <canvas id='application'></canvas>
    <script>
        // create a PlayCanvas application
        var canvas = document.getElementById('application');
        var app = new pc.Application(canvas, {
            mouse: new pc.Mouse(canvas),
            touch: !!('ontouchstart' in window) ? new pc.TouchDevice(canvas) : null,
        });
        app.scene.ambientLight = new pc.Color(0.5, 0.5, 0.5);
        app.start();

        // fill the available space at full resolution
        app.setCanvasFillMode(pc.FILLMODE_FILL_WINDOW);
        app.setCanvasResolution(pc.RESOLUTION_AUTO);

        // ensure canvas is resized when window changes size
        window.addEventListener('resize', function() {
            app.resizeCanvas();
        });


        var Light = new pc.Entity('Light');
        Light.addComponent('light', {
            type: "directional",
            castShadows: true,
            shadowBias: 0.2,
            shadowDistance: 16,
            normalOffsetBias: 0.05,
            shadowResolution: 2048
        });
        Light.setLocalPosition(2, 2, -2);
        Light.setLocalRotation(45, 135, 0);
        Light.enabled = false;
        app.root.addChild(Light);


        var Camera = new pc.Entity('Camera');
        Camera.addComponent('camera', {
            clearColor: new pc.Color(0.1, 0.1, 0.1, 0),
        });
        Camera.setLocalPosition(0, 0, 4);
        app.root.addChild(Camera);

        var Target = new pc.Entity("Target");
        Target.addComponent('model', {
            type: "box"
        });
        app.root.addChild(Target);


        app.assets.loadFromUrl('xr.js', 'script', function(err, asset) {
            app.root.addComponent('script');
            app.root.script.create("xrBasic", {
                attributes: {
                    cameraEntity: Camera
                }
            });
        });
      
        app.assets.loadFromUrl('hit-test.js', 'script', function(err, asset) {
            //root.addComponent('script');
            app.root.script.create("hitTest", {
                attributes: {
                    grass: Target
                }
            });
        });

        // register a global update event
        app.on('update', function(deltaTime) {
            //cube.rotate(0 * deltaTime, 50 * deltaTime, 0 * deltaTime);
        });
    </script>
</body>

</html>

xr.js

var XrBasic = pc.createScript('xrBasic');

// entity with camera component
XrBasic.attributes.add('cameraEntity', {
    type: 'entity'
});

XrBasic.prototype.initialize = function() {
    this.app.touch.on(pc.EVENT_TOUCHSTART, function() {
        console.log("touched");
        // check support
        if (this.app.xr.isAvailable(pc.XRTYPE_AR)) {
            console.log("supported");
            // start session
            this.cameraEntity.camera.startXr(pc.XRTYPE_AR, pc.XRSPACE_LOCALFLOOR);
            console.log("started");
        }
    }, this);
};

hit-test.js

var HitTest = pc.createScript('hitTest');

// initialize code called once per entity
HitTest.prototype.initialize = function() {
    if (!this.app.xr.hitTest)
        return;
    else
        console.log("app.xr.hitTest exists");

    // in AR touch on screen adds new input source every time
    this.app.xr.input.on('add', function(inputSource) {
        console.log("inside add event");
        // start hit test for added input source

        inputSource.hitTestStart({
            callback: function(err, hitTestSource) {
                if (err) {
                    console.error(err);
                } else {
                    console.log("working"); // Everything works except this
                }
            }
        });
    });
};

I’ve tried the example you posted here are get the following output:

touched
supported
started
inside add event
working

Haven’t changed any code. Using playcanvas engine 1.35.0. Using ngrok to test over https (WebXR only works over https AFAIK)

1 Like

Ah. Turns out I was using v1.34.0 revision 71086a3 of the engine. Works now. Sorry for the trouble.