Is it possible to manage teleport and physical movement in VR holistically?

I’ve seen, and followed, various ways to teleport in a VR session, including in the official examples. All work nicely, including the official example here.

An increasing number of users have VR headsets with 6 Degrees of Freedom, allowing them to physically move around their local environment. Say a headset viewer does these three things:

  1. Teleports to some point (x1, y, z), say because a controller ray has intersected with the floor at that point.
  2. Then moves in their local area to a new point (x2, y, z).
  3. Then wants to teleport to the intersection (x3, y, z) made by their controller pointing to another place on the floor.

How should this second teleport be computed? If I jump to the actual intersection point (x3, y, z) the teleport will not account for the local movement I made to x2. It doesn’t seem to matter how I jump (eg lerp a rig that has the camera as a child or create a new reference space) the end result is that the physical movement to x2 is never accounted for.

I see that webXR has an experimental feature called getFrame(), which then allows me to getViewerPose, which contains exactly the information I want - i.e. how much the viewer has moved within their local physical space:

         const xrFrame = renderer.xr.getFrame();
         const baseReferenceSpace = renderer.xr.getReferenceSpace();
         const viewerPose = xrFrame.getViewerPose(baseReferenceSpace);
         const physicalViewerMovement = viewerPose.transform.position;

BUT, this is an experimental feature with poor browser support.

Am I missing something? What is the correct way to teleport a VR viewer while accounting for any physical movement made by the viewer, who I can’t assume is always standing/sitting still?

I found the answer using a camera rig and it’s quite simple. I was overcomplicating.

The three.js camera’s world position will reflect any physical movement made by the headset wearer.

Let D be the camera “dolly”, C the three.js Perspective camera and T a target we want to teleport to. We make D a child of C.

When a headset wearer physically moves, their movement is reflected in C.

So to teleport to a point T we need to move D to the new location given by:

D.position + T.position - C.worldPosition

2 Likes

can you show an example? i tried to make my vr camera move around the world but it goes in a straight line no matter how much i move the vr headset.

i followed this tutorial:
https://www.youtube.com/watch?v=mpVG2Iitkqg&t=200s

my code:

I init the scene with this

 createDolly() {
        this.dolly = new THREE.Object3D();
        this.dolly.position.z = 5;

        this.dolly.add(camera);
        scene.add(this.dolly);

        this.dummy = new THREE.Object3D();
        camera.add(this.dummy);

    }

I call this in the animate loop

handleMovement() {
        const quaternionDolly = this.dolly.quaternion.clone();

        const quaternionCam = new THREE.Quaternion();

        this.dummy.getWorldQuaternion(quaternionCam);
        

        this.dolly.quaternion.copy(quaternionCam);
        this.dolly.translateZ(0.025);
        this.dolly.position.y = 0;
        this.dolly.quaternion.copy(quaternionDolly);

    }