Signatur
Beschreibung
Mit getOffsetReferenceSpace() leitest du aus einem bestehenden Referenzraum einen neuen ab, dessen Koordinatenursprung um eine feste Transformation verschoben bzw. gedreht ist. Die Transformation wird als XRRigidTransform übergeben und bezieht sich auf das Koordinatensystem des Referenzraums, auf dem die Methode aufgerufen wird. Der ursprüngliche Referenzraum bleibt dabei unverändert.
Typische Einsätze sind Fortbewegung per Teleport, Drehen per Controller-Stick („snap turning“) und das Verschieben der Szene per Maus oder Tastatur in Inline-Sessions. Statt jedes Objekt der Szene zu verschieben, verschiebst du einfach den Ursprung, von dem aus der Betrachter die Szene sieht. Posen, die du danach mit XRFrame.getViewerPose() oder XRFrame.getPose() abfragst, beziehen den Versatz automatisch mit ein.
Wird die Methode auf einem XRBoundedReferenceSpace aufgerufen, ist das Ergebnis ebenfalls ein XRBoundedReferenceSpace. Dessen boundsGeometry wird entsprechend transformiert. Versätze lassen sich verketten, indem du getOffsetReferenceSpace() auf einem bereits versetzten Raum aufrufst. Dabei summieren sich die Transformationen.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $originOffset Pflicht | XRRigidTransform | Starre Transformation aus position (DOMPointInit) und orientation (Quaternion), die den Ursprung des neuen Raums relativ zum aktuellen Raum festlegt. Achtung: Um den Betrachter um +x zu bewegen, muss der Ursprung um −x verschoben werden. |
Rückgabewert
XRBoundedReferenceSpace, hat auch der Rückgabewert diesen Typ.Beispiele
Teleport: Betrachter an eine Zielposition versetzen
let refSpace; // aktueller Referenzraum der Session
const startXR = async () => {
const session = await navigator.xr.requestSession('immersive-vr');
refSpace = await session.requestReferenceSpace('local-floor');
return session;
};
// Ziel z. B. per Raycast auf den Boden ermittelt
const teleportTo = (x, z) => {
// Ursprung entgegengesetzt verschieben, damit der Betrachter nach (x, 0, z) wandert
const offset = new XRRigidTransform({ x: -x, y: 0, z: -z });
refSpace = refSpace.getOffsetReferenceSpace(offset);
console.log('Teleportiert nach', x, z);
};
Snap-Turn: um 45° um die Y-Achse drehen
const snapTurn = (refSpace, degrees) => {
const rad = (degrees * Math.PI) / 180;
// Quaternion für Rotation um die Y-Achse
const orientation = {
x: 0,
y: Math.sin(rad / 2),
z: 0,
w: Math.cos(rad / 2)
};
const offset = new XRRigidTransform({ x: 0, y: 0, z: 0 }, orientation);
return refSpace.getOffsetReferenceSpace(offset);
};
// im Controller-Handler
refSpace = snapTurn(refSpace, 45);
Versatz im Render-Loop verwenden
const onXRFrame = (time, frame) => {
const session = frame.session;
session.requestAnimationFrame(onXRFrame);
// refSpace wurde ggf. vorher per getOffsetReferenceSpace() ersetzt
const pose = frame.getViewerPose(refSpace);
if (!pose) return;
const { x, y, z } = pose.transform.position;
console.log(`Betrachter: ${x.toFixed(2)}, ${y.toFixed(2)}, ${z.toFixed(2)}`);
};
// Wichtig · Fallstricke
- Vorzeichen-Falle: Der Versatz beschreibt den neuen Ursprung, nicht den Betrachter. Für eine Bewegung des Nutzers nach vorn muss der Ursprung entgegengesetzt verschoben werden. Alternativ kannst du
transform.inverseverwenden. - Die Methode liefert immer ein neues Objekt. Du musst die Variable, die du für
getViewerPose()nutzt, selbst ersetzen, sonst hat der Versatz keine Wirkung. - Bei häufigem Verketten (z. B. jede Frame-Bewegung) sammeln sich Rundungsfehler an. Speichere deshalb besser die Gesamtposition selbst und leite den Raum jedes Mal neu vom ursprünglichen Basisraum ab.
- Listener für das
reset-Ereignis gelten nur für das Objekt, auf dem sie registriert wurden. Neue, versetzte Räume brauchen bei Bedarf eigene Listener. - Kompatibilität: WebXR ist nur in einem sicheren Kontext (HTTPS) verfügbar. Unterstützt wird es in Chromium-Browsern und im Meta Quest Browser, nicht in Firefox. In Safari ist es nur auf visionOS verfügbar. Prüfe vorab mit
navigator.xr?.isSessionSupported(), ob die gewünschte Session möglich ist.