Example of touch start event?

I’ve spent ages today trying to get a touch event to fire in a script, I tried the following:

  1. Using the same syntax as ‘pointerdown’, which actually fires for pointer down:
    document.addEventListener("touchstart", evt => {
        console.log("touchstart");
        this.touched();
    });
  1. Using some example I found in VideoPlayer.ts in the engine files:
    window.addEventListener("touchstart", e => {
            console.log("touchstart");
    })

Neither of these seem to fire when testing on device or using WebXR AR simulator. Am I missing something really obvious?

Original Post on Discord

by user 103054507105067008

I just tried this little bit - works both in browser with touch simulation, on device and in WebAR (Android Pixel 4a):


export class MyScript extends Behaviour {
    start() {
        this.context.domElement.addEventListener("touchstart", e => {
            console.log("touchstart", e);
            for (let i = 0; i < e.changedTouches.length; i++) {
                const touch = e.changedTouches[i];
                const ray = this.context.mainCameraComponent!.screenPointToRay(touch.clientX, touch.clientY);
                Gizmos.DrawRay(ray.origin, ray.direction, 0xff0000, 10);
            }
        });
    }

}

I’m adding a little helper method to the camera in the next version, that’s the code for it:

    private static _origin: THREE.Vector3 = new THREE.Vector3();
    private static _direction: THREE.Vector3 = new THREE.Vector3();

    public screenPointToRay(x: number, y: number, ray?: Ray): Ray {
        const origin = Camera._origin;
        origin.set(x, y, -1);
        this.context.input.convertScreenspaceToRaycastSpace(origin);
        origin.z = -1;
        origin.unproject(this.cam);

        const dir = Camera._direction.set(origin.x, origin.y, origin.z);
        const camPosition = getWorldPosition(this.cam);
        dir.sub(camPosition);
        dir.normalize();
        if (ray) {
            ray.set(camPosition, dir);
            return ray;
        }
        else {
            return new Ray(camPosition.clone(), dir.clone());
        }
    }

So maybe something with the WebAR simulator?

Just tried and get errors about screenPointToRay not existing on 2.47.2-pre

by user 103054507105067008

That’s what I wrote and why I sent you the method too :slightly_smiling_face:

Ah I see, adding that

by user 103054507105067008

Do I add that to the source Camera ICamera script?

by user 103054507105067008

You can or you can just add it as a separate function to your component for testing and replace this.cam with this.context.mainCamera

I’m having trouble migrating that second sample into my test script due to things like camera not having something called _origin and other bits but if it’s landing in the next version I will give it a proper test for sure

by user 103054507105067008

Those are just static vector fields, see the code sample, you can replace them too or even get rid of them for testing and create new vectors :slightly_smiling_face:

Got it down to this but Ray is not defined

private _origin: THREE.Vector3 = new THREE.Vector3(0,0,0);
private _direction: THREE.Vector3 = new THREE.Vector3();
public screenPointToRay(x: number, y: number, ray?: Ray): Ray {
    const origin = this._origin;
    origin.set(x, y, -1);
    this.context.input.convertScreenspaceToRaycastSpace(origin);
    origin.z = -1;
    origin.unproject(this.context.mainCamera);

    const dir = this._direction.set(origin.x, origin.y, origin.z);
    const camPosition = getWorldPosition(this.context.mainCamera);
    dir.sub(camPosition);
    dir.normalize();
    if (ray) {
        ray.set(camPosition, dir);
        return ray;
    }
    else {
        return new Ray(camPosition.clone(), dir.clone());
    }
}

by user 103054507105067008

It’s a threejs type

import { Ray } from threejs

Rays from touches are now drawing! I am not doing a victory dance, thank you!

by user 103054507105067008

I think the reason why the touch events weren’t firing is the this.context.domElement.addEventListener() bit rather than document.addEventListener(), guessing that is a quirk of WebXR? Would be useful if that was documented somewhere as I wouldn’t have guess that

by user 103054507105067008

Btw @ROBYER1 latest release contains the method on the camera!

Thankyou!

by user 103054507105067008

@marcel :cactus: I tried a load of things and still can’t get touch events to fire on iOS in Mozilla WebXR viewer, I documented what I did here, any thoughts on what else I can try?

by user 103054507105067008

Made a new repro, works good on Chrome Android but on iOS Mozilla WebXR no touch events fire in AR. touchstart is subscribed to through this.context.domElement, document and window in all three places just in case and I also use WebXREvent.XRStarted to refresh those event listeners https://rectangular-noble-dentist.glitch.me/

by user 103054507105067008

I got touch events registering on iOS WebXR AR using window.addEventListener, however there is an error with screenPointToRay which is THREE.BufferGeometry.computeBoundingSphere():
https://github.com/needle-tools/needle-engine-support/issues/118#issuecomment-1330869123

by user 103054507105067008