Error in event handler of controller in three.js webxr

I am trying to learn webxr and basic concept of it.

For it, I am doing this:


function buildControllers() {
    const controllerModelFactory = new XRControllerModelFactory()
    const controllers: Array<any> = []

    const rayGeometry = new BufferGeometry().setFromPoints([
        new THREE.Vector3(0, 0, 0),
        new THREE.Vector3(0, 0, -1),
    ])
    const line = new Line(rayGeometry)
    line.scale.z = 10

    for (let i = 0; i < 2; i++) {
        const _controller = renderer.xr.getController(i)
        _controller.name = 'controller' + (i + 1)
        _controller.userData.selectPressed = false
        _controller.userData.selectPressedPrev = false
        // add ray in it
        scene.add(_controller)
        controllers.push(_controller)
        const grip = renderer.xr.getControllerGrip(i)
        grip.add(controllerModelFactory.createControllerModel(grip))
        scene.add(grip)
    }
    return controllers
}

function selectStartHandler() {
    ;(this as THREE.XRTargetRaySpace).children[0].scale.z = 10
    :(this as THREE.XRTargetRaySpace).userData.selectPressed = true
}

function selectEndHandler() {
    this.children[0].scale.z = 0
    this.userData.selectPressed = false
}
function initVR() {
    controllers = buildControllers()
    controllers.forEach(function (controller, index) {
        controller.addEventListener('selectstart', selectStartHandler)
        controller.addEventListener('selectend', selectEndHandler)
    })
}

initVR()

and I am getting this error:

and when i hover over it show its this:

i thought it might be because of ts

type in this

;(this as THREE.XRTargetRaySpace).children[0].scale.z = 10

PS: My code is in ts file.

what can i do to get rid of this?

Thank you

selectStart and selectEnd handlers should take an event parameter. Try adding that and printing to the console. You’ll probably find what you’re looking for in the event context.

function selectStartHandler(e: any) {
console.log(e);
}

Another option is to wrap the functions into a class so there is a this.

Oh yeah,

Thank you so much !! It worked !!

But now my webxr camera is not at position of camera given in three.js perspective camera used in render function !!

I found somewhere that the way to make webxr camera appear in same position in the camera is this so I added this in the animate function

const xrManager = renderer.xr
let firstTime = true
function animate(now: number) {
    let delta = clock.getDelta()
    delta = Math.max(delta, 0.1)
    world.step(delta)
    if (ballAdded) {
        balls.forEach((element, index) => {
            element.position.set(
                ballBodies[index].position.x,
                ballBodies[index].position.y,
                ballBodies[index].position.z
            )
        })
    }
    if (orbitControls.enabled) {
        orbitControls.update()
    }
    

    cannonDebugRenderer.update()
    TWEEN.update()
    KeyBoardHandler.keyUpdate(handlers, keys, delta * 1000)
    if (character) {
        character.position.copy(camera.position)
    }
    
    if (xrManager.isPresenting && firstTime) {
        firstTime = false
        const baseReferenceSpace = xrManager.getReferenceSpace(),
            offsetPosition = camera!.position,
            offsetRotation = camera!.rotation
        console.log(baseReferenceSpace)
        const transform = new XRRigidTransform(
                { x: offsetPosition.x, y: offsetPosition.y, z: offsetPosition.z, w: 1 },
                {
                    x: offsetRotation.x,
                    y: -1 * offsetRotation.y,
                    z: offsetRotation.z,
                    w: 1,
                }
            ),
            //const transform = new XRRigidTransform( offsetPosition, { x: offsetRotation.x, y: -(offsetRotation.y - 0.5) , z: offsetRotation.z, w: offsetRotation.w } ),
            teleportSpaceOffset = baseReferenceSpace!.getOffsetReferenceSpace(transform)

        xrManager.setReferenceSpace(teleportSpaceOffset)
    }
    updateControllerAction()
    render(delta)
}

but the problem is that camera scene is this:

but after adding that code camera render this:

I guess this is either outside of my mesh

when i go out without VR mode, this is my mesh outside

after changing camera position to somewhere and positioning VR headset in webxr emulator for so many time,

I managed to get this manually

Is there anyway i can have webxr camera at the camera position !!!

Thank you again for helping me, i am feeling little lost in webxr but progressing !!

As you’ve discovered when Web XR activates, the camera is moved into XR space.

The trick is to move XR space to where the three camera is. You can do this by

group = new Group();
scene.add(group);
  
//attach VR camera to group and move group to player start
group.add(camera);
position.y = 0;
group.position.copy(position);
group.rotation.copy(rotation);

// https://developer.mozilla.org/en-US/docs/web/api/xrsession/requestreferencespace#return_value
gl.xr.setReferenceSpaceType('local-floor');

scene.remove(group);

This is how the rollercoaster example works

Thank you,

I got this as an output now:

after adding two controllers in that group as well

but when i drag this headset in emulator it does not move the controller with it.

And, is this right place for controller to appear in the scene because for me it looks like little high even for position of (0, 0, 0) set for camera group