XRRigidTransform and getOffsetReferenceSpace: rotation makes given position change

Hello,

I have been trying several configurations for a while now, but I cannot figure out how to reach what I need and why I get the current results.

Before entering the VR session, I need to place my camera at a certain location, with a certain rotation.

For the location only, I was using this, and it worked very well:

const offsetPosition = { x: -position.x, y: -position.y, z: -position.z, w: 1 };

const offsetRotation = new THREE.Quaternion(); // no rotation

const transform = new XRRigidTransform(offsetPosition, offsetRotation);
const teleportSpaceOffset = this.baseReferenceSpace.getOffsetReferenceSpace(transform);
this.parentRenderer.xr.setReferenceSpace(teleportSpaceOffset);

But now, I want to have the rotation too. I tried this:

const offsetPosition = { x: -position.x, y: -position.y, z: -position.z, w: 1 };

const offsetRotation = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0, 1, 0), THREE.MathUtils.DEG2RAD * 90); // 90 degrees rotation

const transform = new XRRigidTransform(offsetPosition, offsetRotation);
const teleportSpaceOffset = this.baseReferenceSpace.getOffsetReferenceSpace(transform);
this.parentRenderer.xr.setReferenceSpace(teleportSpaceOffset);

But with this very small difference, my camera is indeed rotated the expected way, but the position is totally wrong from the one I had given in “offsetPosition”.

From what I read here on Mozilla Doc, XRRigidTransform should be applying the rotation and then, after, the translation. So, I think the code above should be fine.

What do I do wrong?
And also, why do I need to invert my position? (is it because THREE and the XR standards use different axes systems?)

1 Like

I’m having the same problem, have you found the solution yet?
Much appreciated if anyone can give idea to solve this

Hello,

No, I have not found a solution yet. At least, not with all this stuff.

I am currently using a workaround?? that seems to work well.
I am using a Group to encapsulate the PerspectiveCamera, and then I can modify the group’s position and rotation. Please have a look to my (simplified) code below.

If you use a PerspectiveCamera, you can make some modifications on it when entering XR. I tried with OrthographicCamera, it does not work (or I did something wrong, maybe).

// Event when XR session has started
this.renderer.xr.addEventListener('sessionstart', () => {
  if (this.renderer.xr.getReferenceSpace() != null) {
    this.teleportVrCameraToWorldPosition(this.vrStartPosition);
  }
});

// -------------------

private teleportVrCameraToWorldPosition(position: THREE.Vector3) {
  this.cameraGroup.position.copy(position);

  // Watch in a certain direction by default
  const lookAtTargetPosition = new THREE.Vector3().copy(this.vrTargetPosition);
  lookAtTargetPosition.y = this.cameraGroup.position.y; // Keep eyes height

  this.cameraGroup.lookAt(lookAtTargetPosition);
  this.cameraGroup.rotateOnAxis(new THREE.Vector3(0, 1, 0), THREE.MathUtils.DEG2RAD * 180);
}
1 Like