XRReferenceSpace: getOffsetReferenceSpace() method
Limited availability
This feature is not Baseline because it does not work in some of the most widely-used browsers.
Secure context: This feature is available only insecure contexts (HTTPS), in some or allsupporting browsers.
TheXRReferenceSpaceinterface'sgetOffsetReferenceSpace() method returns anew reference space object which describes the relative difference in position betweenthe object on which the method is called and a given point in 3D space. Theobject returned bygetOffsetReferenceSpace() is anXRReferenceSpace if called on anXRReferenceSpace, or anXRBoundedReferenceSpace if called on an object of that type.
In other words, when you have an object in 3D space and need to position another objectrelative to that one, you can callgetOffsetReferenceSpace(), passing intoit the position and orientation you want the second object to haverelative to the position and orientation of the object on which you callgetOffsetReferenceSpace().
Then, when drawing the scene, you can use the offset reference space to not onlyposition objects relative to one another, but to apply the needed transforms to renderobjects properly based upon the viewer's position. This is demonstrated in the exampleImplementing rotation based on non-XR inputs, which demonstrates a way touse this method to let the user use their mouse to pitch and yaw their viewing angle.
In this article
Syntax
getOffsetReferenceSpace(originOffset)Parameters
originOffsetAn
XRRigidTransformspecifying the offset to the origin of the newreference space. These values are added to the position and orientation of the currentreference space and then the result is used as the position and orientation of thenewly createdXRReferenceSpace.
Return value
A newXRReferenceSpace object describing a reference space with the samenative origin as the reference space on which the method was called, but with an originoffset indicating the distance from the object to the point givenbyoriginOffset.
If the object on which you call this method is anXRBoundedReferenceSpace, the returned object is one as well. TheboundsGeometry of the newreference space is set to the original object'sboundsGeometry with each ofits points multiplied by the inverse oforiginOffset.
Examples
Below are some examples showing how to usegetOffsetReferenceSpace().
Teleporting or setting the position of the viewer
Upon first creating a scene, you may need to set the user's position within the 3Dworld. You can do that usinggetOffsetReferenceSpace().
xrSession.requestReferenceSpace("local").then((refSpace) => { xrReferenceSpace = refSpace; xrReferenceSpace = xrReferenceSpace.getOffsetReferenceSpace( new XRRigidTransform(startPosition, { x: 0, y: 0, z: 1.0, w: 1.0 }), ); xrSession.requestAnimationFrame(drawFrame);});In this code, we obtain a local reference space, thenusegetOffsetReferenceSpace() to create a new space whose origin isadjusted to a position given bystartPosition and whose orientation islooking directly along the Z axis. Then the first animation frame is requested usingXRSession'srequestAnimationFrame().
Implementing rotation based on non-XR inputs
The input controls supported directly by WebXR are all dedicated VR or AR inputdevices. In order to use mouse, keyboard, or other input devices to move or otherwisetransform objects in the 3D space—or to allow the user to move through the space—you'llneed to write some code to read the inputs and move perform the movements.
This is another good use case forgetOffsetReferenceSpace(). In thisexample, we'll show code that lets the user look around by right-clicking and moving themouse to change the viewing angle.
First, we add an event handler formousemoveevents, which calls our code to perform the rotation if the right mouse button is down.Note also that we setoncontextmenu up to beignored by callingpreventDefault() on thoseevents. This prevents the right-clicks from causing the context menu from appearing inthe browser.
canvas.oncontextmenu = (event) => { event.preventDefault();};canvas.addEventListener("mousemove", (event) => { if (event.buttons & 2) { rotateViewBy(event.movementX, event.movementY); }});Next, therotateViewBy() function, which updates the mouse lookdirection's yaw and pitch based on the mouse delta values fromthemousemove event. The pitch is restricted so that you can't look beyondstraight up and straight down. Each time this is called, the new offsets are used toupdate the current values ofmousePitch andmouseYaw.
let mouseYaw = 0.0;let mousePitch = 0.0;const inverseOrientation = quat.create();const MOUSE_SPEED = 0.003;function rotateViewBy(dx, dy) { mouseYaw += dx * MOUSE_SPEED; mousePitch += dy * MOUSE_SPEED; if (mousePitch < -Math.PI * 0.5) { mousePitch = -Math.PI * 0.5; } else if (mousePitch > Math.PI * 0.5) { mousePitch = Math.PI * 0.5; }}Finally, we need code that actually applies the computed yaw and pitch to the viewer'sorientation. This function,applyMouseMovement(), handles that:
function applyMouseMovement(refSpace) { if (!mouseYaw && !mousePitch) { return refSpace; } quat.identity(inverseOrientation); quat.rotateX(inverseOrientation, inverseOrientation, -mousePitch); quat.rotateY(inverseOrientation, inverseOrientation, -mouseYaw); let newTransform = new XRRigidTransform( { x: 0, y: 0, z: 0 }, { x: inverseOrientation[0], y: inverseOrientation[1], z: inverseOrientation[2], w: inverseOrientation[3], }, ); return refSpace.getOffsetReferenceSpace(newTransform);}This function creates an inverse orientation matrix—used to orient the viewer—from thecurrent pitch and yaw values, then uses that matrix as the source of the orientationwhen callingXRRigidTransform().The newXRRigidTransform's reference space is then fetched and returnedto the caller.
This new reference space is one in which the viewer's position is unchanged, but theirorientation has been altered based on the pitch and yaw values generated from theaccumulated mouse inputs.applyMouseMovement() should be called whendrawing a frame, immediately before fetching the viewer's pose usinggetViewerPose(), and the rendering should beperformed in this reference space.
You can see code similar to this in use in our broader WebXR tutorial article calledMovement, orientation, and motion. In particular, check out the section calledStarting up the WebXR session.
Specifications
| Specification |
|---|
| WebXR Device API> # dom-xrreferencespace-getoffsetreferencespace> |