Skip to content

WebXRManager - Allow changing/setting the reference space #19615

@dbuck

Description

@dbuck
Description of the problem

As a dev, I'd like to align the XR view to an arbitrary space. It would help to be able to set an offset reference space for the WebXRManager, to be used when reading the getViewerPose and getPose from the XRFrame.

Proposing:

// add an override reference space to use for reading XR poses
renderer.xr.setOffsetReferenceSpace(space: XRReferenceSpace);

// reset to the initial reference space
renderer.xr.resetReferenceSpace();

WebXRManager.onAnimationFrame : if there is an offsetReferenceSpace set, prefer that space while reading the poses for the player/controllers during the onAnimationFrame

frame.getViewerPose(offsetReferenceSpace || referenceSpace)
frame.getPose(offsetReferenceSpace || referenceSpace)

Usage:

// Shift to an arbitrary position/alignment!

// From the base tracking space.
const baseReferenceSpace: XRReferenceSpace = renderer.xr.getReferenceSpace();

// offset the rotation by 30 degress
const playerRotation = new Quaternion().setFromAxisAngle(new Vector3(0, 1, 0), MathUtils.DEG2RAD * 30);
const offsetRotation = { x: playerRotation.x, y: playerRotation.y, z: playerRotation.z, w: playerRotation.w };

// offset the tracking to center on our player
const playerPosition = new Vector3(100, 1, 30);
const offsetPosition = { x: playerPosition.x, y: playerPosition.y, z: playerPosition.z, w: 1 };

const transform = new XRRigidTransform(offsetPosition, offsetRotation);
const viewerSpace = baseReferenceSpace.getOffsetReferenceSpace(transform);

renderer.xr.setOffsetReferenceSpace(viewerSpace);

This will enable use of the native webxr XRRigidTransform and XRReferenceSpace for locomotion/movement without requiring the controllers + cameras conform to a specific hierarchy with the camera.parent to be placed at the guess of the floor location.

The controllers already support alternate reference frames now by way of the WebXRController.update(inputSource, frame, referenceSpace) call, which is great, however without a way to set a referenceSpace on the WebXRManager:
1: It only has a visible effect on the view if done in the scene.onBeforeRender (?)
2: Shifting the controllers to a custom reference space duplicates the updates for everything in that hierarchy, which was more perf impactful than I'd imagined when using the XRControllerModelFactory controllers attached.

Note: It is technically possible to use XRTransforms/XRReferenceSpace style currently, but requires a lot of ugly workarounds and intimate knowledge of what WebGLRenderer/WebXRManager is doing and when.

  • Noticing that the WebXRManager onAnimationFrameCallback includes the XRFrame in the callback, and storing/referencing the XRFrame in your setAnimationLoop.
  • Inserting a callback into scene.onBeforeRender to read the frame.getViewerPose(myCustomReferenceSpace), and apply to the cameras.
  • very fragile!

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions